From 5ad51c36fb5bc0d3055977409512e099a0e79a38 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 5 Mar 2001 03:43:10 +0000 Subject: [PATCH 0001/1042] Turned off "enable minimal rebuild", which causes INTERNAL COMPILER ERRORs [SVN r9437] --- build/bpl_static.dsp | 4 ++-- build/example1/example1.dsp | 4 ++-- build/rwgk1/rwgk1.dsp | 4 ++-- build/test/test.dsp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/bpl_static.dsp b/build/bpl_static.dsp index 92af59c7..ca70236d 100644 --- a/build/bpl_static.dsp +++ b/build/bpl_static.dsp @@ -65,7 +65,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W4 /WX /Gm- /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -88,7 +88,7 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "DebugPython" # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /EHs /c +# ADD CPP /nologo /MDd /W4 /WX /Gm- /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /EHs /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe diff --git a/build/example1/example1.dsp b/build/example1/example1.dsp index dcff3f55..4d95aa97 100644 --- a/build/example1/example1.dsp +++ b/build/example1/example1.dsp @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" @@ -97,7 +97,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /EHs /c +# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /EHs /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" diff --git a/build/rwgk1/rwgk1.dsp b/build/rwgk1/rwgk1.dsp index daf736b3..67476984 100644 --- a/build/rwgk1/rwgk1.dsp +++ b/build/rwgk1/rwgk1.dsp @@ -69,7 +69,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm- /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" @@ -96,7 +96,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm- /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" diff --git a/build/test/test.dsp b/build/test/test.dsp index 0816bf1e..4bd2822a 100644 --- a/build/test/test.dsp +++ b/build/test/test.dsp @@ -71,7 +71,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c +# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c # SUBTRACT CPP /Fr # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 @@ -100,7 +100,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c -# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /Zm200 /EHs /c +# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /Zm200 /EHs /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" From 7d29c6a0f79680e5a0512b396dc4c0691a2a5482 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 5 Mar 2001 03:44:46 +0000 Subject: [PATCH 0002/1042] tests for null pointer <=> None conversions [SVN r9438] --- test/comprehensive.cpp | 24 +++++++++++++++++++++++- test/comprehensive.py | 15 +++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 57edd687..3d173310 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -242,6 +242,23 @@ boost::shared_ptr Baz::create_foo() return boost::shared_ptr(new DerivedFromFoo(0)); } +// Used to check conversion to None +boost::shared_ptr foo_factory(bool create) +{ + return boost::shared_ptr(create ? new DerivedFromFoo(0) : 0); +} + +// Used to check conversion from None +bool foo_ptr_is_null(Foo* p) +{ + return p == 0; +} + +bool foo_shared_ptr_is_null(boost::shared_ptr p) +{ + return p.get() == 0; +} + // We can accept smart pointer parameters int Baz::get_foo_value(boost::shared_ptr foo) { @@ -408,7 +425,7 @@ static int testUpcast(Base* b) static std::auto_ptr derived1Factory(int i) { - return std::auto_ptr(new Derived1(i)); + return std::auto_ptr(i < 0 ? 0 : new Derived1(i)); } static std::auto_ptr derived2Factory(int i) @@ -1081,6 +1098,11 @@ void init_module(boost::python::module_builder& m) m.def(fpolar, "fpolar"); m.def(freal, "freal"); m.def(fimag, "fimag"); + + // Test new null-pointer<->None conversions + m.def(foo_factory, "foo_factory"); + m.def(foo_ptr_is_null, "foo_ptr_is_null"); + m.def(foo_shared_ptr_is_null, "foo_shared_ptr_is_null"); } PyObject* raw(const boost::python::tuple& args, const boost::python::dictionary& keywords) diff --git a/test/comprehensive.py b/test/comprehensive.py index c8033575..c1424d25 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -73,6 +73,21 @@ We can subclass Foo. >>> b.call_pure() 'not pure anymore!' +None corresponds to a NULL pointer or smart pointer + >>> f = foo_factory(1) + >>> f.add_len('xxx') + 1000 + >>> foo_factory(0) is None + 1 + >>> foo_ptr_is_null(None) + 1 + >>> foo_ptr_is_null(f) + 0 + >>> foo_shared_ptr_is_null(None) + 1 + >>> foo_shared_ptr_is_null(f) + 0 + If no __init__ function is defined, the one from the base class takes effect, just like in a Python class. From a559a371b1c839e7189afa3aa7c8b8da9890d17e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 5 Mar 2001 03:48:38 +0000 Subject: [PATCH 0003/1042] enable null pointer <=> None conversions [SVN r9439] --- .../boost/python/detail/extension_class.hpp | 82 +++++++++++++++---- src/gen_extclass.py | 82 +++++++++++++++---- 2 files changed, 130 insertions(+), 34 deletions(-) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index bf43ec5c..987d753e 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -22,6 +22,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -133,6 +134,26 @@ class class_registry static std::vector static_derived_class_info; }; +template +struct is_null_helper +{ + template + static bool test(Ptr x) { return x == 0; } +}; + +template <> +struct is_null_helper +{ + template + static bool test(const Ptr& x) { return x.get() == 0; } +}; + +template +bool is_null(const Ptr& x) +{ + return is_null_helper<(is_pointer::value)>::test(x); +}; + }}} // namespace boost::python::detail BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE @@ -178,9 +199,9 @@ class python_extension_class_converters new boost::python::detail::instance_value_holder(result.get(), x))); return result.release(); } - - // Convert to T* - friend T* from_python(PyObject* obj, boost::python::type) + + friend + T* non_null_from_python(PyObject* obj, boost::python::type) { // downcast to an extension_instance, then find the actual T boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); @@ -201,9 +222,18 @@ class python_extension_class_converters throw boost::python::argument_error(); } - // Convert to PtrType, where PtrType can be dereferenced to obtain a T. + // Convert to T* + friend T* from_python(PyObject* obj, boost::python::type) + { + if (obj == Py_None) + return 0; + else + return non_null_from_python(obj, boost::python::type()); + } + + // Extract from obj a mutable reference to the PtrType object which is holding a T. template - static PtrType& ptr_from_python(PyObject* obj, boost::python::type) + static PtrType& smart_ptr_reference(PyObject* obj, boost::python::type) { // downcast to an extension_instance, then find the actual T boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); @@ -220,9 +250,27 @@ class python_extension_class_converters throw boost::python::argument_error(); } + // Extract from obj a constant reference to the PtrType object which is holding a T. + // If obj is None, the reference denotes a default-constructed PtrType template - static PyObject* ptr_to_python(PtrType x) + static const PtrType& smart_ptr_value(PyObject* obj, boost::python::type) { + if (obj == Py_None) + { + static PtrType null_ptr; + return null_ptr; + } + return smart_ptr_reference(obj, boost::python::type()); + } + + template + static PyObject* smart_ptr_to_python(PtrType x) + { + if (boost::python::detail::is_null(x)) + { + return boost::python::detail::none(); + } + boost::python::reference result(create_instance()); result->add_implementation( std::auto_ptr( @@ -254,7 +302,7 @@ class python_extension_class_converters // Convert to T& friend T& from_python(PyObject* p, boost::python::type) - { return *boost::python::detail::check_non_null(from_python(p, boost::python::type())); } + { return *boost::python::detail::check_non_null(non_null_from_python(p, boost::python::type())); } // Convert to const T& friend const T& from_python(PyObject* p, boost::python::type) @@ -265,28 +313,28 @@ class python_extension_class_converters { return from_python(p, boost::python::type()); } friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_reference(p, boost::python::type >()); } - friend std::auto_ptr& from_python(PyObject* p, boost::python::type >) - { return ptr_from_python(p, boost::python::type >()); } + friend const std::auto_ptr& from_python(PyObject* p, boost::python::type >) + { return smart_ptr_value(p, boost::python::type >()); } friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_value(p, boost::python::type >()); } friend PyObject* to_python(std::auto_ptr x) - { return ptr_to_python(x); } + { return smart_ptr_to_python(x); } friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_reference(p, boost::python::type >()); } - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type >) - { return ptr_from_python(p, boost::python::type >()); } + friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type >) + { return smart_ptr_value(p, boost::python::type >()); } friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_value(p, boost::python::type >()); } friend PyObject* to_python(boost::shared_ptr x) - { return ptr_to_python(x); } + { return smart_ptr_to_python(x); } }; // Convert T to_python, instantiated on demand and only if there isn't a diff --git a/src/gen_extclass.py b/src/gen_extclass.py index 7c378d45..2d261289 100644 --- a/src/gen_extclass.py +++ b/src/gen_extclass.py @@ -27,6 +27,7 @@ def gen_extclass(args): # include # include # include +# include namespace boost { namespace python { @@ -138,6 +139,26 @@ class class_registry static std::vector static_derived_class_info; }; +template +struct is_null_helper +{ + template + static bool test(Ptr x) { return x == 0; } +}; + +template <> +struct is_null_helper +{ + template + static bool test(const Ptr& x) { return x.get() == 0; } +}; + +template +bool is_null(const Ptr& x) +{ + return is_null_helper<(is_pointer::value)>::test(x); +}; + }}} // namespace boost::python::detail BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE @@ -183,9 +204,9 @@ class python_extension_class_converters new boost::python::detail::instance_value_holder(result.get(), x))); return result.release(); } - - // Convert to T* - friend T* from_python(PyObject* obj, boost::python::type) + + friend + T* non_null_from_python(PyObject* obj, boost::python::type) { // downcast to an extension_instance, then find the actual T boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); @@ -206,9 +227,18 @@ class python_extension_class_converters throw boost::python::argument_error(); } - // Convert to PtrType, where PtrType can be dereferenced to obtain a T. + // Convert to T* + friend T* from_python(PyObject* obj, boost::python::type) + { + if (obj == Py_None) + return 0; + else + return non_null_from_python(obj, boost::python::type()); + } + + // Extract from obj a mutable reference to the PtrType object which is holding a T. template - static PtrType& ptr_from_python(PyObject* obj, boost::python::type) + static PtrType& smart_ptr_reference(PyObject* obj, boost::python::type) { // downcast to an extension_instance, then find the actual T boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); @@ -225,9 +255,27 @@ class python_extension_class_converters throw boost::python::argument_error(); } + // Extract from obj a constant reference to the PtrType object which is holding a T. + // If obj is None, the reference denotes a default-constructed PtrType template - static PyObject* ptr_to_python(PtrType x) + static const PtrType& smart_ptr_value(PyObject* obj, boost::python::type) { + if (obj == Py_None) + { + static PtrType null_ptr; + return null_ptr; + } + return smart_ptr_reference(obj, boost::python::type()); + } + + template + static PyObject* smart_ptr_to_python(PtrType x) + { + if (boost::python::detail::is_null(x)) + { + return boost::python::detail::none(); + } + boost::python::reference result(create_instance()); result->add_implementation( std::auto_ptr( @@ -259,7 +307,7 @@ class python_extension_class_converters // Convert to T& friend T& from_python(PyObject* p, boost::python::type) - { return *boost::python::detail::check_non_null(from_python(p, boost::python::type())); } + { return *boost::python::detail::check_non_null(non_null_from_python(p, boost::python::type())); } // Convert to const T& friend const T& from_python(PyObject* p, boost::python::type) @@ -270,28 +318,28 @@ class python_extension_class_converters { return from_python(p, boost::python::type()); } friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_reference(p, boost::python::type >()); } - friend std::auto_ptr& from_python(PyObject* p, boost::python::type >) - { return ptr_from_python(p, boost::python::type >()); } + friend const std::auto_ptr& from_python(PyObject* p, boost::python::type >) + { return smart_ptr_value(p, boost::python::type >()); } friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_value(p, boost::python::type >()); } friend PyObject* to_python(std::auto_ptr x) - { return ptr_to_python(x); } + { return smart_ptr_to_python(x); } friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_reference(p, boost::python::type >()); } - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type >) - { return ptr_from_python(p, boost::python::type >()); } + friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type >) + { return smart_ptr_value(p, boost::python::type >()); } friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return ptr_from_python(p, boost::python::type >()); } + { return smart_ptr_value(p, boost::python::type >()); } friend PyObject* to_python(boost::shared_ptr x) - { return ptr_to_python(x); } + { return smart_ptr_to_python(x); } }; // Convert T to_python, instantiated on demand and only if there isn't a From 1edec9ff89141b4624e8824f7b806369d70c8fe1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 5 Mar 2001 14:41:57 +0000 Subject: [PATCH 0004/1042] no message [SVN r9443] --- build/build.opt | Bin 80384 -> 86528 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/build/build.opt b/build/build.opt index 9cdea95b7eef30bf876fd69fc7e9971cd8f4a6f9..5086795feff7997de1d0b50d82b2404da330c819 100644 GIT binary patch literal 86528 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;!F$-42&?o00YCn|NsAkxG);Tu3%tb_&*AU zObGn_|Np-N0|Nsy0|NsK0|Nsq0|PkD*%=rZI2afhI2jlixEL51xEUbv&C9^Rz{kMA zz|X+IAi%)DAjrVLAjH7HAk4tPAi}`FAPQ9{&cMJR!N9;E$-uxM#lXNI&A`AQ!@$5G z%fP@O$H2fK4^`*Sz`&ryz`&r)z`&rwz`&r&z`&r!z`&r+z`&rvz`&r%z`&pdRjb3m zz@W>(z@W##z@X2-z+k|@z+lM0z+l9{z+lY4z+eJZXU4$5V9vn6V8Ot^V9CJ1V8y_| zV9mh5V8g(`V9UV3V8_6~V9&t7;K0DZ;K;zh-~`p@!oa}b%D}+j#=yYf&cMLn!N9=a z$-uzi#lXPe&A`Cm!@$7c%fP_k2UXw9z`zj5z`zj1z`zj9z`zi~z`zj7z`zj3z`zjB zz`zi}z`zj6z`zj2z`zg<)f3CWz!1m4z!1;Cz>vVez>vtmz>vhiz>v(qz>vbgz>vzo zz>vnkz>vvYfz>vwnz>vkjz>v+rz>vehz>o_yC!c|Vp@4ybp^$-rp@@Njp_qYz zp@e~fp_GAvp^Slnp&Y6X6u(sr3=Gu_3=B043=Fjl3=DM)3=H)Q3=9omx92nDGn6nW zFt{@0F_bVAF;s%GG0|9zffb(Lk;@8f1}MDhZ&P1-fDyU82xrJ=C}PNFC}t>NNMuN6 zNM%r92xcf@NMtAhhXposki`@jm>5Bs4U|4XG_o8nHmDo}CsuIW7ct~Blrt1Fq=Lf{ zmmXZ=0t`%ypu7XhE5zE*12PPhS-|Nng&~un1RM$=VNx+40}~@Ce}e1=VPf=)ffPaQ zXJlXn=X;it)Z!8iXRDZ`{QTmQn4HX{;+TTUl8pSkn55FooRk=lJebf+DJ}rj0$fQ2 zIq}6Mi6xoInt1dfRKYZ|7L})G8*1Uv16B|NCSjU5QY#X33vyBo4e;oLsfmFxV7fu& z8Z(0=0}}&N5vYa&;cJWx41A0X3}#FW4BJ2<0>z+E1YuJq28NxCkdl#+fuR8;whOAB zxq&k%H9fPqB(QB7&j>2DL2QtZKw${NfBygf|MLI; z{~$RK-p|CqFbx#e4V>ZmMcKs#iOH#EoS;BrW?*GtWDqC@nFxwCSh${rhAqfsQ2zV( z|9?HmKe;G1H4l`#K_-B_%Ul8~lR+`52(2SQW`Qu+MGd@Q+ZB8> z^D>=@z$s+&Q9&Cc-u zKV#`xGyt+0gdw(b1f>?|mlh?bLNtN0+W-H|1T?X^WG3e1r^|!Gor!^&;s1XYtXg1h z1(){F5G#d;7>9FyUP)1YPBAFBKn)*|L9C?)po9pjl0k(6)YC`~b}vdS$jD4C7G(sr zmRP{Hvw<~%6jd=XFnBRS>VFU)2*TY)lv<14B6z z1H)-XNRtBHm?I1f3{BAH26F>vNNPoiLP&mojyMa*L68vSD4hg#xdsyh!wG0cftkeI zz~Y*cSpo}kCQ$8-HT)17SY1++O4H52Ar5NM{r}HUwulkZ=4)kww2eTjVIdAmqqYnT z4O1Bz7$(C*oXx2yzq~jV)c67=PmsloWoYT+EXWuT1_d2+18ZPuYEdPqsR+^`3(CLc z_;m=lB$gy5B^IYDxMU`#7bWH*Yi1;%nKdLaDJKp3*%;gr0kVa)E zBczcB@(~C_e8m!$nOcr)3k#^R29kqgkYW%92{1SC1%q>m0yN3OLJ(Xq5^x|}P-=31 zQ3}j935Ngw69{PG49~1eEJ|@oEHZ+|I1j`B{~hHMnHU&AF*<>nf#EAOfg#8Epa1{s zGng0{BAFni(t|hsjQ{^LGH@_ByW}Tlhv%g*GRUwnH2nJizaA9%utF8mhm-=f%E5Ik z0|RT3BttQ%RR?OMf`Wj7f#JoR4o2k$CQ$#g;V0CDzu+<-s(_&a)E}*fmk1H+6W1_q^K28OA{3=Fy@3=9S(3=D=P3=E|u3=ES>7#P-;Ffgny zVPM!^!oYB^gn@yjl!1Z0l!1Yxlz}0vl!2kDl!0MFDFefiQU-=&r3?(`N*Ng5mNGDW zC}m*ySjxcQSjNE6TE@U|v5bL1qMU&trksIcWjO=GnQ{h(kL3&uIu#5IdKC-|W)%z! zu@wvqy%h`$eH9E02P+sDu2nEFysKbf(5Pf!aI9otNUmgHSW?NraIlhr;cX=YgJ~55 zLs%69Lr)b0!)<5>&7qosVOliIMdeoec~OyFeYgMg|70Mg|7$Mg|7cMg|7Y zMg|6-Mg|7oMh1r2jSLL88yOgsniv?on-~~6niv?mniv=+H!(2mYhqw{+{D1}q=|t+ zvYCNFu9<-$rI~@DznOtyW-|lBnq~%u_00?n8=4syZZ|V9+-+uHc-G9oAkxCXpx?s4 zVA8_CP}{=5P}jo1u)BqU;dKiGgJ3HIgLEqcgMBLlgHtO5gL5kbgIg;DLv||zLtZNb zLw+j*Lw73!!T43AqG7zElF7=+pw7=+sx81&m17&6)z7&_Y+7`odS7oeT`$I~f>QyBHYQyBHWax)>N#x)>Pzx)>M& zx)>PhyBHW6yBHXnx)>Oyb}=yA>0)5G*Tujf-Oa$@*v-HY*Ui9?(9OV**v-ID(#^oI zx0``se>VdIQx5}!Mh^o+a1R4RK@S5%Q4a${aSsDSTMq-nnH~m)b3F_U-+LGse)cdh z{OVy~;O%8#i0oxxi0)-zXzyiU=Q+;FgpJCe{}qBbo_60{BLypZ*=@` zbo>w6JQ$@0Q3(8pj{k8eq_f;e0CoEZk>f_4G8zJ-Awbg*;9y{8@b&TXVPfD6Ni8mM zE-flcRdlh6DK1KmNh~fXOEv>hp(U9)Fj_CUpkOO#xg%)hZ$N5MT7FS(VqS8pf{{W% zeo+Zw&AOn45+F|{_?fbS)*1gu&}DnhzyO+=XZXAaJR->elLM&(VbH+dS3GjR@yPu{ zlLOf&zzDIAWiP6IAUQ#(92*unA*dWT7P%KtKM0`7f!q(mAU}xWk(0t92O4dWMUw-$ zlNIU~Y;wX-IVCLmM4*cZRj|mh;gMs9nu)Ftu$Z6w|)4?NW zh(it(W+rHIpfKZr`T?69%$??F`at3!4Dy5M`=8~YC4e_rY{6+4Bo4wLIcYp{N;u>| zdX@3Wf#gT=Xb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S0iBLx1lLe~FPFzPdmj{i|3 zL`TgS4S}H(0@(Inhcjd{ecgC|2CLmC5UuRBN|Hmm{N{|&Mmgt4hX7t;m_K=(g; zG6XPqGQ=|^F%*DpEQanq&jjzt2PwplwAhj4-g2OE{Cl#Sb9=>^3K^?qnT-{2+M4_N4KPxr4M59HEaR{JT3Q+?g(R{-&I{wQ5 zABP8xosN$GGBAve{}L{fMpcZ4z-S1JhQMeDjE2By2#kinXb6mkz-R~z&JY+K{~et1 zGU}?)5THj0IL?6_9426smtUfg3^^1nCpE=RBpJ(DkPMKqLShv|PI@F(HT;N23=JGG zw=gguojM5`KO7zZ1D&ahwq6l5RyVr-lYs%-8qd-7pY$kIM(r34fzc2c4S~@R7!85Z z5Eu=C(GVC7fzc2cj3F>O{x=w7Wzu z0~aK;-HY-|3!o}kIYeB%!ci7L;!($(l3KvXAj076l3I|Omy(*7T z=jNxB=A`0N#g&|&mzJ51-%1Y1NB@t>!6L$*dNy$tmB7iwEa|`l|O7L06lbfGXTv|X#8GB}O zD*mLwnM~OC{H1xB$@wWnWMPhiNQPIs?l$e)Jgw1@psU;ctDTF=4 zm6%jqQk0mCH+Z>0DpHdY2_)U*{JgT%qTDAW0i6LX0xhae3$WD?Zg8^xm`Fd71*Auv!OFgpG>P$55R?`Q}Nd{0*PL6oYAjhXFWPL5d(VpCFICVTIhV4q^{s zUqhk}3v$^DRt@wt2|6e}z}cxZGbaU_KI2nhDfA61 zH#oW>xd`M*M94sAK+&g{ab_A&fq)}5fu!&TG)Mu|K59=a^97|ALvE)BP3sopnSw^z zxx>gH1ewrIO)f!9NJCvn%^7IOXe-esLX<D&7#J9M85kIdwLb=Ayb6dw*bm{6PI56Yf$as^4Z_5j zkOxu(J%8SrA%`K6p_rkVA&eoDA(f$=L4kq9^Y=-%zY@uQ*!+(qf!SpEQDuq$2&+JL(d<{s*?_6KR}!bpID<6D(4IjPCzJ z3y{(MUzJG7V|4!)V%BeT{}+4$baek0sGTy3M?+vV1cqV=jL!cI#aJ74^JoZACj>_4 zf2b3Vqo$08z)%bU*!aH$Xy6-l3>&g)odYC+KKhSSwFpQx+!&;>f5ryTEy18cRKyrD z!2xo_h&yBexd(MlASpk;xFjC3HzXcpF^Tg7pmT(ZQZrKXiZjbntrbwXh|zx?1$ABB zq@w)n)I8n9(vp1Lf|4T4jUGZE`{5o3&jElu3-LC{^+b3UGV%^m{E~Ihc@+|EAU`2S z!Eq)7kTQtZL9ADx%b^(tp}#;*dc(@Arw@)VNO}i}QF~edYpwv57FbdZNEm0hf+R=h z1dtCCL?7|zCGyxi;!h;w0iDAHImip&fk&jCLPzYmQ$!zRMdHClM4nqmR02-qFE2_gfHs-%JCFE*Z6eR4B<^rlBF?}h_ViF< zXKaW)p^)%iCr;3zbOd66*fUzNS%AtRJ#hK}Oi6x~)1d}g>myZBDIB$IJ>rEG4e$CI0M8Vo!%9 zYSSk%CkqpK3MXlYOT&(q#+PG>If0m*U3*kKla}~HJ&9bs!c&w8s<%Ps+~Nxw>sO)G64A&5Vt^bi>KsuihbR{I(o=u0 z2g;-=R19MV3@VN^g9a5ro4J6Bq7U*yh2bOXP(E~?1t7Jo1>U?|5p z!jb_wEI`YaSiw7dsbv}qXsHkb10y3w5DS8)E#NDX^sxJnkpWFv1|&WRdjoxcItv2> z1K2T0Q4jGdJOuy$XJCMwX*;_9CkERwub`ZOSP%tWn}fbBcy#>_-R>M6UH?Pm#bu-G ze-Qf_QK~Y$7uJrh|A7{9qw9a5MH)HBuOkuK$5%u+jBDm>Fzz z{ZBITkp!dbe{kI^Kf3-0GxK0y{{z|oo5}{8|0Dg@-qH0x!*y(E)L+9t1R5C_7@8Ou z824}E=n&@U_-}l1 zNn%N6GH5gz8d{^{zeObq1G|M6wAXWV|0iU{Gsg4*7vzdA_oDpL0%)HUq7tcO7AWPtK3HSe=^`4LMcwnO(kw?Z%Srz3E|CPqx(O>7o&~t z|3odGNB4hXIh=WP|0hOKjlMJp@7&tx`0wcWZ*Z_v(CGe8(5TEP9t{CpA>hK0%8XgnM3bQVhmc1{ ziP1OSEo>Sm@r6TJcJVul8txKbMf)1RnRjsMRqkP2$1=sj;3Bn8yg^p z><|g*A?#?-904fA(L;KFby`t=F7)swo=(I>so*Vqhb02x03`$MTFG?BQ@wb;uuO;TC z5ArhQ2zfs9FH0@T$xloHrOd${b!2)FIqMB>5AG%}2Ho=W2e-fevoKbJ+ZBk`2&91# zkJhq?ha4YTl3G-Z)Kqaa)Iqdc9KqcUP*G}UWmTM;SX2^UP*N0Mk`HSE6_=z~S%FUE z28pAXGO#Tjb3=SBo&VgF1(A^sS^z_uZdO(qsW~a}nR&$}iFwJX$iZP`r+^~__4M=x zv`t7Lq$o>FPRNPLiQL5GWH_i36F)_X3DiCzH93Lw4AlfhS=MvQ&qper-175b^$m{P z1|3DYpX5axK zTwVG9LIa<623>%G0t@G@4j@So)=IXDDap^zK^Z?SNCqD^4;@l9GKf#nOUcP$kY!+C zU}a!*-~?TOP?Vpe>kMmja4;}B@WMo$ic%A^VKPh%3=N_#i6x1k5h4ZO%;LnH%=En6 z)Vvay3RVV&0|Ji8$*IM~3SpV~IpEV%VUlbN3j)H$dYEfbyTuC1T!vPVflFYKqlvIVJN`O!v-b>h5(Q|L4F#=qalDL1V+#Q!xAW?LZcxtLPB8l{J#+r(WBlR4FN16P|w^r zdj2Pta2XXE4S~@R7!85Z5Eu=C;T!^N42%q%3>BuTBNlnht($q+TFFXXVR?xJ=vT|6#pu)hw z!rUY^(FC!G*oXnN8XRK33xtA`YB-k{!|pyT2A!6xR&C_yYGm$c?5t~O?q;fMXy{^~ z>*!|aq-$W{Xy9yV;AZLKYF5j@09|~}02&+vEwcpSKmY&#fBFCae~=sq-)CfC*u}`e zz&^m?a+869;WacQU^JA=fCv}xWFvHvAO^A|AOZGgiCUwYAkrx$GDf=DwN1qD!wzP=x%uCKGO-YUM zb@lZRill0oTw;RcBbEUU6Oi9QafD2R*dVNoEliw)LSjI}^nR}4dd>j>R4H6Q83=^` zK?8+(fCFU-BLl-$P$|fOpg{ow!V1_k5oi+#Ct z7(|e0ko!Pb8y+IayIerWxyN9f+)kC`0;-2V_yRKngEkLV)D`Tzj?)(`FZilIf=!^*w@=TB^E=@|1GhCo&ReE z={w?HPCmN+7u4RfvKn3gi!WV`uKy*jkQ!b8TZFa;$SIKuX=il(Z+>10XjSm&`rrIK eP?roe#4)=5cXa(P+7jc@^}nFZF^WfS2mk=&D+65s literal 80384 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 From 2e145ea9163340ef7f4ab94cf7bb3ddbc74d511d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 5 Mar 2001 23:41:37 +0000 Subject: [PATCH 0005/1042] Use file name "libboost_python.a"; rename makefiles. [SVN r9449] --- build/{Makefile.linux_gcc => linux_gcc.mak} | 10 +++++----- build/{Makefile.mingw32 => mingw32.mak} | 10 +++++----- build/{Makefile.tru64_cxx => tru64_cxx.mak} | 16 ++++++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) rename build/{Makefile.linux_gcc => linux_gcc.mak} (96%) rename build/{Makefile.mingw32 => mingw32.mak} (96%) rename build/{Makefile.tru64_cxx => tru64_cxx.mak} (93%) diff --git a/build/Makefile.linux_gcc b/build/linux_gcc.mak similarity index 96% rename from build/Makefile.linux_gcc rename to build/linux_gcc.mak index 7021e221..a07bb5da 100644 --- a/build/Makefile.linux_gcc +++ b/build/linux_gcc.mak @@ -79,7 +79,7 @@ DEPOBJ= $(OBJ) comprehensive.o abstract.o \ .SUFFIXES: .o .cpp -all: libbpl.a boost_python_test.so abstract.so \ +all: libboost_python.a boost_python_test.so abstract.so \ getting_started1.so getting_started2.so getting_started3.so \ getting_started4.so getting_started5.so @@ -107,9 +107,9 @@ unlink: fi; \ done -libbpl.a: $(OBJ) - rm -f libbpl.a - ar r libbpl.a $(OBJ) +libboost_python.a: $(OBJ) + rm -f libboost_python.a + ar r libboost_python.a $(OBJ) boost_python_test.so: $(OBJ) comprehensive.o $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm @@ -145,7 +145,7 @@ test: $(PYEXE) test_getting_started5.py clean: - rm -f $(OBJ) libbpl.a libbpl.a.input + rm -f $(OBJ) libboost_python.a libboost_python.a.input rm -f comprehensive.o boost_python_test.so rm -f abstract.o abstract.so rm -f getting_started1.o getting_started1.so diff --git a/build/Makefile.mingw32 b/build/mingw32.mak similarity index 96% rename from build/Makefile.mingw32 rename to build/mingw32.mak index 7c5f2c52..014af132 100644 --- a/build/Makefile.mingw32 +++ b/build/mingw32.mak @@ -96,7 +96,7 @@ OBJ = classes.o conversions.o extension_class.o functions.o \ .SUFFIXES: .o .cpp -all: libbpl.a boost_python_test.pyd abstract.pyd \ +all: libboost_python.a boost_python_test.pyd abstract.pyd \ getting_started1.pyd getting_started2.pyd getting_started3.pyd \ getting_started4.pyd getting_started5.pyd @@ -136,9 +136,9 @@ rmdefs: rm $$def.def; \ done -libbpl.a: $(OBJ) - del libbpl.a - ar r libbpl.a $(OBJ) +libboost_python.a: $(OBJ) + del libboost_python.a + ar r libboost_python.a $(OBJ) DLLWRAPOPTS= -s --driver-name g++ -s --entry _DllMainCRTStartup@12 --target=i386-mingw32 @@ -198,7 +198,7 @@ test: $(PYEXE) test_getting_started5.py clean: - rm -f $(OBJ) libbpl.a libbpl.a.input + rm -f $(OBJ) libboost_python.a libboost_python.a.input rm -f comprehensive.o boost_python_test.pyd rm -f abstract.o abstract.pyd rm -f getting_started1.o getting_started1.pyd diff --git a/build/Makefile.tru64_cxx b/build/tru64_cxx.mak similarity index 93% rename from build/Makefile.tru64_cxx rename to build/tru64_cxx.mak index 2b417944..3fd584b7 100644 --- a/build/Makefile.tru64_cxx +++ b/build/tru64_cxx.mak @@ -79,7 +79,7 @@ DEPOBJ= $(OBJ) comprehensive.o abstract.o \ .SUFFIXES: .o .cpp -all: libbpl.a boost_python_test.so abstract.so \ +all: libboost_python.a boost_python_test.so abstract.so \ getting_started1.so getting_started2.so getting_started3.so \ getting_started4.so getting_started5.so @@ -107,13 +107,13 @@ unlink: fi; \ done -libbpl.a: $(OBJ) - rm -f libbpl.a +libboost_python.a: $(OBJ) + rm -f libboost_python.a cd cxx_repository; \ - ls -1 > ../libbpl.a.input; \ - ar r ../libbpl.a -input ../libbpl.a.input - rm -f libbpl.a.input - ar r libbpl.a $(OBJ) + ls -1 > ../libboost_python.a.input; \ + ar r ../libboost_python.a -input ../libboost_python.a.input + rm -f libboost_python.a.input + ar r libboost_python.a $(OBJ) boost_python_test.so: $(OBJ) comprehensive.o $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm @@ -149,7 +149,7 @@ test: $(PYEXE) test_getting_started5.py clean: - rm -f $(OBJ) libbpl.a libbpl.a.input + rm -f $(OBJ) libboost_python.a libboost_python.a.input rm -f comprehensive.o boost_python_test.so rm -f abstract.o abstract.so rm -f getting_started1.o getting_started1.so From 149cc499ede69475159d5a120c3213597c9d410a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 5 Mar 2001 23:46:43 +0000 Subject: [PATCH 0006/1042] Remove spurious ";" [SVN r9450] --- include/boost/python/detail/extension_class.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 987d753e..4afffcae 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -152,7 +152,7 @@ template bool is_null(const Ptr& x) { return is_null_helper<(is_pointer::value)>::test(x); -}; +} }}} // namespace boost::python::detail From fdff5e33b3745a4768caf0145d57d3cce7f1a668 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 00:02:01 +0000 Subject: [PATCH 0007/1042] temp file for branching [SVN r9451] --- src/x_class_builder.cpp | 118 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/x_class_builder.cpp diff --git a/src/x_class_builder.cpp b/src/x_class_builder.cpp new file mode 100644 index 00000000..cf81a3f7 --- /dev/null +++ b/src/x_class_builder.cpp @@ -0,0 +1,118 @@ +# include +namespace python = boost::python; +# include // MSVC6.0SP4 does not know std::fprintf +# include // MSVC6.0SP4 does not know std::strcmp + +namespace { + + PyObject *get_module_dict(const char *module_name) + { + python::ref module_obj(PyImport_ImportModule((char*) module_name)); + PyObject *module_dict = PyModule_GetDict(module_obj.get()); + if (module_dict == 0) throw python::import_error(); + return module_dict; + } +} + +namespace boost { namespace python { namespace detail { + +#ifndef SPECIAL_PYCVTSOBJECT + +void *import_converters(const std::string& module_name, + const std::string& klass_name, + const std::string& attribute_name) +{ + static std::string err; + PyObject *module_dict + = get_module_dict(const_cast(module_name.c_str())); + PyObject *klass + = PyDict_GetItemString(module_dict, const_cast(klass_name.c_str())); + if (klass == 0) { + err = std::string("module ") + module_name + " has no attribute " + + klass_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + python::ref c_obj(PyObject_GetAttrString(klass, + const_cast(attribute_name.c_str())), ref::null_ok); + if (c_obj.get() == 0) { + err = std::string("object ") + module_name + "." + klass_name + + " has no attribute " + attribute_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + if (! PyCObject_Check(c_obj.get())) { + err = std::string("object ") + module_name + "." + klass_name + "." + + attribute_name + " is not a PyCObject"; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + return PyCObject_AsVoidPtr(c_obj.get()); +} + +#else + +PyObject *new_import_converters(const std::string& module_name, + const std::string& klass_name, + const std::string& attribute_name) +{ + static std::string err; + PyObject *module_dict + = get_module_dict(const_cast(module_name.c_str())); + PyObject *klass + = PyDict_GetItemString(module_dict, const_cast(klass_name.c_str())); + if (klass == 0) { + err = std::string("module ") + module_name + " has no attribute " + + klass_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + python::ref cvts_obj(PyObject_GetAttrString(klass, + const_cast(attribute_name.c_str())), ref::null_ok); + if (cvts_obj.get() == 0) { + err = std::string("object ") + module_name + "." + klass_name + + " has no attribute " + attribute_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + // Weak point: direct access to ob_type->tp_name + if (strcmp(cvts_obj->ob_type->tp_name, "PyCvtsObject") != 0) { + err = std::string("object ") + module_name + "." + klass_name + "." + + attribute_name + " is not a PyCvtsObject"; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + return cvts_obj.release(); +} + +#endif // SPECIAL_PYCVTSOBJECT + +void check_export_converters_api(const int importing_major, + const int importing_minor, + const int imported_major, + const int imported_minor) +{ + if (importing_major != imported_major) { + // Python uses fprintf(stderr, ...) for API warnings. + fprintf(stderr, + "Fatal: EXPORT_CONVERTERS_API mismatch:" + " Importing module = %d.%d" + " Imported module = %d.%d\n", + importing_major, importing_minor, + imported_major, imported_minor); + PyErr_SetString(PyExc_RuntimeError, + "Fatal: EXPORT_CONVERTERS_API mismatch"); + throw import_error(); + } + if (importing_minor != imported_minor) { + // Python uses fprintf(stderr, ...) for API warnings. + fprintf(stderr, + "Warning: EXPORT_CONVERTERS_API mismatch:" + " Importing module = %d.%d" + " Imported module = %d.%d\n", + importing_major, importing_minor, + imported_major, imported_minor); + } +} + +}}} // namespace boost::python::detail From f49141f71ede423a1ae6f52f85f3a5b054c869e9 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 00:04:28 +0000 Subject: [PATCH 0008/1042] temp file removed after branching [SVN r9452] --- src/x_class_builder.cpp | 118 ---------------------------------------- 1 file changed, 118 deletions(-) delete mode 100644 src/x_class_builder.cpp diff --git a/src/x_class_builder.cpp b/src/x_class_builder.cpp deleted file mode 100644 index cf81a3f7..00000000 --- a/src/x_class_builder.cpp +++ /dev/null @@ -1,118 +0,0 @@ -# include -namespace python = boost::python; -# include // MSVC6.0SP4 does not know std::fprintf -# include // MSVC6.0SP4 does not know std::strcmp - -namespace { - - PyObject *get_module_dict(const char *module_name) - { - python::ref module_obj(PyImport_ImportModule((char*) module_name)); - PyObject *module_dict = PyModule_GetDict(module_obj.get()); - if (module_dict == 0) throw python::import_error(); - return module_dict; - } -} - -namespace boost { namespace python { namespace detail { - -#ifndef SPECIAL_PYCVTSOBJECT - -void *import_converters(const std::string& module_name, - const std::string& klass_name, - const std::string& attribute_name) -{ - static std::string err; - PyObject *module_dict - = get_module_dict(const_cast(module_name.c_str())); - PyObject *klass - = PyDict_GetItemString(module_dict, const_cast(klass_name.c_str())); - if (klass == 0) { - err = std::string("module ") + module_name + " has no attribute " - + klass_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - python::ref c_obj(PyObject_GetAttrString(klass, - const_cast(attribute_name.c_str())), ref::null_ok); - if (c_obj.get() == 0) { - err = std::string("object ") + module_name + "." + klass_name - + " has no attribute " + attribute_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - if (! PyCObject_Check(c_obj.get())) { - err = std::string("object ") + module_name + "." + klass_name + "." - + attribute_name + " is not a PyCObject"; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - return PyCObject_AsVoidPtr(c_obj.get()); -} - -#else - -PyObject *new_import_converters(const std::string& module_name, - const std::string& klass_name, - const std::string& attribute_name) -{ - static std::string err; - PyObject *module_dict - = get_module_dict(const_cast(module_name.c_str())); - PyObject *klass - = PyDict_GetItemString(module_dict, const_cast(klass_name.c_str())); - if (klass == 0) { - err = std::string("module ") + module_name + " has no attribute " - + klass_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - python::ref cvts_obj(PyObject_GetAttrString(klass, - const_cast(attribute_name.c_str())), ref::null_ok); - if (cvts_obj.get() == 0) { - err = std::string("object ") + module_name + "." + klass_name - + " has no attribute " + attribute_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - // Weak point: direct access to ob_type->tp_name - if (strcmp(cvts_obj->ob_type->tp_name, "PyCvtsObject") != 0) { - err = std::string("object ") + module_name + "." + klass_name + "." - + attribute_name + " is not a PyCvtsObject"; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - return cvts_obj.release(); -} - -#endif // SPECIAL_PYCVTSOBJECT - -void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor) -{ - if (importing_major != imported_major) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Fatal: EXPORT_CONVERTERS_API mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - PyErr_SetString(PyExc_RuntimeError, - "Fatal: EXPORT_CONVERTERS_API mismatch"); - throw import_error(); - } - if (importing_minor != imported_minor) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Warning: EXPORT_CONVERTERS_API mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - } -} - -}}} // namespace boost::python::detail From 23725680c9b8ab8068e26b46512936d260fb95df Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 00:05:41 +0000 Subject: [PATCH 0009/1042] temp file before branching [SVN r9453] --- include/boost/python/x_class_builder.hpp | 361 +++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 include/boost/python/x_class_builder.hpp diff --git a/include/boost/python/x_class_builder.hpp b/include/boost/python/x_class_builder.hpp new file mode 100644 index 00000000..4b3da600 --- /dev/null +++ b/include/boost/python/x_class_builder.hpp @@ -0,0 +1,361 @@ +#ifndef X_CLASS_BUILDER_HPP +# define X_CLASS_BUILDER_HPP + +# include + +//QUESTIONMARK +// Do we really need the special PyCvtsObject? +// Is there a better way of creating the special PyCvtsObject? +// My solution adds a lot of code including several reinterpret_cast. +//#define SPECIAL_PYCVTSOBJECT + +namespace boost { namespace python { + struct import_error : error_already_set {}; + struct export_error : error_already_set {}; +}} + +namespace boost { namespace python { namespace detail { + +// Concept: throw exception if api_major is changed +// show warning on stderr if api_minor is changed +const int EXPORT_CONVERTERS_API_MAJOR = 1; +const int EXPORT_CONVERTERS_API_MINOR = 1; +const std::string converters_attribute_name = "__converters__"; +#ifndef SPECIAL_PYCVTSOBJECT +void *import_converters(const std::string& module_name, + const std::string& klass_name, + const std::string& attribute_name); +#else +PyObject *new_import_converters(const std::string& module_name, + const std::string& klass_name, + const std::string& attribute_name); +#endif +void check_export_converters_api(const int importing_major, + const int importing_minor, + const int imported_major, + const int imported_minor); + +}}} + +// forward declaration +namespace boost { namespace python { namespace detail { +template class import_extension_class; +}}} + +BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE + +//QUESTIONMARK +// This class is a look-alike of class python_extension_class_converters. +// Is there a way to ensure that the siblings stay in sync? +template +class python_import_extension_class_converters +{ + public: + + friend python_import_extension_class_converters py_extension_class_converters(boost::python::type) + { + return python_import_extension_class_converters(); + } + + PyObject* to_python(const T& x) const + { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } + + friend T* from_python(PyObject* obj, boost::python::type) + { + return boost::python::detail::import_extension_class::get_converters()->Tptr_from_python(obj); + } + + // Convert to const T* + friend const T* from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to const T* const& + friend const T* from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to T* const& + friend T* from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to T& + friend T& from_python(PyObject* p, boost::python::type) + { return *boost::python::detail::check_non_null(from_python(p, boost::python::type())); } + + // Convert to const T& + friend const T& from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to T + friend const T& from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); + } + + friend std::auto_ptr& from_python(PyObject* p, boost::python::type >) { + return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); + } + + friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); + } + + friend PyObject* to_python(std::auto_ptr x) { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } + + friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); + } + + friend boost::shared_ptr& from_python(PyObject* p, boost::python::type >) { + return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); + } + + friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); + } + + friend PyObject* to_python(boost::shared_ptr x) { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } +}; + +BOOST_PYTHON_END_CONVERSION_NAMESPACE + +namespace boost { namespace python { + +BOOST_PYTHON_IMPORT_CONVERSION(python_import_extension_class_converters); + +// A pointer to this class is exported/imported via the Python API. +// All functions are virtual. This is, what we really export/import +// is essentially just a pointer to a vtbl. +template +struct export_converters_base +{ + virtual const int get_api_major() const { + return detail::EXPORT_CONVERTERS_API_MAJOR; } + virtual const int get_api_minor() const { + return detail::EXPORT_CONVERTERS_API_MINOR; } + virtual PyObject *to_python(const T& x) = 0; + virtual PyObject *to_python(std::auto_ptr x) = 0; + virtual PyObject *to_python(boost::shared_ptr x) = 0; + virtual T* Tptr_from_python(PyObject* obj) = 0; + virtual std::auto_ptr& auto_ptr_from_python(PyObject *obj) = 0; + virtual boost::shared_ptr& shared_ptr_from_python(PyObject *obj) = 0; +}; + +// Converters to be used if T is not copyable. +template +struct export_ptr_converters : export_converters_base +{ + virtual PyObject *to_python(const T& x) { + PyErr_SetString(PyExc_RuntimeError, + "to_python(const T&) converter not exported"); + throw import_error(); + } + virtual PyObject *to_python(std::auto_ptr x) { + return BOOST_PYTHON_CONVERSION::to_python(x); + } + virtual PyObject *to_python(boost::shared_ptr x) { + return BOOST_PYTHON_CONVERSION::to_python(x); + } + virtual T* Tptr_from_python(PyObject* obj) { + return BOOST_PYTHON_CONVERSION::from_python(obj, boost::python::type()); + } + virtual std::auto_ptr& auto_ptr_from_python(PyObject *obj) { + return BOOST_PYTHON_CONVERSION::python_extension_class_converters::ptr_from_python(obj, boost::python::type >()); + } + virtual boost::shared_ptr& shared_ptr_from_python(PyObject *obj) { + return BOOST_PYTHON_CONVERSION::python_extension_class_converters::ptr_from_python(obj, boost::python::type >()); + } +}; + +// The addditional to_python() converter that can be used if T is copyable. +template +struct export_converters : export_ptr_converters +{ + virtual PyObject *to_python(const T& x) { + BOOST_PYTHON_CONVERSION::python_extension_class_converters cv; + return cv.to_python(x); + } +}; + +namespace detail { + +//QUESTIONMARK +// A stripped-down, modified version of class extension_class. +// Would it make sense to establish a formal relationship +// between the two classes? +template +class import_extension_class + : public python_import_extension_class_converters +{ + public: + inline import_extension_class(const char *module, const char* klass) { + m_module = module; + m_klass = klass; + } + + static boost::python::export_converters_base* get_converters(); + + private: + static std::string m_module; + static std::string m_klass; + static boost::python::export_converters_base* imported_converters; +}; + +template std::string import_extension_class::m_module; +template std::string import_extension_class::m_klass; +template +boost::python::export_converters_base* +import_extension_class::imported_converters = 0; + +#ifdef SPECIAL_PYCVTSOBJECT + +// A special PyObject for passing pointers to export_converters_base +template +struct PyCvtsObject { + PyObject_HEAD + export_converters_base* cvts; +}; + +template +void DEL_PyCvtsObject(PyCvtsObject* self) { PyMem_DEL(self); } + +template +PyObject *create_PyCvtsObject(export_converters_base* cvts) +{ + static char PyCvtsObject_Type__doc__[] = + "Boost Python Library (BPL) converters objects to be exported from\n" + "one extension module to another."; + + static PyTypeObject PyCvtsObject_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*ob_size*/ + "PyCvtsObject", /*tp_name*/ + sizeof(PyCvtsObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)(static_cast*)> + (DEL_PyCvtsObject)), /*tp_dealloc*/ + (printfunc)0, /*tp_print*/ + (getattrfunc)0, /*tp_getattr*/ + (setattrfunc)0, /*tp_setattr*/ + (cmpfunc)0, /*tp_compare*/ + (reprfunc)0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + (hashfunc)0, /*tp_hash*/ + (ternaryfunc)0, /*tp_call*/ + (reprfunc)0, /*tp_str*/ + + /* Space for future expansion */ + 0L,0L,0L,0L, + PyCvtsObject_Type__doc__ /* Documentation string */ + }; + + PyCvtsObject* self = PyObject_NEW(PyCvtsObject, &PyCvtsObject_Type); + if (self == 0) throw export_error(); + self->cvts = cvts; + return reinterpret_cast(self); +} + +#endif // SPECIAL_PYCVTSOBJECT + +template +boost::python::export_converters_base* +import_extension_class::get_converters() { + if (imported_converters == 0) { +#ifndef SPECIAL_PYCVTSOBJECT + void *cobject + = import_converters(m_module, m_klass, converters_attribute_name); + imported_converters + = static_cast*>(cobject); +#else + ref cvts_obj( + new_import_converters(m_module, m_klass, converters_attribute_name)); + PyCvtsObject* cvts = reinterpret_cast*>(cvts_obj.get()); + imported_converters = cvts->cvts; +#endif + check_export_converters_api( + EXPORT_CONVERTERS_API_MAJOR, + EXPORT_CONVERTERS_API_MINOR, + imported_converters->get_api_major(), + imported_converters->get_api_minor()); + } + return imported_converters; +} + +}}} // namespace boost::python::detail + +namespace boost { namespace python { + +//QUESTIONMARK +// A stripped-down, modified version of class class_builder. +// Would it make sense to establish a formal relationship +// between the two classes? +template +class import_class_builder + : python_import_extension_class_converters +{ + public: + import_class_builder(const char *module, const char* klass) + : m_class(new detail::import_extension_class(module, klass)) + { } + private: + + //QUESTIONMARK + //reference > m_class; + boost::shared_ptr > m_class; +}; + +}} // namespace boost::python + +namespace boost { namespace python { + +// A class_builder that exports the converter functions. +template , + class C = export_converters > +class x_class_builder + : public class_builder +{ + private: + static C export_cvts; + + public: + x_class_builder(module_builder& module, const char* name) + : class_builder(module, name) { +#ifndef SPECIAL_PYCVTSOBJECT + add( + ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), + const_cast(detail::converters_attribute_name.c_str())); +#else + add(ref(detail::create_PyCvtsObject(&export_cvts)), + const_cast(detail::converters_attribute_name.c_str())); +#endif + } +}; + +template +C x_class_builder::export_cvts; + +//QUESTIONMARK +// Is there a better way of making it easy for the end-user +// to choose between x_class_builder and xptr_class_builder? +template , + class C = export_ptr_converters > +class xptr_class_builder : public x_class_builder +{ + public: + xptr_class_builder(module_builder& module, const char* name) + : x_class_builder(module, name) { } +}; + +}} // namespace boost::python + +#endif // X_CLASS_BUILDER_HPP From 5b13e75fa585d73753627a2f4df1cb2c8fa2128e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 00:06:55 +0000 Subject: [PATCH 0010/1042] temp file removed after branching. [SVN r9454] --- include/boost/python/x_class_builder.hpp | 361 ----------------------- 1 file changed, 361 deletions(-) delete mode 100644 include/boost/python/x_class_builder.hpp diff --git a/include/boost/python/x_class_builder.hpp b/include/boost/python/x_class_builder.hpp deleted file mode 100644 index 4b3da600..00000000 --- a/include/boost/python/x_class_builder.hpp +++ /dev/null @@ -1,361 +0,0 @@ -#ifndef X_CLASS_BUILDER_HPP -# define X_CLASS_BUILDER_HPP - -# include - -//QUESTIONMARK -// Do we really need the special PyCvtsObject? -// Is there a better way of creating the special PyCvtsObject? -// My solution adds a lot of code including several reinterpret_cast. -//#define SPECIAL_PYCVTSOBJECT - -namespace boost { namespace python { - struct import_error : error_already_set {}; - struct export_error : error_already_set {}; -}} - -namespace boost { namespace python { namespace detail { - -// Concept: throw exception if api_major is changed -// show warning on stderr if api_minor is changed -const int EXPORT_CONVERTERS_API_MAJOR = 1; -const int EXPORT_CONVERTERS_API_MINOR = 1; -const std::string converters_attribute_name = "__converters__"; -#ifndef SPECIAL_PYCVTSOBJECT -void *import_converters(const std::string& module_name, - const std::string& klass_name, - const std::string& attribute_name); -#else -PyObject *new_import_converters(const std::string& module_name, - const std::string& klass_name, - const std::string& attribute_name); -#endif -void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor); - -}}} - -// forward declaration -namespace boost { namespace python { namespace detail { -template class import_extension_class; -}}} - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -//QUESTIONMARK -// This class is a look-alike of class python_extension_class_converters. -// Is there a way to ensure that the siblings stay in sync? -template -class python_import_extension_class_converters -{ - public: - - friend python_import_extension_class_converters py_extension_class_converters(boost::python::type) - { - return python_import_extension_class_converters(); - } - - PyObject* to_python(const T& x) const - { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } - - friend T* from_python(PyObject* obj, boost::python::type) - { - return boost::python::detail::import_extension_class::get_converters()->Tptr_from_python(obj); - } - - // Convert to const T* - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to const T* const& - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T* const& - friend T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T& - friend T& from_python(PyObject* p, boost::python::type) - { return *boost::python::detail::check_non_null(from_python(p, boost::python::type())); } - - // Convert to const T& - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); - } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type >) { - return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); - } - - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->auto_ptr_from_python(p); - } - - friend PyObject* to_python(std::auto_ptr x) { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); - } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type >) { - return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); - } - - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->shared_ptr_from_python(p); - } - - friend PyObject* to_python(boost::shared_ptr x) { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } -}; - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -BOOST_PYTHON_IMPORT_CONVERSION(python_import_extension_class_converters); - -// A pointer to this class is exported/imported via the Python API. -// All functions are virtual. This is, what we really export/import -// is essentially just a pointer to a vtbl. -template -struct export_converters_base -{ - virtual const int get_api_major() const { - return detail::EXPORT_CONVERTERS_API_MAJOR; } - virtual const int get_api_minor() const { - return detail::EXPORT_CONVERTERS_API_MINOR; } - virtual PyObject *to_python(const T& x) = 0; - virtual PyObject *to_python(std::auto_ptr x) = 0; - virtual PyObject *to_python(boost::shared_ptr x) = 0; - virtual T* Tptr_from_python(PyObject* obj) = 0; - virtual std::auto_ptr& auto_ptr_from_python(PyObject *obj) = 0; - virtual boost::shared_ptr& shared_ptr_from_python(PyObject *obj) = 0; -}; - -// Converters to be used if T is not copyable. -template -struct export_ptr_converters : export_converters_base -{ - virtual PyObject *to_python(const T& x) { - PyErr_SetString(PyExc_RuntimeError, - "to_python(const T&) converter not exported"); - throw import_error(); - } - virtual PyObject *to_python(std::auto_ptr x) { - return BOOST_PYTHON_CONVERSION::to_python(x); - } - virtual PyObject *to_python(boost::shared_ptr x) { - return BOOST_PYTHON_CONVERSION::to_python(x); - } - virtual T* Tptr_from_python(PyObject* obj) { - return BOOST_PYTHON_CONVERSION::from_python(obj, boost::python::type()); - } - virtual std::auto_ptr& auto_ptr_from_python(PyObject *obj) { - return BOOST_PYTHON_CONVERSION::python_extension_class_converters::ptr_from_python(obj, boost::python::type >()); - } - virtual boost::shared_ptr& shared_ptr_from_python(PyObject *obj) { - return BOOST_PYTHON_CONVERSION::python_extension_class_converters::ptr_from_python(obj, boost::python::type >()); - } -}; - -// The addditional to_python() converter that can be used if T is copyable. -template -struct export_converters : export_ptr_converters -{ - virtual PyObject *to_python(const T& x) { - BOOST_PYTHON_CONVERSION::python_extension_class_converters cv; - return cv.to_python(x); - } -}; - -namespace detail { - -//QUESTIONMARK -// A stripped-down, modified version of class extension_class. -// Would it make sense to establish a formal relationship -// between the two classes? -template -class import_extension_class - : public python_import_extension_class_converters -{ - public: - inline import_extension_class(const char *module, const char* klass) { - m_module = module; - m_klass = klass; - } - - static boost::python::export_converters_base* get_converters(); - - private: - static std::string m_module; - static std::string m_klass; - static boost::python::export_converters_base* imported_converters; -}; - -template std::string import_extension_class::m_module; -template std::string import_extension_class::m_klass; -template -boost::python::export_converters_base* -import_extension_class::imported_converters = 0; - -#ifdef SPECIAL_PYCVTSOBJECT - -// A special PyObject for passing pointers to export_converters_base -template -struct PyCvtsObject { - PyObject_HEAD - export_converters_base* cvts; -}; - -template -void DEL_PyCvtsObject(PyCvtsObject* self) { PyMem_DEL(self); } - -template -PyObject *create_PyCvtsObject(export_converters_base* cvts) -{ - static char PyCvtsObject_Type__doc__[] = - "Boost Python Library (BPL) converters objects to be exported from\n" - "one extension module to another."; - - static PyTypeObject PyCvtsObject_Type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /*ob_size*/ - "PyCvtsObject", /*tp_name*/ - sizeof(PyCvtsObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)(static_cast*)> - (DEL_PyCvtsObject)), /*tp_dealloc*/ - (printfunc)0, /*tp_print*/ - (getattrfunc)0, /*tp_getattr*/ - (setattrfunc)0, /*tp_setattr*/ - (cmpfunc)0, /*tp_compare*/ - (reprfunc)0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)0, /*tp_str*/ - - /* Space for future expansion */ - 0L,0L,0L,0L, - PyCvtsObject_Type__doc__ /* Documentation string */ - }; - - PyCvtsObject* self = PyObject_NEW(PyCvtsObject, &PyCvtsObject_Type); - if (self == 0) throw export_error(); - self->cvts = cvts; - return reinterpret_cast(self); -} - -#endif // SPECIAL_PYCVTSOBJECT - -template -boost::python::export_converters_base* -import_extension_class::get_converters() { - if (imported_converters == 0) { -#ifndef SPECIAL_PYCVTSOBJECT - void *cobject - = import_converters(m_module, m_klass, converters_attribute_name); - imported_converters - = static_cast*>(cobject); -#else - ref cvts_obj( - new_import_converters(m_module, m_klass, converters_attribute_name)); - PyCvtsObject* cvts = reinterpret_cast*>(cvts_obj.get()); - imported_converters = cvts->cvts; -#endif - check_export_converters_api( - EXPORT_CONVERTERS_API_MAJOR, - EXPORT_CONVERTERS_API_MINOR, - imported_converters->get_api_major(), - imported_converters->get_api_minor()); - } - return imported_converters; -} - -}}} // namespace boost::python::detail - -namespace boost { namespace python { - -//QUESTIONMARK -// A stripped-down, modified version of class class_builder. -// Would it make sense to establish a formal relationship -// between the two classes? -template -class import_class_builder - : python_import_extension_class_converters -{ - public: - import_class_builder(const char *module, const char* klass) - : m_class(new detail::import_extension_class(module, klass)) - { } - private: - - //QUESTIONMARK - //reference > m_class; - boost::shared_ptr > m_class; -}; - -}} // namespace boost::python - -namespace boost { namespace python { - -// A class_builder that exports the converter functions. -template , - class C = export_converters > -class x_class_builder - : public class_builder -{ - private: - static C export_cvts; - - public: - x_class_builder(module_builder& module, const char* name) - : class_builder(module, name) { -#ifndef SPECIAL_PYCVTSOBJECT - add( - ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), - const_cast(detail::converters_attribute_name.c_str())); -#else - add(ref(detail::create_PyCvtsObject(&export_cvts)), - const_cast(detail::converters_attribute_name.c_str())); -#endif - } -}; - -template -C x_class_builder::export_cvts; - -//QUESTIONMARK -// Is there a better way of making it easy for the end-user -// to choose between x_class_builder and xptr_class_builder? -template , - class C = export_ptr_converters > -class xptr_class_builder : public x_class_builder -{ - public: - xptr_class_builder(module_builder& module, const char* name) - : x_class_builder(module, name) { } -}; - -}} // namespace boost::python - -#endif // X_CLASS_BUILDER_HPP From 2d568b1c0fd9b786d93b10e5f96a9118ce865274 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Mar 2001 01:13:35 +0000 Subject: [PATCH 0011/1042] Fixed a bug which prevented auto_ptr values from being converted to_python [SVN r9455] --- include/boost/python/detail/extension_class.hpp | 14 ++++++++++---- src/gen_extclass.py | 16 +++++++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 4afffcae..125f1eed 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -9,6 +9,10 @@ // This file automatically generated for 10-argument constructors by // gen_extclass.python +// Revision History: +// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted +// to_python (Dave Abrahams) + #ifndef EXTENSION_CLASS_DWA052000_H_ # define EXTENSION_CLASS_DWA052000_H_ @@ -250,10 +254,12 @@ class python_extension_class_converters throw boost::python::argument_error(); } - // Extract from obj a constant reference to the PtrType object which is holding a T. - // If obj is None, the reference denotes a default-constructed PtrType + // Extract from obj a reference to the PtrType object which is holding a + // T. If it weren't for auto_ptr, it would be a constant reference. Do not + // modify the referent except by copying an auto_ptr! If obj is None, the + // reference denotes a default-constructed PtrType template - static const PtrType& smart_ptr_value(PyObject* obj, boost::python::type) + static PtrType& smart_ptr_value(PyObject* obj, boost::python::type) { if (obj == Py_None) { @@ -315,7 +321,7 @@ class python_extension_class_converters friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { return smart_ptr_reference(p, boost::python::type >()); } - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type >) + friend std::auto_ptr from_python(PyObject* p, boost::python::type >) { return smart_ptr_value(p, boost::python::type >()); } friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) diff --git a/src/gen_extclass.py b/src/gen_extclass.py index 2d261289..8de8a1ae 100644 --- a/src/gen_extclass.py +++ b/src/gen_extclass.py @@ -14,6 +14,10 @@ def gen_extclass(args): // This file automatically generated for %d-argument constructors by // gen_extclass.python +// Revision History: +// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted +// to_python (Dave Abrahams) + #ifndef EXTENSION_CLASS_DWA052000_H_ # define EXTENSION_CLASS_DWA052000_H_ @@ -157,7 +161,7 @@ template bool is_null(const Ptr& x) { return is_null_helper<(is_pointer::value)>::test(x); -}; +} }}} // namespace boost::python::detail @@ -255,10 +259,12 @@ class python_extension_class_converters throw boost::python::argument_error(); } - // Extract from obj a constant reference to the PtrType object which is holding a T. - // If obj is None, the reference denotes a default-constructed PtrType + // Extract from obj a reference to the PtrType object which is holding a + // T. If it weren't for auto_ptr, it would be a constant reference. Do not + // modify the referent except by copying an auto_ptr! If obj is None, the + // reference denotes a default-constructed PtrType template - static const PtrType& smart_ptr_value(PyObject* obj, boost::python::type) + static PtrType& smart_ptr_value(PyObject* obj, boost::python::type) { if (obj == Py_None) { @@ -320,7 +326,7 @@ class python_extension_class_converters friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { return smart_ptr_reference(p, boost::python::type >()); } - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type >) + friend std::auto_ptr from_python(PyObject* p, boost::python::type >) { return smart_ptr_value(p, boost::python::type >()); } friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) From b0d6d40c2a800159cacbe796f96c069ec503fc2a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Mar 2001 01:14:47 +0000 Subject: [PATCH 0012/1042] Suppress warnings under Cygwin with Python 2.0 [SVN r9456] --- include/boost/python/detail/wrap_python.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index d5b75374..b7a47513 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -16,9 +16,13 @@ // compiler command-line. // Revision History: +// 05 Mar 01 Suppress warnings under Cygwin with Python 2.0 (Dave Abrahams) // 04 Mar 01 Rolled in some changes from the Dragon fork (Dave Abrahams) // 01 Mar 01 define PyObject_INIT() for Python 1.x (Dave Abrahams) + +#include + #ifdef _DEBUG # ifndef BOOST_DEBUG_PYTHON # undef _DEBUG // Don't let Python force the debug library just because we're debugging. @@ -37,9 +41,11 @@ typedef int pid_t; # define WORD_BIT 32 # define hypot _hypot # include -# define HAVE_CLOCK -# define HAVE_STRFTIME -# define HAVE_STRERROR +# if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2 +# define HAVE_CLOCK +# define HAVE_STRFTIME +# define HAVE_STRERROR +# endif # define NT_THREADS # define WITH_THREAD # ifndef NETSCAPE_PI From dd0e42cf7252e41d3c3e1c5d5854d614c446d57a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 02:44:32 +0000 Subject: [PATCH 0013/1042] temp files before branching [SVN r9457] --- example/dvect.cpp | 68 ++++++++++++++++++++++++++++++++++ example/dvect.h | 32 ++++++++++++++++ example/ivect.cpp | 68 ++++++++++++++++++++++++++++++++++ example/ivect.h | 32 ++++++++++++++++ example/noncopyable.h | 14 +++++++ example/noncopyable_export.cpp | 23 ++++++++++++ example/noncopyable_import.cpp | 41 ++++++++++++++++++++ example/tst_dvect.py | 16 ++++++++ example/tst_ivect.py | 16 ++++++++ example/tst_noncopyable.py | 8 ++++ 10 files changed, 318 insertions(+) create mode 100644 example/dvect.cpp create mode 100644 example/dvect.h create mode 100644 example/ivect.cpp create mode 100644 example/ivect.h create mode 100644 example/noncopyable.h create mode 100644 example/noncopyable_export.cpp create mode 100644 example/noncopyable_import.cpp create mode 100644 example/tst_dvect.py create mode 100644 example/tst_ivect.py create mode 100644 example/tst_noncopyable.py diff --git a/example/dvect.cpp b/example/dvect.cpp new file mode 100644 index 00000000..47f70d3b --- /dev/null +++ b/example/dvect.cpp @@ -0,0 +1,68 @@ +#include "ivect.h" +#include "dvect.h" +#include +namespace python = boost::python; + +namespace { + + vects::ivect dvect_as_ivect(const vects::dvect& dv) + { + vects::ivect iv(dv.size()); + vects::ivect::iterator iviter = iv.begin(); + for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); + return iv; + } + + boost::python::tuple ivect_as_tuple(const vects::ivect& iv) + { + return iv.as_tuple(); + } + + std::auto_ptr auto_ptr_ivect(const vects::dvect& dv) + { + return std::auto_ptr(new vects::ivect(dvect_as_ivect(dv))); + } + + boost::shared_ptr shared_ptr_ivect(const vects::dvect& dv) + { + return boost::shared_ptr(new vects::ivect(dvect_as_ivect(dv))); + } + + boost::python::tuple auto_ptr_ivect_as_tuple(std::auto_ptr& iv) + { + return iv->as_tuple(); + } + + boost::python::tuple shared_ptr_ivect_as_tuple(boost::shared_ptr& iv) + { + return iv->as_tuple(); + } +} + +extern "C" +DL_EXPORT(void) +initdvect() +{ + try + { + python::module_builder this_module("dvect"); + + python::x_class_builder dvect_class(this_module, "dvect"); + + python::import_class_builder ivect_class("ivect", "ivect"); + + dvect_class.def(python::constructor()); + dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); + dvect_class.def(dvect_as_ivect, "as_ivect"); + + this_module.def(ivect_as_tuple, "ivect_as_tuple"); + dvect_class.def(auto_ptr_ivect, "auto_ptr_ivect"); + dvect_class.def(shared_ptr_ivect, "shared_ptr_ivect"); + this_module.def(auto_ptr_ivect_as_tuple, "auto_ptr_ivect_as_tuple"); + this_module.def(shared_ptr_ivect_as_tuple, "shared_ptr_ivect_as_tuple"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/dvect.h b/example/dvect.h new file mode 100644 index 00000000..8ffe7b50 --- /dev/null +++ b/example/dvect.h @@ -0,0 +1,32 @@ +#ifndef DVECT_H +#define DVECT_H + +#include +#include + +namespace vects { + + struct dvect : public std::vector + { + dvect() : std::vector() {} + dvect(size_t n) : std::vector(n) {} + dvect(boost::python::tuple tuple) : std::vector(tuple.size()) + { + std::vector::iterator v_it = begin(); + for (int i = 0; i < tuple.size(); i++) + v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + + boost::python::tuple as_tuple() const + { + boost::python::tuple t(size()); + for (int i = 0; i < size(); i++) + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); + return t; + } + }; +} + +#endif // DVECT_H diff --git a/example/ivect.cpp b/example/ivect.cpp new file mode 100644 index 00000000..dfd90fc9 --- /dev/null +++ b/example/ivect.cpp @@ -0,0 +1,68 @@ +#include "ivect.h" +#include "dvect.h" +#include +namespace python = boost::python; + +namespace { + + vects::dvect ivect_as_dvect(const vects::ivect& iv) + { + vects::dvect dv(iv.size()); + vects::dvect::iterator dviter = dv.begin(); + for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); + return dv; + } + + boost::python::tuple dvect_as_tuple(const vects::dvect& dv) + { + return dv.as_tuple(); + } + + std::auto_ptr auto_ptr_dvect(const vects::ivect& iv) + { + return std::auto_ptr(new vects::dvect(ivect_as_dvect(iv))); + } + + boost::shared_ptr shared_ptr_dvect(const vects::ivect& iv) + { + return boost::shared_ptr(new vects::dvect(ivect_as_dvect(iv))); + } + + boost::python::tuple auto_ptr_dvect_as_tuple(std::auto_ptr& dv) + { + return dv->as_tuple(); + } + + boost::python::tuple shared_ptr_dvect_as_tuple(boost::shared_ptr& dv) + { + return dv->as_tuple(); + } +} + +extern "C" +DL_EXPORT(void) +initivect() +{ + try + { + python::module_builder this_module("ivect"); + + python::x_class_builder ivect_class(this_module, "ivect"); + + python::import_class_builder dvect_class("dvect", "dvect"); + + ivect_class.def(python::constructor()); + ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); + ivect_class.def(ivect_as_dvect, "as_dvect"); + + this_module.def(dvect_as_tuple, "dvect_as_tuple"); + ivect_class.def(auto_ptr_dvect, "auto_ptr_dvect"); + ivect_class.def(shared_ptr_dvect, "shared_ptr_dvect"); + this_module.def(auto_ptr_dvect_as_tuple, "auto_ptr_dvect_as_tuple"); + this_module.def(shared_ptr_dvect_as_tuple, "shared_ptr_dvect_as_tuple"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/ivect.h b/example/ivect.h new file mode 100644 index 00000000..a0187307 --- /dev/null +++ b/example/ivect.h @@ -0,0 +1,32 @@ +#ifndef IVECT_H +#define IVECT_H + +#include +#include + +namespace vects { + + struct ivect : public std::vector + { + ivect() : std::vector() {} + ivect(size_t n) : std::vector(n) {} + ivect(boost::python::tuple tuple) : std::vector(tuple.size()) + { + std::vector::iterator v_it = begin(); + for (int i = 0; i < tuple.size(); i++) + v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + + boost::python::tuple as_tuple() const + { + boost::python::tuple t(size()); + for (int i = 0; i < size(); i++) + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); + return t; + } + }; +} + +#endif // IVECT_H diff --git a/example/noncopyable.h b/example/noncopyable.h new file mode 100644 index 00000000..de7b3672 --- /dev/null +++ b/example/noncopyable.h @@ -0,0 +1,14 @@ +#ifndef NONCOPYABLE_H +#define NONCOPYABLE_H + +class store +{ + private: + store(const store&) { } // Disable the copy constructor. + int number; + public: + store(const int i) : number(i) { } + int recall() const { return number; } +}; + +#endif // NONCOPYABLE_H diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp new file mode 100644 index 00000000..31cbe7c8 --- /dev/null +++ b/example/noncopyable_export.cpp @@ -0,0 +1,23 @@ +#include +namespace python = boost::python; + +#include "noncopyable.h" + +extern "C" +DL_EXPORT(void) +initnoncopyable_export() +{ + try + { + python::module_builder this_module("noncopyable_export"); + + python::xptr_class_builder store_class(this_module, "store"); + + store_class.def(python::constructor()); + store_class.def(&store::recall, "recall"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp new file mode 100644 index 00000000..f2b2c6d0 --- /dev/null +++ b/example/noncopyable_import.cpp @@ -0,0 +1,41 @@ +#include +namespace python = boost::python; + +#include "noncopyable.h" + +namespace { // Avoid cluttering the global namespace. + + // A function with store objects as both input and output parameters. + // Because the copy constructor is disabled, we cannot pass a store + // object by value. Instead, we pass a smart pointer. + std::auto_ptr add_stores(const store& s1, const store& s2) + { + int sum = s1.recall() + s2.recall(); + std::auto_ptr ss = std::auto_ptr(new store(sum)); + return ss; + } +} + +extern "C" +DL_EXPORT(void) +initnoncopyable_import() +{ + try + { + python::module_builder this_module("noncopyable_import"); + + python::import_class_builder + dvect_class("noncopyable_export", "store"); + + // Imagine all the additional classes with member functions + // that have store objects as input and output parameters. + // Lots and lots of them. + // However, to keep this example simple, we only define a + // module-level function. + this_module.def(add_stores, "add_stores"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/tst_dvect.py b/example/tst_dvect.py new file mode 100644 index 00000000..563f0ad5 --- /dev/null +++ b/example/tst_dvect.py @@ -0,0 +1,16 @@ +import dvect +print dvect.dvect.__converters__ +dv = dvect.dvect((1,2,3,4,5)) +print dv +print dv.as_tuple() +iv = dv.as_ivect() +print iv +print iv.as_tuple() +print dvect.ivect_as_tuple(iv) +aiv = dv.auto_ptr_ivect() +print aiv +siv = dv.shared_ptr_ivect() +print dvect.auto_ptr_ivect_as_tuple(aiv) +print dvect.ivect_as_tuple(aiv) +print dvect.shared_ptr_ivect_as_tuple(siv) +print dvect.ivect_as_tuple(siv) diff --git a/example/tst_ivect.py b/example/tst_ivect.py new file mode 100644 index 00000000..58bc323f --- /dev/null +++ b/example/tst_ivect.py @@ -0,0 +1,16 @@ +import ivect +print ivect.ivect.__converters__ +iv = ivect.ivect((1,2,3,4,5)) +print iv +print iv.as_tuple() +dv = iv.as_dvect() +print dv +print dv.as_tuple() +print ivect.dvect_as_tuple(dv) +adv = iv.auto_ptr_dvect() +print adv +sdv = iv.shared_ptr_dvect() +print ivect.auto_ptr_dvect_as_tuple(adv) +print ivect.dvect_as_tuple(adv) +print ivect.shared_ptr_dvect_as_tuple(sdv) +print ivect.dvect_as_tuple(sdv) diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py new file mode 100644 index 00000000..913df039 --- /dev/null +++ b/example/tst_noncopyable.py @@ -0,0 +1,8 @@ +import noncopyable_export +import noncopyable_import +s1 = noncopyable_export.store(1) +print s1.recall() +s2 = noncopyable_export.store(2) +print s2.recall() +s3 = noncopyable_import.add_stores(s1, s2) +print s3.recall() From 53d2398e0654b67463c4326b7dc8ba134d925711 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 6 Mar 2001 02:45:39 +0000 Subject: [PATCH 0014/1042] remove temp files after branching. [SVN r9459] --- example/dvect.cpp | 68 ---------------------------------- example/dvect.h | 32 ---------------- example/ivect.cpp | 68 ---------------------------------- example/ivect.h | 32 ---------------- example/noncopyable.h | 14 ------- example/noncopyable_export.cpp | 23 ------------ example/noncopyable_import.cpp | 41 -------------------- example/tst_dvect.py | 16 -------- example/tst_ivect.py | 16 -------- example/tst_noncopyable.py | 8 ---- 10 files changed, 318 deletions(-) delete mode 100644 example/dvect.cpp delete mode 100644 example/dvect.h delete mode 100644 example/ivect.cpp delete mode 100644 example/ivect.h delete mode 100644 example/noncopyable.h delete mode 100644 example/noncopyable_export.cpp delete mode 100644 example/noncopyable_import.cpp delete mode 100644 example/tst_dvect.py delete mode 100644 example/tst_ivect.py delete mode 100644 example/tst_noncopyable.py diff --git a/example/dvect.cpp b/example/dvect.cpp deleted file mode 100644 index 47f70d3b..00000000 --- a/example/dvect.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "ivect.h" -#include "dvect.h" -#include -namespace python = boost::python; - -namespace { - - vects::ivect dvect_as_ivect(const vects::dvect& dv) - { - vects::ivect iv(dv.size()); - vects::ivect::iterator iviter = iv.begin(); - for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); - return iv; - } - - boost::python::tuple ivect_as_tuple(const vects::ivect& iv) - { - return iv.as_tuple(); - } - - std::auto_ptr auto_ptr_ivect(const vects::dvect& dv) - { - return std::auto_ptr(new vects::ivect(dvect_as_ivect(dv))); - } - - boost::shared_ptr shared_ptr_ivect(const vects::dvect& dv) - { - return boost::shared_ptr(new vects::ivect(dvect_as_ivect(dv))); - } - - boost::python::tuple auto_ptr_ivect_as_tuple(std::auto_ptr& iv) - { - return iv->as_tuple(); - } - - boost::python::tuple shared_ptr_ivect_as_tuple(boost::shared_ptr& iv) - { - return iv->as_tuple(); - } -} - -extern "C" -DL_EXPORT(void) -initdvect() -{ - try - { - python::module_builder this_module("dvect"); - - python::x_class_builder dvect_class(this_module, "dvect"); - - python::import_class_builder ivect_class("ivect", "ivect"); - - dvect_class.def(python::constructor()); - dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); - dvect_class.def(dvect_as_ivect, "as_ivect"); - - this_module.def(ivect_as_tuple, "ivect_as_tuple"); - dvect_class.def(auto_ptr_ivect, "auto_ptr_ivect"); - dvect_class.def(shared_ptr_ivect, "shared_ptr_ivect"); - this_module.def(auto_ptr_ivect_as_tuple, "auto_ptr_ivect_as_tuple"); - this_module.def(shared_ptr_ivect_as_tuple, "shared_ptr_ivect_as_tuple"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/dvect.h b/example/dvect.h deleted file mode 100644 index 8ffe7b50..00000000 --- a/example/dvect.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef DVECT_H -#define DVECT_H - -#include -#include - -namespace vects { - - struct dvect : public std::vector - { - dvect() : std::vector() {} - dvect(size_t n) : std::vector(n) {} - dvect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (int i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (int i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - }; -} - -#endif // DVECT_H diff --git a/example/ivect.cpp b/example/ivect.cpp deleted file mode 100644 index dfd90fc9..00000000 --- a/example/ivect.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "ivect.h" -#include "dvect.h" -#include -namespace python = boost::python; - -namespace { - - vects::dvect ivect_as_dvect(const vects::ivect& iv) - { - vects::dvect dv(iv.size()); - vects::dvect::iterator dviter = dv.begin(); - for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); - return dv; - } - - boost::python::tuple dvect_as_tuple(const vects::dvect& dv) - { - return dv.as_tuple(); - } - - std::auto_ptr auto_ptr_dvect(const vects::ivect& iv) - { - return std::auto_ptr(new vects::dvect(ivect_as_dvect(iv))); - } - - boost::shared_ptr shared_ptr_dvect(const vects::ivect& iv) - { - return boost::shared_ptr(new vects::dvect(ivect_as_dvect(iv))); - } - - boost::python::tuple auto_ptr_dvect_as_tuple(std::auto_ptr& dv) - { - return dv->as_tuple(); - } - - boost::python::tuple shared_ptr_dvect_as_tuple(boost::shared_ptr& dv) - { - return dv->as_tuple(); - } -} - -extern "C" -DL_EXPORT(void) -initivect() -{ - try - { - python::module_builder this_module("ivect"); - - python::x_class_builder ivect_class(this_module, "ivect"); - - python::import_class_builder dvect_class("dvect", "dvect"); - - ivect_class.def(python::constructor()); - ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); - ivect_class.def(ivect_as_dvect, "as_dvect"); - - this_module.def(dvect_as_tuple, "dvect_as_tuple"); - ivect_class.def(auto_ptr_dvect, "auto_ptr_dvect"); - ivect_class.def(shared_ptr_dvect, "shared_ptr_dvect"); - this_module.def(auto_ptr_dvect_as_tuple, "auto_ptr_dvect_as_tuple"); - this_module.def(shared_ptr_dvect_as_tuple, "shared_ptr_dvect_as_tuple"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/ivect.h b/example/ivect.h deleted file mode 100644 index a0187307..00000000 --- a/example/ivect.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef IVECT_H -#define IVECT_H - -#include -#include - -namespace vects { - - struct ivect : public std::vector - { - ivect() : std::vector() {} - ivect(size_t n) : std::vector(n) {} - ivect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (int i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (int i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - }; -} - -#endif // IVECT_H diff --git a/example/noncopyable.h b/example/noncopyable.h deleted file mode 100644 index de7b3672..00000000 --- a/example/noncopyable.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef NONCOPYABLE_H -#define NONCOPYABLE_H - -class store -{ - private: - store(const store&) { } // Disable the copy constructor. - int number; - public: - store(const int i) : number(i) { } - int recall() const { return number; } -}; - -#endif // NONCOPYABLE_H diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp deleted file mode 100644 index 31cbe7c8..00000000 --- a/example/noncopyable_export.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include -namespace python = boost::python; - -#include "noncopyable.h" - -extern "C" -DL_EXPORT(void) -initnoncopyable_export() -{ - try - { - python::module_builder this_module("noncopyable_export"); - - python::xptr_class_builder store_class(this_module, "store"); - - store_class.def(python::constructor()); - store_class.def(&store::recall, "recall"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp deleted file mode 100644 index f2b2c6d0..00000000 --- a/example/noncopyable_import.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -namespace python = boost::python; - -#include "noncopyable.h" - -namespace { // Avoid cluttering the global namespace. - - // A function with store objects as both input and output parameters. - // Because the copy constructor is disabled, we cannot pass a store - // object by value. Instead, we pass a smart pointer. - std::auto_ptr add_stores(const store& s1, const store& s2) - { - int sum = s1.recall() + s2.recall(); - std::auto_ptr ss = std::auto_ptr(new store(sum)); - return ss; - } -} - -extern "C" -DL_EXPORT(void) -initnoncopyable_import() -{ - try - { - python::module_builder this_module("noncopyable_import"); - - python::import_class_builder - dvect_class("noncopyable_export", "store"); - - // Imagine all the additional classes with member functions - // that have store objects as input and output parameters. - // Lots and lots of them. - // However, to keep this example simple, we only define a - // module-level function. - this_module.def(add_stores, "add_stores"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/tst_dvect.py b/example/tst_dvect.py deleted file mode 100644 index 563f0ad5..00000000 --- a/example/tst_dvect.py +++ /dev/null @@ -1,16 +0,0 @@ -import dvect -print dvect.dvect.__converters__ -dv = dvect.dvect((1,2,3,4,5)) -print dv -print dv.as_tuple() -iv = dv.as_ivect() -print iv -print iv.as_tuple() -print dvect.ivect_as_tuple(iv) -aiv = dv.auto_ptr_ivect() -print aiv -siv = dv.shared_ptr_ivect() -print dvect.auto_ptr_ivect_as_tuple(aiv) -print dvect.ivect_as_tuple(aiv) -print dvect.shared_ptr_ivect_as_tuple(siv) -print dvect.ivect_as_tuple(siv) diff --git a/example/tst_ivect.py b/example/tst_ivect.py deleted file mode 100644 index 58bc323f..00000000 --- a/example/tst_ivect.py +++ /dev/null @@ -1,16 +0,0 @@ -import ivect -print ivect.ivect.__converters__ -iv = ivect.ivect((1,2,3,4,5)) -print iv -print iv.as_tuple() -dv = iv.as_dvect() -print dv -print dv.as_tuple() -print ivect.dvect_as_tuple(dv) -adv = iv.auto_ptr_dvect() -print adv -sdv = iv.shared_ptr_dvect() -print ivect.auto_ptr_dvect_as_tuple(adv) -print ivect.dvect_as_tuple(adv) -print ivect.shared_ptr_dvect_as_tuple(sdv) -print ivect.dvect_as_tuple(sdv) diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py deleted file mode 100644 index 913df039..00000000 --- a/example/tst_noncopyable.py +++ /dev/null @@ -1,8 +0,0 @@ -import noncopyable_export -import noncopyable_import -s1 = noncopyable_export.store(1) -print s1.recall() -s2 = noncopyable_export.store(2) -print s2.recall() -s3 = noncopyable_import.add_stores(s1, s2) -print s3.recall() From 116b3db1d1b6ebbaab7aca99401b6a8dd332d613 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Mar 2001 20:55:09 +0000 Subject: [PATCH 0015/1042] Fixed typo in use of "PYTHON_LIB" [SVN r9467] --- build/como.mak | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/como.mak b/build/como.mak index c6f340a5..581eefea 100644 --- a/build/como.mak +++ b/build/como.mak @@ -1,5 +1,7 @@ # Revision History: +# 06 Mar 01 Fixed typo in use of "PYTHON_LIB" (Dave Abrahams) # 04 Mar 01 Changed library name to libboost_python.a (David Abrahams) + LIBSRC = \ classes.cpp \ conversions.cpp \ @@ -33,7 +35,7 @@ endif [ -s $@ ] || rm -f $@ example1: example1.o libboost_python.a - como-dyn-link -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYHTON_LIB) example1.o -L. -lboost_python + como-dyn-link -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYTHON_LIB) example1.o -L. -lboost_python python ../example/test_example1.py example1.o: ../example/example1.cpp From 617bcdac9f81d1486c585158b9c7694f2f5c48fd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 7 Mar 2001 03:39:31 +0000 Subject: [PATCH 0016/1042] Major doc updates [SVN r9470] --- doc/building.html | 195 +++++++++++++++++++++++++++++-------- doc/comparisons.html | 61 +++++++----- doc/enums.html | 43 +++++--- doc/example1.html | 112 ++++++--------------- doc/exporting_classes.html | 144 +++++++++++++++++++++++++++ doc/extending.html | 4 +- doc/index.html | 91 +++++++++-------- doc/inheritance.html | 26 ++--- doc/overloading.html | 6 +- doc/overriding.html | 98 +++++++++++-------- doc/pickle.html | 28 +++--- doc/pointers.html | 4 +- doc/special.html | 28 +++--- doc/under-the-hood.html | 4 +- 14 files changed, 551 insertions(+), 293 deletions(-) create mode 100644 doc/exporting_classes.html diff --git a/doc/building.html b/doc/building.html index 4ac2343c..6627bbe8 100644 --- a/doc/building.html +++ b/doc/building.html @@ -1,44 +1,157 @@ - - - Building an Extension Module - + + + + + Building an Extension Module +
-

- c++boost.gif (8819 bytes)Building an Extension Module -

-

- Right now, the only supported configuration is one in which the BPL - source files are statically linked with the source for your extension - module. You may first build them into a library and link it with your - extension module source, but the effect is the same as compiling all - the source files together. Some users have successfully built the - sources into a shared library, and support for a shared library - build is planned, but not yet implemented. The BPL source files are: -

-
-extclass.cpp
-functions.cpp
-init_function.cpp
-module.cpp
-newtypes.cpp
-objects.cpp
-py.cpp
-subclass.cpp
-         
-
-

- Next: Enums - Previous: A Peek Under the Hood - Up: Top -

- © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as - is'' without express or implied warranty, and with no claim as to - its suitability for any purpose. -

- Updated: Nov 26, 2000 +

c++boost.gif (8819 bytes)Building an + Extension Module

+ +

The build process for Boost is currently undergoing some evolution, + and, it is to be hoped, improvement. The following facts may help: + +

    +
  • + Makefiles for various platforms reside in the Boost subdirectory + libs/python/build: + +
      +
    • como.mak (Comeau C++ on Linux) + +
    • linux_gcc.mak (GCC on + Linux/Unix) + +
    • gcc.mak (older makefile for GCC + on Linux/Unix. Deprecated.) + +
    • mingw32.mak + (highly-specialized makefile for mingw32 (Win32-targeted) GCC. Read + the header comment). + +
    • tru64_cxx.mak (Compaq + Alpha). +
    +
    + +
  • + A project workspace for Microsoft Visual Studio is provided at libs/python/build/build.dsw. The + include paths for this project may need to be changed for your + installation. They currently assume that python has been installed at + c:\tools\python. Three configurations of all targets are + supported: + +
      +
    • Release (optimization, -DNDEBUG) + +
    • Debug (no optimization -D_DEBUG) + +
    • DebugPython (no optimization, -D_DEBUG + -DBOOST_DEBUG_PYTHON) +
    + +

    When extension modules are built with Visual C++ using + -D_DEBUG, Python defaults to force linking with a + special debugging version of the Python DLL. Since this debug DLL + isn't supplied with the default Python installation for Windows, + Boost.Python uses boost/python/detail/wrap_python.hpp + to temporarily undefine _DEBUG when Python.h is + #included. + +

    If you want the extra runtime checks available with the debugging + version of the library, #define BOOST_DEBUG_PYTHON to + re-enable library forcing, and link with the DebugPython version of + boost_python.lib. You'll need to get the debugging version + of the Python executable (python_d.exe) and DLL + (python20_d.dll or python15_d.dll). The Python + sources include project files for building these. If you download them, change the name of the + top-level directory to src, and install it under + c:\tools\python, the workspace supplied by Boost.Python will + be able to use it without modification. Just open + c:\tools\python\src\pcbuild\pcbuild.dsw and invoke "build + all" to generate all the debugging targets. + +

    If you do not #define BOOST_DEBUG_PYTHON, be sure that + any source files #include <boost/python/detail/wrap_python.hpp> + instead of the usual Python.h, or you will have link + incompatibilities.
    +
    + + +

  • + The makefiles and Visual Studio project can all build at least the + following: + +
      +
    • The boost_python library for static linking with your + extension module. On the various Unices, this library will be + called libboost_python.a. On Win32 platforms, the library + will be called boost_python.lib. + +
    • A comprehensive test of Boost.Python features. This test builds + a Boost.Python extension module, then runs Python to import the + module, and runs a series of tests on it using doctest. Source code for the module + and tests is available in the Boost subdirectory + libs/python/test.
      + + +
    • Various examples from the Boost subdirectory + libs/python/example. Which examples are built currently + depends on the platform. The most up-to-date examples are + getting_startedn.cpp from Ralf W. + Grosse-Kunstleve. All these examples include a doctest modeled + on the comprehensive test above.
      +
      + +
    + +
  • + If your platform isn't directly supported, you can build a static + library from the following source files (in the Boost subdirectory + libs/python/src), or compile them directly and link the + resulting objects into your extension module: + + +
+ +

Next: Wrapping Enums Previous: A Peek Under the Hood Up: Top + +

© Copyright David Abrahams 2000. Permission to copy, use, modify, + sell and distribute this document is granted provided this copyright + notice appears in all copies. This document is provided ``as is'' without + express or implied warranty, and with no claim as to its suitability for + any purpose. + +

Updated: Mar 6, 2001

diff --git a/doc/comparisons.html b/doc/comparisons.html index 336220fb..6f082d51 100644 --- a/doc/comparisons.html +++ b/doc/comparisons.html @@ -6,13 +6,14 @@

c++boost.gif (8819 bytes)Comparisons with + src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">
+ Comparisons with Other Systems

CXX

- Like BPL, CXX attempts to + Like Boost.Python, CXX attempts to provide a C++-oriented interface to Python. In most cases, as with the boost library, it relieves the user from worrying about reference-counts. Both libraries automatically convert thrown C++ @@ -40,9 +41,15 @@

As far as I can tell, CXX enables one to write what is essentially idiomatic Python code in C++, manipulating Python objects through the - same fully-generic interfaces we use in Python. While you're hardly programming directly to the ``bare - metal'' with CXX, it basically presents a ``C++-ized'' - version of the Python 'C' API. + same fully-generic interfaces we use in Python. While you're hardly + programming directly to the ``bare metal'' with CXX, it basically + presents a ``C++-ized'' version of the Python 'C' API. Some fraction of + that capability is available in Boost.Python through boost/python/objects.hpp, + which provides C++ objects corresponding to Python lists, tuples, + strings, and dictionaries, and through boost/python/callback.hpp, + which allows you to call back into python with C++ arguments.

Paul F. Dubois, the original @@ -65,7 +72,7 @@ that.''
-Paul Dubois languages. Swig relies on a parser to read your source code and produce additional source code files which can be compiled into a Python (or Perl or Tcl) extension module. It has been successfully used to create - many Python extension modules. Like BPL, SWIG is trying to allow an + many Python extension modules. Like Boost.Python, SWIG is trying to allow an existing interface to be wrapped with little or no change to the existing code. The documentation says ``SWIG parses a form of ANSI C syntax that has been extended with a number of special directives. As a @@ -78,15 +85,15 @@ that.''
-Paul Dubois couldnt handle templates, didnt do func overloading properly etc. For ANSI C libraries this was fine. But for usual C++ code this was a problem. Simple things work. But for anything very complicated (or - realistic), one had to write code by hand. I believe BPL doesn't have + realistic), one had to write code by hand. I believe Boost.Python doesn't have this problem[sic]... IMHO overloaded functions are very important to wrap correctly.''
-Prabhu Ramachandran

- By contrast, BPL doesn't attempt to parse C++ - the problem is simply + By contrast, Boost.Python doesn't attempt to parse C++ - the problem is simply too complex to do correctly. Technically, one does - write code by hand to use BPL. The goal, however, has been to make + write code by hand to use Boost.Python. The goal, however, has been to make that code nearly as simple as listing the names of the classes and member functions you want to expose in Python. @@ -95,7 +102,7 @@ that.''
-Paul Dubois SIP is a system similar to SWIG, though seemingly more - C++-oriented. The author says that like BPL, SIP supports overriding + C++-oriented. The author says that like Boost.Python, SIP supports overriding extension class member functions in Python subclasses. It appears to have been designed specifically to directly support some features of PyQt/PyKDE, which is its primary client. Documentation is almost @@ -113,7 +120,7 @@ that.''
-Paul Dubois to a wide range of computer languages, including Common Lisp, C++, C, Modula-3, and Python. ILU can parse the ISL to generate a C++ language header file describing the interface, of which the user is expected to - provide an implementation. Unlike BPL, this means that the system + provide an implementation. Unlike Boost.Python, this means that the system imposes implementation details on your C++ code at the deepest level. It is worth noting that some of the C++ names generated by ILU are supposed to be reserved to the C++ implementation. It is unclear from the @@ -148,7 +155,7 @@ an inheritance relationship?

Zope ExtensionClasses

- ExtensionClasses in Zope use the same underlying mechanism as BPL + ExtensionClasses in Zope use the same underlying mechanism as Boost.Python to support subclassing of extension types in Python, including multiple-inheritance. Both systems support pickling/unpickling of extension class instances in very similar ways. Both systems rely on the @@ -158,31 +165,35 @@ an inheritance relationship?

The major differences are:

    +
  • Zope is entirely 'C' language-based. It doesn't require a C++ + compiler, so it's much more portable than Boost.Python, which stresses + the limits of even some modern C++ implementations. +
  • - BPL lifts the burden on the user to parse and convert function + Boost.Python lifts the burden on the user to parse and convert function argument types. Zope provides no such facility.
  • - BPL lifts the burden on the user to maintain Python + Boost.Python lifts the burden on the user to maintain Python reference-counts.
  • - BPL supports function overloading; Zope does not. + Boost.Python supports function overloading; Zope does not.
  • - BPL supplies a simple mechanism for exposing read-only and + Boost.Python supplies a simple mechanism for exposing read-only and read/write access to data members of the wrapped C++ type as Python attributes.
  • Writing a Zope ExtensionClass is significantly more complex than - exposing a C++ class to python using BPL (mostly a summary of the + exposing a C++ class to python using Boost.Python (mostly a summary of the previous 4 items). A Zope Example illustrates the differences.
  • Zope's ExtensionClasses are specifically motivated by ``the need for a - C-based persistence mechanism''. BPL's are motivated by the desire + C-based persistence mechanism''. Boost.Python's are motivated by the desire to simply reflect a C++ API into Python with as little modification as possible.
  • - The following Zope restriction does not apply to BPL: ``At most one + The following Zope restriction does not apply to Boost.Python: ``At most one base extension direct or indirect super class may define C data members. If an extension subclass inherits from multiple base extension classes, then all but one must be mix-in classes that @@ -191,21 +202,21 @@ an inheritance relationship? Zope requires use of the somewhat funky inheritedAttribute (search for ``inheritedAttribute'' on this page) - method to access base class methods. In BPL, base class methods can + method to access base class methods. In Boost.Python, base class methods can be accessed in the usual way by writing ``BaseClass.method''.
  • Zope supplies some creative but esoteric idioms such as - Acquisition. No specific support for this is built into BPL. + Acquisition. No specific support for this is built into Boost.Python.
  • Zope's ComputedAttribute support is designed to be used from Python. The analogous feature of - BPL can be used from C++ or Python. The feature is arguably - easier to use in BPL. + Boost.Python can be used from C++ or Python. The feature is arguably + easier to use in Boost.Python.

- Next: A Simple Example Using BPL + Next: A Simple Example Using Boost.Python Previous: A Brief Introduction to writing Python Extension Modules Up: Top

@@ -215,6 +226,6 @@ an inheritance relationship? express or implied warranty, and with no claim as to its suitability for any purpose.

- Updated: Nov 26, 2000 + Updated: Mar 6, 2001

diff --git a/doc/enums.html b/doc/enums.html index 04138ff1..32d61447 100644 --- a/doc/enums.html +++ b/doc/enums.html @@ -6,7 +6,8 @@

c++boost.gif (8819 bytes)Wrapping enums + src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">
+ Wrapping enums

Because there is in general no way to deduce that a value of arbitrary type T @@ -17,24 +18,39 @@ enums). Once you have done that, you can write some simple from_python() and to_python() functions.

If you are satisfied with a Python int as a way to represent your enum -values, we provide a shorthand for these functions. You just need to -instantiate boost::python::enum_as_int_converters<EnumType> where +values, we provide a shorthand for these functions. You just need to cause +boost::python::enum_as_int_converters<EnumType> to be +instantiated, where EnumType is your enumerated type. There are two convenient ways to do this:

    -
  1. +
  2. Explicit instantiation: + +
    +  template class boost::python::enum_as_int_converters<my_enum>;
    +
    + +Some buggy C++ implementations require a class to be instantiated in the same +namespace in which it is defined. In that case, the simple incantation above becomes: + +
        ...
     } // close my_namespace
    +
     // drop into namespace python and explicitly instantiate
    -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
    -  template class enum_as_int_converters;
    -BOOST_PYTHON_END_CONVERSION_NAMESPACE
    +namespace boost { namespace python {
    +  template class enum_as_int_converters<my_enum_type>;
    +}} // namespace boost::python
    +
     namespace my_namespace { // re-open my_namespace
        ...
     
    -
  3. +
    +
    +
  4. If you have such an implementation, you may find this technique more convenient +
     // instantiate as base class in any namespace
     struct EnumTypeConverters
         : boost::python::enum_as_int_converters<EnumType>
    @@ -71,7 +87,8 @@ BOOST_PYTHON_END_CONVERSION_NAMESPACE
      long type.
     
     You may also want to add a bunch of lines like this to your module
    -initialization:
    +initialization. These bind the corresponding enum values to the appropriate
    +names so they can be used from Python:
     
     
     mymodule.add(boost::python::to_python(enum_value_1), "enum_value_1");
    @@ -83,12 +100,12 @@ You can also add these to an extension class definition, if your enum happens to
     be local to a class and you want the analogous interface in Python:
     
     
    -my_class.add(boost::python::to_python(enum_value_1), "enum_value_1");
    -my_class.add(boost::python::to_python(enum_value_2), "enum_value_2");
    +my_class_builder.add(boost::python::to_python(enum_value_1), "enum_value_1");
    +my_class_builder.add(boost::python::to_python(enum_value_2), "enum_value_2");
     ...
     

    - Next: Pointers + Next: Pointers and Smart Pointers Previous: Building an Extension Module Up: Top

    @@ -98,6 +115,6 @@ my_class.add(boost::python::to_python(enum_value_2), "enum_value_2"); is'' without express or implied warranty, and with no claim as to its suitability for any purpose.

    - Updated: Nov 26, 2000 + Updated: Mar 6, 2001

diff --git a/doc/example1.html b/doc/example1.html index 655f3d6a..402cc7a6 100644 --- a/doc/example1.html +++ b/doc/example1.html @@ -18,104 +18,56 @@
 #include <string>
 
-namespace hello {
-  class world
-  {
-   public:
-      world(int);
-      ~world();
-      std::string greet() const { return "hi, world"; }
-    ...
-  };
-  std::size_t length(const world& x) { return std::strlen(x.greet()); }
+namespace { // Avoid cluttering the global namespace.
+
+  // A couple of simple C++ functions that we want to expose to Python.
+  std::string greet() { return "hello, world"; }
+  int square(int number) { return number * number; }
 }
 
 

- Here is the C++ code for a python module called hello - which exposes the API using: + Here is the C++ code for a python module called getting_started1 + which exposes the API.

 #include <boost/python/class_builder.hpp>
-// Python requires an exported function called init<module-name> in every
-// extension module. This is where we build the module contents.
-extern "C"
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-void inithello()
+namespace python = boost::python;
+
+BOOST_PYTHON_MODULE_INIT(getting_started1)
 {
-    try
-    {
-       // create an object representing this extension module
-       boost::python::module_builder m("hello");
-       // Create the Python type object for our extension class
-       boost::python::class_builder<hello::world> world_class(m, "world");
-       // Add the __init__ function
-       world_class.def(boost::python::constructor<int>());
-       // Add a regular member function
-       world_class.def(&hello::world::get, "get");
-       // Add a regular function to the module
-       m.def(hello::length, "length");
-    }
-    catch(...)
-    {
-       boost::python::handle_exception();    // Deal with the exception for Python
-    }
+  try
+  {
+    // Create an object representing this extension module.
+    python::module_builder this_module("getting_started1");
+
+    // Add regular functions to the module.
+    this_module.def(greet, "greet");
+    this_module.def(square, "square");
+  }
+  catch(...)
+  {
+    python::handle_exception(); // Deal with the exception for Python
+  }
 }
-// Win32 DLL boilerplate
-#if defined(_WIN32)
-#include <windows.h>
-extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
-{
-    return 1;
-}
-#endif // _WIN32
 

That's it! If we build this shared library and put it on our - PYTHONPATH we can now access our C++ class and function from + PYTHONPATH we can now access our C++ functions from Python.

->>> import hello
->>> hi_world = hello.world(3)
->>> hi_world.greet()
-'hi, world'
->>> hello.length(hi_world)
-9
+>>> import getting_started1
+>>> print getting_started1.greet()
+hello, world
+>>> number = 11
+>>> print number, '*', number, '=', getting_started1.square(number)
+11 * 11 = 121
 
-

- We can even make a subclass of hello.world: -

-
->>> class my_subclass(hello.world):
-...     def greet(self):
-...         return 'hello, world'
-...
->>> y = my_subclass(4)
->>> y.greet()
-'hello, world'
-
-
-

- Pretty cool! You can't do that with an ordinary Python extension type! -

-
->>> hello.length(y)
-9
-
-
-

- Of course, you may now have a slightly empty feeling in the pit of - your little pythonic stomach. Perhaps you feel your subclass deserves - to have a length() of 12? If so, read on... -

- Next: Overridable virtual functions + Next: Exporting Classes Previous: Comparisons with other systems Up: Top

@@ -125,6 +77,6 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) express or implied warranty, and with no claim as to its suitability for any purpose.

- Updated: Nov 26, 2000 + Updated: Mar 6, 2000 diff --git a/doc/exporting_classes.html b/doc/exporting_classes.html new file mode 100644 index 00000000..e5932e70 --- /dev/null +++ b/doc/exporting_classes.html @@ -0,0 +1,144 @@ + + + Exporting Classes + +

+

+ + +

+

+ Exporting Classes +

+

+ Now let's expose a C++ class to Python: + +

+#include <iostream>
+#include <string>
+
+namespace { // Avoid cluttering the global namespace.
+
+  // A friendly class.
+  class hello
+  {
+    public:
+      hello(const std::string& country) { this->country = country; }
+      std::string greet() const { return "Hello from " + country; }
+    private:
+      std::string country;
+  };
+
+  // A function taking a hello object as an argument.
+  std::string invite(const hello& w) {
+    return w.greet() + "! Please come soon!";
+  }
+}
+
+

+ To expose the class, we use a class_builder in addition to the + module_builder from the previous example. Class member functions + are exposed by using the def() member function on the + class_builder: +

+#include <boost/python/class_builder.hpp>
+namespace python = boost::python;
+
+BOOST_PYTHON_MODULE_INIT(getting_started2)
+{
+  try
+  {
+    // Create an object representing this extension module.
+    python::module_builder this_module("getting_started2");
+
+    // Create the Python type object for our extension class.
+    python::class_builder<hello> hello_class(this_module, "hello");
+
+    // Add the __init__ function.
+    hello_class.def(python::constructor<std::string>());
+    // Add a regular member function.
+    hello_class.def(&hello::greet, "greet");
+
+    // Add invite() as a regular function to the module.
+    this_module.def(invite, "invite");
+
+    // Even better, invite() can also be made a member of hello_class!!!
+    hello_class.def(invite, "invite");
+  }
+  catch(...)
+  {
+    python::handle_exception(); // Deal with the exception for Python
+  }
+}
+
+

+Now we can use the class normally from Python: + +

+>>> from getting_started2 import *
+>>> hi = hello('California')
+>>> hi.greet()
+'Hello from California'
+>>> invite(hi)
+'Hello from California! Please come soon!'
+>>> hi.invite()
+'Hello from California! Please come soon!'
+
+ +Notes:
    +
  • We expose the class' constructor by calling def() on the + class_builder with an argument whose type is + constructor<params>, where params + matches the list of constructor argument types: + + +
  • Regular member functions are defined by calling def() with a + member function pointer and its Python name: + +
  • Any function added to a class whose initial argument matches the class (or +any base) will act like a member function in Python. +
+

+ We can even make a subclass of hello.world: + +

+>>> class wordy(hello):
+...     def greet(self):
+...         return hello.greet(self) + ', where the weather is fine'
+...
+>>> hi2 = wordy('Florida')
+>>> hi2.greet()
+'Hello from Florida, where the weather is fine'
+>>> invite(hi2)
+'Hello from Florida! Please come soon!'
+
+

+ Pretty cool! You can't do that with an ordinary Python extension type! + + Of course, you may now have a slightly empty feeling in the pit of + your little pythonic stomach. Perhaps you wanted to see the following + wordy invitation: + +

+'Hello from Florida, where the weather is fine! Please come soon!'
+
+ + After all, invite calls hello::greet(), and you + reimplemented that in your Python subclass, wordy. If so, read on... + +

+ Next: Overridable virtual functions + Previous: A Simple Example Up: + Top +

+ © Copyright David Abrahams 2000. Permission to copy, use, modify, + sell and distribute this document is granted provided this copyright + notice appears in all copies. This document is provided "as is" without + express or implied warranty, and with no claim as to its suitability + for any purpose. +

+ Updated: Mar 6, 2001 +

+ diff --git a/doc/extending.html b/doc/extending.html index c4a3a5e4..8839ab43 100644 --- a/doc/extending.html +++ b/doc/extending.html @@ -56,10 +56,10 @@ sublcassing the extension type. Aside from being tedious, it's not really the same as having a true class, because there's no way for the user to override a method of the extension type which is called from the - extension module. BPL solves this problem by taking advantage of Python's metaclass feature to provide objects which look, walk, and hiss almost exactly - like regular Python classes. BPL classes are actually cleaner than + like regular Python classes. Boost.Python classes are actually cleaner than Python classes in some subtle ways; a more detailed discussion will follow (someday).

Next: Comparisons with Other Systems Up: - The Boost Python Library (BPL) + The Boost Python Library (Boost.Python)

c++boost.gif (8819 bytes)The Boost Python Library (BPL) + align="center" height="86">
The Boost Python Library (Boost.Python)

Synopsis

@@ -15,9 +15,9 @@ href="http://www.python.org">Python
such that the Python interface is very similar to the C++ interface. It is designed to be minimally intrusive on your C++ design. In most cases, you should not have to alter - your C++ classes in any way in order to use them with BPL. The system + your C++ classes in any way in order to use them with Boost.Python. The system should simply ``reflect'' your C++ classes and functions into - Python. The major features of BPL include support for: + Python. The major features of Boost.Python include support for:
  • Subclassing extension types in Python
  • Overriding virtual functions in Python @@ -28,9 +28,27 @@ among others.

    Supported Platforms

    -

    BPL has been tested in the following configurations: +

    Boost.Python is known to have been tested in the following configurations:

      +
    • Against Python 2.0 using the following compiler/library combinations: + +
    • Against Python 1.5.2 using the following compiler/library:
        @@ -52,24 +70,17 @@ among others. href="mailto:rwgk@cci.lbl.gov">Ralf W. Grosse-Kunstleve]
      • An upcoming release of Metrowerks CodeWarrior - Pro6 for Windows (the first release has a bug that's fatal to BPL) + Pro6 for Windows (the first release has a bug that's fatal to Boost.Python)
      -
      -
    • Against Python 2.0 using the following compiler/library combinations: -

    Credits

    • David Abrahams originated - and wrote the library. + and wrote most of the library, and continues to coordinate development.
    • Ullrich Koethe - had independently developed a similar system. When he discovered BPL, + had independently developed a similar system. When he discovered Boost.Python, he generously contributed countless hours of coding and much insight into improving it. He is responsible for an early version of the support for function overloading and wrote the support for @@ -78,16 +89,22 @@ among others. Python and C++, and has designed an extremely easy-to-use way of exposing numeric operators, including a way to avoid explicit coercion by means of overloading. + +
    • Ralf W. + Grosse-Kunstleve contributed pickle support + and numerous other small improvements. He's working on a way to allow + types exported by multiple modules to interact.
    • The members of the boost mailing list and the Python community supplied invaluable early feedback. In particular, Ron Clarke, Mark Evans, - Anton Gluck, Ralf W. Grosse-Kunstleve, Chuck Ingold, Prabhu Ramachandran, - and Barry Scott took the brave step of trying to use BPL while it was - still in early stages of development. + Anton Gluck, Chuck Ingold, Prabhu Ramachandran,n and Barry Scott took the + brave step of trying to use Boost.Python while it was still in early + stages of development. -
    • The development of BPL wouldn't have been - possible without the generous support of Dragon Systems/Lernout and - Hauspie, Inc who supported its development as an open-source project. +
    • The development of Boost.Python wouldn't have been possible without + the generous support of Dragon + Systems/Lernout and Hauspie, Inc who supported its development as an + open-source project.

    Table of Contents

    @@ -96,11 +113,13 @@ among others.
  • A Brief Introduction to writing Python extension modules -
  • Comparisons between BPL and other +
  • Comparisons between Boost.Python and other systems for extending Python
  • A Simple Example +
  • Exporting Classes +
  • Overridable Virtual Functions
  • Function Overloading @@ -113,33 +132,19 @@ among others.
  • Building an Extension Module -
  • Advanced Topics +
  • Pickle Support -
      -
    1. Pickle Support +
    2. Wrapping Enums -
    3. class_builder<> +
    4. Pointers and Smart Pointers -
    5. enums - -
    6. References - -
    7. Pointers and Smart Pointers - -
    8. Built-in Python Types - -
    9. Other Extension Types - -
    10. Templates - -
    11. Internal Data Structures -
    +
  • Internal Data Structures

    Documentation is a major ongoing project; assistance is greatly - appreciated! In the meantime, useful examples of every BPL feature should + appreciated! In the meantime, useful examples of every Boost.Python feature should be evident in the regression test files test/comprehensive.[py/hpp/the boost mailing list.

    - © Copyright David Abrahams 2000. Permission to copy, use, modify, + © Copyright David Abrahams 2001. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided ``as is'' without express or implied warranty, and with no claim as to its suitability for any purpose.

    - Updated: Nov 26, 2000 + Updated: Mar 6, 2001 diff --git a/doc/inheritance.html b/doc/inheritance.html index d11899c8..cd95c744 100644 --- a/doc/inheritance.html +++ b/doc/inheritance.html @@ -12,10 +12,10 @@

    Inheritance in Python

    - BPL extension classes support single and multiple-inheritance in + Boost.Python extension classes support single and multiple-inheritance in Python, just like regular Python classes. You can arbitrarily mix built-in Python classes with extension classes in a derived class' - tuple of bases. Whenever a BPL extension class is among the bases for a + tuple of bases. Whenever a Boost.Python extension class is among the bases for a new class in Python, the result is an extension class:

    @@ -37,7 +37,7 @@
     
     

    Reflecting C++ Inheritance Relationships

    - BPL also allows us to represent C++ inheritance relationships so that + Boost.Python also allows us to represent C++ inheritance relationships so that wrapped derived classes may be passed where values, pointers, or references to a base class are expected as arguments. The declare_base member function of @@ -76,11 +76,7 @@ int get_derived_x(const Derived& d) { // namespace alias for code brevity namespace python = boost::python; -extern "C" -#ifdef _WIN32 -__declspec(dllexport) -#endif -void initmy_module() +BOOST_PYTHON_MODULE_INIT(my_module) {     try     { @@ -115,11 +111,19 @@ void initmy_module() >>> derived = Derived() >>> get_name(base) 'Base' -

    objects of wrapped class Derived may be passed where Base is expected
    +
    +
    +objects of wrapped class Derived may be passed where Base is expected +
    +
     >>> get_name(derived) 
     'Derived'
    -
    objects of wrapped class Derived can be passed where Derived is -expected but where type information has been lost.
    +
    +
    +objects of wrapped class Derived can be passed where Derived is +expected but where type information has been lost. +
    +
     >>> get_derived_x(derived_as_base()) 
     -1
     
    diff --git a/doc/overloading.html b/doc/overloading.html index 6979efd0..242e023f 100644 --- a/doc/overloading.html +++ b/doc/overloading.html @@ -29,7 +29,7 @@ private: }; ... -void initoverload_demo() +BOOST_PYTHON_MODULE_INIT(overload_demo) {     try     { @@ -144,12 +144,12 @@ namespace scope as Python member functions. Previous: Overridable Virtual Functions Up: Top

    - © Copyright David Abrahams 2000. Permission to copy, use, modify, + © Copyright David Abrahams 2001. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided ``as is'' without express or implied warranty, and with no claim as to its suitability for any purpose.

    - Updated: Nov 26, 2000 + Updated: Mar 6, 2001 diff --git a/doc/overriding.html b/doc/overriding.html index ae629580..7b28add1 100644 --- a/doc/overriding.html +++ b/doc/overriding.html @@ -9,7 +9,7 @@

    Overridable Virtual Functions

    - In the previous example we exposed a simple + In the previous example we exposed a simple C++ class in Python and showed that we could write a subclass. We even redefined one of the functions in our derived class. Now we will learn how to make the function behave virtually when called from C++. @@ -17,16 +17,17 @@

    Example

    -

    In this example, it is assumed that world::greet() is a virtual +

    In this example, it is assumed that hello::greet() is a virtual member function:

    -class world
    +class hello
     {
      public:
    -    world(int);
    -    virtual ~world();
    -    virtual std::string greet() const { return "hi, world"; }
    +    hello(const std::string& country) { this->country = country; }
    +    virtual std::string greet() const { return "Hello from " + country; }
    +    virtual ~hello(); // Good practice 
    +    ...
     };
     
    @@ -37,21 +38,28 @@ class world
      -
    1. A PyObject* data member that holds a - reference to the corresponding Python object. +
    2. A PyObject* data member (usually + called self) that holds a pointer to the Python object corresponding + to our C++ hello instance. -
    3. A constructor for each exposed constructor of the - base class which stores an additional initial PyObject* argument - in the data member described above. +
    4. For each exposed constructor of the + base class T, a constructor which takes the same parameters preceded by an initial + PyObject* argument. The initial argument should be stored in the self data + member described above. + +
    5. If the class being wrapped is ever returned by + value from a wrapped function, be sure you do the same for the + T's copy constructor: you'll need a constructor taking arguments + (PyObject*, const T&).
    6. An implementation of each virtual function you may wish to override in Python which uses - boost::python::callback<return-type>::call_method() to call + callback<return-type>::call_method(self, "name", args...) to call the Python override.
    7. For each non-pure virtual function meant to be overridable from Python, a static member function (or a free function) taking - a reference or pointer to the base type as the first parameter and which + a reference or pointer to the T as the first parameter and which forwards any additional parameters neccessary to the default implementation of the virtual function. See also this note if the base class virtual function is private. @@ -59,52 +67,60 @@ class world
    -struct world_callback : world
    +struct hello_callback : hello
     {
    -    world_callback(PyObject* self, int x) // 2
    -        : world(x),
    -          m_self(self) {}
    +    // hello constructor storing initial self_ parameter
    +    hello_callback(PyObject* self_, const std::string& x) // 2
    +        : hello(x), self(self_) {}
     
    -    std::string greet() const // 3
    -        { return boost::python::callback<std::string>::call_method(m_self, "get"); }
    +    // In case hello is returned by-value from a wrapped function
    +    hello_callback(PyObject* self_, const hello& x) // 3
    +        : hello(x), self(self_) {}
     
    -    static std::string default_get(const hello::world& self) const // 4
    -        { return self.world::greet(); }
    +    // Override greet to call back into Python
    +    std::string greet() const // 4
    +        { return boost::python::callback<std::string>::call_method(m_self, "greet"); }
    +
    +    // Supplies the default implementation of greet
    +    static std::string default_greet(const hello& self) const // 5
    +        { return self.hello::greet(); }
      private:
         PyObject* m_self; // 1
     };
     

    - Finally, we add world_callback to the - class_builder<> declaration in our module initialization + Finally, we add hello_callback to the + class_builder<> declaration in our module initialization function, and when we define the function, we must tell py_cpp about the default implementation:

     // Create the Python type object for our extension class
    -boost::python::class_builder<hello::world,world_callback> world_class(hello, "world");
    +"hello_class">Python type object for our extension class
    +boost::python::class_builder<hello,hello_callback> hello_class(hello, "hello");
     // Add a virtual member function
    -world_class.def(&world::get, "get", &world_callback::default_get);
    +hello_class.def(&hello::greet, "greet", &hello_callback::default_greet);
     

    - Now our subclass of hello.world behaves as expected: + Now our Python subclass of hello behaves as expected:

    ->>> class my_subclass(hello.world):
    +>>> class wordy(hello):
     ...     def greet(self):
    -...         return 'hello, world'
    +...         return hello.greet(self) + ', where the weather is fine'
     ...
    ->>> hello.length(my_subclass())
    -12
    +>>> hi2 = wordy('Florida')
    +>>> hi2.greet()
    +'Hello from Florida, where the weather is fine'
    +>>> invite(hi2)
    +'Hello from Florida, where the weather is fine! Please come soon!'
     
    -

    *You may ask, "Why do we need this derived class? This could have been designed so that everything gets done right - inside of hello::world." One of the goals of py_cpp is to be + inside of hello." One of the goals of py_cpp is to be minimally intrusive on an existing C++ design. In principle, it should be possible to expose the interface for a 3rd party library without changing it. To unintrusively hook into the virtual functions so that a Python @@ -117,10 +133,10 @@ world_class.def(&world::get, "get", &world_callback::default_get) deal with than a virtual function with a default implementation. First of all, you obviously don't need to supply a default implementation. Secondly, you don't need to call - def() on the extension_class<> instance + def() on the extension_class<> instance for the virtual function. In fact, you wouldn't want to: if the corresponding attribute on the Python class stays undefined, you'll get an - AttributeError in Python when you try to call the function, + AttributeError in Python when you try to call the function, indicating that it should have been implemented. For example:

    @@ -132,11 +148,7 @@ struct baz_callback {
         int pure(int x) { boost::python::callback<int>::call_method(m_self, "pure", x); }
     };
     
    -extern "C"
    -#ifdef _WIN32
    -__declspec(dllexport)
    -#endif
    -initfoobar()
    +BOOST_PYTHON_MODULE_INIT(foobar)
     {
         try
         {
    @@ -182,14 +194,14 @@ href="http://cs.calvin.edu/c++/C++Standard-Nov97/basic.html#basic.def.odr">ODR
           Next: Function Overloading
    -      Previous: A Simple Example Using py_cpp
    +      Previous: Exporting Classes
           Up: Top
         

    - © Copyright David Abrahams 2000. Permission to copy, use, modify, + © Copyright David Abrahams 2001. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.

    - Updated: Nov 26, 2000 + Updated: Mar 6, 2001 diff --git a/doc/pickle.html b/doc/pickle.html index 0e64d6fc..7b559e68 100644 --- a/doc/pickle.html +++ b/doc/pickle.html @@ -1,6 +1,6 @@ - BPL Pickle Support + Boost.Python Pickle Support @@ -11,7 +11,7 @@


    -

    BPL Pickle Support

    +

    Boost.Python Pickle Support

    Pickle is a Python module for object serialization, also known as persistence, marshalling, or flattening. @@ -39,16 +39,16 @@ described in detail in the Python Library Reference for pickle:

    -

    The BPL Pickle Interface

    +

    The Boost.Python Pickle Interface

    -At the user level, the BPL pickle interface involves three special +At the user level, the Boost.Python pickle interface involves three special methods:
    __getinitargs__
    - When an instance of a BPL extension class is pickled, the pickler + When an instance of a Boost.Python extension class is pickled, the pickler tests if the instance has a __getinitargs__ method. This method must return a Python tuple. When the instance is restored by the unpickler, the contents of this tuple are used as the arguments for @@ -63,7 +63,7 @@ methods: __getstate__
    - When an instance of a BPL extension class is pickled, the pickler + When an instance of a Boost.Python extension class is pickled, the pickler tests if the instance has a __getstate__ method. This method should return a Python object representing the state of the instance. @@ -76,7 +76,7 @@ methods: __setstate__
    - When an instance of a BPL extension class is restored by the + When an instance of a Boost.Python extension class is restored by the unpickler, it is first constructed using the result of __getinitargs__ as arguments (see above). Subsequently the unpickler tests if the new instance has a __setstate__ method. If so, this @@ -96,13 +96,13 @@ __setstate__ methods can do what they want.

    Pitfalls and Safety Guards

    -In BPL extension modules with many extension classes, providing +In Boost.Python extension modules with many extension classes, providing complete pickle support for all classes would be a significant overhead. In general complete pickle support should only be implemented for extension classes that will eventually be pickled. However, the -author of a BPL extension module might not anticipate correctly which +author of a Boost.Python extension module might not anticipate correctly which classes need support for pickle. Unfortunately, the pickle protocol -described above has two important pitfalls that the end user of a BPL +described above has two important pitfalls that the end user of a Boost.Python extension module might not be aware of:
    @@ -116,10 +116,10 @@ Both __getinitargs__ and __getstate__ are not defined. that of the new instance.

    - However, most C++ classes wrapped with the BPL will have member data + However, most C++ classes wrapped with Boost.Python will have member data that are not restored correctly by this procedure. To alert the user to this problem, a safety guard is provided. If both __getinitargs__ - and __getstate__ are not defined, the BPL tests if the class has an + and __getstate__ are not defined, Boost.Python tests if the class has an attribute __dict_defines_state__. An exception is raised if this attribute is not defined: @@ -151,7 +151,7 @@ Both __getinitargs__ and __getstate__ are not defined. __getstate__ is defined and the instance's __dict__ is not empty.

    - The author of a BPL extension class might provide a __getstate__ + The author of a Boost.Python extension class might provide a __getstate__ method without considering the possibilities that:

    @@ -170,7 +170,7 @@ __getstate__ is defined and the instance's __dict__ is not empty. To alert the user to this highly unobvious problem, a safety guard is provided. If __getstate__ is defined and the instance's __dict__ is - not empty, the BPL tests if the class has an attribute + not empty, Boost.Python tests if the class has an attribute __getstate_manages_dict__. An exception is raised if this attribute is not defined: diff --git a/doc/pointers.html b/doc/pointers.html index e26cea02..fdbee797 100644 --- a/doc/pointers.html +++ b/doc/pointers.html @@ -13,7 +13,7 @@

    In general, raw pointers passed to or returned from functions are problematic -for BPL because pointers have too many potential meanings. Is it an iterator? +for Boost.Python because pointers have too many potential meanings. Is it an iterator? A pointer to a single element? An array? When used as a return value, is the caller expected to manage (delete) the pointed-to object or is the pointer really just a reference? If the latter, what happens to Python references to the @@ -46,7 +46,7 @@ const Foo& f_wrapper() { return *f(); } my_module.def(f_wrapper, "f");

    -Foo must have a public copy constructor for this technique to work, since BPL +Foo must have a public copy constructor for this technique to work, since Boost.Python converts const T& values to_python by copying the T value into a new extension instance. diff --git a/doc/special.html b/doc/special.html index 50cee505..0caa1924 100644 --- a/doc/special.html +++ b/doc/special.html @@ -12,7 +12,7 @@ Overview

    - BPL supports all of the standard special method names supported by real Python class instances except __complex__ (more on the reasons my_class.def(boost::python::constructor<...>()) - (see section "A Simple Example Using BPL").

    + (see section "A Simple Example Using Boost.Python").

    __del__(self)
    @@ -104,7 +104,7 @@ std::string to_string(Foo const& f) boost::python::class_builder<Foo> foo_class(my_module, "Foo"); foo_class.def(&to_string, "__str__"); - Note that BPL also supports automatic wrapping of + Note that Boost.Python also supports automatic wrapping of __str__ and __cmp__. This is explained in the next section and the Table of Automatically Wrapped Methods. @@ -117,7 +117,7 @@ foo_class.def(&to_string, "__str__"); href="http://www.python.org/doc/current/ref/numeric-types.html">numeric protocols. This is the same basic technique used to expose to_string() as __str__() above, and is covered in detail below. BPL also supports + href="#numeric_manual">covered in detail below. Boost.Python also supports automatic wrapping of numeric operators whenever they have already been defined in C++. @@ -174,7 +174,7 @@ a = i + b; bignum_class.def(boost::python::operators<boost::python::op_add>(), boost::python::right_operand<int>()); bignum_class.def(boost::python::operators<boost::python::op_add>(), boost::python::left_operand<int>()); - BPL uses overloading to register several variants of the same + Boost.Python uses overloading to register several variants of the same operation (more on this in the context of coercion). Again, several operators can be exported at once:
    @@ -283,13 +283,13 @@ bignum_class.def(&rmod,  "__rmod__");
           coercion functions can be difficult if many type combinations must be
           supported. 
           

    - BPL solves this problem the same way that C++ does: with overloading. This technique drastically simplifies the code neccessary to support operators: you just register - operators for all desired type combinations, and BPL automatically + operators for all desired type combinations, and Boost.Python automatically ensures that the correct function is called in each case; there is no need for user-defined coercion functions. To enable operator - overloading, BPL provides a standard coercion which is implicitly + overloading, Boost.Python provides a standard coercion which is implicitly registered whenever automatic operator wrapping is used.

    If you wrap all operator functions manually, but still want to use @@ -370,7 +370,7 @@ bignum_class.def((ternary_function2)&power, "__pow__"); In the second variant, however, BigNum appears only as second argument, and in the last one it's the third argument. These functions - must be presented to BPL such that that the BigNum + must be presented to Boost.Python such that that the BigNum argument appears in first position:

    @@ -397,7 +397,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
     
     

    Table of Automatically Wrapped Methods

    - BPL can automatically wrap the following special methods: @@ -772,13 +772,13 @@ KeyError: 2

    Customized Attribute Access

    - Just like built-in Python classes, BPL extension classes support special the usual attribute access methods __getattr__, __setattr__, and __delattr__. Because writing these functions can be tedious in the common case where the attributes being accessed are - known statically, BPL checks the special names + known statically, Boost.Python checks the special names

    • @@ -794,7 +794,7 @@ KeyError: 2 following shows how we can implement a ``computed attribute'' in Python:
      ->>> class Range(AnyBPLExtensionClass):
      +>>> class Range(AnyBoost.PythonExtensionClass):
       ...    def __init__(self, start, end):
       ...        self.start = start
       ...        self.end = end
      @@ -810,7 +810,7 @@ KeyError: 2
                Direct Access to Data Members
             
             

      - BPL uses the special + Boost.Python uses the special __xxxattr__<name>__ functionality described above to allow direct access to data members through the following special functions on class_builder<> and diff --git a/doc/under-the-hood.html b/doc/under-the-hood.html index 902804d3..733f0f54 100644 --- a/doc/under-the-hood.html +++ b/doc/under-the-hood.html @@ -22,7 +22,7 @@ "example1.html#add_world_class">add it to the module it goes into the module's dictionary to be looked up under the name "world".

      - BPL uses C++'s template argument deduction mechanism to determine the + Boost.Python uses C++'s template argument deduction mechanism to determine the types of arguments to functions (except constructors, for which we must provide an argument list because they can't be named in C++). Then, it calls the appropriate @@ -48,7 +48,7 @@ the top of your module's init function, then def the member functions later to avoid problems with inter-class dependencies.

      - Next: Building a Module with BPL + Next: Building a Module with Boost.Python Previous: Special Method and Operator Support Up: Top

      From 00cea4ff83e2d64c3273fab652171cf4ca192a88 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 7 Mar 2001 03:40:47 +0000 Subject: [PATCH 0017/1042] Added getting_started targets [SVN r9471] --- build/build.dsw | 34 ++++++++++++++++++++++++++++++++++ build/build.opt | Bin 86528 -> 116224 bytes 2 files changed, 34 insertions(+) diff --git a/build/build.dsw b/build/build.dsw index f4ee1a11..8de38493 100644 --- a/build/build.dsw +++ b/build/build.dsw @@ -30,6 +30,40 @@ Package=<4> ############################################################################### +Project: "getting_started1"=.\getting_started1\getting_started1.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name bpl_static + End Project Dependency +}}} + +############################################################################### + +Project: "getting_started2"=.\getting_started2\getting_started2.dsp - Package Owner=<4> + +Package=<5> +{{{ + begin source code control + getting_started2 + .\getting_started2 + end source code control +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name bpl_static + End Project Dependency +}}} + +############################################################################### + Project: "rwgk1"=.\rwgk1\rwgk1.dsp - Package Owner=<4> Package=<5> diff --git a/build/build.opt b/build/build.opt index 5086795feff7997de1d0b50d82b2404da330c819..89eb84a706504d37bff9685be4808fda8baf9b81 100644 GIT binary patch literal 116224 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;!F$-42&?o00YCn|NsAkxG);Tu3}(d_&*AU zObGn_|Np-N0|Nsy0|NsK0|Nsq0|PkD*%=rZI2afhI2jlixEL51xEUbv&C9^Rz{kMA zz|X+IAi%)DAjrVLAjH7HAk4tPAi}`FAPQ9{&cMJR!N9;E$-uxM#lXNI&A`AQ!@$5G z%fP@O$H2fK4^(z@W##z@X2-z+k|@z+lM0z+l9{z+lY4z+eJZXU4$5V9vn6V8Ot^V9CJ1V8y_| zV9mh5V8g(`V9UV3V8_6~V9&t7;K0DZ;K;zh;Kabd;LO0l;KIPb;L50|P@M0|P@60|P@c0|P?} z0|P@UR8Kks149M_14AYQ149-A14A|g149l214AwY14AAI14BLo1497=14AJL149u5 z14A(b149V|14AhT149`D14B6j149J^14AX$JWxE>FfcIGGB7aIF)%RHGcYhTfZd+Y zkk3%UpuphDkjGHMPz2Ti%E`oGF$Pw6en&1VumLn?y;Loh=LLn1>7I4rQ5gCwZHz{Cj3Y@l=rqLHLDA=7H=6VPf=) zffPaQXJlXn=XaKp)Z!8iXRDZ`{QTmQn4HX{;+TTUl8pSkn55FooRk=lJebf+DJ}rj z0$fQ2Iq}6Mi6xoInt1dfRKYZ|7L})G8*1Uv16B|NCSjU5QY#X33vyBo4e;oLsfmFx zV7dj;Q%g!R^U^`?Eh~hEf)gs8gN9V)j%%dNInlmsioPNPx3)WJQ+6AUT64>g% zhO5T{Kng$@)W!v=gEoJlOb7*%2eF_us3{C?+nhan_AHV(xS>X@`$0Vv3wSo2B`&=%pe*WlUeV8jX*XJZV9N*Ph`CbD}_ON zQR^KBaQy=k2Vsz9Ao?Em^Z-N*|7$gSbg6LZy1`-B|fw&<0Hi&_QL1G{-h`s}2 zAYqUghzp|cf*42`BnIMw=zAar5(bHZxFGsIh=GJbVjwPz2C-rIO~wJxP!gC68V9?f z!o>p`QveGvFff2?Wyo+1Ob9&Q2H|jkYG4SHfq~%%!*50=1|Eh3&#y8V{6mED1gOQ# zOpJy;rOBBoi3-m7dBypk7#NvAtp%9+?~DJGUl8D`1&t|y#{Q7q0V}&46XK1dA+!_0%J0nsNI7#OBOryW3QK==$31A_*%tOKb5VVF9Q zu^=@djLSTbdXRRI8W6^(4x|=jCbp4I^x;1Akvc=zNFDm9;^_F_;7;qKWzpb@A5bP7 z#Um#KM#uj~$Nxsh{{~kXJQC}~kyGN1`VT?anRi00<@%T$Nxs_bXeLLrH58p;9y{8@b&TXVPfD6 zNi8mME-flcRdlh6DK1KmNh~fXOEv>hp(U9)Fj_CUpkOO#xg%)hZ$N5MT7FS(VqS8p zf{{W%eo+Zw&AQMzh0*ap;FdAJu(cfvV+pH9@K^y#Um#KM#uj~$Nxsh|3+3B zPiY-N3;iRf#2xi1CDwebJyY5+7D#U}6N7p`bGYkk_o^)1wHIgzi5MX2@qKWhesg{ElaE zX2^%`LeFQ&VTfn&WXNMk1MhVQX~Bjy7(lC+K{i7$HZ|yC+8_a_{hkZ~44w?}3`ql2}d(Sh$JMuva@nbm#CPvVrL(qapkPGmuhRB+NDA3^r;PV9__NOvbFeEbMf?bgc zKGguEh%lCd?tcf_4Z?(VFfjOn6oC$B058B~Wx!a+$myJuSX>;InOe?jqhIM!4*HCVrUePoDdit{~aCw9UcE2TxIY`tP@90i9703 zPzZqfr=#P)qvOAzv;f1PGy!6R=+W`t(edArSPzc+d9*F&I0tg(E5;b0b~5g>AkoL) z7)Vi!VUvJOUVe!}a(-S(QGQNNYKol*HmeyJz(-UPs~B>~B(bXDr%PgJ;DEV>fdT2j zOYo@Z==k3VTdz1;UQ)Nb1hv0L@yH2*(ec00@xRgWKkAmDqjeJL;W=_j+)x$ zz)c_}P+L(J9WpX-K|?$VOXoXnC+{Lbeo zNGwUt$Vn|r#cL@~PG&I??&nP|BP!6iGxJJ{k~311v+?;6|omo=BDQ2Q^8xDlbK9Z@Pi9(!d?Rv z3WQbhC6%V7r4|uZ$eUjPse%X;;Jn4TiA5#x1tkRPDsD){QB<0TFH|@PJB**`x`ihv zpO`eklUABXL|)}cPAo3LpXE79DnW@0U(L=BQbJUk7AYx8%qs?+`9qxY#GK6Zyxi2h z5~7sz7boTtS58QxyCc51AT=3(KnOyjktmlynpZ?Ln}|)3#HBRilM&&(OjIL=$Ye%j z(~ro82X$MB#8+1&wE+pYhe@p3h$uyfZBp_Q*<2*1jY4E2kk|s1s74?W?Gz%KeMC0q zh;JPd(^98P#5975>yHfPMjdet6jFOF#P*r!+C(I_aYsa}p2$WF zAEbW|sdw?Uu!w2B65U87Vl;p{%_edhA;dSeNNKJR-*6Hktwly+dynX56Om;%kwX+j zb@GU)e~Ij76Wit^wiF<~h9cZkB(i=Yrj{VN&?B;qKvXqL+*l*welc-fdtw`|)E=E6 zrj8}tSR$@(K|=8ly7wJlaZOycPkh6i=xUJY3Wad%ow(s=B3jVIwIGP>Xc1k>k=XeF zIg;?;ED<$7alK07#yE)W#t_?IB)<1dR0EiZaamFu=Y)Ih#Ef?n(^?{_uS;ydlRC{N z;u|Z(HO8 z#=yYvhLs&@KLBJG07(1=t5mX8Oi6xzPH_xml^&GRORY!+DR{{`SvONbH(5amvVK+} zBQ+-{-&z66%P+Q8$S>AQ&Pd5D(ooma(}y6?!NBU8a8)V!$siFlrBIh6sRJpBhYA~7 zE1+=oic0e|qSbZF)MGW3KpP8w!#6O9!L-1`0356!MUd?aAdkFZWd)0Z*hARYkf;NB z4dH*h2?V4R5(*#|L^~)924}>AT=s%h13gWGE=mk=b}G%xNr9%%_!L+QeZ$HPj#x-8 z0(lYb?5OX2q==y&mmVpy7Ur6FScP702i|AQzqF3G!xfF%Cl@mm)93p<|naHJcM6MU0(v0lr`hU=t zNTj`vkV=4vDu&n;NnA=JJ{b|t%fzkJAa0w<==y)ywppY!LSofML@7e-It*eL&JeMB ziO3a}L~p1XUH=c>HcrIaAtD!>lG^GZW@RU0`O|p@MkZ!P9)>Uf|NjSd6JU4(Xfr&cxI3za>fXabUJhDQ-kl_LoGsw%# z`V0&p3}TOBx`zPl{=*`Ma)xwufqPey^Hq4y8M>@Q(R zWdPm12$CWN3o$S;@-Z+l@G~$l5Nm%L$N~)z!N35sKb;|!p@g9XeDh^GLp<0mi3~*y zAa|wU2^B2{CPr2U1_o{t?5_q{Z37~RwciM$7z?RI#{HKwLFTA{2nGh&{EsB$@P5lo;qx8j&h7M~&h3B=h0og1U~UI$0eE5u%to2j0S*46PE;XA@`b_5 z;T{H$_=D6FF_kkIJqekM0!>yxW@JDtglBQbJ4hWw2gviNQy(Cam#l-&wLe3bp8iibRmrzkIw(#J}{5?oq^=+vLj{FAEYWEqUIQ#|3OaM#2q|I z?0#P2wrCT-&77n?v4nS!kIw%XEj~Gn@Ln94~t25zxRld<+{pXwLx>L?8Lb zsuHUpXvmbY0kpyc#6pY>6C4;vjI=`rj(bq&0+RCci%a4mdqUztP9$+&0CXaGQEEnN zUU6nws=TToJjxxqsSWIsIIz+?X)&qBNnay=2A zg^aj^6u)F0bY6u-8^}+H(QgS%Pb0QCK)epp@Cr0B#xMx|1#;3GR$e`QaC||W4icmG zbO6>|0m}DSQVmELXSjkSN90_9Ao!r;_$1Kwnp6U3xf8Jzng?`BJLH&ue8-^^vzDGC zFF%jKT?<4X|5#p>SO6{0@Sk8VoLW%=Dz@_T;=uufUo|&aO)8a+$|rW9ixae#oPeE( z^@jzx2LnkQUf~6;WG>0f&m&+rH)J~kAyq_Ow8B@MnVy$eQd&ePkOedIGE3rNF2o;g zLiG}b$kPzeuVd9DaF4(O-_;NRqYuQOZ z{WLQ#Jtws!KM#NO62HWsA9SThJS4f|H6NH;>oZ};U12HiNt`oOalW^0OwB8zt#|#rQ%}4yqIMFlm zM0P2OYYG!Lzfas@^MpG@#N7lyO!t+@+X6sy;e<;SqFRC=qXfScWC6|9&Is*dJn;M~d4`PY z8V!Nb5Eu=C(GVC7fzc2cQX$aDz`)SNz`)SVz`)SLz`)STz`)SPz`)SXz`)SKz`)SS zz`)SOz`)SWz`)SMz`)SUz`)SQz`)SYz`!tpfq`Kn0|Ub(1_p-73=9lY7#J9)GB7Yq zV_;yI&cMJhgMoqJ-~a#rXE87^%w}LkLUmVtp`9RmZydIkoD4Gatn z8yOfFHZd?TY-V6!*uucTuobFyI|Bp54h9B>oeT^NyBHW4b~7+A>|tPF*vr7cu#bU( zVLw#eK?VkfLktWIhZz_cjxaDV9A#i&IL5%haGZgG;RFK%!$}4PhEog-45t|w7|t*- zFq~yzU^vIXz;K>{f#CuJ1H(lI28K%v3=Ef{=7CyJ*BBTWt}`$&++bi}xXHl4aEpO~ z;Wh&U!yN_&hPw<54EGoq816GLFg##jV0Z}C2RgfAATVtGr(Ak!Nl9j2dVFz7Vo^zI ziXrNnMiF#r^i`n*^edq2hZ_%FY6@zDLe7GQEW{&l_BZ+p(M_l;MA2;{v_KSkN;lGZ z-^G>1)(XXy#d-yaB^i2&1)$^qK&Obu#DLa5A}IuM<1y{SDvVfM3Oy(s+u}+BAxUyT zA+IhSM!}?l9_H{Ag|w&>J+MeTy&H3d=u6gN6ok+frRaxP5X`Hf3XVW31t}pahCm9T z?id!QToAuVftZB_q%Q0sdbtbX#j8Xt)gf|jmdIHtBGy)swA6vRmO(1P1m)M02 zB}IvO#cBCPx$z}MiJ2t?7UL1W_J-IAeqyGOiM&pps8w6Uu2&*vnFFayCwPmAo02AK zAy|H1T4p-_6`8~=Atz^ImAFZ4B367+`zCu*mMjsq2m>;6PAF3ly?TuBx)>totO>9C zAZ|vVs0HT4E;%Ch++XnK(nIWeTf%Eih+OAKpits8XVpd?$Y`q~ViyjFt9)_%1BH|Pw5*wJr z#W0asos^oJ$a0O?G(%ioC#Ri6M5CUlW%xvuaKvr2<0rbULTopVxRsH_W_04au0%C( zi0t+eS0)gyaf#_p6H~Gf+fg8;pdh~MMohPX$VLM(y(l7k@FexSiAx;B?UEv5On~?{ zAkhN?wCTSS-TO@@Tz3=Gfg-hsOwzJ^;#(uc?l>WOOBadFN#aH(U^{aObT^6XeG}1K zC%$1ye2IipoiSMP6*kmR=c0oi-lW=dJ*d8-+dr?Vgj}ke~Ky<$vRD%*O zGKlJl5ZenPc7&1WUMaB_6EP}HTvwlP+nw0q3R1`Di5Oudy4yfZqlZ-Y5!?7AqPQU< zwuo$j5ZRa{qP;*;TZZT+0}By!k}=u>!zZN!q;AtI{fPSju~k*C~{(76ZC!VvC!5IY`BM9&VCs7BNr0`bGL zkZuDq30hq>ibq3WGz3ONU^E0qLjW@b{xdSNF$pj*jPC!$44YAr(GVC7fzc2c4S~@R z7!85Z5Eu=C(GVDJA%JWDuMz5YO7#7|MuhhNqUlH9Q;3j8+W!mL4NKJiUqbsZjp)4N z*T`A{+m2r&lpVhypCL9bgHjUuE=okOfH$#%G!VQ$W(WrbWNR{LlP)CcK`g{AGwAzA z(E^98Yg<4eitXl?AsL9E;DQ7kC@n!JUC?*)5=df5I)}yn+X0#fDJd<;A>zJtVwYl% zym=7fXE_M3+!|dKm6u$JbSLlVswn(>bw^i4A*U8n*NqdqVPd4LiXwU;JF&~BMps3_ zSCovdigHN>okWz1TELI4ipont3lbtXNfEJCgXlHvL~gevZbxBeUJ2o4H8fcjMf}zj z;?_?M z=>0DvEyhRvI~oFr5b$IOVDMy!M+lI};$mQ8K)$zt80~97ibOyJ1A{X|4nrbCF+(v! z7(*sQDnmJg0z)`MCPN-W3PV0aIYbd2Qi%-vw}H%q+V8@U%8}0gw$EAcBFxg(06InW2;+mm!rQkD-L27$QtGDME(*S3suAfCvT#*!nLS2Ck%n z9MJ6#C7H<#42%qDt3enU;G@0C1qGm$Cn&o_p<)3ra1{FD*(=MVNpT79ax! z(C-=mg&n$}5d#AQBWqE4dN$SUWdW@zqn0N?xfJAX7-nH$U;tZybp02;1J?+jiZ#0a z3v)3}a$-(SQetv8{&kq6r(&Tl>l!^33(HzJB2S{GJ!^LKzDx| z{JYNZees|23j$oVJPZsBoD2*M%&_hv0|Ns)6i)#4i5VCe5};V_zq|qi1A`ezDM$*Y zZj?rZ*=SgdhQ(k^1B?u;44_SM|Nk>Ga5FeN=M=l;qy*>WCn1drf%A0(d{hX+g$xxz z*x+F#2orr&%n-XUXt0c-Bp!C`x*l{W550Q{6&@Y`3q~8DBx4YBbo?*1A{CU>NB4h* zXXY6jDS)>agR&=d=nQSdpNqjcpeR4fy(qu50ICAAgc>dF;Z%n)u8vbBQdz^uAOx{D zHMs=Qw};wK#6?P@k%q)RRaW(Hx*1qDer`M@Zy{$xaK^K;f=F0d zl~fj_+JF}Gf>w`OSp_AQholylC}`Pf>gegkz!6xNK17p#N@_`BW{!SpMM-L2ab|vA zJosW4P`8;%iO9&v5??CXL!RH95{pv@x5o~U=P{SmqRg_?6vN@{IitbtxfA5YoHKN( z3n{G2fe*aVGubX z2ayxGLF8mOsDp@`qEzITpO2J`-175btp5B0VBg_myOE@GzT^rOB>LJI0gO(qHuvW5FOi6xz4$4qOL2^=Q zW=;xpbi&9WK1DAjCx-$3YXt{q$oc}*BK-V@-hblqXREY)Tt;nF&ies#K6!X>XKNJ2;N3%+EP6kJmC@{4j4a}@kR*A?f%mGm(%91wvj$t=rENmWRyRESC~ z%7>Yu26jbWSz=CRih@gKaY24@CbBE~5e9hXrB);+mna0K7MJG0eLsPL;ea^A22ZFl zU^gHeGLeDd03SpRs2!D-lMmjT3<`xw3=9VZAyUC5iOJat&Kar6@W7wUz;J*cA{&~Q zl3IkUQ=Ea}0H>fg%o&pM3 z&%Bb<^wc5+7p&n%gp#SCbOAF3-QUwdRs*Qq798XpLxfflG}FOGgLdq)g(sFI zXBaXtKo~|ahB1s`!oaYBiGd*i*U-E;kt% z7+yo&3!|Z2q;LUGVnJs%Vj!!zVnD;oJw_|l6OJiTBG7et!LC@7#x*oZMOFo5t$ zXxOj~aM<)QFfh!6CK4D8~Ixb%4VJ2rFX?6X&3i7|?LNpKG|Db3g!93KviY0^xtqKw%l+Kv}}b zz_1lm3Nj#QP=J820`^P3`_$YIQtkF7_Nds0*Qul8D!vr z11WRiOLnN1R6rRAgr7k}gK>aE<0Gilhh`ozC=Ck@gJjr-2uNr^rUhX&Gumn>s)bMl z0|NsHb3-!|!vKd6C^Wc11Oo#DjD~Uub>Z0Y*b-<(RfI*3BbRF>MI^dGzjL~(#pekt;lN(z@W##z@X2-z+k|@z+lM0z+l9{z+lY4z+eJZXU4$5V9vn6V8Ot^V9CJ1V8y_| zV9mh5V8g(`V9UV3V8_6~V9&t7;K0DZ;K;zh-~`p@!oa}b%D}+j#=yYf&cMLn!N9=a z$-uzi#lXPe&A`Cm!@$7c%fP_k2UXw9z`zj5z`zj1z`zj9z`zi~z`zj7z`zj3z`zjB zz`zi}z`zj6z`zj2z`zg<)f3CWz!1m4z!1;Cz>vVez>vtmz>vhiz>v(qz>vbgz>vzo zz>vnkz>vvYfz>vwnz>vkjz>v+rz>vehz>o_yC!c|Vp@4ybp^$-rp@@Njp_qYz zp@e~fp_GAvp^Slnp&Y6X6u(sr3=Gu_3=B043=Fjl3=DM)3=H)Q3=9omx92nDGn6nW zFt{@0F_bVAF;s%GG0|9zffb(Lk;@8f1}MDhZ&P1-fDyU82xrJ=C}PNFC}t>NNMuN6 zNM%r92xcf@NMtAhhXposki`@jm>5Bs4U|4XG_o8nHmDo}CsuIW7ct~Blrt1Fq=Lf{ zmmXZ=0t`%ypu7XhE5zE*12PPhS-|Nng&~un1RM$=VNx+40}~@Ce}e1=VPf=)ffPaQ zXJlXn=X;it)Z!8iXRDZ`{QTmQn4HX{;+TTUl8pSkn55FooRk=lJebf+DJ}rj0$fQ2 zIq}6Mi6xoInt1dfRKYZ|7L})G8*1Uv16B|NCSjU5QY#X33vyBo4e;oLsfmFxV7fu& z8Z(0=0}}&N5vYa&;cJWx41A0X3}#FW4BJ2<0>z+E1YuJq28NxCkdl#+fuR8;whOAB zxq&k%H9fPqB(QB7&j>2DL2QtZKw${NfBygf|MLI; z{~$RK-p|CqFbx#e4V>ZmMcKs#iOH#EoS;BrW?*GtWDqC@nFxwCSh${rhAqfsQ2zV( z|9?HmKe;G1H4l`#K_-B_%Ul8~lR+`52(2SQW`Qu+MGd@Q+ZB8> z^D>=@z$s+&Q9&Cc-u zKV#`xGyt+0gdw(b1f>?|mlh?bLNtN0+W-H|1T?X^WG3e1r^|!Gor!^&;s1XYtXg1h z1(){F5G#d;7>9FyUP)1YPBAFBKn)*|L9C?)po9pjl0k(6)YC`~b}vdS$jD4C7G(sr zmRP{Hvw<~%6jd=XFnBRS>VFU)2*TY)lv<14B6z z1H)-XNRtBHm?I1f3{BAH26F>vNNPoiLP&mojyMa*L68vSD4hg#xdsyh!wG0cftkeI zz~Y*cSpo}kCQ$8-HT)17SY1++O4H52Ar5NM{r}HUwulkZ=4)kww2eTjVIdAmqqYnT z4O1Bz7$(C*oXx2yzq~jV)c67=PmsloWoYT+EXWuT1_d2+18ZPuYEdPqsR+^`3(CLc z_;m=lB$gy5B^IYDxMU`#7bWH*Yi1;%nKdLaDJKp3*%;gr0kVa)E zBczcB@(~C_e8m!$nOcr)3k#^R29kqgkYW%92{1SC1%q>m0yN3OLJ(Xq5^x|}P-=31 zQ3}j935Ngw69{PG49~1eEJ|@oEHZ+|I1j`B{~hHMnHU&AF*<>nf#EAOfg#8Epa1{s zGng0{BAFni(t|hsjQ{^LGH@_ByW}Tlhv%g*GRUwnH2nJizaA9%utF8mhm-=f%E5Ik z0|RT3BttQ%RR?OMf`Wj7f#JoR4o2k$CQ$#g;V0CDzu+<-s(_&a)E}*fmk1H+6W1_q^K28OA{3=Fy@3=9S(3=D=P3=E|u3=ES>7#P-;Ffgny zVPM!^!oYB^gn@yjl!1Z0l!1Yxlz}0vl!2kDl!0MFDFefiQU-=&r3?(`N*Ng5mNGDW zC}m*ySjxcQSjNE6TE@U|v5bL1qMU&trksIcWjO=GnQ{h(kL3&uIu#5IdKC-|W)%z! zu@wvqy%h`$eH9E02P+sDu2nEFysKbf(5Pf!aI9otNUmgHSW?NraIlhr;cX=YgJ~55 zLs%69Lr)b0!)<5>&7qosVOliIMdeoec~OyFeYgMg|70Mg|7$Mg|7cMg|7Y zMg|6-Mg|7oMh1r2jSLL88yOgsniv?on-~~6niv?mniv=+H!(2mYhqw{+{D1}q=|t+ zvYCNFu9<-$rI~@DznOtyW-|lBnq~%u_00?n8=4syZZ|V9+-+uHc-G9oAkxCXpx?s4 zVA8_CP}{=5P}jo1u)BqU;dKiGgJ3HIgLEqcgMBLlgHtO5gL5kbgIg;DLv||zLtZNb zLw+j*Lw73!!T43AqG7zElF7=+pw7=+sx81&m17&6)z7&_Y+7`odS7oeT`$I~f>QyBHYQyBHWax)>N#x)>Pzx)>M& zx)>PhyBHW6yBHXnx)>Oyb}=yA>0)5G*Tujf-Oa$@*v-HY*Ui9?(9OV**v-ID(#^oI zx0``se>VdIQx5}!Mh^o+a1R4RK@S5%Q4a${aSsDSTMq-nnH~m)b3F_U-+LGse)cdh z{OVy~;O%8#i0oxxi0)-zXzyiU=Q+;FgpJCe{}qBbo_60{BLypZ*=@` zbo>w6JQ$@0Q3(8pj{k8eq_f;e0CoEZk>f_4G8zJ-Awbg*;9y{8@b&TXVPfD6Ni8mM zE-flcRdlh6DK1KmNh~fXOEv>hp(U9)Fj_CUpkOO#xg%)hZ$N5MT7FS(VqS8pf{{W% zeo+Zw&AOn45+F|{_?fbS)*1gu&}DnhzyO+=XZXAaJR->elLM&(VbH+dS3GjR@yPu{ zlLOf&zzDIAWiP6IAUQ#(92*unA*dWT7P%KtKM0`7f!q(mAU}xWk(0t92O4dWMUw-$ zlNIU~Y;wX-IVCLmM4*cZRj|mh;gMs9nu)Ftu$Z6w|)4?NW zh(it(W+rHIpfKZr`T?69%$??F`at3!4Dy5M`=8~YC4e_rY{6+4Bo4wLIcYp{N;u>| zdX@3Wf#gT=Xb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S0iBLx1lLe~FPFzPdmj{i|3 zL`TgS4S}H(0@(Inhcjd{ecgC|2CLmC5UuRBN|Hmm{N{|&Mmgt4hX7t;m_K=(g; zG6XPqGQ=|^F%*DpEQanq&jjzt2PwplwAhj4-g2OE{Cl#Sb9=>^3K^?qnT-{2+M4_N4KPxr4M59HEaR{JT3Q+?g(R{-&I{wQ5 zABP8xosN$GGBAve{}L{fMpcZ4z-S1JhQMeDjE2By2#kinXb6mkz-R~z&JY+K{~et1 zGU}?)5THj0IL?6_9426smtUfg3^^1nCpE=RBpJ(DkPMKqLShv|PI@F(HT;N23=JGG zw=gguojM5`KO7zZ1D&ahwq6l5RyVr-lYs%-8qd-7pY$kIM(r34fzc2c4S~@R7!85Z z5Eu=C(GVC7fzc2cj3F>O{x=w7Wzu z0~aK;-HY-|3!o}kIYeB%!ci7L;!($(l3KvXAj076l3I|Omy(*7T z=jNxB=A`0N#g&|&mzJ51-%1Y1NB@t>!6L$*dNy$tmB7iwEa|`l|O7L06lbfGXTv|X#8GB}O zD*mLwnM~OC{H1xB$@wWnWMPhiNQPIs?l$e)Jgw1@psU;ctDTF=4 zm6%jqQk0mCH+Z>0DpHdY2_)U*{JgT%qTDAW0i6LX0xhae3$WD?Zg8^xm`Fd71*Auv!OFgpG>P$55R?`Q}Nd{0*PL6oYAjhXFWPL5d(VpCFICVTIhV4q^{s zUqhk}3v$^DRt@wt2|6e}z}cxZGbaU_KI2nhDfA61 zH#oW>xd`M*M94sAK+&g{ab_A&fq)}5fu!&TG)Mu|K59=a^97|ALvE)BP3sopnSw^z zxx>gH1ewrIO)f!9NJCvn%^7IOXe-esLX<D&7#J9M85kIdwLb=Ayb6dw*bm{6PI56Yf$as^4Z_5j zkOxu(J%8SrA%`K6p_rkVA&eoDA(f$=L4kq9^Y=-%zY@uQ*!+(qf!SpEQDuq$2&+JL(d<{s*?_6KR}!bpID<6D(4IjPCzJ z3y{(MUzJG7V|4!)V%BeT{}+4$baek0sGTy3M?+vV1cqV=jL!cI#aJ74^JoZACj>_4 zf2b3Vqo$08z)%bU*!aH$Xy6-l3>&g)odYC+KKhSSwFpQx+!&;>f5ryTEy18cRKyrD z!2xo_h&yBexd(MlASpk;xFjC3HzXcpF^Tg7pmT(ZQZrKXiZjbntrbwXh|zx?1$ABB zq@w)n)I8n9(vp1Lf|4T4jUGZE`{5o3&jElu3-LC{^+b3UGV%^m{E~Ihc@+|EAU`2S z!Eq)7kTQtZL9ADx%b^(tp}#;*dc(@Arw@)VNO}i}QF~edYpwv57FbdZNEm0hf+R=h z1dtCCL?7|zCGyxi;!h;w0iDAHImip&fk&jCLPzYmQ$!zRMdHClM4nqmR02-qFE2_gfHs-%JCFE*Z6eR4B<^rlBF?}h_ViF< zXKaW)p^)%iCr;3zbOd66*fUzNS%AtRJ#hK}Oi6x~)1d}g>myZBDIB$IJ>rEG4e$CI0M8Vo!%9 zYSSk%CkqpK3MXlYOT&(q#+PG>If0m*U3*kKla}~HJ&9bs!c&w8s<%Ps+~Nxw>sO)G64A&5Vt^bi>KsuihbR{I(o=u0 z2g;-=R19MV3@VN^g9a5ro4J6Bq7U*yh2bOXP(E~?1t7Jo1>U?|5p z!jb_wEI`YaSiw7dsbv}qXsHkb10y3w5DS8)E#NDX^sxJnkpWFv1|&WRdjoxcItv2> z1K2T0Q4jGdJOuy$XJCMwX*;_9CkERwub`ZOSP%tWn}fbBcy#>_-R>M6UH?Pm#bu-G ze-Qf_QK~Y$7uJrh|A7{9qw9a5MH)HBuOkuK$5%u+jBDm>Fzz z{ZBITkp!dbe{kI^Kf3-0GxK0y{{z|oo5}{8|0Dg@-qH0x!*y(E)L+9t1R5C_7@8Ou z824}E=n&@U_-}l1 zNn%N6GH5gz8d{^{zeObq1G|M6wAXWV|0iU{Gsg4*7vzdA_oDpL0%)HUq7tcO7AWPtK3HSe=^`4LMcwnO(kw?Z%Srz3E|CPqx(O>7o&~t z|3odGNB4hXIh=WP|0hOKjlMJp@7&tx`0wcWZ*Z_v(CGe8(5TEP9t{CpA>hK0%8XgnM3bQVhmc1{ ziP1OSEo>Sm@r6TJcJVul8txKbMf)1RnRjsMRqkP2$1=sj;3Bn8yg^p z><|g*A?#?-904fA(L;KFby`t=F7)swo=(I>so*Vqhb02x03`$MTFG?BQ@wb;uuO;TC z5ArhQ2zfs9FH0@T$xloHrOd${b!2)FIqMB>5AG%}2Ho=W2e-fevoKbJ+ZBk`2&91# zkJhq?ha4YTl3G-Z)Kqaa)Iqdc9KqcUP*G}UWmTM;SX2^UP*N0Mk`HSE6_=z~S%FUE z28pAXGO#Tjb3=SBo&VgF1(A^sS^z_uZdO(qsW~a}nR&$}iFwJX$iZP`r+^~__4M=x zv`t7Lq$o>FPRNPLiQL5GWH_i36F)_X3DiCzH93Lw4AlfhS=MvQ&qper-175b^$m{P z1|3DYpX5axK zTwVG9LIa<623>%G0t@G@4j@So)=IXDDap^zK^Z?SNCqD^4;@l9GKf#nOUcP$kY!+C zU}a!*-~?TOP?Vpe>kMmja4;}B@WMo$ic%A^VKPh%3=N_#i6x1k5h4ZO%;LnH%=En6 z)Vvay3RVV&0|Ji8$*IM~3SpV~IpEV%VUlbN3j)H$dYEfbyTuC1T!vPVflFYKqlvIVJN`O!v-b>h5(Q|L4F#=qalDL1V+#Q!xAW?LZcxtLPB8l{J#+r(WBlR4FN16P|w^r zdj2Pta2XXE4S~@R7!85Z5Eu=C;T!^N42%q%3>BuTBNlnht($q+TFFXXVR?xJ=vT|6#pu)hw z!rUY^(FC!G*oXnN8XRK33xtA`YB-k{!|pyT2A!6xR&C_yYGm$c?5t~O?q;fMXy{^~ z>*!|aq-$W{Xy9yV;AZLKYF5j@09|~}02&+vEwcpSKmY&#fBFCae~=sq-)CfC*u}`e zz&^m?a+869;WacQU^JA=fCv}xWFvHvAO^A|AOZGgiCUwYAkrx$GDf=DwN1qD!wzP=x%uCKGO-YUM zb@lZRill0oTw;RcBbEUU6Oi9QafD2R*dVNoEliw)LSjI}^nR}4dd>j>R4H6Q83=^` zK?8+(fCFU-BLl-$P$|fOpg{ow!V1_k5oi+#Ct z7(|e0ko!Pb8y+IayIerWxyN9f+)kC`0;-2V_yRKngEkLV)D`Tzj?)(`FZilIf=!^*w@=TB^E=@|1GhCo&ReE z={w?HPCmN+7u4RfvKn3gi!WV`uKy*jkQ!b8TZFa;$SIKuX=il(Z+>10XjSm&`rrIK eP?roe#4)=5cXa(P+7jc@^}nFZF^WfS2mk=&D+65s From 98b31ed07389a28079818dc2806674e5da1f2137 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 7 Mar 2001 03:53:14 +0000 Subject: [PATCH 0018/1042] use BOOST_PYTHON_MODULE_INIT, update getting_started2 for better documentation [SVN r9472] --- example/getting_started1.cpp | 4 +--- example/getting_started2.cpp | 33 ++++++++++++++++---------------- example/getting_started3.cpp | 4 +--- example/getting_started4.cpp | 4 +--- example/getting_started5.cpp | 4 +--- example/test_getting_started2.py | 26 +++++++++++++++++-------- 6 files changed, 38 insertions(+), 37 deletions(-) diff --git a/example/getting_started1.cpp b/example/getting_started1.cpp index 9679a2a4..7a8e9087 100644 --- a/example/getting_started1.cpp +++ b/example/getting_started1.cpp @@ -12,9 +12,7 @@ namespace python = boost::python; // Python requires an exported function called init in every // extension module. This is where we build the module contents. -extern "C" -DL_EXPORT(void) -initgetting_started1() +BOOST_PYTHON_MODULE_INIT(getting_started1) { try { diff --git a/example/getting_started2.cpp b/example/getting_started2.cpp index 82b4a6df..72b04105 100644 --- a/example/getting_started2.cpp +++ b/example/getting_started2.cpp @@ -1,29 +1,28 @@ #include #include -#include -namespace python = boost::python; namespace { // Avoid cluttering the global namespace. // A friendly class. - class world + class hello { + public: + hello(const std::string& country) { this->country = country; } + std::string greet() const { return "Hello from " + country; } private: std::string country; - public: - world(const std::string& country) { this->country = country; } - std::string greet() const { return "Hello from " + country + "!"; } }; - // A function taking a world object as an argument. - std::string invite(const world& w) { - return w.greet() + " Please come soon!"; + // A function taking a hello object as an argument. + std::string invite(const hello& w) { + return w.greet() + "! Please come soon!"; } } -extern "C" -DL_EXPORT(void) -initgetting_started2() +#include +namespace python = boost::python; + +BOOST_PYTHON_MODULE_INIT(getting_started2) { try { @@ -31,18 +30,18 @@ initgetting_started2() python::module_builder this_module("getting_started2"); // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); + python::class_builder hello_class(this_module, "hello"); // Add the __init__ function. - world_class.def(python::constructor()); + hello_class.def(python::constructor()); // Add a regular member function. - world_class.def(&world::greet, "greet"); + hello_class.def(&hello::greet, "greet"); // Add invite() as a regular function to the module. this_module.def(invite, "invite"); - // Even better, invite() can also be made a member of world_class!!! - world_class.def(invite, "invite"); + // Even better, invite() can also be made a member of hello_class!!! + hello_class.def(invite, "invite"); } catch(...) { diff --git a/example/getting_started3.cpp b/example/getting_started3.cpp index 7e827249..799f5cac 100644 --- a/example/getting_started3.cpp +++ b/example/getting_started3.cpp @@ -91,9 +91,7 @@ namespace { // Avoid cluttering the global namespace. } } -extern "C" -DL_EXPORT(void) -initgetting_started3() +BOOST_PYTHON_MODULE_INIT(getting_started3) { try { diff --git a/example/getting_started4.cpp b/example/getting_started4.cpp index 0c7bd7ee..199ef7a9 100644 --- a/example/getting_started4.cpp +++ b/example/getting_started4.cpp @@ -74,9 +74,7 @@ namespace { // Avoid cluttering the global namespace. } } -extern "C" -DL_EXPORT(void) -initgetting_started4() +BOOST_PYTHON_MODULE_INIT(getting_started4) { try { diff --git a/example/getting_started5.cpp b/example/getting_started5.cpp index c9f1ce36..be033224 100644 --- a/example/getting_started5.cpp +++ b/example/getting_started5.cpp @@ -103,9 +103,7 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE BOOST_PYTHON_END_CONVERSION_NAMESPACE -extern "C" -DL_EXPORT(void) -initgetting_started5() +BOOST_PYTHON_MODULE_INIT(getting_started5) { try { diff --git a/example/test_getting_started2.py b/example/test_getting_started2.py index 09215816..49cf765d 100644 --- a/example/test_getting_started2.py +++ b/example/test_getting_started2.py @@ -1,11 +1,21 @@ -r'''>>> import getting_started2 - >>> w = getting_started2.world('California') - >>> print w.greet() - Hello from California! - >>> print getting_started2.invite(w) - Hello from California! Please come soon! - >>> print w.invite() - Hello from California! Please come soon! +r'''>>> from getting_started2 import * + >>> hi = hello('California') + >>> hi.greet() + 'Hello from California' + >>> invite(hi) + 'Hello from California! Please come soon!' + >>> hi.invite() + 'Hello from California! Please come soon!' + + >>> class wordy(hello): + ... def greet(self): + ... return hello.greet(self) + ', where the weather is fine' + ... + >>> hi2 = wordy('Florida') + >>> hi2.greet() + 'Hello from Florida, where the weather is fine' + >>> invite(hi2) + 'Hello from Florida! Please come soon!' ''' def run(args = None): From 041409d71570d18cd25351936c4f817db47cd520 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 7 Mar 2001 03:53:56 +0000 Subject: [PATCH 0019/1042] use BOOST_PYTHON_MODULE_INIT [SVN r9473] --- test/comprehensive.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 3d173310..7699b01f 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -1131,11 +1131,7 @@ void init_module() boost_python_test.add(new boost::python::meta_class); } -extern "C" -#ifdef _WIN32 -__declspec(dllexport) -#endif -void initboost_python_test() +BOOST_PYTHON_MODULE_INIT(boost_python_test) { try { bpl_test::init_module(); From a350b666faafe048311aabcc7d9baa48732fce72 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 7 Mar 2001 03:56:25 +0000 Subject: [PATCH 0020/1042] Added BOOST_PYTHON_MODULE_INIT [SVN r9475] --- include/boost/python/detail/config.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 3207f7c6..9792695e 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -57,4 +57,10 @@ # define BOOST_CSTD_ std # endif +#ifdef _WIN32 +# define BOOST_PYTHON_MODULE_INIT(name) extern "C" __declspec(dllexport) void init##name() +#else +# define BOOST_PYTHON_MODULE_INIT(name) extern "C" void init##name() +#endif + #endif // CONFIG_DWA052200_H_ From 5759ce9ba0ad80126051762d56492ce0a33b5239 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 7 Mar 2001 22:27:22 +0000 Subject: [PATCH 0021/1042] no message [SVN r9482] --- build/getting_started1/getting_started1.dsp | 136 ++++++++++++++++++++ build/getting_started2/getting_started2.dsp | 135 +++++++++++++++++++ 2 files changed, 271 insertions(+) create mode 100644 build/getting_started1/getting_started1.dsp create mode 100644 build/getting_started2/getting_started2.dsp diff --git a/build/getting_started1/getting_started1.dsp b/build/getting_started1/getting_started1.dsp new file mode 100644 index 00000000..a41eb057 --- /dev/null +++ b/build/getting_started1/getting_started1.dsp @@ -0,0 +1,136 @@ +# Microsoft Developer Studio Project File - Name="getting_started1" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=getting_started1 - Win32 DebugPython +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "getting_started1.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "getting_started1.mak" CFG="getting_started1 - Win32 DebugPython" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "getting_started1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "getting_started1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "getting_started1 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "getting_started1 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /libpath:"c:\tools\python\libs" + +!ELSEIF "$(CFG)" == "getting_started1 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /GR /GX /ZI /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" + +!ELSEIF "$(CFG)" == "getting_started1 - Win32 DebugPython" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugPython" +# PROP BASE Intermediate_Dir "DebugPython" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugPython" +# PROP Intermediate_Dir "DebugPython" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /pdb:"DebugPython/boost_python_test_d.pdb" /debug /machine:I386 /out:"DebugPython/getting_started1_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "getting_started1 - Win32 Release" +# Name "getting_started1 - Win32 Debug" +# Name "getting_started1 - Win32 DebugPython" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\example\getting_started1.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/build/getting_started2/getting_started2.dsp b/build/getting_started2/getting_started2.dsp new file mode 100644 index 00000000..284bab21 --- /dev/null +++ b/build/getting_started2/getting_started2.dsp @@ -0,0 +1,135 @@ +# Microsoft Developer Studio Project File - Name="getting_started2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=getting_started2 - Win32 DebugPython +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "getting_started2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "getting_started2.mak" CFG="getting_started2 - Win32 DebugPython" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "getting_started2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "getting_started2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "getting_started2 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "getting_started2" +# PROP Scc_LocalPath "." +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "getting_started2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /libpath:"c:\tools\python\libs" + +!ELSEIF "$(CFG)" == "getting_started2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" + +!ELSEIF "$(CFG)" == "getting_started2 - Win32 DebugPython" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "getting_started2___Win32_DebugPython" +# PROP BASE Intermediate_Dir "getting_started2___Win32_DebugPython" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "getting_started2___Win32_DebugPython" +# PROP Intermediate_Dir "getting_started2___Win32_DebugPython" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"DebugPython/getting_started2_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\pcbuild" + +!ENDIF + +# Begin Target + +# Name "getting_started2 - Win32 Release" +# Name "getting_started2 - Win32 Debug" +# Name "getting_started2 - Win32 DebugPython" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\example\getting_started2.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project From 945344b3cd440b9260b2536cb2b3c3f9e0c24714 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 7 Mar 2001 23:31:32 +0000 Subject: [PATCH 0022/1042] *** empty log message *** [SVN r9483] --- doc/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index 5a64bf62..c6e0722e 100644 --- a/doc/index.html +++ b/doc/index.html @@ -97,7 +97,7 @@ among others.

    • The members of the boost mailing list and the Python community supplied invaluable early feedback. In particular, Ron Clarke, Mark Evans, - Anton Gluck, Chuck Ingold, Prabhu Ramachandran,n and Barry Scott took the + Anton Gluck, Chuck Ingold, Prabhu Ramachandran, and Barry Scott took the brave step of trying to use Boost.Python while it was still in early stages of development. From bdbd9a0f5fcd711bd3fbca0477914fbf9c741348 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 8 Mar 2001 01:32:12 +0000 Subject: [PATCH 0023/1042] class_builder -> class_builder<your_class> [SVN r9484] --- doc/pickle.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/pickle.html b/doc/pickle.html index 7b559e68..ef3d8d0d 100644 --- a/doc/pickle.html +++ b/doc/pickle.html @@ -132,7 +132,7 @@ Both __getinitargs__ and __getstate__ are not defined. this is, e.g.:
      -    class_builder py_your_class(your_module, "your_class");
      +    class_builder<your_class> py_your_class(your_module, "your_class");
           py_your_class.dict_defines_state();
       
      @@ -185,7 +185,7 @@ __getstate__ is defined and the instance's __dict__ is not empty. E.g. in C++:
      -    class_builder py_your_class(your_module, "your_class");
      +    class_builder<your_class> py_your_class(your_module, "your_class");
           py_your_class.getstate_manages_dict();
       
      From a55948071695439f870126c1d686d4aeac4df8b3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 8 Mar 2001 03:01:29 +0000 Subject: [PATCH 0024/1042] py_cpp => Boost.Python [SVN r9485] --- doc/overriding.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/overriding.html b/doc/overriding.html index 7b28add1..b29bf0e6 100644 --- a/doc/overriding.html +++ b/doc/overriding.html @@ -92,7 +92,7 @@ struct hello_callback : hello

      Finally, we add hello_callback to the class_builder<> declaration in our module initialization - function, and when we define the function, we must tell py_cpp about the default + function, and when we define the function, we must tell Boost.Python about the default implementation:

      @@ -120,7 +120,7 @@ hello_class.def(&hello::greet, "greet", &hello_callback::default_gree
           

      *You may ask, "Why do we need this derived class? This could have been designed so that everything gets done right - inside of hello." One of the goals of py_cpp is to be + inside of hello." One of the goals of Boost.Python is to be minimally intrusive on an existing C++ design. In principle, it should be possible to expose the interface for a 3rd party library without changing it. To unintrusively hook into the virtual functions so that a Python From 33ea0dbdeeadd3b4ad77f223843276d9a08867f6 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 9 Mar 2001 02:40:06 +0000 Subject: [PATCH 0025/1042] temp file before branching [SVN r9515] --- doc/cross_module_dependencies.html | 253 +++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 doc/cross_module_dependencies.html diff --git a/doc/cross_module_dependencies.html b/doc/cross_module_dependencies.html new file mode 100644 index 00000000..3d416bf5 --- /dev/null +++ b/doc/cross_module_dependencies.html @@ -0,0 +1,253 @@ + + + Cross-extension-module dependencies + + + +c++boost.gif (8819 bytes) + + +


      +

      Cross-extension-module dependencies

      + +It is good programming practice to organize large projects as modules +that interact with each other via well defined interfaces. With +Boost.Python it is possible to reflect this organization at the C++ +level at the Python level. This is, each logical C++ module can be +organized as a separate Python extension module. + +

      +At first sight this might seem natural and straightforward. However, it +is a fairly complex problem to establish cross-extension-module +dependencies while maintaining the same ease of use Boost.Python +provides for classes that are wrapped in the same extension module. To +a large extent this complexity can be hidden from the author of a +Boost.Python extension module, but not entirely. + +

      The recipe

      + +Suppose there is an extension module that exposes certain instances of +the C++ std::vector template library such that it can be used from +Python in the following manner: + +
      +import std_vector
      +v = std_vector.double([1, 2, 3, 4])
      +v.push_back(5)
      +v.size()
      +
      + +Suppose the std_vector module is done well and reflects all C++ +functions that are useful at the Python level, for all C++ built-in +data types (std_vector.int, std_vector.long, etc.). + +

      +Suppose further that there is statistic module with a C++ class that +has constructors or member functions that use or return a std::vector. +For example: + +

      +class xy {
      +  private:
      +    std::vector<double> m_x;
      +    std::vector<double> m_y;
      +  public:
      +    xy(const std::vector<double>& x, const std::vector<double>& y) : m_x(x), m_y(y) {}
      +    const std::vector<double>& x() const { return m_x; }
      +    const std::vector<double>& y() const { return m_y; }
      +    double correlation();
      +}
      +
      + +What is more natural then reusing the std_vector extension module to +expose these constructors or functions to Python? + +

      +Unfortunately, what seems natural needs a little work in both the +std_vector and the statistics module. + +

      +In the std_vector extension module, std::vector<double> needs to be +exposed to Python with the x_class_builder<> template instead of the +regular class_builder<>. For example: + +

      +  x_class_builder<std::vector<double> > v_double(std_vector_module, "double");
      +
      + +In the extension module that wraps class xy we need to use +the import_class_builder<> template: + +
      +  import_class_builder<std::vector<double> > v_double("std_vector", "double");
      +
      + +That is all. All the properties that are defined for std_vector.double +in the std_vector Boost.Python module will be available for the +returned objects of xy.x() and xy.y(). Similarly, the constructor for +xy will accept objects that were created by the std_vector module. + +

      Non-copyable types

      + +The x_class_builder<T> instantiates template functions that invoke the +copy constructor of T. For a T that is non-copyable this will result in +compile-time error messages. In such a case, another variety of the +class_builder<>, the xptr_class_builder<> must be used. +For example: + +
      +xptr_class_builder<store> py_store(your_module, "store");
      +
      + +The corresponding import_class_builder<> does not need any special +attention: + +
      +import_class_builder<store> py_store("noncopyable_export", "store");
      +
      + +

      Python module search path

      + +The std_vector and statistics modules can now be used in the following +way: + +
      +import std_vector
      +import statistics
      +x = std_vector.double([1, 2, 3, 4])
      +y = std_vector.double([2, 4, 6, 8])
      +xy = statistics.xy(x, y)
      +xy.correlation()
      +
      + +In this example it is clear that Python has to be able to find both the +std_vector and the statistics extension module. In other words, both +extension modules need to be in the Python module search path +(sys.path). + +

      +The situation is not always that obvious. Suppose the statistics +module has a random function that returns a vector of random +numbers with a given length: + +

      +import statistics
      +x = statistics.random(5)
      +y = statistics.random(5)
      +xy = statistics.xy(x, y)
      +xy.correlation()
      +
      + +A naive user will not easily anticipate that the std_vector module is +used to pass the x and y vectors around. If the std_vector module is in +the Python module search path, this form of ignorance is of no harm. +On the contrary, we are glad that we do not have to bother the user +with details like this. + +

      +If the std_vector module is not in the Python module search path, a +Python exception will be raised: + +

      +Traceback (innermost last):
      +  File "foo.py", line 2, in ?
      +    x = statistics.random(5)
      +ImportError: No module named std_vector
      +
      + +As is the case with any system of a non-trivial complexity, it is +important that the setup is consistent and complete. + +

      Two-way module dependencies

      + +Boost.Python supports two-way module dependencies. This is best +illustrated by a simple example. + +

      +Suppose there is a module ivect that implements vectors of integers, +and a similar module dvect that implements vectors of doubles. We want +to be able do convert an integer vector to a double vector and vice +versa. For example: + +

      +import ivect
      +iv = ivect.ivect((1,2,3,4,5))
      +dv = iv.as_dvect()
      +
      + +The last expression will implicitly import the dvect module in order to +enable the conversion of the C++ representation of dvect to a Python +object. The analogous is possible for a dvect: + +
      +import dvect
      +dv = dvect.dvect((1,2,3,4,5))
      +iv = dv.as_ivect()
      +
      + +Now the ivect module is imported implicitly. + +

      +Note that the two-way dependencies are possible because the +dependencies are resolved only when needed. This is, the initialization +of the ivect module does not rely on the dvect module, and vice versa. +Only if as_dvect() or as_ivect() is actually invoked will the +corresponding module be implicitly imported. This also means that, for +example, the dvect module does not have to be available at all if +as_dvect() is never used. + +

      Clarification of compile-time and link-time dependencies

      + +Boost.Python's support for resolving cross-module dependencies at +runtime does not imply that compile-time dependencies are eliminated. +For example, the statistics extension module in the example above will +need to #include <vector>. This is immediately obvious from the +definition of class xy. + +

      +If a library is wrapped that consists of both header files and compiled +components (e.g. libdvect.a, dvect.lib, etc.), both the Boost.Python +extension module with the x_class_wrapper<> and the module with the +import_class_wrapper<> need to be linked against the object library. +Ideally one would build a shared library (e.g. libdvect.so, dvect.dll, +etc.). However, this introduces the issue of getting the search path +for the dynamic loading configured correctly. For small libraries it is +therefore often more convenient to ignore the fact that the object +files are loaded into memory more than once. + +

      +The main purpose of Boost.Python's support for resolving cross-module +dependencies at runtime is to allow for a modular system layout. With +this support it is straightforward to reflect C++ code organization at +the Python level. Without the cross-module support, a multi-purpose +module like std_vector would be impractical because the entire wrapper +code would somehow have to be duplicated in all extension modules that +use it, making them harder to maintain and harder to build. + +

      +Finally, there is an important psychological component. If a group of +classes is lumped together with many others in a huge module, the +authors will have difficulties in being identified with their work. +The situation is much more transparent if the work is represented by +a module with a recognizable name. This is not just a question of +strong egos, but also of getting credit and funding. + +

      Why not use the x_class_builder universally?

      + +There is some overhead associated with the Boost.Python cross-module +support. Depending on the platform, the code generated by +x_class_builder<> is roughly 10%-20% larger than that generated by +class_builder<>. For a large extension module with many wrapped +classes, this could mean a significant difference. Therefore the +general recommendation is to use x_class_wrapper<> only for classes +that are likely to be used as function arguments or return values in +other modules. + +
      +
      +Author: Ralf W. Grosse-Kunstleve, March 2001 +
      + From a6b0fa546a1d0f0cfc08068ebaa9bfad3c7c8b9a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 9 Mar 2001 02:41:16 +0000 Subject: [PATCH 0026/1042] temp file removed after branching. [SVN r9516] --- doc/cross_module_dependencies.html | 253 ----------------------------- 1 file changed, 253 deletions(-) delete mode 100644 doc/cross_module_dependencies.html diff --git a/doc/cross_module_dependencies.html b/doc/cross_module_dependencies.html deleted file mode 100644 index 3d416bf5..00000000 --- a/doc/cross_module_dependencies.html +++ /dev/null @@ -1,253 +0,0 @@ - - - Cross-extension-module dependencies - - - -c++boost.gif (8819 bytes) - - -
      -

      Cross-extension-module dependencies

      - -It is good programming practice to organize large projects as modules -that interact with each other via well defined interfaces. With -Boost.Python it is possible to reflect this organization at the C++ -level at the Python level. This is, each logical C++ module can be -organized as a separate Python extension module. - -

      -At first sight this might seem natural and straightforward. However, it -is a fairly complex problem to establish cross-extension-module -dependencies while maintaining the same ease of use Boost.Python -provides for classes that are wrapped in the same extension module. To -a large extent this complexity can be hidden from the author of a -Boost.Python extension module, but not entirely. - -

      The recipe

      - -Suppose there is an extension module that exposes certain instances of -the C++ std::vector template library such that it can be used from -Python in the following manner: - -
      -import std_vector
      -v = std_vector.double([1, 2, 3, 4])
      -v.push_back(5)
      -v.size()
      -
      - -Suppose the std_vector module is done well and reflects all C++ -functions that are useful at the Python level, for all C++ built-in -data types (std_vector.int, std_vector.long, etc.). - -

      -Suppose further that there is statistic module with a C++ class that -has constructors or member functions that use or return a std::vector. -For example: - -

      -class xy {
      -  private:
      -    std::vector<double> m_x;
      -    std::vector<double> m_y;
      -  public:
      -    xy(const std::vector<double>& x, const std::vector<double>& y) : m_x(x), m_y(y) {}
      -    const std::vector<double>& x() const { return m_x; }
      -    const std::vector<double>& y() const { return m_y; }
      -    double correlation();
      -}
      -
      - -What is more natural then reusing the std_vector extension module to -expose these constructors or functions to Python? - -

      -Unfortunately, what seems natural needs a little work in both the -std_vector and the statistics module. - -

      -In the std_vector extension module, std::vector<double> needs to be -exposed to Python with the x_class_builder<> template instead of the -regular class_builder<>. For example: - -

      -  x_class_builder<std::vector<double> > v_double(std_vector_module, "double");
      -
      - -In the extension module that wraps class xy we need to use -the import_class_builder<> template: - -
      -  import_class_builder<std::vector<double> > v_double("std_vector", "double");
      -
      - -That is all. All the properties that are defined for std_vector.double -in the std_vector Boost.Python module will be available for the -returned objects of xy.x() and xy.y(). Similarly, the constructor for -xy will accept objects that were created by the std_vector module. - -

      Non-copyable types

      - -The x_class_builder<T> instantiates template functions that invoke the -copy constructor of T. For a T that is non-copyable this will result in -compile-time error messages. In such a case, another variety of the -class_builder<>, the xptr_class_builder<> must be used. -For example: - -
      -xptr_class_builder<store> py_store(your_module, "store");
      -
      - -The corresponding import_class_builder<> does not need any special -attention: - -
      -import_class_builder<store> py_store("noncopyable_export", "store");
      -
      - -

      Python module search path

      - -The std_vector and statistics modules can now be used in the following -way: - -
      -import std_vector
      -import statistics
      -x = std_vector.double([1, 2, 3, 4])
      -y = std_vector.double([2, 4, 6, 8])
      -xy = statistics.xy(x, y)
      -xy.correlation()
      -
      - -In this example it is clear that Python has to be able to find both the -std_vector and the statistics extension module. In other words, both -extension modules need to be in the Python module search path -(sys.path). - -

      -The situation is not always that obvious. Suppose the statistics -module has a random function that returns a vector of random -numbers with a given length: - -

      -import statistics
      -x = statistics.random(5)
      -y = statistics.random(5)
      -xy = statistics.xy(x, y)
      -xy.correlation()
      -
      - -A naive user will not easily anticipate that the std_vector module is -used to pass the x and y vectors around. If the std_vector module is in -the Python module search path, this form of ignorance is of no harm. -On the contrary, we are glad that we do not have to bother the user -with details like this. - -

      -If the std_vector module is not in the Python module search path, a -Python exception will be raised: - -

      -Traceback (innermost last):
      -  File "foo.py", line 2, in ?
      -    x = statistics.random(5)
      -ImportError: No module named std_vector
      -
      - -As is the case with any system of a non-trivial complexity, it is -important that the setup is consistent and complete. - -

      Two-way module dependencies

      - -Boost.Python supports two-way module dependencies. This is best -illustrated by a simple example. - -

      -Suppose there is a module ivect that implements vectors of integers, -and a similar module dvect that implements vectors of doubles. We want -to be able do convert an integer vector to a double vector and vice -versa. For example: - -

      -import ivect
      -iv = ivect.ivect((1,2,3,4,5))
      -dv = iv.as_dvect()
      -
      - -The last expression will implicitly import the dvect module in order to -enable the conversion of the C++ representation of dvect to a Python -object. The analogous is possible for a dvect: - -
      -import dvect
      -dv = dvect.dvect((1,2,3,4,5))
      -iv = dv.as_ivect()
      -
      - -Now the ivect module is imported implicitly. - -

      -Note that the two-way dependencies are possible because the -dependencies are resolved only when needed. This is, the initialization -of the ivect module does not rely on the dvect module, and vice versa. -Only if as_dvect() or as_ivect() is actually invoked will the -corresponding module be implicitly imported. This also means that, for -example, the dvect module does not have to be available at all if -as_dvect() is never used. - -

      Clarification of compile-time and link-time dependencies

      - -Boost.Python's support for resolving cross-module dependencies at -runtime does not imply that compile-time dependencies are eliminated. -For example, the statistics extension module in the example above will -need to #include <vector>. This is immediately obvious from the -definition of class xy. - -

      -If a library is wrapped that consists of both header files and compiled -components (e.g. libdvect.a, dvect.lib, etc.), both the Boost.Python -extension module with the x_class_wrapper<> and the module with the -import_class_wrapper<> need to be linked against the object library. -Ideally one would build a shared library (e.g. libdvect.so, dvect.dll, -etc.). However, this introduces the issue of getting the search path -for the dynamic loading configured correctly. For small libraries it is -therefore often more convenient to ignore the fact that the object -files are loaded into memory more than once. - -

      -The main purpose of Boost.Python's support for resolving cross-module -dependencies at runtime is to allow for a modular system layout. With -this support it is straightforward to reflect C++ code organization at -the Python level. Without the cross-module support, a multi-purpose -module like std_vector would be impractical because the entire wrapper -code would somehow have to be duplicated in all extension modules that -use it, making them harder to maintain and harder to build. - -

      -Finally, there is an important psychological component. If a group of -classes is lumped together with many others in a huge module, the -authors will have difficulties in being identified with their work. -The situation is much more transparent if the work is represented by -a module with a recognizable name. This is not just a question of -strong egos, but also of getting credit and funding. - -

      Why not use the x_class_builder universally?

      - -There is some overhead associated with the Boost.Python cross-module -support. Depending on the platform, the code generated by -x_class_builder<> is roughly 10%-20% larger than that generated by -class_builder<>. For a large extension module with many wrapped -classes, this could mean a significant difference. Therefore the -general recommendation is to use x_class_wrapper<> only for classes -that are likely to be used as function arguments or return values in -other modules. - -
      -
      -Author: Ralf W. Grosse-Kunstleve, March 2001 -
      - From 55321b87785ef71e51669bc562211dc534884032 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 9 Mar 2001 18:59:59 +0000 Subject: [PATCH 0027/1042] HTML 4.0 Strict fixes. [SVN r9530] --- doc/pickle.html | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/doc/pickle.html b/doc/pickle.html index ef3d8d0d..49f5c605 100644 --- a/doc/pickle.html +++ b/doc/pickle.html @@ -1,15 +1,15 @@ - - - Boost.Python Pickle Support - - + + +Boost.Python Pickle Support + +
      c++boost.gif (8819 bytes) -

      Boost.Python Pickle Support

      @@ -28,15 +28,14 @@ can be written to a file.

      The Boost Python Library supports the pickle module by emulating the interface implemented by Jim Fulton's ExtensionClass module that is -included in the ZOPE distribution -(http://www.zope.org/). +included in the +ZOPE +distribution. This interface is similar to that for regular Python classes as -described in detail in the Python Library Reference for pickle: - -

      - http://www.python.org/doc/current/lib/module-pickle.html -
      +described in detail in the +Python Library Reference for pickle.

      The Boost.Python Pickle Interface

      @@ -220,4 +219,4 @@ __getstate__ is defined and the instance's __dict__ is not empty.
      Author: Ralf W. Grosse-Kunstleve, March 2001
      - +
      From 494f12090f4090d1678f7f2b5fb06130e9814fca Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 9 Mar 2001 19:02:12 +0000 Subject: [PATCH 0028/1042] Use only one

      (although the validator did not complain). [SVN r9531] --- doc/pickle.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/pickle.html b/doc/pickle.html index 49f5c605..3ec8c928 100644 --- a/doc/pickle.html +++ b/doc/pickle.html @@ -38,7 +38,7 @@ described in detail in the >Python Library Reference for pickle.
      -

      The Boost.Python Pickle Interface

      +

      The Boost.Python Pickle Interface

      At the user level, the Boost.Python pickle interface involves three special methods: @@ -93,7 +93,7 @@ returned by __getstate__ need not be a dictionary. The __getstate__ and __setstate__ methods can do what they want.
      -

      Pitfalls and Safety Guards

      +

      Pitfalls and Safety Guards

      In Boost.Python extension modules with many extension classes, providing complete pickle support for all classes would be a significant @@ -202,7 +202,7 @@ __getstate__ is defined and the instance's __dict__ is not empty.
      -

      Practical Advice

      +

      Practical Advice

      • From 585063f6e18a37e90febc4409595f99f8d35c3f8 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 9 Mar 2001 20:04:56 +0000 Subject: [PATCH 0029/1042] Small enhancements. [SVN r9532] --- doc/pickle.html | 136 +++++++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 59 deletions(-) diff --git a/doc/pickle.html b/doc/pickle.html index 3ec8c928..39cb07dc 100644 --- a/doc/pickle.html +++ b/doc/pickle.html @@ -45,81 +45,87 @@ methods:
        -__getinitargs__ +__getinitargs__
        - When an instance of a Boost.Python extension class is pickled, the pickler - tests if the instance has a __getinitargs__ method. This method must - return a Python tuple. When the instance is restored by the + When an instance of a Boost.Python extension class is pickled, the + pickler tests if the instance has a __getinitargs__ method. + This method must return a Python tuple (it is most convenient to use + a boost::python::tuple). When the instance is restored by the unpickler, the contents of this tuple are used as the arguments for the class constructor.

        - If __getinitargs__ is not defined, the class constructor will be - called without arguments. + If __getinitargs__ is not defined, the class constructor + will be called without arguments.

        -__getstate__ +__getstate__
        - When an instance of a Boost.Python extension class is pickled, the pickler - tests if the instance has a __getstate__ method. This method should - return a Python object representing the state of the instance. + When an instance of a Boost.Python extension class is pickled, the + pickler tests if the instance has a __getstate__ method. + This method should return a Python object representing the state of + the instance.

        - If __getstate__ is not defined, the instance's __dict__ is pickled - (if it is not empty). + If __getstate__ is not defined, the instance's + __dict__ is pickled (if it is not empty).

        -__setstate__ +__setstate__
        When an instance of a Boost.Python extension class is restored by the unpickler, it is first constructed using the result of - __getinitargs__ as arguments (see above). Subsequently the unpickler - tests if the new instance has a __setstate__ method. If so, this - method is called with the result of __getstate__ (a Python object) as - the argument. + __getinitargs__ as arguments (see above). Subsequently the + unpickler tests if the new instance has a __setstate__ + method. If so, this method is called with the result of + __getstate__ (a Python object) as the argument.

        - If __setstate__ is not defined, the result of __getstate__ must be - a Python dictionary. The items of this dictionary are added to - the instance's __dict__. + If __setstate__ is not defined, the result of + __getstate__ must be a Python dictionary. The items of this + dictionary are added to the instance's __dict__. +

        -If both __getstate__ and __setstate__ are defined, the Python object -returned by __getstate__ need not be a dictionary. The __getstate__ and -__setstate__ methods can do what they want. +If both __getstate__ and __setstate__ are defined, +the Python object returned by __getstate__ need not be a +dictionary. The __getstate__ and __setstate__ methods +can do what they want.

        Pitfalls and Safety Guards

        -In Boost.Python extension modules with many extension classes, providing -complete pickle support for all classes would be a significant -overhead. In general complete pickle support should only be implemented -for extension classes that will eventually be pickled. However, the -author of a Boost.Python extension module might not anticipate correctly which -classes need support for pickle. Unfortunately, the pickle protocol -described above has two important pitfalls that the end user of a Boost.Python -extension module might not be aware of: +In Boost.Python extension modules with many extension classes, +providing complete pickle support for all classes would be a +significant overhead. In general complete pickle support should only be +implemented for extension classes that will eventually be pickled. +However, the author of a Boost.Python extension module might not +anticipate correctly which classes need support for pickle. +Unfortunately, the pickle protocol described above has two important +pitfalls that the end user of a Boost.Python extension module might not +be aware of:
        Pitfall 1: -Both __getinitargs__ and __getstate__ are not defined. +Both __getinitargs__ and __getstate__ are not defined.
        In this situation the unpickler calls the class constructor without - arguments and then adds the __dict__ that was pickled by default to - that of the new instance. + arguments and then adds the __dict__ that was pickled by + default to that of the new instance.

        - However, most C++ classes wrapped with Boost.Python will have member data - that are not restored correctly by this procedure. To alert the user - to this problem, a safety guard is provided. If both __getinitargs__ - and __getstate__ are not defined, Boost.Python tests if the class has an - attribute __dict_defines_state__. An exception is raised if this + However, most C++ classes wrapped with Boost.Python will have member + data that are not restored correctly by this procedure. To alert the + user to this problem, a safety guard is provided. If both + __getinitargs__ and __getstate__ are not defined, + Boost.Python tests if the class has an attribute + __dict_defines_state__. An exception is raised if this attribute is not defined:

        @@ -147,41 +153,44 @@ Both __getinitargs__ and __getstate__ are not defined.
         

        Pitfall 2: -__getstate__ is defined and the instance's __dict__ is not empty. +__getstate__ is defined and the instance's __dict__ is not empty.
        - The author of a Boost.Python extension class might provide a __getstate__ - method without considering the possibilities that: + The author of a Boost.Python extension class might provide a + __getstate__ method without considering the possibilities + that:

        • - his class is used as a base class. Most likely the __dict__ of - instances of the derived class needs to be pickled in order to - restore the instances correctly. + his class is used in Python as a base class. Most likely the + __dict__ of instances of the derived class needs to be + pickled in order to restore the instances correctly.

        • - the user adds items to the instance's __dict__ directly. Again, - the __dict__ of the instance then needs to be pickled. + the user adds items to the instance's __dict__ directly. + Again, the __dict__ of the instance then needs to be + pickled. +

        To alert the user to this highly unobvious problem, a safety guard is - provided. If __getstate__ is defined and the instance's __dict__ is - not empty, Boost.Python tests if the class has an attribute - __getstate_manages_dict__. An exception is raised if this attribute - is not defined: + provided. If __getstate__ is defined and the instance's + __dict__ is not empty, Boost.Python tests if the class has + an attribute __getstate_manages_dict__. An exception is + raised if this attribute is not defined:

             RuntimeError: Incomplete pickle support (__getstate_manages_dict__ not set)
         
        To resolve this problem, it should first be established that the - __getstate__ and __setstate__ methods manage the instances's __dict__ - correctly. Note that this can be done both at the C++ and the Python - level. Finally, the safety guard should intentionally be overridden. - E.g. in C++: + __getstate__ and __setstate__ methods manage the + instances's __dict__ correctly. Note that this can be done + both at the C++ and the Python level. Finally, the safety guard + should intentionally be overridden. E.g. in C++:
             class_builder<your_class> py_your_class(your_module, "your_class");
        @@ -206,15 +215,24 @@ __getstate__ is defined and the instance's __dict__ is not empty.
         
         
        • - Avoid using __getstate__ if the instance can also be reconstructed - by way of __getinitargs__. This automatically avoids Pitfall 2. + Avoid using __getstate__ if the instance can also be + reconstructed by way of __getinitargs__. This automatically + avoids Pitfall 2.

        • - If __getstate__ is required, include the instance's __dict__ in the - Python object that is returned. + If __getstate__ is required, include the instance's + __dict__ in the Python object that is returned. +
        +
        +

        Example

        + +An example that shows how to provide pickle support is available in the +boost/lib/python/example directory +(getting_started3.cpp). +
        Author: Ralf W. Grosse-Kunstleve, March 2001 From f5416ebce07b914ed6fd83754f414e53bd2b5563 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 10 Mar 2001 00:36:03 +0000 Subject: [PATCH 0030/1042] Fixed some doc bugs and improved an example [SVN r9533] --- doc/overriding.html | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/overriding.html b/doc/overriding.html index b29bf0e6..0fc7a2e6 100644 --- a/doc/overriding.html +++ b/doc/overriding.html @@ -142,6 +142,7 @@ hello_class.def(&hello::greet, "greet", &hello_callback::default_gree
         struct baz {
             virtual int pure(int) = 0;
        +    int calls_pure(int x) { return pure(x) + 1000; }
         };
         
         struct baz_callback {
        @@ -154,7 +155,7 @@ BOOST_PYTHON_MODULE_INIT(foobar)
             {
                boost::python::module_builder foobar("foobar");
                boost::python::class_builder<baz,baz_callback> baz_class("baz");
        -       baz_class.def(&baz::pure, "pure");
        +       baz_class.def(&baz::calls_pure, "calls_pure");
             }
             catch(...)
             {
        @@ -173,12 +174,18 @@ BOOST_PYTHON_MODULE_INIT(foobar)
         Traceback (innermost last):
           File "<stdin>", line 1, in ?
         AttributeError: pure
        +>>> x.calls_pure(1)
        +Traceback (innermost last):
        +  File "<stdin>", line 1, in ?
        +AttributeError: pure
         >>> class mumble(baz):
         ...    def pure(self, x): return x + 1
         ...
         >>> y = mumble()
         >>> y.pure(99)
         100
        +>>> y.calls_pure(99)
        +1100
         

      Private Non-Pure Virtual Functions

      @@ -192,6 +199,7 @@ this limited way without breaking binary compatibility (though it will certainly break the ODR). +

      Next: Function Overloading Previous: Exporting Classes From 678fa006de24673b654fc057a165e79a2108a734 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 10 Mar 2001 08:23:37 +0000 Subject: [PATCH 0031/1042] Copyright notice & minor fixes. [SVN r9536] --- doc/pickle.html | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/pickle.html b/doc/pickle.html index 39cb07dc..842112d3 100644 --- a/doc/pickle.html +++ b/doc/pickle.html @@ -8,7 +8,7 @@ c++boost.gif (8819 bytes) + width="277" height="86">


      Boost.Python Pickle Support

      @@ -229,12 +229,17 @@ Both __getinitargs__ and __getstate__ are not defined.

      Example

      -An example that shows how to provide pickle support is available in the +An example that shows how to configure pickle support is available in the boost/lib/python/example directory (getting_started3.cpp).
      -
      -Author: Ralf W. Grosse-Kunstleve, March 2001 -
      +© Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, +use, modify, sell and distribute this document is granted provided this +copyright notice appears in all copies. This document is provided "as +is" without express or implied warranty, and with no claim as to its +suitability for any purpose. + +

      +Updated: March 10, 2001 From 14acb1af8c1ef20c1a49ea1a2901e6b49817f2e2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 10 Mar 2001 19:09:10 +0000 Subject: [PATCH 0032/1042] Fix bugs (m_self => self) [SVN r9539] --- doc/overriding.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/overriding.html b/doc/overriding.html index 0fc7a2e6..66c3610c 100644 --- a/doc/overriding.html +++ b/doc/overriding.html @@ -79,13 +79,13 @@ struct hello_callback : hello // Override greet to call back into Python std::string greet() const // 4 - { return boost::python::callback<std::string>::call_method(m_self, "greet"); } + { return boost::python::callback<std::string>::call_method(self, "greet"); } // Supplies the default implementation of greet static std::string default_greet(const hello& self) const // 5 { return self.hello::greet(); } private: - PyObject* m_self; // 1 + PyObject* self; // 1 };

    • From 7dc8fab961c798a832c959096462f901c8ec48f7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 11 Mar 2001 21:29:31 +0000 Subject: [PATCH 0033/1042] 11 Mar 01 std::string *MAY* include nulls (Alex Martelli) [SVN r9544] --- src/conversions.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/conversions.cpp b/src/conversions.cpp index 88e30048..9445c7f3 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -7,6 +7,7 @@ // producing this work. // // Revision History: +// 11 Mar 01 std::string *MAY* include nulls (Alex Martelli) // 04 Mar 01 std::complex<> fixes for MSVC (Dave Abrahams) // 03 Mar 01 added: converters for [plain] char (Ralf W. Grosse-Kunstleve) @@ -149,7 +150,7 @@ int from_python(PyObject* p, boost::python::type type) PyObject* to_python(unsigned int i) { - return integer_to_python(i); + return integer_to_python(i); } unsigned int from_python(PyObject* p, boost::python::type type) @@ -169,7 +170,7 @@ float from_python(PyObject* p, boost::python::type) PyObject* to_python(unsigned short i) { - return integer_to_python(i); + return integer_to_python(i); } unsigned short from_python(PyObject* p, boost::python::type type) @@ -197,7 +198,7 @@ char from_python(PyObject* p, boost::python::type) PyObject* to_python(unsigned char i) { - return integer_to_python(i); + return integer_to_python(i); } unsigned char from_python(PyObject* p, boost::python::type type) @@ -207,7 +208,7 @@ unsigned char from_python(PyObject* p, boost::python::type type) PyObject* to_python(signed char i) { - return integer_to_python(i); + return integer_to_python(i); } signed char from_python(PyObject* p, boost::python::type type) @@ -243,12 +244,15 @@ const char* from_python(PyObject* p, boost::python::type) PyObject* to_python(const std::string& s) { - return PyString_FromString(s.c_str()); + return PyString_FromStringAndSize(s.data(), s.size()); } std::string from_python(PyObject* p, boost::python::type) { - return std::string(from_python(p, boost::python::type())); + char* buffer = 0; + int length = 0; + int rc = PyString_AsStringAndSize(p, &buffer, &length); + return std::string(buffer, length); } bool from_python(PyObject* p, boost::python::type) From ed34cd45f1da43539e40e8b9d51e360312c422c0 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 12 Mar 2001 19:32:40 +0000 Subject: [PATCH 0034/1042] Python 1.5.2 fixes [SVN r9546] --- src/conversions.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/conversions.cpp b/src/conversions.cpp index 9445c7f3..1bc923b1 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -7,6 +7,7 @@ // producing this work. // // Revision History: +// 12 Mar 01 Python 1.5.2 fixes (Ralf W. Grosse-Kunstleve) // 11 Mar 01 std::string *MAY* include nulls (Alex Martelli) // 04 Mar 01 std::complex<> fixes for MSVC (Dave Abrahams) // 03 Mar 01 added: converters for [plain] char (Ralf W. Grosse-Kunstleve) @@ -249,10 +250,7 @@ PyObject* to_python(const std::string& s) std::string from_python(PyObject* p, boost::python::type) { - char* buffer = 0; - int length = 0; - int rc = PyString_AsStringAndSize(p, &buffer, &length); - return std::string(buffer, length); + return std::string(PyString_AsString(p), PyString_Size(p)); } bool from_python(PyObject* p, boost::python::type) From ff04d9f03c85e173a0d6084d20ef3f2416b699c7 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 12 Mar 2001 19:34:14 +0000 Subject: [PATCH 0035/1042] Minute enhancement. [SVN r9547] --- doc/overriding.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/overriding.html b/doc/overriding.html index 66c3610c..af458d79 100644 --- a/doc/overriding.html +++ b/doc/overriding.html @@ -82,8 +82,8 @@ struct hello_callback : hello { return boost::python::callback<std::string>::call_method(self, "greet"); } // Supplies the default implementation of greet - static std::string default_greet(const hello& self) const // 5 - { return self.hello::greet(); } + static std::string default_greet(const hello& self_) const // 5 + { return self_.hello::greet(); } private: PyObject* self; // 1 }; From 012b4025a48e056da251b58eb50c402079740894 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 13 Mar 2001 00:01:06 +0000 Subject: [PATCH 0036/1042] temp files before branching [SVN r9549] --- example/pickle1.cpp | 57 +++++++++++++++++++ example/pickle2.cpp | 80 ++++++++++++++++++++++++++ example/pickle3.cpp | 121 ++++++++++++++++++++++++++++++++++++++++ example/test_pickle1.py | 31 ++++++++++ example/test_pickle2.py | 45 +++++++++++++++ example/test_pickle3.py | 38 +++++++++++++ 6 files changed, 372 insertions(+) create mode 100644 example/pickle1.cpp create mode 100644 example/pickle2.cpp create mode 100644 example/pickle3.cpp create mode 100644 example/test_pickle1.py create mode 100644 example/test_pickle2.py create mode 100644 example/test_pickle3.py diff --git a/example/pickle1.cpp b/example/pickle1.cpp new file mode 100644 index 00000000..2f786f69 --- /dev/null +++ b/example/pickle1.cpp @@ -0,0 +1,57 @@ +/* + This example shows how to make an Extension Class "pickleable". + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include + +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + private: + std::string country; + int secret_number; + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + }; + + // Support for pickle. + python::ref world_getinitargs(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_country()); + return result.reference(); + } +} + +BOOST_PYTHON_MODULE_INIT(pickle1) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("pickle1"); + + // Create the Python type object for our extension class. + python::class_builder world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(python::constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + + // Support for pickle. + world_class.def(world_getinitargs, "__getinitargs__"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/pickle2.cpp b/example/pickle2.cpp new file mode 100644 index 00000000..c33776a0 --- /dev/null +++ b/example/pickle2.cpp @@ -0,0 +1,80 @@ +/* + This example shows how to make an Extension Class "pickleable". + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include + +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + void set_secret_number(int number) { secret_number = number; } + int get_secret_number() const { return secret_number; } + private: + std::string country; + int secret_number; + }; + + // Support for pickle. + python::ref world_getinitargs(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_country()); + return result.reference(); // returning the reference avoids the copying. + } + + python::ref world_getstate(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_secret_number()); + return result.reference(); // returning the reference avoids the copying. + } + + void world_setstate(world& w, python::tuple state) { + if (state.size() != 1) { + PyErr_SetString(PyExc_ValueError, + "Unexpected argument in call to __setstate__."); + throw python::error_already_set(); + } + int number = state[0].get(); + if (number != 42) + w.set_secret_number(number); + } +} + +BOOST_PYTHON_MODULE_INIT(pickle2) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("pickle2"); + + // Create the Python type object for our extension class. + python::class_builder world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(python::constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + world_class.def(&world::get_secret_number, "get_secret_number"); + world_class.def(&world::set_secret_number, "set_secret_number"); + + // Support for pickle. + world_class.def(world_getinitargs, "__getinitargs__"); + world_class.def(world_getstate, "__getstate__"); + world_class.def(world_setstate, "__setstate__"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/pickle3.cpp b/example/pickle3.cpp new file mode 100644 index 00000000..19ddec43 --- /dev/null +++ b/example/pickle3.cpp @@ -0,0 +1,121 @@ +/* + This example shows how to make an Extension Class "pickleable". + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include + +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + void set_secret_number(int number) { secret_number = number; } + int get_secret_number() const { return secret_number; } + private: + std::string country; + int secret_number; + }; + + // Support for pickle. + python::ref world_getinitargs(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_country()); + return result.reference(); // returning the reference avoids the copying. + } + + python::ref world_getstate(python::tuple const & args, + python::dictionary const & keywords); + + PyObject* world_setstate(python::tuple const & args, + python::dictionary const & keywords); +} + +BOOST_PYTHON_MODULE_INIT(pickle3) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("pickle3"); + + // Create the Python type object for our extension class. + python::class_builder world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(python::constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + world_class.def(&world::get_secret_number, "get_secret_number"); + world_class.def(&world::set_secret_number, "set_secret_number"); + + // Support for pickle. + world_class.def(world_getinitargs, "__getinitargs__"); + world_class.def_raw(world_getstate, "__getstate__"); + world_class.def_raw(world_setstate, "__setstate__"); + world_class.getstate_manages_dict(); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} + +namespace { + + python::ref world_getstate(python::tuple const & args, + python::dictionary const & keywords) + { + if(args.size() != 1 || keywords.size() != 0) { + PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); + throw boost::python::argument_error(); + } + const world& w = args[0].get(); + python::ref mydict(args[0].getattr("__dict__")); + python::tuple result(2); + // store the object's __dict__ + result.set_item(0, mydict); + // store the internal state of the C++ object + result.set_item(1, w.get_secret_number()); + return result.reference(); // returning the reference avoids the copying. + } + + PyObject* world_setstate(python::tuple const & args, + python::dictionary const & keywords) + { + if(args.size() != 2 || keywords.size() != 0) { + PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); + throw boost::python::argument_error(); + } + world& w = args[0].get(); + python::ref mydict(args[0].getattr("__dict__")); + const python::tuple& state(args[1].get()); + if (state.size() != 2) { + PyErr_SetString(PyExc_ValueError, + "Unexpected argument in call to __setstate__."); + throw python::error_already_set(); + } + // restore the object's __dict__ + python::dictionary odict(mydict.get()); + const python::dictionary& pdict(state[0].get()); + python::list pkeys(pdict.keys()); + for (int i = 0; i < pkeys.size(); i++) { + python::ref k(pkeys[i]); + //odict[k] = pdict[k]; // XXX memory leak! + odict[k] = pdict.get_item(k); // this does not leak. + } + // restore the internal state of the C++ object + int number = state[1].get(); + if (number != 42) + w.set_secret_number(number); + return python::detail::none(); + } +} diff --git a/example/test_pickle1.py b/example/test_pickle1.py new file mode 100644 index 00000000..05696d4a --- /dev/null +++ b/example/test_pickle1.py @@ -0,0 +1,31 @@ +r'''>>> import pickle1 + >>> import re + >>> import pickle + >>> pickle1.world.__module__ + 'pickle1' + >>> pickle1.world.__safe_for_unpickling__ + 1 + >>> pickle1.world.__reduce__() + 'world' + >>> assert re.match( + ... "\(, \('Hello',\)\)", + ... repr(pickle1.world('Hello').__reduce__())) + >>> + >>> wd = pickle1.world('California') + >>> pstr = pickle.dumps(wd) + >>> wl = pickle.loads(pstr) + >>> print wd.greet() + Hello from California! + >>> print wl.greet() + Hello from California! +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_pickle1 + doctest.testmod(test_pickle1) + +if __name__ == '__main__': + run() diff --git a/example/test_pickle2.py b/example/test_pickle2.py new file mode 100644 index 00000000..463befa6 --- /dev/null +++ b/example/test_pickle2.py @@ -0,0 +1,45 @@ +r'''>>> import pickle2 + >>> import re + >>> import pickle + >>> pickle2.world.__module__ + 'pickle2' + >>> pickle2.world.__safe_for_unpickling__ + 1 + >>> pickle2.world.__reduce__() + 'world' + >>> assert re.match( + ... "\(, \('Hello',\), \(0,\)\)", + ... repr(pickle2.world('Hello').__reduce__())) + >>> + >>> for number in (24, 42): + ... wd = pickle2.world('California') + ... wd.set_secret_number(number) + ... pstr = pickle.dumps(wd) + ... wl = pickle.loads(pstr) + ... print wd.greet(), wd.get_secret_number() + ... print wl.greet(), wl.get_secret_number() + Hello from California! 24 + Hello from California! 24 + Hello from California! 42 + Hello from California! 0 + +# Now show that the __dict__ is not taken care of. + >>> wd = pickle2.world('California') + >>> wd.x = 1 + >>> wd.__dict__ + {'x': 1} + >>> try: pstr = pickle.dumps(wd) + ... except RuntimeError, err: print err[0] + ... + Incomplete pickle support (__getstate_manages_dict__ not set) +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_pickle2 + doctest.testmod(test_pickle2) + +if __name__ == '__main__': + run() diff --git a/example/test_pickle3.py b/example/test_pickle3.py new file mode 100644 index 00000000..b964f1a2 --- /dev/null +++ b/example/test_pickle3.py @@ -0,0 +1,38 @@ +r'''>>> import pickle3 + >>> import re + >>> import pickle + >>> pickle3.world.__module__ + 'pickle3' + >>> pickle3.world.__safe_for_unpickling__ + 1 + >>> pickle3.world.__reduce__() + 'world' + >>> assert re.match( + ... "\(, \('Hello',\), \(\{\}, 0\)\)", + ... repr(pickle3.world('Hello').__reduce__())) + >>> + >>> for number in (24, 42): + ... wd = pickle3.world('California') + ... wd.set_secret_number(number) + ... wd.x = 2 * number + ... wd.y = 'y' * number + ... wd.z = 3. * number + ... pstr = pickle.dumps(wd) + ... wl = pickle.loads(pstr) + ... print wd.greet(), wd.get_secret_number(), wd.__dict__ + ... print wl.greet(), wl.get_secret_number(), wl.__dict__ + Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'} + Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'} + Hello from California! 42 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'} + Hello from California! 0 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'} +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_pickle3 + doctest.testmod(test_pickle3) + +if __name__ == '__main__': + run() From c979ab01af48fc814c42beb89f857d7db4e85068 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 13 Mar 2001 00:03:58 +0000 Subject: [PATCH 0037/1042] temp files removed after branching. [SVN r9551] --- example/pickle1.cpp | 57 ------------------- example/pickle2.cpp | 80 -------------------------- example/pickle3.cpp | 121 ---------------------------------------- example/test_pickle1.py | 31 ---------- example/test_pickle2.py | 45 --------------- example/test_pickle3.py | 38 ------------- 6 files changed, 372 deletions(-) delete mode 100644 example/pickle1.cpp delete mode 100644 example/pickle2.cpp delete mode 100644 example/pickle3.cpp delete mode 100644 example/test_pickle1.py delete mode 100644 example/test_pickle2.py delete mode 100644 example/test_pickle3.py diff --git a/example/pickle1.cpp b/example/pickle1.cpp deleted file mode 100644 index 2f786f69..00000000 --- a/example/pickle1.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - This example shows how to make an Extension Class "pickleable". - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - private: - std::string country; - int secret_number; - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - }; - - // Support for pickle. - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); - } -} - -BOOST_PYTHON_MODULE_INIT(pickle1) -{ - try - { - // Create an object representing this extension module. - python::module_builder this_module("pickle1"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/pickle2.cpp b/example/pickle2.cpp deleted file mode 100644 index c33776a0..00000000 --- a/example/pickle2.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - This example shows how to make an Extension Class "pickleable". - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - private: - std::string country; - int secret_number; - }; - - // Support for pickle. - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); // returning the reference avoids the copying. - } - - python::ref world_getstate(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_secret_number()); - return result.reference(); // returning the reference avoids the copying. - } - - void world_setstate(world& w, python::tuple state) { - if (state.size() != 1) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); - throw python::error_already_set(); - } - int number = state[0].get(); - if (number != 42) - w.set_secret_number(number); - } -} - -BOOST_PYTHON_MODULE_INIT(pickle2) -{ - try - { - // Create an object representing this extension module. - python::module_builder this_module("pickle2"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - world_class.def(&world::get_secret_number, "get_secret_number"); - world_class.def(&world::set_secret_number, "set_secret_number"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - world_class.def(world_getstate, "__getstate__"); - world_class.def(world_setstate, "__setstate__"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/pickle3.cpp b/example/pickle3.cpp deleted file mode 100644 index 19ddec43..00000000 --- a/example/pickle3.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - This example shows how to make an Extension Class "pickleable". - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - private: - std::string country; - int secret_number; - }; - - // Support for pickle. - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); // returning the reference avoids the copying. - } - - python::ref world_getstate(python::tuple const & args, - python::dictionary const & keywords); - - PyObject* world_setstate(python::tuple const & args, - python::dictionary const & keywords); -} - -BOOST_PYTHON_MODULE_INIT(pickle3) -{ - try - { - // Create an object representing this extension module. - python::module_builder this_module("pickle3"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - world_class.def(&world::get_secret_number, "get_secret_number"); - world_class.def(&world::set_secret_number, "set_secret_number"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - world_class.def_raw(world_getstate, "__getstate__"); - world_class.def_raw(world_setstate, "__setstate__"); - world_class.getstate_manages_dict(); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} - -namespace { - - python::ref world_getstate(python::tuple const & args, - python::dictionary const & keywords) - { - if(args.size() != 1 || keywords.size() != 0) { - PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - throw boost::python::argument_error(); - } - const world& w = args[0].get(); - python::ref mydict(args[0].getattr("__dict__")); - python::tuple result(2); - // store the object's __dict__ - result.set_item(0, mydict); - // store the internal state of the C++ object - result.set_item(1, w.get_secret_number()); - return result.reference(); // returning the reference avoids the copying. - } - - PyObject* world_setstate(python::tuple const & args, - python::dictionary const & keywords) - { - if(args.size() != 2 || keywords.size() != 0) { - PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - throw boost::python::argument_error(); - } - world& w = args[0].get(); - python::ref mydict(args[0].getattr("__dict__")); - const python::tuple& state(args[1].get()); - if (state.size() != 2) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); - throw python::error_already_set(); - } - // restore the object's __dict__ - python::dictionary odict(mydict.get()); - const python::dictionary& pdict(state[0].get()); - python::list pkeys(pdict.keys()); - for (int i = 0; i < pkeys.size(); i++) { - python::ref k(pkeys[i]); - //odict[k] = pdict[k]; // XXX memory leak! - odict[k] = pdict.get_item(k); // this does not leak. - } - // restore the internal state of the C++ object - int number = state[1].get(); - if (number != 42) - w.set_secret_number(number); - return python::detail::none(); - } -} diff --git a/example/test_pickle1.py b/example/test_pickle1.py deleted file mode 100644 index 05696d4a..00000000 --- a/example/test_pickle1.py +++ /dev/null @@ -1,31 +0,0 @@ -r'''>>> import pickle1 - >>> import re - >>> import pickle - >>> pickle1.world.__module__ - 'pickle1' - >>> pickle1.world.__safe_for_unpickling__ - 1 - >>> pickle1.world.__reduce__() - 'world' - >>> assert re.match( - ... "\(, \('Hello',\)\)", - ... repr(pickle1.world('Hello').__reduce__())) - >>> - >>> wd = pickle1.world('California') - >>> pstr = pickle.dumps(wd) - >>> wl = pickle.loads(pstr) - >>> print wd.greet() - Hello from California! - >>> print wl.greet() - Hello from California! -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_pickle1 - doctest.testmod(test_pickle1) - -if __name__ == '__main__': - run() diff --git a/example/test_pickle2.py b/example/test_pickle2.py deleted file mode 100644 index 463befa6..00000000 --- a/example/test_pickle2.py +++ /dev/null @@ -1,45 +0,0 @@ -r'''>>> import pickle2 - >>> import re - >>> import pickle - >>> pickle2.world.__module__ - 'pickle2' - >>> pickle2.world.__safe_for_unpickling__ - 1 - >>> pickle2.world.__reduce__() - 'world' - >>> assert re.match( - ... "\(, \('Hello',\), \(0,\)\)", - ... repr(pickle2.world('Hello').__reduce__())) - >>> - >>> for number in (24, 42): - ... wd = pickle2.world('California') - ... wd.set_secret_number(number) - ... pstr = pickle.dumps(wd) - ... wl = pickle.loads(pstr) - ... print wd.greet(), wd.get_secret_number() - ... print wl.greet(), wl.get_secret_number() - Hello from California! 24 - Hello from California! 24 - Hello from California! 42 - Hello from California! 0 - -# Now show that the __dict__ is not taken care of. - >>> wd = pickle2.world('California') - >>> wd.x = 1 - >>> wd.__dict__ - {'x': 1} - >>> try: pstr = pickle.dumps(wd) - ... except RuntimeError, err: print err[0] - ... - Incomplete pickle support (__getstate_manages_dict__ not set) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_pickle2 - doctest.testmod(test_pickle2) - -if __name__ == '__main__': - run() diff --git a/example/test_pickle3.py b/example/test_pickle3.py deleted file mode 100644 index b964f1a2..00000000 --- a/example/test_pickle3.py +++ /dev/null @@ -1,38 +0,0 @@ -r'''>>> import pickle3 - >>> import re - >>> import pickle - >>> pickle3.world.__module__ - 'pickle3' - >>> pickle3.world.__safe_for_unpickling__ - 1 - >>> pickle3.world.__reduce__() - 'world' - >>> assert re.match( - ... "\(, \('Hello',\), \(\{\}, 0\)\)", - ... repr(pickle3.world('Hello').__reduce__())) - >>> - >>> for number in (24, 42): - ... wd = pickle3.world('California') - ... wd.set_secret_number(number) - ... wd.x = 2 * number - ... wd.y = 'y' * number - ... wd.z = 3. * number - ... pstr = pickle.dumps(wd) - ... wl = pickle.loads(pstr) - ... print wd.greet(), wd.get_secret_number(), wd.__dict__ - ... print wl.greet(), wl.get_secret_number(), wl.__dict__ - Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'} - Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'} - Hello from California! 42 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'} - Hello from California! 0 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'} -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_pickle3 - doctest.testmod(test_pickle3) - -if __name__ == '__main__': - run() From 60b91ac6780ee9c7594892185377cebbde95652b Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Wed, 14 Mar 2001 15:11:55 +0000 Subject: [PATCH 0038/1042] 1.21.1 run up, including new download instructions and fix broken hyperlinks [SVN r9557] --- doc/building.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/building.html b/doc/building.html index 6627bbe8..2a8c9cae 100644 --- a/doc/building.html +++ b/doc/building.html @@ -57,7 +57,7 @@ special debugging version of the Python DLL. Since this debug DLL isn't supplied with the default Python installation for Windows, Boost.Python uses boost/python/detail/wrap_python.hpp + "../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp to temporarily undefine _DEBUG when Python.h is #included. @@ -77,7 +77,7 @@

      If you do not #define BOOST_DEBUG_PYTHON, be sure that any source files #include <boost/python/detail/wrap_python.hpp> + "../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp> instead of the usual Python.h, or you will have link incompatibilities.

      From c068a300f429a81a78c486579feda5418a8b22e8 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Thu, 15 Mar 2001 16:05:25 +0000 Subject: [PATCH 0039/1042] template file is not longer needed, causes "broken links" messages [SVN r9562] --- doc/template.html | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 doc/template.html diff --git a/doc/template.html b/doc/template.html deleted file mode 100644 index 1d0cd7a4..00000000 --- a/doc/template.html +++ /dev/null @@ -1,26 +0,0 @@ - - - The Title Of This Page - -

      -

      - c++boost.gif (8819 bytes)The Title Of This - Page -

      -

      -

      - Prev: Previous - Next: Next - Up: Top -

      - © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability - for any purpose. -

      - Updated: Nov 26, 2000 -

      - From 13b2e072d25cc3b7e11471afd3b8098a26c458ec Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 16 Mar 2001 21:56:41 +0000 Subject: [PATCH 0040/1042] Remove const qualifications that will confuse VC++'s buggy brain [SVN r9567] --- example/getting_started4.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/getting_started4.cpp b/example/getting_started4.cpp index 199ef7a9..cf6c2ff2 100644 --- a/example/getting_started4.cpp +++ b/example/getting_started4.cpp @@ -55,7 +55,7 @@ namespace { // Avoid cluttering the global namespace. // Function returning a vector_double object to Python. // - std::vector foo(const int n) + std::vector foo(int n) { std::vector vd(n); std::vector::iterator vditer = vd.begin(); @@ -65,7 +65,7 @@ namespace { // Avoid cluttering the global namespace. // Same as foo(), but avoid copying on return. // - std::auto_ptr > bar(const int n) + std::auto_ptr > bar(int n) { std::auto_ptr > vdptr(new std::vector(n)); std::vector::iterator vditer = vdptr->begin(); From 098eadefe0f4849d762d227c7df27fc6b82abffc Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 20 Mar 2001 02:07:39 +0000 Subject: [PATCH 0041/1042] temp file before branching [SVN r9599] --- include/boost/python/cross_module.hpp | 274 ++++++++++++++++++++++++++ src/cross_module.cpp | 77 ++++++++ 2 files changed, 351 insertions(+) create mode 100644 include/boost/python/cross_module.hpp create mode 100644 src/cross_module.cpp diff --git a/include/boost/python/cross_module.hpp b/include/boost/python/cross_module.hpp new file mode 100644 index 00000000..a6c32889 --- /dev/null +++ b/include/boost/python/cross_module.hpp @@ -0,0 +1,274 @@ +#ifndef CROSS_MODULE_HPP +# define CROSS_MODULE_HPP + +# include + +namespace boost { namespace python { + struct import_error : error_already_set {}; + struct export_error : error_already_set {}; +}} + +namespace boost { namespace python { namespace detail { + +// Concept: throw exception if api_major is changed +// show warning on stderr if api_minor is changed +const int export_converters_api_major = 2; +const int export_converters_api_minor = 1; +extern const char* converters_attribute_name; +void* import_converter_object(const std::string& module_name, + const std::string& py_class_name, + const std::string& attribute_name); +void check_export_converters_api(const int importing_major, + const int importing_minor, + const int imported_major, + const int imported_minor); + +}}} + +// forward declaration +namespace boost { namespace python { namespace detail { +template class import_extension_class; +}}} + +BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE + +//QUESTIONMARK +// This class is a look-alike of class python_extension_class_converters. +// Is there a formal way to ensure that the siblings stay in sync? +template +class python_import_extension_class_converters +{ + public: + + friend python_import_extension_class_converters py_extension_class_converters(boost::python::type) + { + return python_import_extension_class_converters(); + } + + PyObject* to_python(const T& x) const + { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } + + friend T* from_python(PyObject* p, boost::python::type) + { + return boost::python::detail::import_extension_class::get_converters()->T_pointer_from_python(p); + } + + // Convert to const T* + friend const T* from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to const T* const& + friend const T* from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to T* const& + friend T* from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to T& + friend T& from_python(PyObject* p, boost::python::type) { + return boost::python::detail::import_extension_class::get_converters()->T_reference_from_python(p); + } + + // Convert to const T& + friend const T& from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + // Convert to T + friend const T& from_python(PyObject* p, boost::python::type) + { return from_python(p, boost::python::type()); } + + friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->auto_ptr_reference_from_python(p); + } + + friend std::auto_ptr& from_python(PyObject* p, boost::python::type >) { + return boost::python::detail::import_extension_class::get_converters()->auto_ptr_value_from_python(p); + } + + friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->auto_ptr_value_from_python(p); + } + + friend PyObject* to_python(std::auto_ptr x) { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } + + friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->shared_ptr_reference_from_python(p); + } + + friend boost::shared_ptr& from_python(PyObject* p, boost::python::type >) { + return boost::python::detail::import_extension_class::get_converters()->shared_ptr_value_from_python(p); + } + + friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { + return boost::python::detail::import_extension_class::get_converters()->shared_ptr_value_from_python(p); + } + + friend PyObject* to_python(boost::shared_ptr x) { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } +}; + +BOOST_PYTHON_END_CONVERSION_NAMESPACE + +namespace boost { namespace python { + +BOOST_PYTHON_IMPORT_CONVERSION(python_import_extension_class_converters); + +// A pointer to this class is exported/imported via the Python API. +// All functions are virtual. This is, what we really export/import +// is essentially just a pointer to a vtbl. +template +struct export_converter_object_base +{ + virtual const int get_api_major() const { + return detail::export_converters_api_major; } + virtual const int get_api_minor() const { + return detail::export_converters_api_minor; } + virtual PyObject* to_python(const T& x) = 0; + virtual PyObject* to_python(std::auto_ptr x) = 0; + virtual PyObject* to_python(boost::shared_ptr x) = 0; + virtual T* T_pointer_from_python(PyObject* obj) = 0; + virtual T& T_reference_from_python(PyObject* obj) = 0; + virtual std::auto_ptr& auto_ptr_reference_from_python(PyObject* obj) = 0; + virtual std::auto_ptr auto_ptr_value_from_python(PyObject* obj) = 0; + virtual boost::shared_ptr& shared_ptr_reference_from_python(PyObject* obj) = 0; + virtual boost::shared_ptr shared_ptr_value_from_python(PyObject* obj) = 0; +}; + +// Converters to be used if T is not copyable. +template +struct export_converter_object_noncopyable : export_converter_object_base +{ + virtual PyObject* to_python(const T& x) { + PyErr_SetString(PyExc_RuntimeError, + "to_python(const T&) converter not exported"); + throw import_error(); + } + virtual PyObject* to_python(std::auto_ptr x) { + return BOOST_PYTHON_CONVERSION::to_python(x); + } + virtual PyObject* to_python(boost::shared_ptr x) { + return BOOST_PYTHON_CONVERSION::to_python(x); + } + virtual T* T_pointer_from_python(PyObject* obj) { + return BOOST_PYTHON_CONVERSION::from_python(obj, boost::python::type()); + } + virtual T& T_reference_from_python(PyObject* obj) { + return BOOST_PYTHON_CONVERSION::from_python(obj, boost::python::type()); + } + virtual std::auto_ptr& auto_ptr_reference_from_python(PyObject* obj) { + return BOOST_PYTHON_CONVERSION::python_extension_class_converters::smart_ptr_reference(obj, boost::python::type >()); + } + virtual std::auto_ptr auto_ptr_value_from_python(PyObject* obj) { + return BOOST_PYTHON_CONVERSION::python_extension_class_converters::smart_ptr_value(obj, boost::python::type >()); + } + virtual boost::shared_ptr& shared_ptr_reference_from_python(PyObject* obj) { + return BOOST_PYTHON_CONVERSION::python_extension_class_converters::smart_ptr_reference(obj, boost::python::type >()); + } + virtual boost::shared_ptr shared_ptr_value_from_python(PyObject* obj) { + return BOOST_PYTHON_CONVERSION::python_extension_class_converters::smart_ptr_value(obj, boost::python::type >()); + } +}; + +// The addditional to_python() converter that can be used if T is copyable. +template +struct export_converter_object : export_converter_object_noncopyable +{ + virtual PyObject* to_python(const T& x) { + BOOST_PYTHON_CONVERSION::python_extension_class_converters cv; + return cv.to_python(x); + } +}; + +namespace detail { + +//QUESTIONMARK +// A stripped-down, modified version of class extension_class. +// Would it make sense to establish a formal relationship +// between the two classes? +template +class import_extension_class + : public python_import_extension_class_converters +{ + public: + inline import_extension_class(const char* module, const char* py_class) { + m_module = module; + m_py_class = py_class; + } + + static boost::python::export_converter_object_base* get_converters(); + + private: + static std::string m_module; + static std::string m_py_class; + static boost::python::export_converter_object_base* imported_converters; +}; + +template std::string import_extension_class::m_module; +template std::string import_extension_class::m_py_class; +template +boost::python::export_converter_object_base* +import_extension_class::imported_converters = 0; + +template +boost::python::export_converter_object_base* +import_extension_class::get_converters() { + if (imported_converters == 0) { + void* cobject + = import_converter_object(m_module, m_py_class, + converters_attribute_name); + imported_converters + = static_cast*>(cobject); + check_export_converters_api( + export_converters_api_major, + export_converters_api_minor, + imported_converters->get_api_major(), + imported_converters->get_api_minor()); + } + return imported_converters; +} + +}}} // namespace boost::python::detail + +namespace boost { namespace python { + +template +void export_converters(class_builder& cb) +{ + static export_converter_object export_cvts; + cb.add( + ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), + detail::converters_attribute_name); +} + +template +void export_converters_noncopyable(class_builder& cb) +{ + static export_converter_object_noncopyable export_cvts; + cb.add( + ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), + detail::converters_attribute_name); +} + +template +class import_converters + : python_import_extension_class_converters +{ + public: + import_converters(const char* module, const char* py_class) + : m_class(new detail::import_extension_class(module, py_class)) + { } + private: + //QUESTIONMARK + //reference > m_class; + boost::shared_ptr > m_class; +}; + +}} // namespace boost::python + +#endif // CROSS_MODULE_HPP diff --git a/src/cross_module.cpp b/src/cross_module.cpp new file mode 100644 index 00000000..c14acfda --- /dev/null +++ b/src/cross_module.cpp @@ -0,0 +1,77 @@ +# include +namespace python = boost::python; +# include // MSVC6.0SP4 does not know std::fprintf +# include // MSVC6.0SP4 does not know std::strcmp + +namespace { + + PyObject* get_module_dict(const char* module_name) + { + python::ref module_obj(PyImport_ImportModule((char*) module_name)); + PyObject* module_dict = PyModule_GetDict(module_obj.get()); + if (module_dict == 0) throw python::import_error(); + return module_dict; + } +} + +namespace boost { namespace python { namespace detail { + +const char* converters_attribute_name = "__converters__"; + +void* import_converter_object(const std::string& module_name, + const std::string& py_class_name, + const std::string& attribute_name) +{ + static std::string err; + PyObject* module_dict = get_module_dict(const_cast(module_name.c_str())); + PyObject* py_class = PyDict_GetItemString(module_dict, const_cast(py_class_name.c_str())); + if (py_class == 0) { + err = std::string("module ") + module_name + " has no attribute " + py_class_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + python::ref c_obj(PyObject_GetAttrString(py_class, const_cast(attribute_name.c_str())), ref::null_ok); + if (c_obj.get() == 0) { + err = std::string("object ") + module_name + "." + py_class_name + + " has no attribute " + attribute_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + if (! PyCObject_Check(c_obj.get())) { + err = std::string("object ") + module_name + "." + py_class_name + "." + + attribute_name + " is not a PyCObject"; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + return PyCObject_AsVoidPtr(c_obj.get()); +} + +void check_export_converters_api(const int importing_major, + const int importing_minor, + const int imported_major, + const int imported_minor) +{ + if (importing_major != imported_major) { + // Python uses fprintf(stderr, ...) for API warnings. + fprintf(stderr, + "Fatal: export_converters_api mismatch:" + " Importing module = %d.%d" + " Imported module = %d.%d\n", + importing_major, importing_minor, + imported_major, imported_minor); + PyErr_SetString(PyExc_RuntimeError, + "Fatal: export_converters_api mismatch"); + throw import_error(); + } + if (importing_minor != imported_minor) { + // Python uses fprintf(stderr, ...) for API warnings. + fprintf(stderr, + "Warning: export_converters_api mismatch:" + " Importing module = %d.%d" + " Imported module = %d.%d\n", + importing_major, importing_minor, + imported_major, imported_minor); + } +} + +}}} // namespace boost::python::detail From db943b4109c71c61b7293bfcacb13becfe2d01db Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 20 Mar 2001 02:08:24 +0000 Subject: [PATCH 0042/1042] temp file removed after branching. [SVN r9600] --- include/boost/python/cross_module.hpp | 274 -------------------------- src/cross_module.cpp | 77 -------- 2 files changed, 351 deletions(-) delete mode 100644 include/boost/python/cross_module.hpp delete mode 100644 src/cross_module.cpp diff --git a/include/boost/python/cross_module.hpp b/include/boost/python/cross_module.hpp deleted file mode 100644 index a6c32889..00000000 --- a/include/boost/python/cross_module.hpp +++ /dev/null @@ -1,274 +0,0 @@ -#ifndef CROSS_MODULE_HPP -# define CROSS_MODULE_HPP - -# include - -namespace boost { namespace python { - struct import_error : error_already_set {}; - struct export_error : error_already_set {}; -}} - -namespace boost { namespace python { namespace detail { - -// Concept: throw exception if api_major is changed -// show warning on stderr if api_minor is changed -const int export_converters_api_major = 2; -const int export_converters_api_minor = 1; -extern const char* converters_attribute_name; -void* import_converter_object(const std::string& module_name, - const std::string& py_class_name, - const std::string& attribute_name); -void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor); - -}}} - -// forward declaration -namespace boost { namespace python { namespace detail { -template class import_extension_class; -}}} - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -//QUESTIONMARK -// This class is a look-alike of class python_extension_class_converters. -// Is there a formal way to ensure that the siblings stay in sync? -template -class python_import_extension_class_converters -{ - public: - - friend python_import_extension_class_converters py_extension_class_converters(boost::python::type) - { - return python_import_extension_class_converters(); - } - - PyObject* to_python(const T& x) const - { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } - - friend T* from_python(PyObject* p, boost::python::type) - { - return boost::python::detail::import_extension_class::get_converters()->T_pointer_from_python(p); - } - - // Convert to const T* - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to const T* const& - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T* const& - friend T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T& - friend T& from_python(PyObject* p, boost::python::type) { - return boost::python::detail::import_extension_class::get_converters()->T_reference_from_python(p); - } - - // Convert to const T& - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->auto_ptr_reference_from_python(p); - } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type >) { - return boost::python::detail::import_extension_class::get_converters()->auto_ptr_value_from_python(p); - } - - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->auto_ptr_value_from_python(p); - } - - friend PyObject* to_python(std::auto_ptr x) { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->shared_ptr_reference_from_python(p); - } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type >) { - return boost::python::detail::import_extension_class::get_converters()->shared_ptr_value_from_python(p); - } - - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) { - return boost::python::detail::import_extension_class::get_converters()->shared_ptr_value_from_python(p); - } - - friend PyObject* to_python(boost::shared_ptr x) { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } -}; - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -BOOST_PYTHON_IMPORT_CONVERSION(python_import_extension_class_converters); - -// A pointer to this class is exported/imported via the Python API. -// All functions are virtual. This is, what we really export/import -// is essentially just a pointer to a vtbl. -template -struct export_converter_object_base -{ - virtual const int get_api_major() const { - return detail::export_converters_api_major; } - virtual const int get_api_minor() const { - return detail::export_converters_api_minor; } - virtual PyObject* to_python(const T& x) = 0; - virtual PyObject* to_python(std::auto_ptr x) = 0; - virtual PyObject* to_python(boost::shared_ptr x) = 0; - virtual T* T_pointer_from_python(PyObject* obj) = 0; - virtual T& T_reference_from_python(PyObject* obj) = 0; - virtual std::auto_ptr& auto_ptr_reference_from_python(PyObject* obj) = 0; - virtual std::auto_ptr auto_ptr_value_from_python(PyObject* obj) = 0; - virtual boost::shared_ptr& shared_ptr_reference_from_python(PyObject* obj) = 0; - virtual boost::shared_ptr shared_ptr_value_from_python(PyObject* obj) = 0; -}; - -// Converters to be used if T is not copyable. -template -struct export_converter_object_noncopyable : export_converter_object_base -{ - virtual PyObject* to_python(const T& x) { - PyErr_SetString(PyExc_RuntimeError, - "to_python(const T&) converter not exported"); - throw import_error(); - } - virtual PyObject* to_python(std::auto_ptr x) { - return BOOST_PYTHON_CONVERSION::to_python(x); - } - virtual PyObject* to_python(boost::shared_ptr x) { - return BOOST_PYTHON_CONVERSION::to_python(x); - } - virtual T* T_pointer_from_python(PyObject* obj) { - return BOOST_PYTHON_CONVERSION::from_python(obj, boost::python::type()); - } - virtual T& T_reference_from_python(PyObject* obj) { - return BOOST_PYTHON_CONVERSION::from_python(obj, boost::python::type()); - } - virtual std::auto_ptr& auto_ptr_reference_from_python(PyObject* obj) { - return BOOST_PYTHON_CONVERSION::python_extension_class_converters::smart_ptr_reference(obj, boost::python::type >()); - } - virtual std::auto_ptr auto_ptr_value_from_python(PyObject* obj) { - return BOOST_PYTHON_CONVERSION::python_extension_class_converters::smart_ptr_value(obj, boost::python::type >()); - } - virtual boost::shared_ptr& shared_ptr_reference_from_python(PyObject* obj) { - return BOOST_PYTHON_CONVERSION::python_extension_class_converters::smart_ptr_reference(obj, boost::python::type >()); - } - virtual boost::shared_ptr shared_ptr_value_from_python(PyObject* obj) { - return BOOST_PYTHON_CONVERSION::python_extension_class_converters::smart_ptr_value(obj, boost::python::type >()); - } -}; - -// The addditional to_python() converter that can be used if T is copyable. -template -struct export_converter_object : export_converter_object_noncopyable -{ - virtual PyObject* to_python(const T& x) { - BOOST_PYTHON_CONVERSION::python_extension_class_converters cv; - return cv.to_python(x); - } -}; - -namespace detail { - -//QUESTIONMARK -// A stripped-down, modified version of class extension_class. -// Would it make sense to establish a formal relationship -// between the two classes? -template -class import_extension_class - : public python_import_extension_class_converters -{ - public: - inline import_extension_class(const char* module, const char* py_class) { - m_module = module; - m_py_class = py_class; - } - - static boost::python::export_converter_object_base* get_converters(); - - private: - static std::string m_module; - static std::string m_py_class; - static boost::python::export_converter_object_base* imported_converters; -}; - -template std::string import_extension_class::m_module; -template std::string import_extension_class::m_py_class; -template -boost::python::export_converter_object_base* -import_extension_class::imported_converters = 0; - -template -boost::python::export_converter_object_base* -import_extension_class::get_converters() { - if (imported_converters == 0) { - void* cobject - = import_converter_object(m_module, m_py_class, - converters_attribute_name); - imported_converters - = static_cast*>(cobject); - check_export_converters_api( - export_converters_api_major, - export_converters_api_minor, - imported_converters->get_api_major(), - imported_converters->get_api_minor()); - } - return imported_converters; -} - -}}} // namespace boost::python::detail - -namespace boost { namespace python { - -template -void export_converters(class_builder& cb) -{ - static export_converter_object export_cvts; - cb.add( - ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), - detail::converters_attribute_name); -} - -template -void export_converters_noncopyable(class_builder& cb) -{ - static export_converter_object_noncopyable export_cvts; - cb.add( - ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), - detail::converters_attribute_name); -} - -template -class import_converters - : python_import_extension_class_converters -{ - public: - import_converters(const char* module, const char* py_class) - : m_class(new detail::import_extension_class(module, py_class)) - { } - private: - //QUESTIONMARK - //reference > m_class; - boost::shared_ptr > m_class; -}; - -}} // namespace boost::python - -#endif // CROSS_MODULE_HPP diff --git a/src/cross_module.cpp b/src/cross_module.cpp deleted file mode 100644 index c14acfda..00000000 --- a/src/cross_module.cpp +++ /dev/null @@ -1,77 +0,0 @@ -# include -namespace python = boost::python; -# include // MSVC6.0SP4 does not know std::fprintf -# include // MSVC6.0SP4 does not know std::strcmp - -namespace { - - PyObject* get_module_dict(const char* module_name) - { - python::ref module_obj(PyImport_ImportModule((char*) module_name)); - PyObject* module_dict = PyModule_GetDict(module_obj.get()); - if (module_dict == 0) throw python::import_error(); - return module_dict; - } -} - -namespace boost { namespace python { namespace detail { - -const char* converters_attribute_name = "__converters__"; - -void* import_converter_object(const std::string& module_name, - const std::string& py_class_name, - const std::string& attribute_name) -{ - static std::string err; - PyObject* module_dict = get_module_dict(const_cast(module_name.c_str())); - PyObject* py_class = PyDict_GetItemString(module_dict, const_cast(py_class_name.c_str())); - if (py_class == 0) { - err = std::string("module ") + module_name + " has no attribute " + py_class_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - python::ref c_obj(PyObject_GetAttrString(py_class, const_cast(attribute_name.c_str())), ref::null_ok); - if (c_obj.get() == 0) { - err = std::string("object ") + module_name + "." + py_class_name - + " has no attribute " + attribute_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - if (! PyCObject_Check(c_obj.get())) { - err = std::string("object ") + module_name + "." + py_class_name + "." - + attribute_name + " is not a PyCObject"; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - return PyCObject_AsVoidPtr(c_obj.get()); -} - -void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor) -{ - if (importing_major != imported_major) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Fatal: export_converters_api mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - PyErr_SetString(PyExc_RuntimeError, - "Fatal: export_converters_api mismatch"); - throw import_error(); - } - if (importing_minor != imported_minor) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Warning: export_converters_api mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - } -} - -}}} // namespace boost::python::detail From 1f45a846c64420b56fb9da13d963f97035a18525 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 20 Mar 2001 02:13:28 +0000 Subject: [PATCH 0043/1042] VC++ 6.0 fixes and misc. other modifications. [SVN r9601] --- example/getting_started4.cpp | 9 ++++----- example/getting_started5.cpp | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/example/getting_started4.cpp b/example/getting_started4.cpp index cf6c2ff2..fe6a3421 100644 --- a/example/getting_started4.cpp +++ b/example/getting_started4.cpp @@ -15,7 +15,7 @@ namespace { // Avoid cluttering the global namespace. vector_double_wrapper(PyObject* self) : std::vector() {} - vector_double_wrapper(PyObject* self, const int n) + vector_double_wrapper(PyObject* self, int n) : std::vector(n) {} vector_double_wrapper(PyObject* self, python::tuple tuple) @@ -28,17 +28,16 @@ namespace { // Avoid cluttering the global namespace. } }; - double getitem(const std::vector& vd, const std::size_t key) { + double getitem(const std::vector& vd, std::size_t key) { return vd[key]; } - void setitem(std::vector& vd, const std::size_t key, - const double &d) { + void setitem(std::vector& vd, std::size_t key, double d) { std::vector::iterator vditer = vd.begin(); vditer[key] = d; } - void delitem(std::vector& vd, const std::size_t key) { + void delitem(std::vector& vd, std::size_t key) { std::vector::iterator vditer = vd.begin(); vd.erase(&vditer[key]); } diff --git a/example/getting_started5.cpp b/example/getting_started5.cpp index be033224..9e9e7c75 100644 --- a/example/getting_started5.cpp +++ b/example/getting_started5.cpp @@ -60,7 +60,7 @@ namespace { // Avoid cluttering the global namespace. std::vector VMIx; public: void add(const MillerIndex& MIx) { VMIx.push_back(MIx); } - MillerIndex get(const std::size_t i) const { return VMIx[i]; } + MillerIndex get(std::size_t i) const { return VMIx[i]; } }; } From 591eaeaafbaa53bce030c06af0198690886a915a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 20 Mar 2001 02:16:08 +0000 Subject: [PATCH 0044/1042] VC++ 6.0 makefile; filemgr.py used by all ralf_grosse_kunstleve makefiles. [SVN r9602] --- build/filemgr.py | 122 ++++++++++++++++++++++++++++++++++++++++++++ build/vc60.mak | 129 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 251 insertions(+) create mode 100644 build/filemgr.py create mode 100644 build/vc60.mak diff --git a/build/filemgr.py b/build/filemgr.py new file mode 100644 index 00000000..51c87403 --- /dev/null +++ b/build/filemgr.py @@ -0,0 +1,122 @@ +bpl_src = "/libs/python/src" +bpl_tst = "/libs/python/test" +bpl_exa = "/libs/python/example" +files = ( +bpl_src + "/classes.cpp", +bpl_src + "/conversions.cpp", +bpl_src + "/extension_class.cpp", +bpl_src + "/functions.cpp", +bpl_src + "/init_function.cpp", +bpl_src + "/module_builder.cpp", +bpl_src + "/objects.cpp", +bpl_src + "/types.cpp", +bpl_src + "/cross_module.cpp", +bpl_tst + "/comprehensive.cpp", +bpl_tst + "/comprehensive.hpp", +bpl_tst + "/comprehensive.py", +bpl_tst + "/doctest.py", +bpl_exa + "/abstract.cpp", +bpl_exa + "/getting_started1.cpp", +bpl_exa + "/getting_started2.cpp", +bpl_exa + "/getting_started3.cpp", +bpl_exa + "/getting_started4.cpp", +bpl_exa + "/getting_started5.cpp", +bpl_exa + "/pickle1.cpp", +bpl_exa + "/pickle2.cpp", +bpl_exa + "/pickle3.cpp", +bpl_exa + "/test_abstract.py", +bpl_exa + "/test_getting_started1.py", +bpl_exa + "/test_getting_started2.py", +bpl_exa + "/test_getting_started3.py", +bpl_exa + "/test_getting_started4.py", +bpl_exa + "/test_getting_started5.py", +bpl_exa + "/test_pickle1.py", +bpl_exa + "/test_pickle2.py", +bpl_exa + "/test_pickle3.py", +bpl_exa + "/noncopyable.h", +bpl_exa + "/noncopyable_export.cpp", +bpl_exa + "/noncopyable_import.cpp", +bpl_exa + "/tst_noncopyable.py", +bpl_exa + "/ivect.h", +bpl_exa + "/ivect.cpp", +bpl_exa + "/dvect.h", +bpl_exa + "/dvect.cpp", +bpl_exa + "/tst_ivect.py", +bpl_exa + "/tst_dvect.py", +) + +defs = ( +"boost_python_test", +"abstract", +"getting_started1", +"getting_started2", +"getting_started3", +"getting_started4", +"getting_started5", +"pickle1", +"pickle2", +"pickle3", +"noncopyable_export", +"noncopyable_import", +"ivect", +"dvect", +) + +if (__name__ == "__main__"): + + import sys, os, string + + path = sys.argv[1] + mode = sys.argv[2] + if (not mode in ("softlinks", "unlink", "cp", "rm", "copy", "del")): + raise RuntimeError, \ + "usage: python filemgr.py path " + + translation_table = string.maketrans("/", "\\") + + if (mode == "copy"): + for fn in files: + fn = string.translate(fn, translation_table) + os.system("copy " + path + fn + " .") + + elif (mode == "cp"): + for fn in files: + os.system("cp " + path + fn + " .") + + elif (mode == "softlinks"): + for fn in files: + f = string.split(fn, "/")[-1] + if (os.access(f, os.F_OK)): + print "File exists: " + f + else: + os.system("ln -s " + path + os.sep + fn + " .") + + elif (mode in ("rm", "del")): + for fn in files: + flds = string.split(fn, "/") + try: os.unlink(flds[-1]) + except: pass + + elif (mode == "unlink"): + for fn in files: + f = string.split(fn, "/")[-1] + if (os.system("test -e " + f) == 0): + if (os.system("test -L " + f) == 0): + try: os.unlink(f) + except: pass + else: + print "Not a softlink: " + f + + if (mode in ("softlinks", "cp", "copy")): + for d in defs: + fn = d + ".def" + f = open(fn, "w") + f.write("EXPORTS\n") + f.write("\tinit" + d + "\n") + f.close() + + if (mode in ("unlink", "rm", "del")): + for d in defs: + fn = d + ".def" + try: os.unlink(fn) + except: pass diff --git a/build/vc60.mak b/build/vc60.mak new file mode 100644 index 00000000..a05d04f4 --- /dev/null +++ b/build/vc60.mak @@ -0,0 +1,129 @@ +# Usage: +# +# make copy Copy the sources and tests +# make Compile all sources +# make test Run doctest tests +# make clean Remove all object files +# make del Remove the sources and tests + +BOOST_WIN= "L:\boost" +BOOST_UNIX= /net/cci/rwgk/boost + +PYEXE= "C:\Program files\Python\python.exe" +PYINC= /I"C:\Program files\Python\include" +PYLIB= "C:\Program files\Python\libs\python15.lib" + +STDOPTS= /nologo /MD /GR /GX /FD /Zm200 +WARNOPTS= + +CPP= cl.exe +CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) /I$(BOOST_WIN) $(PYINC) \ + $(STDOPTS) $(WARNOPTS) + +LD= link.exe +LDOPTS= /nologo /dll /incremental:no + +OBJ = classes.obj conversions.obj extension_class.obj functions.obj \ + init_function.obj module_builder.obj \ + objects.obj types.obj cross_module.obj + +.SUFFIXES: .obj .cpp + +all: libboost_python.a \ + boost_python_test.pyd \ + abstract.pyd \ + getting_started1.pyd getting_started2.pyd getting_started3.pyd \ + getting_started4.pyd getting_started5.pyd \ + pickle1.pyd pickle2.pyd pickle3.pyd \ + noncopyable_export.pyd noncopyable_import.pyd \ + ivect.pyd dvect.pyd + +libboost_python.a: $(OBJ) + +boost_python_test.pyd: $(OBJ) comprehensive.obj + $(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) /export:initboost_python_test /out:"boost_python_test.pyd" + +abstract.pyd: $(OBJ) abstract.obj + $(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) /export:initabstract /out:"abstract.pyd" + +getting_started1.pyd: $(OBJ) getting_started1.obj + $(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) /export:initgetting_started1 /out:"getting_started1.pyd" + +getting_started2.pyd: $(OBJ) getting_started2.obj + $(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) /export:initgetting_started2 /out:"getting_started2.pyd" + +getting_started3.pyd: $(OBJ) getting_started3.obj + $(LD) $(LDOPTS) $(OBJ) getting_started3.obj $(PYLIB) /export:initgetting_started3 /out:"getting_started3.pyd" + +getting_started4.pyd: $(OBJ) getting_started4.obj + $(LD) $(LDOPTS) $(OBJ) getting_started4.obj $(PYLIB) /export:initgetting_started4 /out:"getting_started4.pyd" + +getting_started5.pyd: $(OBJ) getting_started5.obj + $(LD) $(LDOPTS) $(OBJ) getting_started5.obj $(PYLIB) /export:initgetting_started5 /out:"getting_started5.pyd" + +pickle1.pyd: $(OBJ) pickle1.obj + $(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) /export:initpickle1 /out:"pickle1.pyd" + +pickle2.pyd: $(OBJ) pickle2.obj + $(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) /export:initpickle2 /out:"pickle2.pyd" + +pickle3.pyd: $(OBJ) pickle3.obj + $(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) /export:initpickle3 /out:"pickle3.pyd" + +noncopyable_export.pyd: $(OBJ) noncopyable_export.obj + $(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) /export:initnoncopyable_export /out:"noncopyable_export.pyd" + +noncopyable_import.pyd: $(OBJ) noncopyable_import.obj + $(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) /export:initnoncopyable_import /out:"noncopyable_import.pyd" + +ivect.pyd: $(OBJ) ivect.obj + $(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) /export:initivect /out:"ivect.pyd" + +dvect.pyd: $(OBJ) dvect.obj + $(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) /export:initdvect /out:"dvect.pyd" + +.cpp.obj: + $(CPP) $(CPPOPTS) /c $*.cpp + +test: + $(PYEXE) comprehensive.py --broken-auto-ptr + $(PYEXE) test_abstract.py + $(PYEXE) test_getting_started1.py + $(PYEXE) test_getting_started2.py + $(PYEXE) test_getting_started3.py + $(PYEXE) test_getting_started4.py + $(PYEXE) test_getting_started5.py + $(PYEXE) test_pickle1.py + $(PYEXE) test_pickle2.py + $(PYEXE) test_pickle3.py + +tst: + $(PYEXE) tst_noncopyable.py + $(PYEXE) tst_ivect.py + $(PYEXE) tst_dvect.py + +clean: + del *.obj + del *.lib + del *.exp + del *.idb + del *.pyd + del *.pyc + +softlinks: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks + +unlink: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink + +cp: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp + +rm: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm + +copy: + python $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy + +del: + python $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del From c4775a581edb6aaf6c7e9cde17c5e4a26be9f36d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 21 Mar 2001 01:05:30 +0000 Subject: [PATCH 0045/1042] temp files before branching [SVN r9615] --- example/dvect_conversions.cpp | 51 +++++++++++++++++++++ example/dvect_defs.cpp | 13 ++++++ example/ivect_conversions.cpp | 51 +++++++++++++++++++++ example/ivect_defs.cpp | 13 ++++++ example/swap_iv_dv.sh | 1 + example/tst_dvect1.py | 23 ++++++++++ example/tst_dvect2.py | 85 +++++++++++++++++++++++++++++++++++ example/tst_ivect1.py | 23 ++++++++++ example/tst_ivect2.py | 85 +++++++++++++++++++++++++++++++++++ 9 files changed, 345 insertions(+) create mode 100644 example/dvect_conversions.cpp create mode 100644 example/dvect_defs.cpp create mode 100644 example/ivect_conversions.cpp create mode 100644 example/ivect_defs.cpp create mode 100644 example/swap_iv_dv.sh create mode 100644 example/tst_dvect1.py create mode 100644 example/tst_dvect2.py create mode 100644 example/tst_ivect1.py create mode 100644 example/tst_ivect2.py diff --git a/example/dvect_conversions.cpp b/example/dvect_conversions.cpp new file mode 100644 index 00000000..21527243 --- /dev/null +++ b/example/dvect_conversions.cpp @@ -0,0 +1,51 @@ + // basics first: const reference converters + boost::python::tuple const_dvect_reference_as_tuple(const vects::dvect& dv) + { + return dv.as_tuple(); + } + + // to_python smart pointer conversions + std::auto_ptr dvect_as_auto_ptr(const vects::dvect& dv) + { + return std::auto_ptr(new vects::dvect(dv)); + } + boost::shared_ptr dvect_as_shared_ptr(const vects::dvect& dv) + { + return boost::shared_ptr(new vects::dvect(dv)); + } + + // smart pointers passed by value + boost::python::ref auto_ptr_value_dvect_as_tuple(std::auto_ptr dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } + boost::python::ref shared_ptr_value_dvect_as_tuple(boost::shared_ptr dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } + + // smart pointers passed by reference + boost::python::ref auto_ptr_reference_dvect_as_tuple(std::auto_ptr& dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } + boost::python::ref shared_ptr_reference_dvect_as_tuple(boost::shared_ptr& dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } + + // smart pointers passed by const reference + boost::python::ref auto_ptr_const_reference_dvect_as_tuple(const std::auto_ptr& dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } + boost::python::ref shared_ptr_const_reference_dvect_as_tuple(const boost::shared_ptr& dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } diff --git a/example/dvect_defs.cpp b/example/dvect_defs.cpp new file mode 100644 index 00000000..2739b219 --- /dev/null +++ b/example/dvect_defs.cpp @@ -0,0 +1,13 @@ + this_module.def(dvect_as_auto_ptr, "dvect_as_auto_ptr"); + this_module.def(dvect_as_shared_ptr, "dvect_as_shared_ptr"); + + this_module.def(const_dvect_reference_as_tuple, "const_dvect_reference_as_tuple"); + + this_module.def(auto_ptr_value_dvect_as_tuple, "auto_ptr_value_dvect_as_tuple"); + this_module.def(shared_ptr_value_dvect_as_tuple, "shared_ptr_value_dvect_as_tuple"); + + this_module.def(auto_ptr_reference_dvect_as_tuple, "auto_ptr_reference_dvect_as_tuple"); + this_module.def(shared_ptr_reference_dvect_as_tuple, "shared_ptr_reference_dvect_as_tuple"); + + this_module.def(auto_ptr_const_reference_dvect_as_tuple, "auto_ptr_const_reference_dvect_as_tuple"); + this_module.def(shared_ptr_const_reference_dvect_as_tuple, "shared_ptr_const_reference_dvect_as_tuple"); diff --git a/example/ivect_conversions.cpp b/example/ivect_conversions.cpp new file mode 100644 index 00000000..4f59573d --- /dev/null +++ b/example/ivect_conversions.cpp @@ -0,0 +1,51 @@ + // basics first: const reference converters + boost::python::tuple const_ivect_reference_as_tuple(const vects::ivect& iv) + { + return iv.as_tuple(); + } + + // to_python smart pointer conversions + std::auto_ptr ivect_as_auto_ptr(const vects::ivect& iv) + { + return std::auto_ptr(new vects::ivect(iv)); + } + boost::shared_ptr ivect_as_shared_ptr(const vects::ivect& iv) + { + return boost::shared_ptr(new vects::ivect(iv)); + } + + // smart pointers passed by value + boost::python::ref auto_ptr_value_ivect_as_tuple(std::auto_ptr iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } + boost::python::ref shared_ptr_value_ivect_as_tuple(boost::shared_ptr iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } + + // smart pointers passed by reference + boost::python::ref auto_ptr_reference_ivect_as_tuple(std::auto_ptr& iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } + boost::python::ref shared_ptr_reference_ivect_as_tuple(boost::shared_ptr& iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } + + // smart pointers passed by const reference + boost::python::ref auto_ptr_const_reference_ivect_as_tuple(const std::auto_ptr& iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } + boost::python::ref shared_ptr_const_reference_ivect_as_tuple(const boost::shared_ptr& iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } diff --git a/example/ivect_defs.cpp b/example/ivect_defs.cpp new file mode 100644 index 00000000..811c243d --- /dev/null +++ b/example/ivect_defs.cpp @@ -0,0 +1,13 @@ + this_module.def(ivect_as_auto_ptr, "ivect_as_auto_ptr"); + this_module.def(ivect_as_shared_ptr, "ivect_as_shared_ptr"); + + this_module.def(const_ivect_reference_as_tuple, "const_ivect_reference_as_tuple"); + + this_module.def(auto_ptr_value_ivect_as_tuple, "auto_ptr_value_ivect_as_tuple"); + this_module.def(shared_ptr_value_ivect_as_tuple, "shared_ptr_value_ivect_as_tuple"); + + this_module.def(auto_ptr_reference_ivect_as_tuple, "auto_ptr_reference_ivect_as_tuple"); + this_module.def(shared_ptr_reference_ivect_as_tuple, "shared_ptr_reference_ivect_as_tuple"); + + this_module.def(auto_ptr_const_reference_ivect_as_tuple, "auto_ptr_const_reference_ivect_as_tuple"); + this_module.def(shared_ptr_const_reference_ivect_as_tuple, "shared_ptr_const_reference_ivect_as_tuple"); diff --git a/example/swap_iv_dv.sh b/example/swap_iv_dv.sh new file mode 100644 index 00000000..fc072bee --- /dev/null +++ b/example/swap_iv_dv.sh @@ -0,0 +1 @@ +sed 's/iv/xv/g' $1 | sed 's/dv/iv/g' | sed 's/xv/dv/g' diff --git a/example/tst_dvect1.py b/example/tst_dvect1.py new file mode 100644 index 00000000..12c53739 --- /dev/null +++ b/example/tst_dvect1.py @@ -0,0 +1,23 @@ +def f(): + import dvect + print dvect.dvect.__converters__ + dv = dvect.dvect((1,2,3,4,5)) + print dv + print dv.as_tuple() + iv = dv.as_ivect() + print iv + print iv.as_tuple() + print dvect.const_ivect_reference_as_tuple(iv) + aiv = dvect.ivect_as_auto_ptr(iv) + print dvect.const_ivect_reference_as_tuple(aiv) + siv = dvect.ivect_as_shared_ptr(iv) + print dvect.const_ivect_reference_as_tuple(siv) + print aiv.as_tuple() + print siv.as_tuple() + +if (__name__ == "__main__"): + import sys, string + n = 1 + if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) + for i in xrange(n): + f() diff --git a/example/tst_dvect2.py b/example/tst_dvect2.py new file mode 100644 index 00000000..868c107d --- /dev/null +++ b/example/tst_dvect2.py @@ -0,0 +1,85 @@ +def f(): + import dvect + import ivect + # + dv = dvect.dvect((1,2,3,4,5)) + iv = dv.as_ivect() + # + aiv = dvect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_value_ivect_as_tuple' + print ivect.auto_ptr_value_ivect_as_tuple(aiv) + print '2. auto_ptr_value_ivect_as_tuple' + print ivect.auto_ptr_value_ivect_as_tuple(aiv) + # + adv = dvect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_value_dvect_as_tuple' + print ivect.auto_ptr_value_dvect_as_tuple(adv) + print '2. auto_ptr_value_dvect_as_tuple' + print ivect.auto_ptr_value_dvect_as_tuple(adv) + # + siv = dvect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_value_ivect_as_tuple' + print ivect.shared_ptr_value_ivect_as_tuple(siv) + print '2. shared_ptr_value_ivect_as_tuple' + print ivect.shared_ptr_value_ivect_as_tuple(siv) + # + sdv = dvect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_value_dvect_as_tuple' + print ivect.shared_ptr_value_dvect_as_tuple(sdv) + print '2. shared_ptr_value_dvect_as_tuple' + print ivect.shared_ptr_value_dvect_as_tuple(sdv) + # + aiv = dvect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_reference_ivect_as_tuple' + print ivect.auto_ptr_reference_ivect_as_tuple(aiv) + print '2. auto_ptr_reference_ivect_as_tuple' + print ivect.auto_ptr_reference_ivect_as_tuple(aiv) + # + adv = dvect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_reference_dvect_as_tuple' + print ivect.auto_ptr_reference_dvect_as_tuple(adv) + print '2. auto_ptr_reference_dvect_as_tuple' + print ivect.auto_ptr_reference_dvect_as_tuple(adv) + # + siv = dvect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_reference_ivect_as_tuple' + print ivect.shared_ptr_reference_ivect_as_tuple(siv) + print '2. shared_ptr_reference_ivect_as_tuple' + print ivect.shared_ptr_reference_ivect_as_tuple(siv) + # + sdv = dvect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_reference_dvect_as_tuple' + print ivect.shared_ptr_reference_dvect_as_tuple(sdv) + print '2. shared_ptr_reference_dvect_as_tuple' + print ivect.shared_ptr_reference_dvect_as_tuple(sdv) + # + aiv = dvect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_const_reference_ivect_as_tuple' + print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv) + print '2. auto_ptr_const_reference_ivect_as_tuple' + print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv) + # + adv = dvect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_const_reference_dvect_as_tuple' + print ivect.auto_ptr_const_reference_dvect_as_tuple(adv) + print '2. auto_ptr_const_reference_dvect_as_tuple' + print ivect.auto_ptr_const_reference_dvect_as_tuple(adv) + # + siv = dvect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_const_reference_ivect_as_tuple' + print ivect.shared_ptr_const_reference_ivect_as_tuple(siv) + print '2. shared_ptr_const_reference_ivect_as_tuple' + print ivect.shared_ptr_const_reference_ivect_as_tuple(siv) + # + sdv = dvect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_const_reference_dvect_as_tuple' + print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv) + print '2. shared_ptr_const_reference_dvect_as_tuple' + print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv) + +if (__name__ == "__main__"): + import sys, string + n = 1 + if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) + for i in xrange(n): + f() diff --git a/example/tst_ivect1.py b/example/tst_ivect1.py new file mode 100644 index 00000000..62d3ecf4 --- /dev/null +++ b/example/tst_ivect1.py @@ -0,0 +1,23 @@ +def f(): + import ivect + print ivect.ivect.__converters__ + iv = ivect.ivect((1,2,3,4,5)) + print iv + print iv.as_tuple() + dv = iv.as_dvect() + print dv + print dv.as_tuple() + print ivect.const_dvect_reference_as_tuple(dv) + adv = ivect.dvect_as_auto_ptr(dv) + print ivect.const_dvect_reference_as_tuple(adv) + sdv = ivect.dvect_as_shared_ptr(dv) + print ivect.const_dvect_reference_as_tuple(sdv) + print adv.as_tuple() + print sdv.as_tuple() + +if (__name__ == "__main__"): + import sys, string + n = 1 + if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) + for i in xrange(n): + f() diff --git a/example/tst_ivect2.py b/example/tst_ivect2.py new file mode 100644 index 00000000..0db6903d --- /dev/null +++ b/example/tst_ivect2.py @@ -0,0 +1,85 @@ +def f(): + import ivect + import dvect + # + iv = ivect.ivect((1,2,3,4,5)) + dv = iv.as_dvect() + # + adv = ivect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_value_dvect_as_tuple' + print dvect.auto_ptr_value_dvect_as_tuple(adv) + print '2. auto_ptr_value_dvect_as_tuple' + print dvect.auto_ptr_value_dvect_as_tuple(adv) + # + aiv = ivect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_value_ivect_as_tuple' + print dvect.auto_ptr_value_ivect_as_tuple(aiv) + print '2. auto_ptr_value_ivect_as_tuple' + print dvect.auto_ptr_value_ivect_as_tuple(aiv) + # + sdv = ivect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_value_dvect_as_tuple' + print dvect.shared_ptr_value_dvect_as_tuple(sdv) + print '2. shared_ptr_value_dvect_as_tuple' + print dvect.shared_ptr_value_dvect_as_tuple(sdv) + # + siv = ivect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_value_ivect_as_tuple' + print dvect.shared_ptr_value_ivect_as_tuple(siv) + print '2. shared_ptr_value_ivect_as_tuple' + print dvect.shared_ptr_value_ivect_as_tuple(siv) + # + adv = ivect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_reference_dvect_as_tuple' + print dvect.auto_ptr_reference_dvect_as_tuple(adv) + print '2. auto_ptr_reference_dvect_as_tuple' + print dvect.auto_ptr_reference_dvect_as_tuple(adv) + # + aiv = ivect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_reference_ivect_as_tuple' + print dvect.auto_ptr_reference_ivect_as_tuple(aiv) + print '2. auto_ptr_reference_ivect_as_tuple' + print dvect.auto_ptr_reference_ivect_as_tuple(aiv) + # + sdv = ivect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_reference_dvect_as_tuple' + print dvect.shared_ptr_reference_dvect_as_tuple(sdv) + print '2. shared_ptr_reference_dvect_as_tuple' + print dvect.shared_ptr_reference_dvect_as_tuple(sdv) + # + siv = ivect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_reference_ivect_as_tuple' + print dvect.shared_ptr_reference_ivect_as_tuple(siv) + print '2. shared_ptr_reference_ivect_as_tuple' + print dvect.shared_ptr_reference_ivect_as_tuple(siv) + # + adv = ivect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_const_reference_dvect_as_tuple' + print dvect.auto_ptr_const_reference_dvect_as_tuple(adv) + print '2. auto_ptr_const_reference_dvect_as_tuple' + print dvect.auto_ptr_const_reference_dvect_as_tuple(adv) + # + aiv = ivect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_const_reference_ivect_as_tuple' + print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv) + print '2. auto_ptr_const_reference_ivect_as_tuple' + print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv) + # + sdv = ivect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_const_reference_dvect_as_tuple' + print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv) + print '2. shared_ptr_const_reference_dvect_as_tuple' + print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv) + # + siv = ivect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_const_reference_ivect_as_tuple' + print dvect.shared_ptr_const_reference_ivect_as_tuple(siv) + print '2. shared_ptr_const_reference_ivect_as_tuple' + print dvect.shared_ptr_const_reference_ivect_as_tuple(siv) + +if (__name__ == "__main__"): + import sys, string + n = 1 + if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) + for i in xrange(n): + f() From c7d7cec28190763156ebe44d950f830ffac07c77 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 21 Mar 2001 01:07:07 +0000 Subject: [PATCH 0046/1042] temp files removed after branching. [SVN r9616] --- example/dvect_conversions.cpp | 51 --------------------- example/dvect_defs.cpp | 13 ------ example/ivect_conversions.cpp | 51 --------------------- example/ivect_defs.cpp | 13 ------ example/swap_iv_dv.sh | 1 - example/tst_dvect1.py | 23 ---------- example/tst_dvect2.py | 85 ----------------------------------- example/tst_ivect1.py | 23 ---------- example/tst_ivect2.py | 85 ----------------------------------- 9 files changed, 345 deletions(-) delete mode 100644 example/dvect_conversions.cpp delete mode 100644 example/dvect_defs.cpp delete mode 100644 example/ivect_conversions.cpp delete mode 100644 example/ivect_defs.cpp delete mode 100644 example/swap_iv_dv.sh delete mode 100644 example/tst_dvect1.py delete mode 100644 example/tst_dvect2.py delete mode 100644 example/tst_ivect1.py delete mode 100644 example/tst_ivect2.py diff --git a/example/dvect_conversions.cpp b/example/dvect_conversions.cpp deleted file mode 100644 index 21527243..00000000 --- a/example/dvect_conversions.cpp +++ /dev/null @@ -1,51 +0,0 @@ - // basics first: const reference converters - boost::python::tuple const_dvect_reference_as_tuple(const vects::dvect& dv) - { - return dv.as_tuple(); - } - - // to_python smart pointer conversions - std::auto_ptr dvect_as_auto_ptr(const vects::dvect& dv) - { - return std::auto_ptr(new vects::dvect(dv)); - } - boost::shared_ptr dvect_as_shared_ptr(const vects::dvect& dv) - { - return boost::shared_ptr(new vects::dvect(dv)); - } - - // smart pointers passed by value - boost::python::ref auto_ptr_value_dvect_as_tuple(std::auto_ptr dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - boost::python::ref shared_ptr_value_dvect_as_tuple(boost::shared_ptr dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - - // smart pointers passed by reference - boost::python::ref auto_ptr_reference_dvect_as_tuple(std::auto_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - boost::python::ref shared_ptr_reference_dvect_as_tuple(boost::shared_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - - // smart pointers passed by const reference - boost::python::ref auto_ptr_const_reference_dvect_as_tuple(const std::auto_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - boost::python::ref shared_ptr_const_reference_dvect_as_tuple(const boost::shared_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } diff --git a/example/dvect_defs.cpp b/example/dvect_defs.cpp deleted file mode 100644 index 2739b219..00000000 --- a/example/dvect_defs.cpp +++ /dev/null @@ -1,13 +0,0 @@ - this_module.def(dvect_as_auto_ptr, "dvect_as_auto_ptr"); - this_module.def(dvect_as_shared_ptr, "dvect_as_shared_ptr"); - - this_module.def(const_dvect_reference_as_tuple, "const_dvect_reference_as_tuple"); - - this_module.def(auto_ptr_value_dvect_as_tuple, "auto_ptr_value_dvect_as_tuple"); - this_module.def(shared_ptr_value_dvect_as_tuple, "shared_ptr_value_dvect_as_tuple"); - - this_module.def(auto_ptr_reference_dvect_as_tuple, "auto_ptr_reference_dvect_as_tuple"); - this_module.def(shared_ptr_reference_dvect_as_tuple, "shared_ptr_reference_dvect_as_tuple"); - - this_module.def(auto_ptr_const_reference_dvect_as_tuple, "auto_ptr_const_reference_dvect_as_tuple"); - this_module.def(shared_ptr_const_reference_dvect_as_tuple, "shared_ptr_const_reference_dvect_as_tuple"); diff --git a/example/ivect_conversions.cpp b/example/ivect_conversions.cpp deleted file mode 100644 index 4f59573d..00000000 --- a/example/ivect_conversions.cpp +++ /dev/null @@ -1,51 +0,0 @@ - // basics first: const reference converters - boost::python::tuple const_ivect_reference_as_tuple(const vects::ivect& iv) - { - return iv.as_tuple(); - } - - // to_python smart pointer conversions - std::auto_ptr ivect_as_auto_ptr(const vects::ivect& iv) - { - return std::auto_ptr(new vects::ivect(iv)); - } - boost::shared_ptr ivect_as_shared_ptr(const vects::ivect& iv) - { - return boost::shared_ptr(new vects::ivect(iv)); - } - - // smart pointers passed by value - boost::python::ref auto_ptr_value_ivect_as_tuple(std::auto_ptr iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - boost::python::ref shared_ptr_value_ivect_as_tuple(boost::shared_ptr iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - - // smart pointers passed by reference - boost::python::ref auto_ptr_reference_ivect_as_tuple(std::auto_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - boost::python::ref shared_ptr_reference_ivect_as_tuple(boost::shared_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - - // smart pointers passed by const reference - boost::python::ref auto_ptr_const_reference_ivect_as_tuple(const std::auto_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - boost::python::ref shared_ptr_const_reference_ivect_as_tuple(const boost::shared_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } diff --git a/example/ivect_defs.cpp b/example/ivect_defs.cpp deleted file mode 100644 index 811c243d..00000000 --- a/example/ivect_defs.cpp +++ /dev/null @@ -1,13 +0,0 @@ - this_module.def(ivect_as_auto_ptr, "ivect_as_auto_ptr"); - this_module.def(ivect_as_shared_ptr, "ivect_as_shared_ptr"); - - this_module.def(const_ivect_reference_as_tuple, "const_ivect_reference_as_tuple"); - - this_module.def(auto_ptr_value_ivect_as_tuple, "auto_ptr_value_ivect_as_tuple"); - this_module.def(shared_ptr_value_ivect_as_tuple, "shared_ptr_value_ivect_as_tuple"); - - this_module.def(auto_ptr_reference_ivect_as_tuple, "auto_ptr_reference_ivect_as_tuple"); - this_module.def(shared_ptr_reference_ivect_as_tuple, "shared_ptr_reference_ivect_as_tuple"); - - this_module.def(auto_ptr_const_reference_ivect_as_tuple, "auto_ptr_const_reference_ivect_as_tuple"); - this_module.def(shared_ptr_const_reference_ivect_as_tuple, "shared_ptr_const_reference_ivect_as_tuple"); diff --git a/example/swap_iv_dv.sh b/example/swap_iv_dv.sh deleted file mode 100644 index fc072bee..00000000 --- a/example/swap_iv_dv.sh +++ /dev/null @@ -1 +0,0 @@ -sed 's/iv/xv/g' $1 | sed 's/dv/iv/g' | sed 's/xv/dv/g' diff --git a/example/tst_dvect1.py b/example/tst_dvect1.py deleted file mode 100644 index 12c53739..00000000 --- a/example/tst_dvect1.py +++ /dev/null @@ -1,23 +0,0 @@ -def f(): - import dvect - print dvect.dvect.__converters__ - dv = dvect.dvect((1,2,3,4,5)) - print dv - print dv.as_tuple() - iv = dv.as_ivect() - print iv - print iv.as_tuple() - print dvect.const_ivect_reference_as_tuple(iv) - aiv = dvect.ivect_as_auto_ptr(iv) - print dvect.const_ivect_reference_as_tuple(aiv) - siv = dvect.ivect_as_shared_ptr(iv) - print dvect.const_ivect_reference_as_tuple(siv) - print aiv.as_tuple() - print siv.as_tuple() - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() diff --git a/example/tst_dvect2.py b/example/tst_dvect2.py deleted file mode 100644 index 868c107d..00000000 --- a/example/tst_dvect2.py +++ /dev/null @@ -1,85 +0,0 @@ -def f(): - import dvect - import ivect - # - dv = dvect.dvect((1,2,3,4,5)) - iv = dv.as_ivect() - # - aiv = dvect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_value_ivect_as_tuple' - print ivect.auto_ptr_value_ivect_as_tuple(aiv) - print '2. auto_ptr_value_ivect_as_tuple' - print ivect.auto_ptr_value_ivect_as_tuple(aiv) - # - adv = dvect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_value_dvect_as_tuple' - print ivect.auto_ptr_value_dvect_as_tuple(adv) - print '2. auto_ptr_value_dvect_as_tuple' - print ivect.auto_ptr_value_dvect_as_tuple(adv) - # - siv = dvect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_value_ivect_as_tuple' - print ivect.shared_ptr_value_ivect_as_tuple(siv) - print '2. shared_ptr_value_ivect_as_tuple' - print ivect.shared_ptr_value_ivect_as_tuple(siv) - # - sdv = dvect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_value_dvect_as_tuple' - print ivect.shared_ptr_value_dvect_as_tuple(sdv) - print '2. shared_ptr_value_dvect_as_tuple' - print ivect.shared_ptr_value_dvect_as_tuple(sdv) - # - aiv = dvect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_reference_ivect_as_tuple' - print ivect.auto_ptr_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_reference_ivect_as_tuple' - print ivect.auto_ptr_reference_ivect_as_tuple(aiv) - # - adv = dvect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_reference_dvect_as_tuple' - print ivect.auto_ptr_reference_dvect_as_tuple(adv) - print '2. auto_ptr_reference_dvect_as_tuple' - print ivect.auto_ptr_reference_dvect_as_tuple(adv) - # - siv = dvect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_reference_ivect_as_tuple' - print ivect.shared_ptr_reference_ivect_as_tuple(siv) - print '2. shared_ptr_reference_ivect_as_tuple' - print ivect.shared_ptr_reference_ivect_as_tuple(siv) - # - sdv = dvect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_reference_dvect_as_tuple' - print ivect.shared_ptr_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_reference_dvect_as_tuple' - print ivect.shared_ptr_reference_dvect_as_tuple(sdv) - # - aiv = dvect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_const_reference_ivect_as_tuple' - print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_const_reference_ivect_as_tuple' - print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv) - # - adv = dvect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_const_reference_dvect_as_tuple' - print ivect.auto_ptr_const_reference_dvect_as_tuple(adv) - print '2. auto_ptr_const_reference_dvect_as_tuple' - print ivect.auto_ptr_const_reference_dvect_as_tuple(adv) - # - siv = dvect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_const_reference_ivect_as_tuple' - print ivect.shared_ptr_const_reference_ivect_as_tuple(siv) - print '2. shared_ptr_const_reference_ivect_as_tuple' - print ivect.shared_ptr_const_reference_ivect_as_tuple(siv) - # - sdv = dvect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_const_reference_dvect_as_tuple' - print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_const_reference_dvect_as_tuple' - print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv) - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() diff --git a/example/tst_ivect1.py b/example/tst_ivect1.py deleted file mode 100644 index 62d3ecf4..00000000 --- a/example/tst_ivect1.py +++ /dev/null @@ -1,23 +0,0 @@ -def f(): - import ivect - print ivect.ivect.__converters__ - iv = ivect.ivect((1,2,3,4,5)) - print iv - print iv.as_tuple() - dv = iv.as_dvect() - print dv - print dv.as_tuple() - print ivect.const_dvect_reference_as_tuple(dv) - adv = ivect.dvect_as_auto_ptr(dv) - print ivect.const_dvect_reference_as_tuple(adv) - sdv = ivect.dvect_as_shared_ptr(dv) - print ivect.const_dvect_reference_as_tuple(sdv) - print adv.as_tuple() - print sdv.as_tuple() - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() diff --git a/example/tst_ivect2.py b/example/tst_ivect2.py deleted file mode 100644 index 0db6903d..00000000 --- a/example/tst_ivect2.py +++ /dev/null @@ -1,85 +0,0 @@ -def f(): - import ivect - import dvect - # - iv = ivect.ivect((1,2,3,4,5)) - dv = iv.as_dvect() - # - adv = ivect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_value_dvect_as_tuple' - print dvect.auto_ptr_value_dvect_as_tuple(adv) - print '2. auto_ptr_value_dvect_as_tuple' - print dvect.auto_ptr_value_dvect_as_tuple(adv) - # - aiv = ivect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_value_ivect_as_tuple' - print dvect.auto_ptr_value_ivect_as_tuple(aiv) - print '2. auto_ptr_value_ivect_as_tuple' - print dvect.auto_ptr_value_ivect_as_tuple(aiv) - # - sdv = ivect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_value_dvect_as_tuple' - print dvect.shared_ptr_value_dvect_as_tuple(sdv) - print '2. shared_ptr_value_dvect_as_tuple' - print dvect.shared_ptr_value_dvect_as_tuple(sdv) - # - siv = ivect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_value_ivect_as_tuple' - print dvect.shared_ptr_value_ivect_as_tuple(siv) - print '2. shared_ptr_value_ivect_as_tuple' - print dvect.shared_ptr_value_ivect_as_tuple(siv) - # - adv = ivect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_reference_dvect_as_tuple' - print dvect.auto_ptr_reference_dvect_as_tuple(adv) - print '2. auto_ptr_reference_dvect_as_tuple' - print dvect.auto_ptr_reference_dvect_as_tuple(adv) - # - aiv = ivect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_reference_ivect_as_tuple' - print dvect.auto_ptr_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_reference_ivect_as_tuple' - print dvect.auto_ptr_reference_ivect_as_tuple(aiv) - # - sdv = ivect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_reference_dvect_as_tuple' - print dvect.shared_ptr_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_reference_dvect_as_tuple' - print dvect.shared_ptr_reference_dvect_as_tuple(sdv) - # - siv = ivect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_reference_ivect_as_tuple' - print dvect.shared_ptr_reference_ivect_as_tuple(siv) - print '2. shared_ptr_reference_ivect_as_tuple' - print dvect.shared_ptr_reference_ivect_as_tuple(siv) - # - adv = ivect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_const_reference_dvect_as_tuple' - print dvect.auto_ptr_const_reference_dvect_as_tuple(adv) - print '2. auto_ptr_const_reference_dvect_as_tuple' - print dvect.auto_ptr_const_reference_dvect_as_tuple(adv) - # - aiv = ivect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_const_reference_ivect_as_tuple' - print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_const_reference_ivect_as_tuple' - print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv) - # - sdv = ivect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_const_reference_dvect_as_tuple' - print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_const_reference_dvect_as_tuple' - print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv) - # - siv = ivect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_const_reference_ivect_as_tuple' - print dvect.shared_ptr_const_reference_ivect_as_tuple(siv) - print '2. shared_ptr_const_reference_ivect_as_tuple' - print dvect.shared_ptr_const_reference_ivect_as_tuple(siv) - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() From 4ec0b61de5ec0f677bb4ad7d6d6948bf8cbd00c4 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 21 Mar 2001 01:09:17 +0000 Subject: [PATCH 0047/1042] Now using BOOST_PYTHON_MODULE_INIT. [SVN r9617] --- example/abstract.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/example/abstract.cpp b/example/abstract.cpp index 41d34def..97e38c2e 100644 --- a/example/abstract.cpp +++ b/example/abstract.cpp @@ -21,9 +21,7 @@ struct Abstract_callback: Abstract PyObject * m_self; }; -extern "C" -DL_EXPORT(void) -initabstract() +BOOST_PYTHON_MODULE_INIT(abstract) { boost::python::module_builder a("abstract"); From f610e31a87aafbad86576d99c51c6c5347ca5c66 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 21 Mar 2001 01:15:53 +0000 Subject: [PATCH 0048/1042] temp files removed after branching. [SVN r9619] --- build/filemgr.py | 122 -------------------------------------------- build/vc60.mak | 129 ----------------------------------------------- 2 files changed, 251 deletions(-) delete mode 100644 build/filemgr.py delete mode 100644 build/vc60.mak diff --git a/build/filemgr.py b/build/filemgr.py deleted file mode 100644 index 51c87403..00000000 --- a/build/filemgr.py +++ /dev/null @@ -1,122 +0,0 @@ -bpl_src = "/libs/python/src" -bpl_tst = "/libs/python/test" -bpl_exa = "/libs/python/example" -files = ( -bpl_src + "/classes.cpp", -bpl_src + "/conversions.cpp", -bpl_src + "/extension_class.cpp", -bpl_src + "/functions.cpp", -bpl_src + "/init_function.cpp", -bpl_src + "/module_builder.cpp", -bpl_src + "/objects.cpp", -bpl_src + "/types.cpp", -bpl_src + "/cross_module.cpp", -bpl_tst + "/comprehensive.cpp", -bpl_tst + "/comprehensive.hpp", -bpl_tst + "/comprehensive.py", -bpl_tst + "/doctest.py", -bpl_exa + "/abstract.cpp", -bpl_exa + "/getting_started1.cpp", -bpl_exa + "/getting_started2.cpp", -bpl_exa + "/getting_started3.cpp", -bpl_exa + "/getting_started4.cpp", -bpl_exa + "/getting_started5.cpp", -bpl_exa + "/pickle1.cpp", -bpl_exa + "/pickle2.cpp", -bpl_exa + "/pickle3.cpp", -bpl_exa + "/test_abstract.py", -bpl_exa + "/test_getting_started1.py", -bpl_exa + "/test_getting_started2.py", -bpl_exa + "/test_getting_started3.py", -bpl_exa + "/test_getting_started4.py", -bpl_exa + "/test_getting_started5.py", -bpl_exa + "/test_pickle1.py", -bpl_exa + "/test_pickle2.py", -bpl_exa + "/test_pickle3.py", -bpl_exa + "/noncopyable.h", -bpl_exa + "/noncopyable_export.cpp", -bpl_exa + "/noncopyable_import.cpp", -bpl_exa + "/tst_noncopyable.py", -bpl_exa + "/ivect.h", -bpl_exa + "/ivect.cpp", -bpl_exa + "/dvect.h", -bpl_exa + "/dvect.cpp", -bpl_exa + "/tst_ivect.py", -bpl_exa + "/tst_dvect.py", -) - -defs = ( -"boost_python_test", -"abstract", -"getting_started1", -"getting_started2", -"getting_started3", -"getting_started4", -"getting_started5", -"pickle1", -"pickle2", -"pickle3", -"noncopyable_export", -"noncopyable_import", -"ivect", -"dvect", -) - -if (__name__ == "__main__"): - - import sys, os, string - - path = sys.argv[1] - mode = sys.argv[2] - if (not mode in ("softlinks", "unlink", "cp", "rm", "copy", "del")): - raise RuntimeError, \ - "usage: python filemgr.py path " - - translation_table = string.maketrans("/", "\\") - - if (mode == "copy"): - for fn in files: - fn = string.translate(fn, translation_table) - os.system("copy " + path + fn + " .") - - elif (mode == "cp"): - for fn in files: - os.system("cp " + path + fn + " .") - - elif (mode == "softlinks"): - for fn in files: - f = string.split(fn, "/")[-1] - if (os.access(f, os.F_OK)): - print "File exists: " + f - else: - os.system("ln -s " + path + os.sep + fn + " .") - - elif (mode in ("rm", "del")): - for fn in files: - flds = string.split(fn, "/") - try: os.unlink(flds[-1]) - except: pass - - elif (mode == "unlink"): - for fn in files: - f = string.split(fn, "/")[-1] - if (os.system("test -e " + f) == 0): - if (os.system("test -L " + f) == 0): - try: os.unlink(f) - except: pass - else: - print "Not a softlink: " + f - - if (mode in ("softlinks", "cp", "copy")): - for d in defs: - fn = d + ".def" - f = open(fn, "w") - f.write("EXPORTS\n") - f.write("\tinit" + d + "\n") - f.close() - - if (mode in ("unlink", "rm", "del")): - for d in defs: - fn = d + ".def" - try: os.unlink(fn) - except: pass diff --git a/build/vc60.mak b/build/vc60.mak deleted file mode 100644 index a05d04f4..00000000 --- a/build/vc60.mak +++ /dev/null @@ -1,129 +0,0 @@ -# Usage: -# -# make copy Copy the sources and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make del Remove the sources and tests - -BOOST_WIN= "L:\boost" -BOOST_UNIX= /net/cci/rwgk/boost - -PYEXE= "C:\Program files\Python\python.exe" -PYINC= /I"C:\Program files\Python\include" -PYLIB= "C:\Program files\Python\libs\python15.lib" - -STDOPTS= /nologo /MD /GR /GX /FD /Zm200 -WARNOPTS= - -CPP= cl.exe -CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) /I$(BOOST_WIN) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) - -LD= link.exe -LDOPTS= /nologo /dll /incremental:no - -OBJ = classes.obj conversions.obj extension_class.obj functions.obj \ - init_function.obj module_builder.obj \ - objects.obj types.obj cross_module.obj - -.SUFFIXES: .obj .cpp - -all: libboost_python.a \ - boost_python_test.pyd \ - abstract.pyd \ - getting_started1.pyd getting_started2.pyd getting_started3.pyd \ - getting_started4.pyd getting_started5.pyd \ - pickle1.pyd pickle2.pyd pickle3.pyd \ - noncopyable_export.pyd noncopyable_import.pyd \ - ivect.pyd dvect.pyd - -libboost_python.a: $(OBJ) - -boost_python_test.pyd: $(OBJ) comprehensive.obj - $(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) /export:initboost_python_test /out:"boost_python_test.pyd" - -abstract.pyd: $(OBJ) abstract.obj - $(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) /export:initabstract /out:"abstract.pyd" - -getting_started1.pyd: $(OBJ) getting_started1.obj - $(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) /export:initgetting_started1 /out:"getting_started1.pyd" - -getting_started2.pyd: $(OBJ) getting_started2.obj - $(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) /export:initgetting_started2 /out:"getting_started2.pyd" - -getting_started3.pyd: $(OBJ) getting_started3.obj - $(LD) $(LDOPTS) $(OBJ) getting_started3.obj $(PYLIB) /export:initgetting_started3 /out:"getting_started3.pyd" - -getting_started4.pyd: $(OBJ) getting_started4.obj - $(LD) $(LDOPTS) $(OBJ) getting_started4.obj $(PYLIB) /export:initgetting_started4 /out:"getting_started4.pyd" - -getting_started5.pyd: $(OBJ) getting_started5.obj - $(LD) $(LDOPTS) $(OBJ) getting_started5.obj $(PYLIB) /export:initgetting_started5 /out:"getting_started5.pyd" - -pickle1.pyd: $(OBJ) pickle1.obj - $(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) /export:initpickle1 /out:"pickle1.pyd" - -pickle2.pyd: $(OBJ) pickle2.obj - $(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) /export:initpickle2 /out:"pickle2.pyd" - -pickle3.pyd: $(OBJ) pickle3.obj - $(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) /export:initpickle3 /out:"pickle3.pyd" - -noncopyable_export.pyd: $(OBJ) noncopyable_export.obj - $(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) /export:initnoncopyable_export /out:"noncopyable_export.pyd" - -noncopyable_import.pyd: $(OBJ) noncopyable_import.obj - $(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) /export:initnoncopyable_import /out:"noncopyable_import.pyd" - -ivect.pyd: $(OBJ) ivect.obj - $(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) /export:initivect /out:"ivect.pyd" - -dvect.pyd: $(OBJ) dvect.obj - $(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) /export:initdvect /out:"dvect.pyd" - -.cpp.obj: - $(CPP) $(CPPOPTS) /c $*.cpp - -test: - $(PYEXE) comprehensive.py --broken-auto-ptr - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_getting_started3.py - $(PYEXE) test_getting_started4.py - $(PYEXE) test_getting_started5.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - -tst: - $(PYEXE) tst_noncopyable.py - $(PYEXE) tst_ivect.py - $(PYEXE) tst_dvect.py - -clean: - del *.obj - del *.lib - del *.exp - del *.idb - del *.pyd - del *.pyc - -softlinks: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks - -unlink: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink - -cp: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp - -rm: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm - -copy: - python $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy - -del: - python $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del From 2a96c9f9eea85095c6c1ff889d3c264123e72945 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 21 Mar 2001 02:33:27 +0000 Subject: [PATCH 0049/1042] temp file before branching [SVN r9621] --- example/do_it_yourself_converters.cpp | 126 ++++++++++++++++++++++ example/simple_vector.cpp | 101 +++++++++++++++++ example/test_do_it_yourself_converters.py | 22 ++++ example/test_simple_vector.py | 35 ++++++ 4 files changed, 284 insertions(+) create mode 100644 example/do_it_yourself_converters.cpp create mode 100644 example/simple_vector.cpp create mode 100644 example/test_do_it_yourself_converters.py create mode 100644 example/test_simple_vector.py diff --git a/example/do_it_yourself_converters.cpp b/example/do_it_yourself_converters.cpp new file mode 100644 index 00000000..ad31f708 --- /dev/null +++ b/example/do_it_yourself_converters.cpp @@ -0,0 +1,126 @@ +/* + This example shows how to convert a class from and to native + Python objects, such as tuples. + + We do not want to expose the helper class MillerIndex as an + Extension Class. However, in order to simplify the wrapper code, + we want to define from_python() and to_python() functions for + class MillerIndex. + + Consider the alternatives: + + - Expose MillerIndex as an Extension Class. + We need a constructor MillerIndex(python::tuple). + Python function calls become more complex: + foo(MillerIndex((1,2,3)) instead of foo((1,2,3)) + We need a method such as MillerIndex().as_tuple(). + + - Define a wrapper function for each function that we + want to expose, e.g.: + void add(const IndexingSet& ixset, const python::tuple PyMIx) + + The first alternative introduces a new type that the user has to + deal with. Other modules using Miller indices might organize them in + different ways, for example to increase runtime efficiency for + important procedures. This means, the user has to know how to + convert between the different kinds of Miller index representations. + This can quickly become a nuisance. Relying on native Python data + structures minimizes the number of special types the user has to + learn and convert. Of course, this argument is only valid for + small and relatively simply classes. + + If there are many member functions with MillerIndex arguments, the + second alternative is impractical, and concentrating the conversion + mechanism in one central place is essential for code + maintainability. An added benefit is that more convenient (smarter) + conversion functions can be provided without cluttering the rest of + the wrapper code. + + */ + +#include +#include +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // The helper class. + // + class MillerIndex { + public: + int v[3]; + }; + + // The main class. Imagine that there are MANY member functions + // like add() and get(). + // + class IndexingSet { + private: + std::vector VMIx; + public: + void add(const MillerIndex& MIx) { VMIx.push_back(MIx); } + MillerIndex get(std::size_t i) const { return VMIx[i]; } + }; +} + +BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE + + // Convert a Python tuple to a MillerIndex object. + // + MillerIndex from_python(PyObject* p, python::type) + { + python::tuple tup + = python::tuple(python::ref(p, python::ref::increment_count)); + if (tup.size() != 3) { + PyErr_SetString(PyExc_ValueError, + "expecting exactly 3 values in tuple."); + throw python::error_already_set(); + } + MillerIndex result; + for (int i = 0; i < 3; i++) + result.v[i] = from_python(tup[i].get(), python::type()); + return result; + } + + // Similar conversion for MillerIndex objects passed by value. + // Not actually used, but included to show the principle. + // + MillerIndex from_python(PyObject* p, python::type) + { + return from_python(p, python::type()); + } + + // Convert a MillerIndex object to a Python tuple. + // + PyObject* to_python(const MillerIndex& hkl) + { + python::tuple result(3); + for (int i = 0; i < 3; i++) + result.set_item(i, python::ref(to_python(hkl.v[i]))); + return result.reference().release(); + } + +BOOST_PYTHON_END_CONVERSION_NAMESPACE + +BOOST_PYTHON_MODULE_INIT(do_it_yourself_converters) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("do_it_yourself_converters"); + + // Create the Python type object for our extension class. + python::class_builder ixset_class(this_module, "IndexingSet"); + + // Add the __init__ function. + ixset_class.def(python::constructor<>()); + // Add the member functions. + ixset_class.def(&IndexingSet::add, "add"); + ixset_class.def(&IndexingSet::get, "get"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp new file mode 100644 index 00000000..f18f2cad --- /dev/null +++ b/example/simple_vector.cpp @@ -0,0 +1,101 @@ +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A wrapper is used to define additional constructors. + // + struct vector_double_wrapper: std::vector + { + // Tell the compiler how to convert a base class object to + // this wrapper object. + vector_double_wrapper(PyObject*, const std::vector& vd) + : std::vector(vd) {} + + vector_double_wrapper(PyObject* self) + : std::vector() {} + + vector_double_wrapper(PyObject* self, int n) + : std::vector(n) {} + + vector_double_wrapper(PyObject* self, python::tuple tuple) + : std::vector(tuple.size()) + { + std::vector::iterator vd = begin(); + for (int i = 0; i < tuple.size(); i++) + vd[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + python::type()); + } + }; + + double getitem(const std::vector& vd, std::size_t key) { + return vd[key]; + } + + void setitem(std::vector& vd, std::size_t key, double d) { + std::vector::iterator vditer = vd.begin(); + vditer[key] = d; + } + + void delitem(std::vector& vd, std::size_t key) { + std::vector::iterator vditer = vd.begin(); + vd.erase(&vditer[key]); + } + + // Convert vector_double to a regular Python tuple. + // + python::tuple as_tuple(const std::vector& vd) + { + python::tuple t(vd.size()); + for (int i = 0; i < vd.size(); i++) t.set_item(i, + python::ref(BOOST_PYTHON_CONVERSION::to_python(vd[i]))); + return t; + } + + // Function returning a vector_double object to Python. + // + std::vector foo(int n) + { + std::vector vd(n); + std::vector::iterator vditer = vd.begin(); + for (int i = 0; i < n; i++) vditer[i] = double(i); + return vd; + } + + // Same as foo(), but avoid copying on return. + // + std::auto_ptr > bar(int n) + { + std::auto_ptr > vdptr(new std::vector(n)); + std::vector::iterator vditer = vdptr->begin(); + for (int i = 0; i < n; i++) vditer[i] = double(10 * i); + return vdptr; + } +} + +BOOST_PYTHON_MODULE_INIT(simple_vector) +{ + try + { + python::module_builder this_module("simple_vector"); + + python::class_builder, vector_double_wrapper> + vector_double(this_module, "vector_double"); + + vector_double.def(python::constructor<>()); + vector_double.def(python::constructor()); + vector_double.def(python::constructor()); + vector_double.def(&std::vector::size, "__len__"); + vector_double.def(getitem, "__getitem__"); + vector_double.def(setitem, "__setitem__"); + vector_double.def(delitem, "__delitem__"); + vector_double.def(as_tuple, "as_tuple"); + + this_module.def(foo, "foo"); + this_module.def(bar, "bar"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/test_do_it_yourself_converters.py b/example/test_do_it_yourself_converters.py new file mode 100644 index 00000000..e256c614 --- /dev/null +++ b/example/test_do_it_yourself_converters.py @@ -0,0 +1,22 @@ +r'''>>> import do_it_yourself_converters + >>> ixset = do_it_yourself_converters.IndexingSet() + >>> ixset.add((1,2,3)) + >>> ixset.add((4,5,6)) + >>> ixset.add((7,8,9)) + >>> print ixset.get(0) + (1, 2, 3) + >>> print ixset.get(1) + (4, 5, 6) + >>> print ixset.get(2) + (7, 8, 9) +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_do_it_yourself_converters + doctest.testmod(test_do_it_yourself_converters) + +if __name__ == '__main__': + run() diff --git a/example/test_simple_vector.py b/example/test_simple_vector.py new file mode 100644 index 00000000..a19e205b --- /dev/null +++ b/example/test_simple_vector.py @@ -0,0 +1,35 @@ +r'''>>> import simple_vector + >>> v=simple_vector.vector_double() + >>> print v.as_tuple() + () + >>> v=simple_vector.vector_double(5) + >>> print v.as_tuple() + (0.0, 0.0, 0.0, 0.0, 0.0) + >>> print len(v) + 5 + >>> v=simple_vector.vector_double((3,4,5)) + >>> print v.as_tuple() + (3.0, 4.0, 5.0) + >>> print v[1] + 4.0 + >>> v[1] = 40 + >>> print v.as_tuple() + (3.0, 40.0, 5.0) + >>> del v[1] + >>> print v.as_tuple() + (3.0, 5.0) + >>> print simple_vector.foo(11).as_tuple() + (0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) + >>> print simple_vector.bar(12).as_tuple() + (0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0) +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_simple_vector + doctest.testmod(test_simple_vector) + +if __name__ == '__main__': + run() From 01bcd460dabfdd58d435dc020d0025ef3a23b914 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 21 Mar 2001 02:35:32 +0000 Subject: [PATCH 0050/1042] temp files removed after branching. [SVN r9623] --- example/do_it_yourself_converters.cpp | 126 ---------------------- example/simple_vector.cpp | 101 ----------------- example/test_do_it_yourself_converters.py | 22 ---- example/test_simple_vector.py | 35 ------ 4 files changed, 284 deletions(-) delete mode 100644 example/do_it_yourself_converters.cpp delete mode 100644 example/simple_vector.cpp delete mode 100644 example/test_do_it_yourself_converters.py delete mode 100644 example/test_simple_vector.py diff --git a/example/do_it_yourself_converters.cpp b/example/do_it_yourself_converters.cpp deleted file mode 100644 index ad31f708..00000000 --- a/example/do_it_yourself_converters.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - This example shows how to convert a class from and to native - Python objects, such as tuples. - - We do not want to expose the helper class MillerIndex as an - Extension Class. However, in order to simplify the wrapper code, - we want to define from_python() and to_python() functions for - class MillerIndex. - - Consider the alternatives: - - - Expose MillerIndex as an Extension Class. - We need a constructor MillerIndex(python::tuple). - Python function calls become more complex: - foo(MillerIndex((1,2,3)) instead of foo((1,2,3)) - We need a method such as MillerIndex().as_tuple(). - - - Define a wrapper function for each function that we - want to expose, e.g.: - void add(const IndexingSet& ixset, const python::tuple PyMIx) - - The first alternative introduces a new type that the user has to - deal with. Other modules using Miller indices might organize them in - different ways, for example to increase runtime efficiency for - important procedures. This means, the user has to know how to - convert between the different kinds of Miller index representations. - This can quickly become a nuisance. Relying on native Python data - structures minimizes the number of special types the user has to - learn and convert. Of course, this argument is only valid for - small and relatively simply classes. - - If there are many member functions with MillerIndex arguments, the - second alternative is impractical, and concentrating the conversion - mechanism in one central place is essential for code - maintainability. An added benefit is that more convenient (smarter) - conversion functions can be provided without cluttering the rest of - the wrapper code. - - */ - -#include -#include -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // The helper class. - // - class MillerIndex { - public: - int v[3]; - }; - - // The main class. Imagine that there are MANY member functions - // like add() and get(). - // - class IndexingSet { - private: - std::vector VMIx; - public: - void add(const MillerIndex& MIx) { VMIx.push_back(MIx); } - MillerIndex get(std::size_t i) const { return VMIx[i]; } - }; -} - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - - // Convert a Python tuple to a MillerIndex object. - // - MillerIndex from_python(PyObject* p, python::type) - { - python::tuple tup - = python::tuple(python::ref(p, python::ref::increment_count)); - if (tup.size() != 3) { - PyErr_SetString(PyExc_ValueError, - "expecting exactly 3 values in tuple."); - throw python::error_already_set(); - } - MillerIndex result; - for (int i = 0; i < 3; i++) - result.v[i] = from_python(tup[i].get(), python::type()); - return result; - } - - // Similar conversion for MillerIndex objects passed by value. - // Not actually used, but included to show the principle. - // - MillerIndex from_python(PyObject* p, python::type) - { - return from_python(p, python::type()); - } - - // Convert a MillerIndex object to a Python tuple. - // - PyObject* to_python(const MillerIndex& hkl) - { - python::tuple result(3); - for (int i = 0; i < 3; i++) - result.set_item(i, python::ref(to_python(hkl.v[i]))); - return result.reference().release(); - } - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -BOOST_PYTHON_MODULE_INIT(do_it_yourself_converters) -{ - try - { - // Create an object representing this extension module. - python::module_builder this_module("do_it_yourself_converters"); - - // Create the Python type object for our extension class. - python::class_builder ixset_class(this_module, "IndexingSet"); - - // Add the __init__ function. - ixset_class.def(python::constructor<>()); - // Add the member functions. - ixset_class.def(&IndexingSet::add, "add"); - ixset_class.def(&IndexingSet::get, "get"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp deleted file mode 100644 index f18f2cad..00000000 --- a/example/simple_vector.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A wrapper is used to define additional constructors. - // - struct vector_double_wrapper: std::vector - { - // Tell the compiler how to convert a base class object to - // this wrapper object. - vector_double_wrapper(PyObject*, const std::vector& vd) - : std::vector(vd) {} - - vector_double_wrapper(PyObject* self) - : std::vector() {} - - vector_double_wrapper(PyObject* self, int n) - : std::vector(n) {} - - vector_double_wrapper(PyObject* self, python::tuple tuple) - : std::vector(tuple.size()) - { - std::vector::iterator vd = begin(); - for (int i = 0; i < tuple.size(); i++) - vd[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - python::type()); - } - }; - - double getitem(const std::vector& vd, std::size_t key) { - return vd[key]; - } - - void setitem(std::vector& vd, std::size_t key, double d) { - std::vector::iterator vditer = vd.begin(); - vditer[key] = d; - } - - void delitem(std::vector& vd, std::size_t key) { - std::vector::iterator vditer = vd.begin(); - vd.erase(&vditer[key]); - } - - // Convert vector_double to a regular Python tuple. - // - python::tuple as_tuple(const std::vector& vd) - { - python::tuple t(vd.size()); - for (int i = 0; i < vd.size(); i++) t.set_item(i, - python::ref(BOOST_PYTHON_CONVERSION::to_python(vd[i]))); - return t; - } - - // Function returning a vector_double object to Python. - // - std::vector foo(int n) - { - std::vector vd(n); - std::vector::iterator vditer = vd.begin(); - for (int i = 0; i < n; i++) vditer[i] = double(i); - return vd; - } - - // Same as foo(), but avoid copying on return. - // - std::auto_ptr > bar(int n) - { - std::auto_ptr > vdptr(new std::vector(n)); - std::vector::iterator vditer = vdptr->begin(); - for (int i = 0; i < n; i++) vditer[i] = double(10 * i); - return vdptr; - } -} - -BOOST_PYTHON_MODULE_INIT(simple_vector) -{ - try - { - python::module_builder this_module("simple_vector"); - - python::class_builder, vector_double_wrapper> - vector_double(this_module, "vector_double"); - - vector_double.def(python::constructor<>()); - vector_double.def(python::constructor()); - vector_double.def(python::constructor()); - vector_double.def(&std::vector::size, "__len__"); - vector_double.def(getitem, "__getitem__"); - vector_double.def(setitem, "__setitem__"); - vector_double.def(delitem, "__delitem__"); - vector_double.def(as_tuple, "as_tuple"); - - this_module.def(foo, "foo"); - this_module.def(bar, "bar"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/test_do_it_yourself_converters.py b/example/test_do_it_yourself_converters.py deleted file mode 100644 index e256c614..00000000 --- a/example/test_do_it_yourself_converters.py +++ /dev/null @@ -1,22 +0,0 @@ -r'''>>> import do_it_yourself_converters - >>> ixset = do_it_yourself_converters.IndexingSet() - >>> ixset.add((1,2,3)) - >>> ixset.add((4,5,6)) - >>> ixset.add((7,8,9)) - >>> print ixset.get(0) - (1, 2, 3) - >>> print ixset.get(1) - (4, 5, 6) - >>> print ixset.get(2) - (7, 8, 9) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_do_it_yourself_converters - doctest.testmod(test_do_it_yourself_converters) - -if __name__ == '__main__': - run() diff --git a/example/test_simple_vector.py b/example/test_simple_vector.py deleted file mode 100644 index a19e205b..00000000 --- a/example/test_simple_vector.py +++ /dev/null @@ -1,35 +0,0 @@ -r'''>>> import simple_vector - >>> v=simple_vector.vector_double() - >>> print v.as_tuple() - () - >>> v=simple_vector.vector_double(5) - >>> print v.as_tuple() - (0.0, 0.0, 0.0, 0.0, 0.0) - >>> print len(v) - 5 - >>> v=simple_vector.vector_double((3,4,5)) - >>> print v.as_tuple() - (3.0, 4.0, 5.0) - >>> print v[1] - 4.0 - >>> v[1] = 40 - >>> print v.as_tuple() - (3.0, 40.0, 5.0) - >>> del v[1] - >>> print v.as_tuple() - (3.0, 5.0) - >>> print simple_vector.foo(11).as_tuple() - (0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) - >>> print simple_vector.bar(12).as_tuple() - (0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_simple_vector - doctest.testmod(test_simple_vector) - -if __name__ == '__main__': - run() From 5a40cec1edd9ee8ca1f8396f1c0ffd230c53822c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 1 Apr 2001 13:47:25 +0000 Subject: [PATCH 0051/1042] temp file before branching [SVN r9689] --- build/irix_CC.mak | 167 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 build/irix_CC.mak diff --git a/build/irix_CC.mak b/build/irix_CC.mak new file mode 100644 index 00000000..91eb819e --- /dev/null +++ b/build/irix_CC.mak @@ -0,0 +1,167 @@ +# Usage: +# +# Create a new empty directory anywhere (preferably not in the boost tree). +# Copy this Makefile to that new directory and rename it to "Makefile" +# Set the BOOST pathname below. +# +# make softlinks Create softlinks to source code and tests +# make Compile all sources +# make test Run doctest tests +# make clean Remove all object files +# make unlink Remove softlinks + +BOOST= /net/cci/rwgk/boost + +#PYEXE= /usr/bin/python +#PYINC= -I/usr/include/python1.5 +PYEXE= /usr/local/Python-1.5.2/bin/python +PYINC= -I/usr/local/Python-1.5.2/include/python1.5 +#PYEXE= /usr/local/Python-2.0/bin/python +#PYINC= -I/usr/local/Python-2.0/include/python2.0 +STLPORTINC= -I/net/cci/xp/C++_C_headers + +STDOPTS= +WARNOPTS= -woff 1001,1234,1682 + +CPP= CC -LANG:std -n32 -mips4 +CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ + $(STDOPTS) $(WARNOPTS) -g +MAKEDEP= -M + +LD= CC -LANG:std -n32 -mips4 +LDOPTS= -shared -all + +OBJ = classes.o conversions.o extension_class.o functions.o \ + init_function.o module_builder.o \ + objects.o types.o cross_module.o +DEPOBJ= $(OBJ) \ + comprehensive.o \ + abstract.o \ + getting_started1.o getting_started2.o getting_started3.o \ + simple_vector.o \ + do_it_yourself_converters.o \ + pickle1.o pickle2.o pickle3.o \ + noncopyable_export.o noncopyable_import.o \ + ivect.o dvect.o + +.SUFFIXES: .o .cpp + +all: libboost_python.a \ + boost_python_test.so \ + abstract.so \ + getting_started1.so getting_started2.so getting_started3.so \ + simple_vector.so \ + do_it_yourself_converters.so \ + pickle1.so pickle2.so pickle3.so \ + noncopyable_export.so noncopyable_import.so \ + ivect.so dvect.so + +libboost_python.a: $(OBJ) + rm -f libboost_python.a + $(CPP) -ar -all -o libboost_python.a $(OBJ) + +boost_python_test.so: $(OBJ) comprehensive.o + $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm + +abstract.so: $(OBJ) abstract.o + $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so + +getting_started1.so: $(OBJ) getting_started1.o + $(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so + +getting_started2.so: $(OBJ) getting_started2.o + $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so + +getting_started3.so: $(OBJ) getting_started3.o + $(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so + +simple_vector.so: $(OBJ) simple_vector.o + $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so + +do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o + $(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so + +pickle1.so: $(OBJ) pickle1.o + $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so + +pickle2.so: $(OBJ) pickle2.o + $(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so + +pickle3.so: $(OBJ) pickle3.o + $(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so + +noncopyable_export.so: $(OBJ) noncopyable_export.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ + noncopyable_export.o -o noncopyable_export.so + +noncopyable_import.so: $(OBJ) noncopyable_import.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ + noncopyable_import.o -o noncopyable_import.so + +ivect.so: $(OBJ) ivect.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so + +dvect.so: $(OBJ) dvect.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so + +.cpp.o: + $(CPP) $(CPPOPTS) -c $*.cpp + +test: + $(PYEXE) comprehensive.py + $(PYEXE) test_abstract.py + $(PYEXE) test_getting_started1.py + $(PYEXE) test_getting_started2.py + $(PYEXE) test_getting_started3.py + $(PYEXE) test_simple_vector.py + $(PYEXE) test_do_it_yourself_converters.py + $(PYEXE) test_pickle1.py + $(PYEXE) test_pickle2.py + $(PYEXE) test_pickle3.py + +tst: + $(PYEXE) tst_noncopyable.py + $(PYEXE) tst_ivect1.py + $(PYEXE) tst_dvect1.py + $(PYEXE) tst_ivect2.py + $(PYEXE) tst_dvect2.py + +clean: + rm -f $(OBJ) libboost_python.a libboost_python.a.input + rm -f comprehensive.o boost_python_test.so + rm -f abstract.o abstract.so + rm -f getting_started1.o getting_started1.so + rm -f getting_started2.o getting_started2.so + rm -f getting_started3.o getting_started3.so + rm -f simple_vector.o simple_vector.so + rm -f do_it_yourself_converters.o do_it_yourself_converters.so + rm -f pickle1.o pickle1.so + rm -f pickle2.o pickle2.so + rm -f pickle3.o pickle3.so + rm -f noncopyable_export.o noncopyable_export.so + rm -f noncopyable_import.o noncopyable_import.so + rm -f ivect.o ivect.so + rm -f dvect.o dvect.so + rm -f so_locations *.pyc + rm -rf ii_files + +softlinks: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks + +unlink: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink + +cp: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp + +rm: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm + +depend: + @ cat Makefile.nodepend; \ + for obj in $(DEPOBJ); \ + do \ + bn=`echo "$$obj" | cut -d. -f1`; \ + $(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \ + done + From 69e69a77d866b19cfe05298ffc580371d7d58983 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 1 Apr 2001 13:49:05 +0000 Subject: [PATCH 0052/1042] temp file removed after branching. [SVN r9691] --- build/irix_CC.mak | 167 ---------------------------------------------- 1 file changed, 167 deletions(-) delete mode 100644 build/irix_CC.mak diff --git a/build/irix_CC.mak b/build/irix_CC.mak deleted file mode 100644 index 91eb819e..00000000 --- a/build/irix_CC.mak +++ /dev/null @@ -1,167 +0,0 @@ -# Usage: -# -# Create a new empty directory anywhere (preferably not in the boost tree). -# Copy this Makefile to that new directory and rename it to "Makefile" -# Set the BOOST pathname below. -# -# make softlinks Create softlinks to source code and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make unlink Remove softlinks - -BOOST= /net/cci/rwgk/boost - -#PYEXE= /usr/bin/python -#PYINC= -I/usr/include/python1.5 -PYEXE= /usr/local/Python-1.5.2/bin/python -PYINC= -I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE= /usr/local/Python-2.0/bin/python -#PYINC= -I/usr/local/Python-2.0/include/python2.0 -STLPORTINC= -I/net/cci/xp/C++_C_headers - -STDOPTS= -WARNOPTS= -woff 1001,1234,1682 - -CPP= CC -LANG:std -n32 -mips4 -CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) -g -MAKEDEP= -M - -LD= CC -LANG:std -n32 -mips4 -LDOPTS= -shared -all - -OBJ = classes.o conversions.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o cross_module.o -DEPOBJ= $(OBJ) \ - comprehensive.o \ - abstract.o \ - getting_started1.o getting_started2.o getting_started3.o \ - simple_vector.o \ - do_it_yourself_converters.o \ - pickle1.o pickle2.o pickle3.o \ - noncopyable_export.o noncopyable_import.o \ - ivect.o dvect.o - -.SUFFIXES: .o .cpp - -all: libboost_python.a \ - boost_python_test.so \ - abstract.so \ - getting_started1.so getting_started2.so getting_started3.so \ - simple_vector.so \ - do_it_yourself_converters.so \ - pickle1.so pickle2.so pickle3.so \ - noncopyable_export.so noncopyable_import.so \ - ivect.so dvect.so - -libboost_python.a: $(OBJ) - rm -f libboost_python.a - $(CPP) -ar -all -o libboost_python.a $(OBJ) - -boost_python_test.so: $(OBJ) comprehensive.o - $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm - -abstract.so: $(OBJ) abstract.o - $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so - -getting_started1.so: $(OBJ) getting_started1.o - $(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so - -getting_started2.so: $(OBJ) getting_started2.o - $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so - -getting_started3.so: $(OBJ) getting_started3.o - $(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so - -simple_vector.so: $(OBJ) simple_vector.o - $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so - -do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so - -pickle1.so: $(OBJ) pickle1.o - $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so - -pickle2.so: $(OBJ) pickle2.o - $(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so - -pickle3.so: $(OBJ) pickle3.o - $(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so - -noncopyable_export.so: $(OBJ) noncopyable_export.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_export.o -o noncopyable_export.so - -noncopyable_import.so: $(OBJ) noncopyable_import.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_import.o -o noncopyable_import.so - -ivect.so: $(OBJ) ivect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so - -dvect.so: $(OBJ) dvect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so - -.cpp.o: - $(CPP) $(CPPOPTS) -c $*.cpp - -test: - $(PYEXE) comprehensive.py - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_getting_started3.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_converters.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - -tst: - $(PYEXE) tst_noncopyable.py - $(PYEXE) tst_ivect1.py - $(PYEXE) tst_dvect1.py - $(PYEXE) tst_ivect2.py - $(PYEXE) tst_dvect2.py - -clean: - rm -f $(OBJ) libboost_python.a libboost_python.a.input - rm -f comprehensive.o boost_python_test.so - rm -f abstract.o abstract.so - rm -f getting_started1.o getting_started1.so - rm -f getting_started2.o getting_started2.so - rm -f getting_started3.o getting_started3.so - rm -f simple_vector.o simple_vector.so - rm -f do_it_yourself_converters.o do_it_yourself_converters.so - rm -f pickle1.o pickle1.so - rm -f pickle2.o pickle2.so - rm -f pickle3.o pickle3.so - rm -f noncopyable_export.o noncopyable_export.so - rm -f noncopyable_import.o noncopyable_import.so - rm -f ivect.o ivect.so - rm -f dvect.o dvect.so - rm -f so_locations *.pyc - rm -rf ii_files - -softlinks: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks - -unlink: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink - -cp: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp - -rm: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm - -depend: - @ cat Makefile.nodepend; \ - for obj in $(DEPOBJ); \ - do \ - bn=`echo "$$obj" | cut -d. -f1`; \ - $(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \ - done - From 748c118ea82c167f3b352023ac906d25ca5aa464 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 5 Apr 2001 17:46:24 +0000 Subject: [PATCH 0053/1042] added: from_python std::string type checking [SVN r9727] --- src/conversions.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/conversions.cpp b/src/conversions.cpp index 1bc923b1..4bfe2011 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -7,6 +7,7 @@ // producing this work. // // Revision History: +// 05 Apr 01 added: from_python std::string type checking (rwgk) // 12 Mar 01 Python 1.5.2 fixes (Ralf W. Grosse-Kunstleve) // 11 Mar 01 std::string *MAY* include nulls (Alex Martelli) // 04 Mar 01 std::complex<> fixes for MSVC (Dave Abrahams) @@ -250,6 +251,10 @@ PyObject* to_python(const std::string& s) std::string from_python(PyObject* p, boost::python::type) { + if (! PyString_Check(p)) { + PyErr_SetString(PyExc_TypeError, "expected a string"); + throw boost::python::argument_error(); + } return std::string(PyString_AsString(p), PyString_Size(p)); } From 9ee563b86415bc9f86cad7404cdf06296e2349fb Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 18:51:17 +0000 Subject: [PATCH 0054/1042] Comment added with reference to cross_module.hpp [SVN r9812] --- include/boost/python/detail/extension_class.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 125f1eed..5c8e720a 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -10,6 +10,7 @@ // gen_extclass.python // Revision History: +// 17 Apr 01 Comment added with reference to cross_module.hpp (R.W. Grosse-Kunstleve) // 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted // to_python (Dave Abrahams) @@ -166,6 +167,14 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // and U. T is the class the user really intends to wrap. U is a class derived // from T with some virtual function overriding boilerplate, or if there are no // virtual functions, U = held_instance. +// +// A look-alike of this class in root/boost/python/cross_module.hpp +// is used for the implementation of the cross-module support +// (export_converters and import_converters). If from_python +// and to_python converters are added or removed from the class +// below, the class python_import_extension_class_converters has +// to be modified accordingly. +// template > class python_extension_class_converters { From 533a0057641283e3ff949c8a0383a77a394e0caa Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 18:53:38 +0000 Subject: [PATCH 0055/1042] moved from branch ralf_grosse_kunstleve to trunk [SVN r9813] --- include/boost/python/cross_module.hpp | 322 ++++++++++++++++++++++++++ src/cross_module.cpp | 87 +++++++ 2 files changed, 409 insertions(+) create mode 100644 include/boost/python/cross_module.hpp create mode 100644 src/cross_module.cpp diff --git a/include/boost/python/cross_module.hpp b/include/boost/python/cross_module.hpp new file mode 100644 index 00000000..7c1fe507 --- /dev/null +++ b/include/boost/python/cross_module.hpp @@ -0,0 +1,322 @@ +/* (C) Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, use, + modify, sell and distribute this software is granted provided this + copyright notice appears in all copies. This software is provided + "as is" without express or implied warranty, and with no claim as to + its suitability for any purpose. + + Revision History: + 17 Apr 01 merged into boost CVS trunk (Ralf W. Grosse-Kunstleve) +*/ + +/* Implementation of Boost.Python cross-module support. + See root/libs/python/doc/cross_module.html for details. +*/ + +#ifndef CROSS_MODULE_HPP +# define CROSS_MODULE_HPP + +# include + +namespace boost { namespace python { + struct import_error : error_already_set {}; + struct export_error : error_already_set {}; +}} + +namespace boost { namespace python { namespace detail { + +// Concept: throw exception if api_major is changed +// show warning on stderr if api_minor is changed +const int export_converters_api_major = 4; +const int export_converters_api_minor = 1; +extern const char* converters_attribute_name; +void* import_converter_object(const std::string& module_name, + const std::string& py_class_name, + const std::string& attribute_name); +void check_export_converters_api(const int importing_major, + const int importing_minor, + const int imported_major, + const int imported_minor); + +}}} + +// forward declaration +namespace boost { namespace python { namespace detail { +template class import_extension_class; +}}} + +BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE + +/* This class template is instantiated by import_converters. + This class is a look-alike of class python_extension_class_converters. + The converters in this class are wrappers that call converters + imported from another module. + To ensure that the dynamic loader resolves all symbols in the + intended way, the signature of all friend functions is changed with + respect to the original functions in class + python_extension_class_converters by adding an arbitrary additional + parameter with a default value, in this case "bool sig = false". + See also: comments for class export_converter_object_base below. + */ +template +class python_import_extension_class_converters +{ + public: + + friend python_import_extension_class_converters py_extension_class_converters(boost::python::type, bool sig = false) { + return python_import_extension_class_converters(); + } + + PyObject* to_python(const T& x) const { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } + + friend T* from_python(PyObject* p, boost::python::type t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_Ts(p, t); + } + friend const T* from_python(PyObject* p, boost::python::type t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_cTs(p, t); + } + friend const T* from_python(PyObject* p, boost::python::type t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_cTscr(p, t); + } + friend T* from_python(PyObject* p, boost::python::type t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_Tscr(p, t); + } + friend T& from_python(PyObject* p, boost::python::type t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_Tr(p, t); + } + friend const T& from_python(PyObject* p, boost::python::type t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_cTr(p, t); + } + friend const T& from_python(PyObject* p, boost::python::type t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_T(p, t); + } + + friend std::auto_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_aTr(p, t); + } + friend std::auto_ptr from_python(PyObject* p, boost::python::type > t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_aT(p, t); + } + friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_caTr(p, t); + } + friend PyObject* to_python(std::auto_ptr x, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } + + friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_sTr(p, t); + } + friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type > t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_sT(p, t); + } + friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->from_python_csTr(p, t); + } + friend PyObject* to_python(boost::shared_ptr x, bool sig = false) { + return boost::python::detail::import_extension_class::get_converters()->to_python(x); + } +}; + +BOOST_PYTHON_END_CONVERSION_NAMESPACE + +namespace boost { namespace python { + +BOOST_PYTHON_IMPORT_CONVERSION(python_import_extension_class_converters); + +/* This class template is instantiated by export_converters(). + A pointer to this class is exported/imported via the Python API. + Using the Python API ensures maximum portability. + All member functions are virtual. This is, what we export/import + is essentially just a pointer to a vtbl. + To work around a deficiency of Visual C++ 6.0, the name of each + from_python() member functions is made unique by appending a few + characters (derived in a ad-hoc manner from the corresponding type). + */ +template +struct export_converter_object_base +{ + virtual int get_api_major() const { return detail::export_converters_api_major; } + virtual int get_api_minor() const { return detail::export_converters_api_minor; } + + virtual PyObject* to_python(const T& x) = 0; + + virtual T* from_python_Ts(PyObject* p, boost::python::type t) = 0; + virtual const T* from_python_cTs(PyObject* p, boost::python::type t) = 0; + virtual const T* from_python_cTscr(PyObject* p, boost::python::type t) = 0; + virtual T* from_python_Tscr(PyObject* p, boost::python::type t) = 0; + virtual T& from_python_Tr(PyObject* p, boost::python::type t) = 0; + virtual const T& from_python_cTr(PyObject* p, boost::python::type t) = 0; + virtual const T& from_python_T(PyObject* p, boost::python::type t) = 0; + + virtual std::auto_ptr& from_python_aTr(PyObject* p, boost::python::type&> t) = 0; + virtual std::auto_ptr from_python_aT(PyObject* p, boost::python::type > t) = 0; + virtual const std::auto_ptr& from_python_caTr(PyObject* p, boost::python::type&> t) = 0; + virtual PyObject* to_python(std::auto_ptr x) = 0; + + virtual boost::shared_ptr& from_python_sTr(PyObject* p, boost::python::type&> t) = 0; + virtual const boost::shared_ptr& from_python_sT(PyObject* p, boost::python::type > t) = 0; + virtual const boost::shared_ptr& from_python_csTr(PyObject* p, boost::python::type&> t) = 0; + virtual PyObject* to_python(boost::shared_ptr x) = 0; +}; + +// Converters to be used if T is not copyable. +template +struct export_converter_object_noncopyable : export_converter_object_base +{ + virtual PyObject* to_python(const T& x) { + PyErr_SetString(PyExc_RuntimeError, + "to_python(const T&) converter not exported"); + throw import_error(); + } + + virtual T* from_python_Ts(PyObject* p, boost::python::type t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual const T* from_python_cTs(PyObject* p, boost::python::type t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual const T* from_python_cTscr(PyObject* p, boost::python::type t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual T* from_python_Tscr(PyObject* p, boost::python::type t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual T& from_python_Tr(PyObject* p, boost::python::type t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual const T& from_python_cTr(PyObject* p, boost::python::type t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual const T& from_python_T(PyObject* p, boost::python::type t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + + virtual std::auto_ptr& from_python_aTr(PyObject* p, boost::python::type&> t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual std::auto_ptr from_python_aT(PyObject* p, boost::python::type > t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual const std::auto_ptr& from_python_caTr(PyObject* p, boost::python::type&> t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual PyObject* to_python(std::auto_ptr x) { + return BOOST_PYTHON_CONVERSION::to_python(x); + } + + virtual boost::shared_ptr& from_python_sTr(PyObject* p, boost::python::type&> t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual const boost::shared_ptr& from_python_sT(PyObject* p, boost::python::type > t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual const boost::shared_ptr& from_python_csTr(PyObject* p, boost::python::type&> t) { + return BOOST_PYTHON_CONVERSION::from_python(p, t); + } + virtual PyObject* to_python(boost::shared_ptr x) { + return BOOST_PYTHON_CONVERSION::to_python(x); + } +}; + +// The addditional to_python() converter that can be used if T is copyable. +template +struct export_converter_object : export_converter_object_noncopyable +{ + virtual PyObject* to_python(const T& x) { + return BOOST_PYTHON_CONVERSION::py_extension_class_converters(boost::python::type()).to_python(x); + } +}; + +namespace detail { + +/* This class template is instantiated by import_converters. + Its purpose is to import the converter_object via the Python API. + The actual import is only done once. The pointer to the + imported converter object is kept in the static data member + imported_converters. + */ +template +class import_extension_class + : public python_import_extension_class_converters +{ + public: + inline import_extension_class(const char* module, const char* py_class) { + m_module = module; + m_py_class = py_class; + } + + static boost::python::export_converter_object_base* get_converters(); + + private: + static std::string m_module; + static std::string m_py_class; + static boost::python::export_converter_object_base* imported_converters; +}; + +template std::string import_extension_class::m_module; +template std::string import_extension_class::m_py_class; +template +boost::python::export_converter_object_base* +import_extension_class::imported_converters = 0; + +template +boost::python::export_converter_object_base* +import_extension_class::get_converters() { + if (imported_converters == 0) { + void* cobject + = import_converter_object(m_module, m_py_class, + converters_attribute_name); + imported_converters + = static_cast*>(cobject); + check_export_converters_api( + export_converters_api_major, + export_converters_api_minor, + imported_converters->get_api_major(), + imported_converters->get_api_minor()); + } + return imported_converters; +} + +}}} // namespace boost::python::detail + +namespace boost { namespace python { + +// Implementation of export_converters(). +template +void export_converters(class_builder& cb) +{ + static export_converter_object export_cvts; + cb.add( + ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), + detail::converters_attribute_name); +} + +// Implementation of export_converters_noncopyable(). +template +void export_converters_noncopyable(class_builder& cb) +{ + static export_converter_object_noncopyable export_cvts; + cb.add( + ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), + detail::converters_attribute_name); +} + +// Implementation of import_converters. +template +class import_converters + : python_import_extension_class_converters // Works around MSVC6.x/GCC2.95.2 bug described + // at the bottom of class_builder.hpp. +{ + public: + import_converters(const char* module, const char* py_class) + : m_class(new detail::import_extension_class(module, py_class)) + { } + private: + boost::shared_ptr > m_class; +}; + +}} // namespace boost::python + +#endif // CROSS_MODULE_HPP diff --git a/src/cross_module.cpp b/src/cross_module.cpp new file mode 100644 index 00000000..ea5a08de --- /dev/null +++ b/src/cross_module.cpp @@ -0,0 +1,87 @@ +/* (C) Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, use, + modify, sell and distribute this software is granted provided this + copyright notice appears in all copies. This software is provided + "as is" without express or implied warranty, and with no claim as to + its suitability for any purpose. + + Revision History: + 17 Apr 01 merged into boost CVS trunk (Ralf W. Grosse-Kunstleve) +*/ + +# include +namespace python = boost::python; +# include // MSVC6.0SP4 does not know std::fprintf +# include // MSVC6.0SP4 does not know std::strcmp + +namespace { + + PyObject* get_module_dict(const char* module_name) + { + python::ref module_obj(PyImport_ImportModule((char*) module_name)); + PyObject* module_dict = PyModule_GetDict(module_obj.get()); + if (module_dict == 0) throw python::import_error(); + return module_dict; + } +} + +namespace boost { namespace python { namespace detail { + +const char* converters_attribute_name = "__converters__"; + +void* import_converter_object(const std::string& module_name, + const std::string& py_class_name, + const std::string& attribute_name) +{ + static std::string err; + PyObject* module_dict = get_module_dict(const_cast(module_name.c_str())); + PyObject* py_class = PyDict_GetItemString(module_dict, const_cast(py_class_name.c_str())); + if (py_class == 0) { + err = std::string("module ") + module_name + " has no attribute " + py_class_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + python::ref c_obj(PyObject_GetAttrString(py_class, const_cast(attribute_name.c_str())), ref::null_ok); + if (c_obj.get() == 0) { + err = std::string("object ") + module_name + "." + py_class_name + + " has no attribute " + attribute_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + if (! PyCObject_Check(c_obj.get())) { + err = std::string("object ") + module_name + "." + py_class_name + "." + + attribute_name + " is not a PyCObject"; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + return PyCObject_AsVoidPtr(c_obj.get()); +} + +void check_export_converters_api(const int importing_major, + const int importing_minor, + const int imported_major, + const int imported_minor) +{ + if (importing_major != imported_major) { + // Python uses fprintf(stderr, ...) for API warnings. + fprintf(stderr, + "Fatal: export_converters_api mismatch:" + " Importing module = %d.%d" + " Imported module = %d.%d\n", + importing_major, importing_minor, + imported_major, imported_minor); + PyErr_SetString(PyExc_RuntimeError, + "Fatal: export_converters_api mismatch"); + throw import_error(); + } + if (importing_minor != imported_minor) { + // Python uses fprintf(stderr, ...) for API warnings. + fprintf(stderr, + "Warning: export_converters_api mismatch:" + " Importing module = %d.%d" + " Imported module = %d.%d\n", + importing_major, importing_minor, + imported_major, imported_minor); + } +} + +}}} // namespace boost::python::detail From 907033f725317d2c8cd7a1e00dc6d6b5ee2a321c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 19:00:43 +0000 Subject: [PATCH 0056/1042] Obsolete files removed. [SVN r9814] --- example/getting_started3.cpp | 120 ----------------------------- example/getting_started4.cpp | 101 ------------------------- example/getting_started5.cpp | 126 ------------------------------- example/test_getting_started3.py | 56 -------------- example/test_getting_started4.py | 35 --------- example/test_getting_started5.py | 22 ------ 6 files changed, 460 deletions(-) delete mode 100644 example/getting_started3.cpp delete mode 100644 example/getting_started4.cpp delete mode 100644 example/getting_started5.cpp delete mode 100644 example/test_getting_started3.py delete mode 100644 example/test_getting_started4.py delete mode 100644 example/test_getting_started5.py diff --git a/example/getting_started3.cpp b/example/getting_started3.cpp deleted file mode 100644 index 799f5cac..00000000 --- a/example/getting_started3.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - This example shows how to make an Extension Class "pickleable". - - Python's pickle module implements a basic but powerful algorithm - for "pickling" (a.k.a. serializing, marshalling or flattening) - nearly arbitrary Python objects. - - The user can influence how an Extension Class instance is pickled - by defining three special methods: __getinitargs__(), - __getstate__(), and __setstate(). This interface is similar to - that for regular Python classes as described in detail in the - Python Library Reference for pickle: - - http://www.python.org/doc/current/lib/module-pickle.html - - When an Extension Class instance is pickled, __getinitargs__() is - called, if implemented. This method should return a tuple - containing the arguments to be passed to the class constructor when - the object is restored. - - If there is no __getstate__() method, the instance's __dict__ is - pickled if it is not empty. If __getstate__() is defined, it should - return an object representing the state of the instance. - - If there is no __setstate__() method, __getstate__() must return a - dictionary. When the instance is restored, the items in this dictionary - are added to the instance's __dict__. - - If the Extension Class defines __setstate__(), the pickle loader - calls it with the result of __getstate__() as arguments. In this - case, the state object need not be a dictionary. The - __getstate__() and __setstate__() methods can do what they want. - - If both __getinitargs__() and __getstate__() are defined, the - instance is restored by first calling the constructor with - the result of __getinitargs__() as argument. After the instance - is reconstructed, the __dict__ is updated or __setstate__() is - called if implemented. - - The mechanism described here is an exact replication of that one - implemented by Jim Fulton's ExtensionClass (included in Zope 2.2.2). - */ - -#include -#include - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - private: - std::string country; - int secret_number; - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - }; - - // Support for pickle. - python::tuple world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result; - } - - python::tuple world_getstate(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_secret_number()); - return result; - } - - void world_setstate(world& w, python::tuple state) { - if (state.size() != 1) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); - throw python::error_already_set(); - } - int number = BOOST_PYTHON_CONVERSION::from_python(state[0].get(), - python::type()); - if (number != 42) - w.set_secret_number(number); - } -} - -BOOST_PYTHON_MODULE_INIT(getting_started3) -{ - try - { - // Create an object representing this extension module. - python::module_builder this_module("getting_started3"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - world_class.def(&world::get_secret_number, "get_secret_number"); - world_class.def(&world::set_secret_number, "set_secret_number"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - world_class.def(world_getstate, "__getstate__"); - world_class.def(world_setstate, "__setstate__"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/getting_started4.cpp b/example/getting_started4.cpp deleted file mode 100644 index fe6a3421..00000000 --- a/example/getting_started4.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A wrapper is used to define additional constructors. - // - struct vector_double_wrapper: std::vector - { - // Tell the compiler how to convert a base class object to - // this wrapper object. - vector_double_wrapper(PyObject*, const std::vector& vd) - : std::vector(vd) {} - - vector_double_wrapper(PyObject* self) - : std::vector() {} - - vector_double_wrapper(PyObject* self, int n) - : std::vector(n) {} - - vector_double_wrapper(PyObject* self, python::tuple tuple) - : std::vector(tuple.size()) - { - std::vector::iterator vd = begin(); - for (int i = 0; i < tuple.size(); i++) - vd[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - python::type()); - } - }; - - double getitem(const std::vector& vd, std::size_t key) { - return vd[key]; - } - - void setitem(std::vector& vd, std::size_t key, double d) { - std::vector::iterator vditer = vd.begin(); - vditer[key] = d; - } - - void delitem(std::vector& vd, std::size_t key) { - std::vector::iterator vditer = vd.begin(); - vd.erase(&vditer[key]); - } - - // Convert vector_double to a regular Python tuple. - // - python::tuple as_tuple(const std::vector& vd) - { - python::tuple t(vd.size()); - for (int i = 0; i < vd.size(); i++) t.set_item(i, - python::ref(BOOST_PYTHON_CONVERSION::to_python(vd[i]))); - return t; - } - - // Function returning a vector_double object to Python. - // - std::vector foo(int n) - { - std::vector vd(n); - std::vector::iterator vditer = vd.begin(); - for (int i = 0; i < n; i++) vditer[i] = double(i); - return vd; - } - - // Same as foo(), but avoid copying on return. - // - std::auto_ptr > bar(int n) - { - std::auto_ptr > vdptr(new std::vector(n)); - std::vector::iterator vditer = vdptr->begin(); - for (int i = 0; i < n; i++) vditer[i] = double(10 * i); - return vdptr; - } -} - -BOOST_PYTHON_MODULE_INIT(getting_started4) -{ - try - { - python::module_builder this_module("getting_started4"); - - python::class_builder, vector_double_wrapper> - vector_double(this_module, "vector_double"); - - vector_double.def(python::constructor<>()); - vector_double.def(python::constructor()); - vector_double.def(python::constructor()); - vector_double.def(&std::vector::size, "__len__"); - vector_double.def(getitem, "__getitem__"); - vector_double.def(setitem, "__setitem__"); - vector_double.def(delitem, "__delitem__"); - vector_double.def(as_tuple, "as_tuple"); - - this_module.def(foo, "foo"); - this_module.def(bar, "bar"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/getting_started5.cpp b/example/getting_started5.cpp deleted file mode 100644 index 9e9e7c75..00000000 --- a/example/getting_started5.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - This example shows how to convert a class from and to native - Python objects, such as tuples. - - We do not want to expose the helper class MillerIndex as an - Extension Class. However, in order to simplify the wrapper code, - we want to define from_python() and to_python() functions for - class MillerIndex. - - Consider the alternatives: - - - Expose MillerIndex as an Extension Class. - We need a constructor MillerIndex(python::tuple). - Python function calls become more complex: - foo(MillerIndex((1,2,3)) instead of foo((1,2,3)) - We need a method such as MillerIndex().as_tuple(). - - - Define a wrapper function for each function that we - want to expose, e.g.: - void add(const IndexingSet& ixset, const python::tuple PyMIx) - - The first alternative introduces a new type that the user has to - deal with. Other modules using Miller indices might organize them in - different ways, for example to increase runtime efficiency for - important procedures. This means, the user has to know how to - convert between the different kinds of Miller index representations. - This can quickly become a nuisance. Relying on native Python data - structures minimizes the number of special types the user has to - learn and convert. Of course, this argument is only valid for - small and relatively simply classes. - - If there are many member functions with MillerIndex arguments, the - second alternative is impractical, and concentrating the conversion - mechanism in one central place is essential for code - maintainability. An added benefit is that more convenient (smarter) - conversion functions can be provided without cluttering the rest of - the wrapper code. - - */ - -#include -#include -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // The helper class. - // - class MillerIndex { - public: - int v[3]; - }; - - // The main class. Imagine that there are MANY member functions - // like add() and get(). - // - class IndexingSet { - private: - std::vector VMIx; - public: - void add(const MillerIndex& MIx) { VMIx.push_back(MIx); } - MillerIndex get(std::size_t i) const { return VMIx[i]; } - }; -} - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - - // Convert a Python tuple to a MillerIndex object. - // - MillerIndex from_python(PyObject* p, python::type) - { - python::tuple tup - = python::tuple(python::ref(p, python::ref::increment_count)); - if (tup.size() != 3) { - PyErr_SetString(PyExc_ValueError, - "expecting exactly 3 values in tuple."); - throw python::error_already_set(); - } - MillerIndex result; - for (int i = 0; i < 3; i++) - result.v[i] = from_python(tup[i].get(), python::type()); - return result; - } - - // Similar conversion for MillerIndex objects passed by value. - // Not actually used, but included to show the principle. - // - MillerIndex from_python(PyObject* p, python::type) - { - return from_python(p, python::type()); - } - - // Convert a MillerIndex object to a Python tuple. - // - PyObject* to_python(const MillerIndex& hkl) - { - python::tuple result(3); - for (int i = 0; i < 3; i++) - result.set_item(i, python::ref(to_python(hkl.v[i]))); - return result.reference().release(); - } - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -BOOST_PYTHON_MODULE_INIT(getting_started5) -{ - try - { - // Create an object representing this extension module. - python::module_builder this_module("getting_started5"); - - // Create the Python type object for our extension class. - python::class_builder ixset_class(this_module, "IndexingSet"); - - // Add the __init__ function. - ixset_class.def(python::constructor<>()); - // Add the member functions. - ixset_class.def(&IndexingSet::add, "add"); - ixset_class.def(&IndexingSet::get, "get"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/test_getting_started3.py b/example/test_getting_started3.py deleted file mode 100644 index d62cf5a2..00000000 --- a/example/test_getting_started3.py +++ /dev/null @@ -1,56 +0,0 @@ -r'''>>> import getting_started3 - >>> import re - >>> import pickle - >>> getting_started3.world.__module__ - 'getting_started3' - >>> getting_started3.world.__safe_for_unpickling__ - 1 - >>> getting_started3.world.__reduce__() - 'world' - >>> assert re.match( - ... "\(, \('Hello',\), \(0,\)\)", - ... repr(getting_started3.world('Hello').__reduce__())) - >>> - >>> for number in (24, 42): - ... wd = getting_started3.world('California') - ... wd.set_secret_number(number) - ... pstr = pickle.dumps(wd) - ... print pstr - ... wl = pickle.loads(pstr) - ... print wd.greet(), wd.get_secret_number() - ... print wl.greet(), wl.get_secret_number() - cgetting_started3 - world - p0 - (S'California' - p1 - tp2 - R(I24 - tp3 - bp4 - . - Hello from California! 24 - Hello from California! 24 - cgetting_started3 - world - p0 - (S'California' - p1 - tp2 - R(I42 - tp3 - bp4 - . - Hello from California! 42 - Hello from California! 0 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_getting_started3 - doctest.testmod(test_getting_started3) - -if __name__ == '__main__': - run() diff --git a/example/test_getting_started4.py b/example/test_getting_started4.py deleted file mode 100644 index 82b5c794..00000000 --- a/example/test_getting_started4.py +++ /dev/null @@ -1,35 +0,0 @@ -r'''>>> import getting_started4 - >>> v=getting_started4.vector_double() - >>> print v.as_tuple() - () - >>> v=getting_started4.vector_double(5) - >>> print v.as_tuple() - (0.0, 0.0, 0.0, 0.0, 0.0) - >>> print len(v) - 5 - >>> v=getting_started4.vector_double((3,4,5)) - >>> print v.as_tuple() - (3.0, 4.0, 5.0) - >>> print v[1] - 4.0 - >>> v[1] = 40 - >>> print v.as_tuple() - (3.0, 40.0, 5.0) - >>> del v[1] - >>> print v.as_tuple() - (3.0, 5.0) - >>> print getting_started4.foo(11).as_tuple() - (0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) - >>> print getting_started4.bar(12).as_tuple() - (0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_getting_started4 - doctest.testmod(test_getting_started4) - -if __name__ == '__main__': - run() diff --git a/example/test_getting_started5.py b/example/test_getting_started5.py deleted file mode 100644 index 8eeba1e2..00000000 --- a/example/test_getting_started5.py +++ /dev/null @@ -1,22 +0,0 @@ -r'''>>> import getting_started5 - >>> ixset = getting_started5.IndexingSet() - >>> ixset.add((1,2,3)) - >>> ixset.add((4,5,6)) - >>> ixset.add((7,8,9)) - >>> print ixset.get(0) - (1, 2, 3) - >>> print ixset.get(1) - (4, 5, 6) - >>> print ixset.get(2) - (7, 8, 9) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_getting_started5 - doctest.testmod(test_getting_started5) - -if __name__ == '__main__': - run() From dc520c6c32a4b0485d583d3ecc11e24df77a3eb7 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 19:04:16 +0000 Subject: [PATCH 0057/1042] Author included [SVN r9815] --- example/getting_started1.cpp | 2 ++ example/getting_started2.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/example/getting_started1.cpp b/example/getting_started1.cpp index 7a8e9087..c6a77723 100644 --- a/example/getting_started1.cpp +++ b/example/getting_started1.cpp @@ -1,3 +1,5 @@ +// Example by Ralf W. Grosse-Kunstleve + #include namespace { // Avoid cluttering the global namespace. diff --git a/example/getting_started2.cpp b/example/getting_started2.cpp index 72b04105..9121b1a0 100644 --- a/example/getting_started2.cpp +++ b/example/getting_started2.cpp @@ -1,3 +1,5 @@ +// Example by Ralf W. Grosse-Kunstleve + #include #include From 8158a509c92eeb0c8917ed7aca6276529ddad1e8 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 19:20:31 +0000 Subject: [PATCH 0058/1042] moved from branch ralf_grosse_kunstleve to trunk [SVN r9816] --- example/do_it_yourself_converters.cpp | 128 ++++++++++++++++++ example/dvect.cpp | 45 +++++++ example/dvect.h | 32 +++++ example/dvect_conversions.cpp | 51 ++++++++ example/dvect_defs.cpp | 13 ++ example/ivect.cpp | 45 +++++++ example/noncopyable.h | 14 ++ example/noncopyable_export.cpp | 25 ++++ example/noncopyable_import.cpp | 42 ++++++ example/pickle1.cpp | 64 +++++++++ example/pickle2.cpp | 100 +++++++++++++++ example/pickle3.cpp | 150 ++++++++++++++++++++++ example/simple_vector.cpp | 103 +++++++++++++++ example/test_do_it_yourself_converters.py | 22 ++++ example/test_pickle1.py | 31 +++++ example/test_pickle2.py | 45 +++++++ example/test_pickle3.py | 38 ++++++ example/test_simple_vector.py | 35 +++++ 18 files changed, 983 insertions(+) create mode 100644 example/do_it_yourself_converters.cpp create mode 100644 example/dvect.cpp create mode 100644 example/dvect.h create mode 100644 example/dvect_conversions.cpp create mode 100644 example/dvect_defs.cpp create mode 100644 example/ivect.cpp create mode 100644 example/noncopyable.h create mode 100644 example/noncopyable_export.cpp create mode 100644 example/noncopyable_import.cpp create mode 100644 example/pickle1.cpp create mode 100644 example/pickle2.cpp create mode 100644 example/pickle3.cpp create mode 100644 example/simple_vector.cpp create mode 100644 example/test_do_it_yourself_converters.py create mode 100644 example/test_pickle1.py create mode 100644 example/test_pickle2.py create mode 100644 example/test_pickle3.py create mode 100644 example/test_simple_vector.py diff --git a/example/do_it_yourself_converters.cpp b/example/do_it_yourself_converters.cpp new file mode 100644 index 00000000..6d2d2d6a --- /dev/null +++ b/example/do_it_yourself_converters.cpp @@ -0,0 +1,128 @@ +// Example by Ralf W. Grosse-Kunstleve +/* + + This example shows how to convert a class from and to native + Python objects, such as tuples. + + We do not want to expose the helper class MillerIndex as an + Extension Class. However, in order to simplify the wrapper code, + we want to define from_python() and to_python() functions for + class MillerIndex. + + Consider the alternatives: + + - Expose MillerIndex as an Extension Class. + We need a constructor MillerIndex(python::tuple). + Python function calls become more complex: + foo(MillerIndex((1,2,3)) instead of foo((1,2,3)) + We need a method such as MillerIndex().as_tuple(). + + - Define a wrapper function for each function that we + want to expose, e.g.: + void add(const IndexingSet& ixset, const python::tuple PyMIx) + + The first alternative introduces a new type that the user has to + deal with. Other modules using Miller indices might organize them in + different ways, for example to increase runtime efficiency for + important procedures. This means, the user has to know how to + convert between the different kinds of Miller index representations. + This can quickly become a nuisance. Relying on native Python data + structures minimizes the number of special types the user has to + learn and convert. Of course, this argument is only valid for + small and relatively simply classes. + + If there are many member functions with MillerIndex arguments, the + second alternative is impractical, and concentrating the conversion + mechanism in one central place is essential for code + maintainability. An added benefit is that more convenient (smarter) + conversion functions can be provided without cluttering the rest of + the wrapper code. + + */ + +#include +#include +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // The helper class. + // + class MillerIndex { + public: + int v[3]; + }; + + // The main class. Imagine that there are MANY member functions + // like add() and get(). + // + class IndexingSet { + private: + std::vector VMIx; + public: + void add(const MillerIndex& MIx) { VMIx.push_back(MIx); } + MillerIndex get(std::size_t i) const { return VMIx[i]; } + }; +} + +BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE + + // Convert a Python tuple to a MillerIndex object. + // + MillerIndex from_python(PyObject* p, python::type) + { + python::tuple tup + = python::tuple(python::ref(p, python::ref::increment_count)); + if (tup.size() != 3) { + PyErr_SetString(PyExc_ValueError, + "expecting exactly 3 values in tuple."); + throw python::error_already_set(); + } + MillerIndex result; + for (int i = 0; i < 3; i++) + result.v[i] = from_python(tup[i].get(), python::type()); + return result; + } + + // Similar conversion for MillerIndex objects passed by value. + // Not actually used, but included to show the principle. + // + MillerIndex from_python(PyObject* p, python::type) + { + return from_python(p, python::type()); + } + + // Convert a MillerIndex object to a Python tuple. + // + PyObject* to_python(const MillerIndex& hkl) + { + python::tuple result(3); + for (int i = 0; i < 3; i++) + result.set_item(i, python::ref(to_python(hkl.v[i]))); + return result.reference().release(); + } + +BOOST_PYTHON_END_CONVERSION_NAMESPACE + +BOOST_PYTHON_MODULE_INIT(do_it_yourself_converters) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("do_it_yourself_converters"); + + // Create the Python type object for our extension class. + python::class_builder ixset_class(this_module, "IndexingSet"); + + // Add the __init__ function. + ixset_class.def(python::constructor<>()); + // Add the member functions. + ixset_class.def(&IndexingSet::add, "add"); + ixset_class.def(&IndexingSet::get, "get"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/dvect.cpp b/example/dvect.cpp new file mode 100644 index 00000000..da6b35a3 --- /dev/null +++ b/example/dvect.cpp @@ -0,0 +1,45 @@ +// Example by Ralf W. Grosse-Kunstleve +// See root/libs/python/doc/cross_module.html for an introduction. + +#include "dvect.h" +#include "ivect.h" +#include +namespace python = boost::python; + +namespace { + +# include "dvect_conversions.cpp" +# include "ivect_conversions.cpp" + + vects::ivect dvect_as_ivect(const vects::dvect& dv) + { + vects::ivect iv(dv.size()); + vects::ivect::iterator iviter = iv.begin(); + for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); + return iv; + } +} + +BOOST_PYTHON_MODULE_INIT(dvect) +{ + try + { + python::module_builder this_module("dvect"); + + python::class_builder dvect_class(this_module, "dvect"); + python::export_converters(dvect_class); + + python::import_converters ivect_converters("ivect", "ivect"); + + dvect_class.def(python::constructor()); + dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); + dvect_class.def(dvect_as_ivect, "as_ivect"); + +# include "dvect_defs.cpp" +# include "ivect_defs.cpp" + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/dvect.h b/example/dvect.h new file mode 100644 index 00000000..8ffe7b50 --- /dev/null +++ b/example/dvect.h @@ -0,0 +1,32 @@ +#ifndef DVECT_H +#define DVECT_H + +#include +#include + +namespace vects { + + struct dvect : public std::vector + { + dvect() : std::vector() {} + dvect(size_t n) : std::vector(n) {} + dvect(boost::python::tuple tuple) : std::vector(tuple.size()) + { + std::vector::iterator v_it = begin(); + for (int i = 0; i < tuple.size(); i++) + v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + + boost::python::tuple as_tuple() const + { + boost::python::tuple t(size()); + for (int i = 0; i < size(); i++) + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); + return t; + } + }; +} + +#endif // DVECT_H diff --git a/example/dvect_conversions.cpp b/example/dvect_conversions.cpp new file mode 100644 index 00000000..21527243 --- /dev/null +++ b/example/dvect_conversions.cpp @@ -0,0 +1,51 @@ + // basics first: const reference converters + boost::python::tuple const_dvect_reference_as_tuple(const vects::dvect& dv) + { + return dv.as_tuple(); + } + + // to_python smart pointer conversions + std::auto_ptr dvect_as_auto_ptr(const vects::dvect& dv) + { + return std::auto_ptr(new vects::dvect(dv)); + } + boost::shared_ptr dvect_as_shared_ptr(const vects::dvect& dv) + { + return boost::shared_ptr(new vects::dvect(dv)); + } + + // smart pointers passed by value + boost::python::ref auto_ptr_value_dvect_as_tuple(std::auto_ptr dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } + boost::python::ref shared_ptr_value_dvect_as_tuple(boost::shared_ptr dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } + + // smart pointers passed by reference + boost::python::ref auto_ptr_reference_dvect_as_tuple(std::auto_ptr& dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } + boost::python::ref shared_ptr_reference_dvect_as_tuple(boost::shared_ptr& dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } + + // smart pointers passed by const reference + boost::python::ref auto_ptr_const_reference_dvect_as_tuple(const std::auto_ptr& dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } + boost::python::ref shared_ptr_const_reference_dvect_as_tuple(const boost::shared_ptr& dv) + { + if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return dv->as_tuple().reference(); + } diff --git a/example/dvect_defs.cpp b/example/dvect_defs.cpp new file mode 100644 index 00000000..2739b219 --- /dev/null +++ b/example/dvect_defs.cpp @@ -0,0 +1,13 @@ + this_module.def(dvect_as_auto_ptr, "dvect_as_auto_ptr"); + this_module.def(dvect_as_shared_ptr, "dvect_as_shared_ptr"); + + this_module.def(const_dvect_reference_as_tuple, "const_dvect_reference_as_tuple"); + + this_module.def(auto_ptr_value_dvect_as_tuple, "auto_ptr_value_dvect_as_tuple"); + this_module.def(shared_ptr_value_dvect_as_tuple, "shared_ptr_value_dvect_as_tuple"); + + this_module.def(auto_ptr_reference_dvect_as_tuple, "auto_ptr_reference_dvect_as_tuple"); + this_module.def(shared_ptr_reference_dvect_as_tuple, "shared_ptr_reference_dvect_as_tuple"); + + this_module.def(auto_ptr_const_reference_dvect_as_tuple, "auto_ptr_const_reference_dvect_as_tuple"); + this_module.def(shared_ptr_const_reference_dvect_as_tuple, "shared_ptr_const_reference_dvect_as_tuple"); diff --git a/example/ivect.cpp b/example/ivect.cpp new file mode 100644 index 00000000..db1c0ec3 --- /dev/null +++ b/example/ivect.cpp @@ -0,0 +1,45 @@ +// Example by Ralf W. Grosse-Kunstleve +// See root/libs/python/doc/cross_module.html for an introduction. + +#include "dvect.h" +#include "ivect.h" +#include +namespace python = boost::python; + +namespace { + +# include "dvect_conversions.cpp" +# include "ivect_conversions.cpp" + + vects::dvect ivect_as_dvect(const vects::ivect& iv) + { + vects::dvect dv(iv.size()); + vects::dvect::iterator dviter = dv.begin(); + for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); + return dv; + } +} + +BOOST_PYTHON_MODULE_INIT(ivect) +{ + try + { + python::module_builder this_module("ivect"); + + python::class_builder ivect_class(this_module, "ivect"); + python::export_converters(ivect_class); + + python::import_converters dvect_converters("dvect", "dvect"); + + ivect_class.def(python::constructor()); + ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); + ivect_class.def(ivect_as_dvect, "as_dvect"); + +# include "dvect_defs.cpp" +# include "ivect_defs.cpp" + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/noncopyable.h b/example/noncopyable.h new file mode 100644 index 00000000..de7b3672 --- /dev/null +++ b/example/noncopyable.h @@ -0,0 +1,14 @@ +#ifndef NONCOPYABLE_H +#define NONCOPYABLE_H + +class store +{ + private: + store(const store&) { } // Disable the copy constructor. + int number; + public: + store(const int i) : number(i) { } + int recall() const { return number; } +}; + +#endif // NONCOPYABLE_H diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp new file mode 100644 index 00000000..794b1200 --- /dev/null +++ b/example/noncopyable_export.cpp @@ -0,0 +1,25 @@ +// Example by Ralf W. Grosse-Kunstleve +// See root/libs/python/doc/cross_module.html for an introduction. + +#include +namespace python = boost::python; + +#include "noncopyable.h" + +BOOST_PYTHON_MODULE_INIT(noncopyable_export) +{ + try + { + python::module_builder this_module("noncopyable_export"); + + python::class_builder store_class(this_module, "store"); + python::export_converters_noncopyable(store_class); + + store_class.def(python::constructor()); + store_class.def(&store::recall, "recall"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp new file mode 100644 index 00000000..ea2477be --- /dev/null +++ b/example/noncopyable_import.cpp @@ -0,0 +1,42 @@ +// Example by Ralf W. Grosse-Kunstleve +// See root/libs/python/doc/cross_module.html for an introduction. + +#include +namespace python = boost::python; + +#include "noncopyable.h" + +namespace { // Avoid cluttering the global namespace. + + // A function with store objects as both input and output parameters. + // Because the copy constructor is disabled, we cannot pass a store + // object by value. Instead, we pass a smart pointer. + std::auto_ptr add_stores(const store& s1, const store& s2) + { + int sum = s1.recall() + s2.recall(); + std::auto_ptr ss = std::auto_ptr(new store(sum)); + return ss; + } +} + +BOOST_PYTHON_MODULE_INIT(noncopyable_import) +{ + try + { + python::module_builder this_module("noncopyable_import"); + + python::import_converters + dvect_converters("noncopyable_export", "store"); + + // Imagine all the additional classes with member functions + // that have store objects as input and output parameters. + // Lots and lots of them. + // However, to keep this example simple, we only define a + // module-level function. + this_module.def(add_stores, "add_stores"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/pickle1.cpp b/example/pickle1.cpp new file mode 100644 index 00000000..cdd78989 --- /dev/null +++ b/example/pickle1.cpp @@ -0,0 +1,64 @@ +// Example by Ralf W. Grosse-Kunstleve + +/* + This example shows how to make an Extension Class "pickleable". + + The world class below can be fully restored by passing the + appropriate argument to the constructor. Therefore it is sufficient + to define the pickle interface method __getinitargs__. + + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include + +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + private: + std::string country; + int secret_number; + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + }; + + // Support for pickle. + python::ref world_getinitargs(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_country()); + return result.reference(); + } +} + +BOOST_PYTHON_MODULE_INIT(pickle1) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("pickle1"); + + // Create the Python type object for our extension class. + python::class_builder world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(python::constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + + // Support for pickle. + world_class.def(world_getinitargs, "__getinitargs__"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/pickle2.cpp b/example/pickle2.cpp new file mode 100644 index 00000000..d6aa3201 --- /dev/null +++ b/example/pickle2.cpp @@ -0,0 +1,100 @@ +// Example by Ralf W. Grosse-Kunstleve + +/* + This example shows how to make an Extension Class "pickleable". + + The world class below contains member data (secret_number) that + cannot be restored by any of the constructors. Therefore it is + necessary to provide the __getstate__/__setstate__ pair of pickle + interface methods. + + For simplicity, the __dict__ is not included in the result of + __getstate__. This is not generally recommended, but a valid + approach if it is anticipated that the object's __dict__ will + always be empty. Note that safety guard are provided to catch the + cases where this assumption is not true. + + pickle3.cpp shows how to include the object's __dict__ in the + result of __getstate__. + + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include + +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + void set_secret_number(int number) { secret_number = number; } + int get_secret_number() const { return secret_number; } + private: + std::string country; + int secret_number; + }; + + // Support for pickle. + + using BOOST_PYTHON_CONVERSION::from_python; + + python::ref world_getinitargs(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_country()); + return result.reference(); // returning the reference avoids the copying. + } + + python::ref world_getstate(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_secret_number()); + return result.reference(); // returning the reference avoids the copying. + } + + void world_setstate(world& w, python::tuple state) { + if (state.size() != 1) { + PyErr_SetString(PyExc_ValueError, + "Unexpected argument in call to __setstate__."); + throw python::error_already_set(); + } + int number = from_python(state[0].get(), python::type()); + if (number != 42) + w.set_secret_number(number); + } +} + +BOOST_PYTHON_MODULE_INIT(pickle2) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("pickle2"); + + // Create the Python type object for our extension class. + python::class_builder world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(python::constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + world_class.def(&world::get_secret_number, "get_secret_number"); + world_class.def(&world::set_secret_number, "set_secret_number"); + + // Support for pickle. + world_class.def(world_getinitargs, "__getinitargs__"); + world_class.def(world_getstate, "__getstate__"); + world_class.def(world_setstate, "__setstate__"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/pickle3.cpp b/example/pickle3.cpp new file mode 100644 index 00000000..bfa7dc54 --- /dev/null +++ b/example/pickle3.cpp @@ -0,0 +1,150 @@ +// Example by Ralf W. Grosse-Kunstleve + +/* + This example shows how to make an Extension Class "pickleable". + + The world class below contains member data (secret_number) that + cannot be restored by any of the constructors. Therefore it is + necessary to provide the __getstate__/__setstate__ pair of pickle + interface methods. + + The object's __dict__ is included in the result of __getstate__. + This requires more code (compare with pickle2.cpp), but is + unavoidable if the object's __dict__ is not always empty. + + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include + +#include +namespace python = boost::python; + +namespace boost { namespace python { + + ref getattr(PyObject* o, const std::string& attr_name) { + return ref(PyObject_GetAttrString(o, const_cast(attr_name.c_str()))); + } + ref getattr(const ref& r, const std::string& attr_name) { + return getattr(r.get(), attr_name); + } + +}} + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + void set_secret_number(int number) { secret_number = number; } + int get_secret_number() const { return secret_number; } + private: + std::string country; + int secret_number; + }; + + // Support for pickle. + python::ref world_getinitargs(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_country()); + return result.reference(); // returning the reference avoids the copying. + } + + python::ref world_getstate(python::tuple const & args, + python::dictionary const & keywords); + + PyObject* world_setstate(python::tuple const & args, + python::dictionary const & keywords); +} + +BOOST_PYTHON_MODULE_INIT(pickle3) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("pickle3"); + + // Create the Python type object for our extension class. + python::class_builder world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(python::constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + world_class.def(&world::get_secret_number, "get_secret_number"); + world_class.def(&world::set_secret_number, "set_secret_number"); + + // Support for pickle. + world_class.def(world_getinitargs, "__getinitargs__"); + world_class.def_raw(world_getstate, "__getstate__"); + world_class.def_raw(world_setstate, "__setstate__"); + world_class.getstate_manages_dict(); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} + +namespace { + + using BOOST_PYTHON_CONVERSION::from_python; + using boost::python::type; + using boost::python::ref; + using boost::python::tuple; + using boost::python::list; + using boost::python::dictionary; + using boost::python::getattr; + + ref world_getstate(tuple const & args, dictionary const & keywords) + { + if(args.size() != 1 || keywords.size() != 0) { + PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); + throw boost::python::argument_error(); + } + const world& w = from_python(args[0].get(), type()); + ref mydict = getattr(args[0], "__dict__"); + tuple result(2); + // store the object's __dict__ + result.set_item(0, mydict); + // store the internal state of the C++ object + result.set_item(1, w.get_secret_number()); + return result.reference(); // returning the reference avoids the copying. + } + + PyObject* world_setstate(tuple const & args, dictionary const & keywords) + { + if(args.size() != 2 || keywords.size() != 0) { + PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); + throw boost::python::argument_error(); + } + world& w = from_python(args[0].get(), type()); + ref mydict = getattr(args[0], "__dict__"); + tuple state = from_python(args[1].get(), type()); + if (state.size() != 2) { + PyErr_SetString(PyExc_ValueError, + "Unexpected argument in call to __setstate__."); + throw python::error_already_set(); + } + // restore the object's __dict__ + dictionary odict = from_python(mydict.get(), type()); + const dictionary& pdict = from_python(state[0].get(), type()); + list pkeys(pdict.keys()); + for (int i = 0; i < pkeys.size(); i++) { + ref k(pkeys[i]); + //odict[k] = pdict[k]; // XXX memory leak! + odict[k] = pdict.get_item(k); // this does not leak. + } + // restore the internal state of the C++ object + int number = from_python(state[1].get(), type()); + if (number != 42) + w.set_secret_number(number); + return python::detail::none(); + } +} diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp new file mode 100644 index 00000000..5ac0767b --- /dev/null +++ b/example/simple_vector.cpp @@ -0,0 +1,103 @@ +// Example by Ralf W. Grosse-Kunstleve + +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A wrapper is used to define additional constructors. + // + struct vector_double_wrapper: std::vector + { + // Tell the compiler how to convert a base class object to + // this wrapper object. + vector_double_wrapper(PyObject*, const std::vector& vd) + : std::vector(vd) {} + + vector_double_wrapper(PyObject* self) + : std::vector() {} + + vector_double_wrapper(PyObject* self, int n) + : std::vector(n) {} + + vector_double_wrapper(PyObject* self, python::tuple tuple) + : std::vector(tuple.size()) + { + std::vector::iterator vd = begin(); + for (int i = 0; i < tuple.size(); i++) + vd[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + python::type()); + } + }; + + double getitem(const std::vector& vd, std::size_t key) { + return vd[key]; + } + + void setitem(std::vector& vd, std::size_t key, double d) { + std::vector::iterator vditer = vd.begin(); + vditer[key] = d; + } + + void delitem(std::vector& vd, std::size_t key) { + std::vector::iterator vditer = vd.begin(); + vd.erase(&vditer[key]); + } + + // Convert vector_double to a regular Python tuple. + // + python::tuple as_tuple(const std::vector& vd) + { + python::tuple t(vd.size()); + for (int i = 0; i < vd.size(); i++) t.set_item(i, + python::ref(BOOST_PYTHON_CONVERSION::to_python(vd[i]))); + return t; + } + + // Function returning a vector_double object to Python. + // + std::vector foo(int n) + { + std::vector vd(n); + std::vector::iterator vditer = vd.begin(); + for (int i = 0; i < n; i++) vditer[i] = double(i); + return vd; + } + + // Same as foo(), but avoid copying on return. + // + std::auto_ptr > bar(int n) + { + std::auto_ptr > vdptr(new std::vector(n)); + std::vector::iterator vditer = vdptr->begin(); + for (int i = 0; i < n; i++) vditer[i] = double(10 * i); + return vdptr; + } +} + +BOOST_PYTHON_MODULE_INIT(simple_vector) +{ + try + { + python::module_builder this_module("simple_vector"); + + python::class_builder, vector_double_wrapper> + vector_double(this_module, "vector_double"); + + vector_double.def(python::constructor<>()); + vector_double.def(python::constructor()); + vector_double.def(python::constructor()); + vector_double.def(&std::vector::size, "__len__"); + vector_double.def(getitem, "__getitem__"); + vector_double.def(setitem, "__setitem__"); + vector_double.def(delitem, "__delitem__"); + vector_double.def(as_tuple, "as_tuple"); + + this_module.def(foo, "foo"); + this_module.def(bar, "bar"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/test_do_it_yourself_converters.py b/example/test_do_it_yourself_converters.py new file mode 100644 index 00000000..e256c614 --- /dev/null +++ b/example/test_do_it_yourself_converters.py @@ -0,0 +1,22 @@ +r'''>>> import do_it_yourself_converters + >>> ixset = do_it_yourself_converters.IndexingSet() + >>> ixset.add((1,2,3)) + >>> ixset.add((4,5,6)) + >>> ixset.add((7,8,9)) + >>> print ixset.get(0) + (1, 2, 3) + >>> print ixset.get(1) + (4, 5, 6) + >>> print ixset.get(2) + (7, 8, 9) +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_do_it_yourself_converters + doctest.testmod(test_do_it_yourself_converters) + +if __name__ == '__main__': + run() diff --git a/example/test_pickle1.py b/example/test_pickle1.py new file mode 100644 index 00000000..05696d4a --- /dev/null +++ b/example/test_pickle1.py @@ -0,0 +1,31 @@ +r'''>>> import pickle1 + >>> import re + >>> import pickle + >>> pickle1.world.__module__ + 'pickle1' + >>> pickle1.world.__safe_for_unpickling__ + 1 + >>> pickle1.world.__reduce__() + 'world' + >>> assert re.match( + ... "\(, \('Hello',\)\)", + ... repr(pickle1.world('Hello').__reduce__())) + >>> + >>> wd = pickle1.world('California') + >>> pstr = pickle.dumps(wd) + >>> wl = pickle.loads(pstr) + >>> print wd.greet() + Hello from California! + >>> print wl.greet() + Hello from California! +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_pickle1 + doctest.testmod(test_pickle1) + +if __name__ == '__main__': + run() diff --git a/example/test_pickle2.py b/example/test_pickle2.py new file mode 100644 index 00000000..463befa6 --- /dev/null +++ b/example/test_pickle2.py @@ -0,0 +1,45 @@ +r'''>>> import pickle2 + >>> import re + >>> import pickle + >>> pickle2.world.__module__ + 'pickle2' + >>> pickle2.world.__safe_for_unpickling__ + 1 + >>> pickle2.world.__reduce__() + 'world' + >>> assert re.match( + ... "\(, \('Hello',\), \(0,\)\)", + ... repr(pickle2.world('Hello').__reduce__())) + >>> + >>> for number in (24, 42): + ... wd = pickle2.world('California') + ... wd.set_secret_number(number) + ... pstr = pickle.dumps(wd) + ... wl = pickle.loads(pstr) + ... print wd.greet(), wd.get_secret_number() + ... print wl.greet(), wl.get_secret_number() + Hello from California! 24 + Hello from California! 24 + Hello from California! 42 + Hello from California! 0 + +# Now show that the __dict__ is not taken care of. + >>> wd = pickle2.world('California') + >>> wd.x = 1 + >>> wd.__dict__ + {'x': 1} + >>> try: pstr = pickle.dumps(wd) + ... except RuntimeError, err: print err[0] + ... + Incomplete pickle support (__getstate_manages_dict__ not set) +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_pickle2 + doctest.testmod(test_pickle2) + +if __name__ == '__main__': + run() diff --git a/example/test_pickle3.py b/example/test_pickle3.py new file mode 100644 index 00000000..b964f1a2 --- /dev/null +++ b/example/test_pickle3.py @@ -0,0 +1,38 @@ +r'''>>> import pickle3 + >>> import re + >>> import pickle + >>> pickle3.world.__module__ + 'pickle3' + >>> pickle3.world.__safe_for_unpickling__ + 1 + >>> pickle3.world.__reduce__() + 'world' + >>> assert re.match( + ... "\(, \('Hello',\), \(\{\}, 0\)\)", + ... repr(pickle3.world('Hello').__reduce__())) + >>> + >>> for number in (24, 42): + ... wd = pickle3.world('California') + ... wd.set_secret_number(number) + ... wd.x = 2 * number + ... wd.y = 'y' * number + ... wd.z = 3. * number + ... pstr = pickle.dumps(wd) + ... wl = pickle.loads(pstr) + ... print wd.greet(), wd.get_secret_number(), wd.__dict__ + ... print wl.greet(), wl.get_secret_number(), wl.__dict__ + Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'} + Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'} + Hello from California! 42 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'} + Hello from California! 0 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'} +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_pickle3 + doctest.testmod(test_pickle3) + +if __name__ == '__main__': + run() diff --git a/example/test_simple_vector.py b/example/test_simple_vector.py new file mode 100644 index 00000000..a19e205b --- /dev/null +++ b/example/test_simple_vector.py @@ -0,0 +1,35 @@ +r'''>>> import simple_vector + >>> v=simple_vector.vector_double() + >>> print v.as_tuple() + () + >>> v=simple_vector.vector_double(5) + >>> print v.as_tuple() + (0.0, 0.0, 0.0, 0.0, 0.0) + >>> print len(v) + 5 + >>> v=simple_vector.vector_double((3,4,5)) + >>> print v.as_tuple() + (3.0, 4.0, 5.0) + >>> print v[1] + 4.0 + >>> v[1] = 40 + >>> print v.as_tuple() + (3.0, 40.0, 5.0) + >>> del v[1] + >>> print v.as_tuple() + (3.0, 5.0) + >>> print simple_vector.foo(11).as_tuple() + (0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) + >>> print simple_vector.bar(12).as_tuple() + (0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0) +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_simple_vector + doctest.testmod(test_simple_vector) + +if __name__ == '__main__': + run() From ef7c4379572ef0f9758a4c1c5add34616a8c0757 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 19:31:00 +0000 Subject: [PATCH 0059/1042] moved from branch ralf_grosse_kunstleve to trunk [SVN r9817] --- example/ivect.h | 32 ++++++++ example/ivect_conversions.cpp | 51 +++++++++++++ example/ivect_defs.cpp | 13 ++++ example/test_cross_module.py | 139 ++++++++++++++++++++++++++++++++++ example/tst_dvect1.py | 20 +++++ example/tst_dvect2.py | 98 ++++++++++++++++++++++++ example/tst_ivect1.py | 20 +++++ example/tst_ivect2.py | 98 ++++++++++++++++++++++++ example/tst_noncopyable.py | 16 ++++ 9 files changed, 487 insertions(+) create mode 100644 example/ivect.h create mode 100644 example/ivect_conversions.cpp create mode 100644 example/ivect_defs.cpp create mode 100644 example/test_cross_module.py create mode 100644 example/tst_dvect1.py create mode 100644 example/tst_dvect2.py create mode 100644 example/tst_ivect1.py create mode 100644 example/tst_ivect2.py create mode 100644 example/tst_noncopyable.py diff --git a/example/ivect.h b/example/ivect.h new file mode 100644 index 00000000..a0187307 --- /dev/null +++ b/example/ivect.h @@ -0,0 +1,32 @@ +#ifndef IVECT_H +#define IVECT_H + +#include +#include + +namespace vects { + + struct ivect : public std::vector + { + ivect() : std::vector() {} + ivect(size_t n) : std::vector(n) {} + ivect(boost::python::tuple tuple) : std::vector(tuple.size()) + { + std::vector::iterator v_it = begin(); + for (int i = 0; i < tuple.size(); i++) + v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + + boost::python::tuple as_tuple() const + { + boost::python::tuple t(size()); + for (int i = 0; i < size(); i++) + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); + return t; + } + }; +} + +#endif // IVECT_H diff --git a/example/ivect_conversions.cpp b/example/ivect_conversions.cpp new file mode 100644 index 00000000..4f59573d --- /dev/null +++ b/example/ivect_conversions.cpp @@ -0,0 +1,51 @@ + // basics first: const reference converters + boost::python::tuple const_ivect_reference_as_tuple(const vects::ivect& iv) + { + return iv.as_tuple(); + } + + // to_python smart pointer conversions + std::auto_ptr ivect_as_auto_ptr(const vects::ivect& iv) + { + return std::auto_ptr(new vects::ivect(iv)); + } + boost::shared_ptr ivect_as_shared_ptr(const vects::ivect& iv) + { + return boost::shared_ptr(new vects::ivect(iv)); + } + + // smart pointers passed by value + boost::python::ref auto_ptr_value_ivect_as_tuple(std::auto_ptr iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } + boost::python::ref shared_ptr_value_ivect_as_tuple(boost::shared_ptr iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } + + // smart pointers passed by reference + boost::python::ref auto_ptr_reference_ivect_as_tuple(std::auto_ptr& iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } + boost::python::ref shared_ptr_reference_ivect_as_tuple(boost::shared_ptr& iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } + + // smart pointers passed by const reference + boost::python::ref auto_ptr_const_reference_ivect_as_tuple(const std::auto_ptr& iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } + boost::python::ref shared_ptr_const_reference_ivect_as_tuple(const boost::shared_ptr& iv) + { + if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); + return iv->as_tuple().reference(); + } diff --git a/example/ivect_defs.cpp b/example/ivect_defs.cpp new file mode 100644 index 00000000..811c243d --- /dev/null +++ b/example/ivect_defs.cpp @@ -0,0 +1,13 @@ + this_module.def(ivect_as_auto_ptr, "ivect_as_auto_ptr"); + this_module.def(ivect_as_shared_ptr, "ivect_as_shared_ptr"); + + this_module.def(const_ivect_reference_as_tuple, "const_ivect_reference_as_tuple"); + + this_module.def(auto_ptr_value_ivect_as_tuple, "auto_ptr_value_ivect_as_tuple"); + this_module.def(shared_ptr_value_ivect_as_tuple, "shared_ptr_value_ivect_as_tuple"); + + this_module.def(auto_ptr_reference_ivect_as_tuple, "auto_ptr_reference_ivect_as_tuple"); + this_module.def(shared_ptr_reference_ivect_as_tuple, "shared_ptr_reference_ivect_as_tuple"); + + this_module.def(auto_ptr_const_reference_ivect_as_tuple, "auto_ptr_const_reference_ivect_as_tuple"); + this_module.def(shared_ptr_const_reference_ivect_as_tuple, "shared_ptr_const_reference_ivect_as_tuple"); diff --git a/example/test_cross_module.py b/example/test_cross_module.py new file mode 100644 index 00000000..81057f23 --- /dev/null +++ b/example/test_cross_module.py @@ -0,0 +1,139 @@ +r'''>>> import tst_noncopyable + >>> tst_noncopyable.f() + 1 + 2 + 3 + >>> import tst_dvect1 + >>> tst_dvect1.f() + (1.0, 2.0, 3.0, 4.0, 5.0) + (1, 2, 3, 4, 5) + (1, 2, 3, 4, 5) + (1, 2, 3, 4, 5) + (1, 2, 3, 4, 5) + (1, 2, 3, 4, 5) + (1, 2, 3, 4, 5) + >>> import tst_ivect1 + >>> tst_ivect1.f() + (1, 2, 3, 4, 5) + (1.0, 2.0, 3.0, 4.0, 5.0) + (1.0, 2.0, 3.0, 4.0, 5.0) + (1.0, 2.0, 3.0, 4.0, 5.0) + (1.0, 2.0, 3.0, 4.0, 5.0) + (1.0, 2.0, 3.0, 4.0, 5.0) + (1.0, 2.0, 3.0, 4.0, 5.0) + >>> import sys + >>> if ("--broken-auto-ptr" in sys.argv): + ... broken_auto_ptr = 1 + ... else: + ... broken_auto_ptr = 0 + >>> import tst_dvect2 + >>> tst_dvect2.f(broken_auto_ptr) + 1. auto_ptr_value_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. auto_ptr_value_ivect_as_tuple + None + 1. auto_ptr_value_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. auto_ptr_value_dvect_as_tuple + None + 1. shared_ptr_value_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. shared_ptr_value_ivect_as_tuple + (1, 2, 3, 4, 5) + 1. shared_ptr_value_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. shared_ptr_value_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 1. auto_ptr_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. auto_ptr_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 1. auto_ptr_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. auto_ptr_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 1. shared_ptr_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. shared_ptr_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 1. shared_ptr_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. shared_ptr_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 1. auto_ptr_const_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. auto_ptr_const_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 1. auto_ptr_const_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. auto_ptr_const_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 1. shared_ptr_const_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. shared_ptr_const_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 1. shared_ptr_const_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. shared_ptr_const_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + >>> import tst_ivect2 + >>> tst_ivect2.f(broken_auto_ptr) + 1. auto_ptr_value_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. auto_ptr_value_dvect_as_tuple + None + 1. auto_ptr_value_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. auto_ptr_value_ivect_as_tuple + None + 1. shared_ptr_value_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. shared_ptr_value_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 1. shared_ptr_value_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. shared_ptr_value_ivect_as_tuple + (1, 2, 3, 4, 5) + 1. auto_ptr_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. auto_ptr_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 1. auto_ptr_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. auto_ptr_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 1. shared_ptr_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. shared_ptr_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 1. shared_ptr_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. shared_ptr_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 1. auto_ptr_const_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. auto_ptr_const_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 1. auto_ptr_const_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. auto_ptr_const_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 1. shared_ptr_const_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 2. shared_ptr_const_reference_dvect_as_tuple + (1.0, 2.0, 3.0, 4.0, 5.0) + 1. shared_ptr_const_reference_ivect_as_tuple + (1, 2, 3, 4, 5) + 2. shared_ptr_const_reference_ivect_as_tuple + (1, 2, 3, 4, 5) +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_cross_module + doctest.testmod(test_cross_module) + +if __name__ == '__main__': + run() diff --git a/example/tst_dvect1.py b/example/tst_dvect1.py new file mode 100644 index 00000000..22315528 --- /dev/null +++ b/example/tst_dvect1.py @@ -0,0 +1,20 @@ +def f(): + import dvect + dv = dvect.dvect((1,2,3,4,5)) + print dv.as_tuple() + iv = dv.as_ivect() + print iv.as_tuple() + print dvect.const_ivect_reference_as_tuple(iv) + aiv = dvect.ivect_as_auto_ptr(iv) + print dvect.const_ivect_reference_as_tuple(aiv) + siv = dvect.ivect_as_shared_ptr(iv) + print dvect.const_ivect_reference_as_tuple(siv) + print aiv.as_tuple() + print siv.as_tuple() + +if (__name__ == "__main__"): + import sys, string + n = 1 + if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) + for i in xrange(n): + f() diff --git a/example/tst_dvect2.py b/example/tst_dvect2.py new file mode 100644 index 00000000..539e0b88 --- /dev/null +++ b/example/tst_dvect2.py @@ -0,0 +1,98 @@ +def f(broken_auto_ptr): + import dvect + import ivect + # + dv = dvect.dvect((1,2,3,4,5)) + iv = dv.as_ivect() + # + aiv = dvect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_value_ivect_as_tuple' + print ivect.auto_ptr_value_ivect_as_tuple(aiv) + print '2. auto_ptr_value_ivect_as_tuple' + if (not broken_auto_ptr): + print ivect.auto_ptr_value_ivect_as_tuple(aiv) + else: + print None + # + adv = dvect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_value_dvect_as_tuple' + print ivect.auto_ptr_value_dvect_as_tuple(adv) + print '2. auto_ptr_value_dvect_as_tuple' + if (not broken_auto_ptr): + print ivect.auto_ptr_value_dvect_as_tuple(adv) + else: + print None + # + siv = dvect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_value_ivect_as_tuple' + print ivect.shared_ptr_value_ivect_as_tuple(siv) + print '2. shared_ptr_value_ivect_as_tuple' + print ivect.shared_ptr_value_ivect_as_tuple(siv) + # + sdv = dvect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_value_dvect_as_tuple' + print ivect.shared_ptr_value_dvect_as_tuple(sdv) + print '2. shared_ptr_value_dvect_as_tuple' + print ivect.shared_ptr_value_dvect_as_tuple(sdv) + # + aiv = dvect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_reference_ivect_as_tuple' + print ivect.auto_ptr_reference_ivect_as_tuple(aiv) + print '2. auto_ptr_reference_ivect_as_tuple' + print ivect.auto_ptr_reference_ivect_as_tuple(aiv) + # + adv = dvect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_reference_dvect_as_tuple' + print ivect.auto_ptr_reference_dvect_as_tuple(adv) + print '2. auto_ptr_reference_dvect_as_tuple' + print ivect.auto_ptr_reference_dvect_as_tuple(adv) + # + siv = dvect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_reference_ivect_as_tuple' + print ivect.shared_ptr_reference_ivect_as_tuple(siv) + print '2. shared_ptr_reference_ivect_as_tuple' + print ivect.shared_ptr_reference_ivect_as_tuple(siv) + # + sdv = dvect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_reference_dvect_as_tuple' + print ivect.shared_ptr_reference_dvect_as_tuple(sdv) + print '2. shared_ptr_reference_dvect_as_tuple' + print ivect.shared_ptr_reference_dvect_as_tuple(sdv) + # + aiv = dvect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_const_reference_ivect_as_tuple' + print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv) + print '2. auto_ptr_const_reference_ivect_as_tuple' + print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv) + # + adv = dvect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_const_reference_dvect_as_tuple' + print ivect.auto_ptr_const_reference_dvect_as_tuple(adv) + print '2. auto_ptr_const_reference_dvect_as_tuple' + print ivect.auto_ptr_const_reference_dvect_as_tuple(adv) + # + siv = dvect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_const_reference_ivect_as_tuple' + print ivect.shared_ptr_const_reference_ivect_as_tuple(siv) + print '2. shared_ptr_const_reference_ivect_as_tuple' + print ivect.shared_ptr_const_reference_ivect_as_tuple(siv) + # + sdv = dvect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_const_reference_dvect_as_tuple' + print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv) + print '2. shared_ptr_const_reference_dvect_as_tuple' + print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv) + +if (__name__ == "__main__"): + import sys, string + broken_auto_ptr = 0 + n = 1 + if (len(sys.argv) > 1): + if (sys.argv[1] == "--broken-auto-ptr"): + broken_auto_ptr = 1 + if (len(sys.argv) > 2): + n = string.atoi(sys.argv[2]) + else: + n = string.atoi(sys.argv[1]) + for i in xrange(n): + f(broken_auto_ptr) diff --git a/example/tst_ivect1.py b/example/tst_ivect1.py new file mode 100644 index 00000000..7369fdbf --- /dev/null +++ b/example/tst_ivect1.py @@ -0,0 +1,20 @@ +def f(): + import ivect + iv = ivect.ivect((1,2,3,4,5)) + print iv.as_tuple() + dv = iv.as_dvect() + print dv.as_tuple() + print ivect.const_dvect_reference_as_tuple(dv) + adv = ivect.dvect_as_auto_ptr(dv) + print ivect.const_dvect_reference_as_tuple(adv) + sdv = ivect.dvect_as_shared_ptr(dv) + print ivect.const_dvect_reference_as_tuple(sdv) + print adv.as_tuple() + print sdv.as_tuple() + +if (__name__ == "__main__"): + import sys, string + n = 1 + if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) + for i in xrange(n): + f() diff --git a/example/tst_ivect2.py b/example/tst_ivect2.py new file mode 100644 index 00000000..6ffd2826 --- /dev/null +++ b/example/tst_ivect2.py @@ -0,0 +1,98 @@ +def f(broken_auto_ptr): + import ivect + import dvect + # + iv = ivect.ivect((1,2,3,4,5)) + dv = iv.as_dvect() + # + adv = ivect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_value_dvect_as_tuple' + print dvect.auto_ptr_value_dvect_as_tuple(adv) + print '2. auto_ptr_value_dvect_as_tuple' + if (not broken_auto_ptr): + print dvect.auto_ptr_value_dvect_as_tuple(adv) + else: + print None + # + aiv = ivect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_value_ivect_as_tuple' + print dvect.auto_ptr_value_ivect_as_tuple(aiv) + print '2. auto_ptr_value_ivect_as_tuple' + if (not broken_auto_ptr): + print dvect.auto_ptr_value_ivect_as_tuple(aiv) + else: + print None + # + sdv = ivect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_value_dvect_as_tuple' + print dvect.shared_ptr_value_dvect_as_tuple(sdv) + print '2. shared_ptr_value_dvect_as_tuple' + print dvect.shared_ptr_value_dvect_as_tuple(sdv) + # + siv = ivect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_value_ivect_as_tuple' + print dvect.shared_ptr_value_ivect_as_tuple(siv) + print '2. shared_ptr_value_ivect_as_tuple' + print dvect.shared_ptr_value_ivect_as_tuple(siv) + # + adv = ivect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_reference_dvect_as_tuple' + print dvect.auto_ptr_reference_dvect_as_tuple(adv) + print '2. auto_ptr_reference_dvect_as_tuple' + print dvect.auto_ptr_reference_dvect_as_tuple(adv) + # + aiv = ivect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_reference_ivect_as_tuple' + print dvect.auto_ptr_reference_ivect_as_tuple(aiv) + print '2. auto_ptr_reference_ivect_as_tuple' + print dvect.auto_ptr_reference_ivect_as_tuple(aiv) + # + sdv = ivect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_reference_dvect_as_tuple' + print dvect.shared_ptr_reference_dvect_as_tuple(sdv) + print '2. shared_ptr_reference_dvect_as_tuple' + print dvect.shared_ptr_reference_dvect_as_tuple(sdv) + # + siv = ivect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_reference_ivect_as_tuple' + print dvect.shared_ptr_reference_ivect_as_tuple(siv) + print '2. shared_ptr_reference_ivect_as_tuple' + print dvect.shared_ptr_reference_ivect_as_tuple(siv) + # + adv = ivect.dvect_as_auto_ptr(dv) + print '1. auto_ptr_const_reference_dvect_as_tuple' + print dvect.auto_ptr_const_reference_dvect_as_tuple(adv) + print '2. auto_ptr_const_reference_dvect_as_tuple' + print dvect.auto_ptr_const_reference_dvect_as_tuple(adv) + # + aiv = ivect.ivect_as_auto_ptr(iv) + print '1. auto_ptr_const_reference_ivect_as_tuple' + print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv) + print '2. auto_ptr_const_reference_ivect_as_tuple' + print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv) + # + sdv = ivect.dvect_as_shared_ptr(dv) + print '1. shared_ptr_const_reference_dvect_as_tuple' + print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv) + print '2. shared_ptr_const_reference_dvect_as_tuple' + print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv) + # + siv = ivect.ivect_as_shared_ptr(iv) + print '1. shared_ptr_const_reference_ivect_as_tuple' + print dvect.shared_ptr_const_reference_ivect_as_tuple(siv) + print '2. shared_ptr_const_reference_ivect_as_tuple' + print dvect.shared_ptr_const_reference_ivect_as_tuple(siv) + +if (__name__ == "__main__"): + import sys, string + broken_auto_ptr = 0 + n = 1 + if (len(sys.argv) > 1): + if (sys.argv[1] == "--broken-auto-ptr"): + broken_auto_ptr = 1 + if (len(sys.argv) > 2): + n = string.atoi(sys.argv[2]) + else: + n = string.atoi(sys.argv[1]) + for i in xrange(n): + f(broken_auto_ptr) diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py new file mode 100644 index 00000000..155910a5 --- /dev/null +++ b/example/tst_noncopyable.py @@ -0,0 +1,16 @@ +def f(): + import noncopyable_export + import noncopyable_import + s1 = noncopyable_export.store(1) + print s1.recall() + s2 = noncopyable_export.store(2) + print s2.recall() + s3 = noncopyable_import.add_stores(s1, s2) + print s3.recall() + +if (__name__ == "__main__"): + import sys, string + n = 1 + if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) + for i in xrange(n): + f() From b5a86a904507dff5777e8aa49b471808a11a5988 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 19:38:20 +0000 Subject: [PATCH 0060/1042] cross_module mods [SVN r9819] --- build/como.mak | 11 +++++++---- build/gcc.mak | 36 +++++++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/build/como.mak b/build/como.mak index 581eefea..8f05e309 100644 --- a/build/como.mak +++ b/build/como.mak @@ -1,10 +1,12 @@ # Revision History: +# 17 Apr 01 include cross-module support, compile getting_started1 (R.W. Grosse-Kunstleve) UNTESTED! # 06 Mar 01 Fixed typo in use of "PYTHON_LIB" (Dave Abrahams) # 04 Mar 01 Changed library name to libboost_python.a (David Abrahams) LIBSRC = \ classes.cpp \ conversions.cpp \ + cross_module.cpp \ extension_class.cpp \ functions.cpp \ init_function.cpp \ @@ -34,11 +36,12 @@ endif | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@ -example1: example1.o libboost_python.a - como-dyn-link -o ../example/hellomodule.$(MODULE_EXTENSION) $(PYTHON_LIB) example1.o -L. -lboost_python - python ../example/test_example1.py +getting_started1: getting_started1.o libboost_python.a + como-dyn-link -o ../example/getting_started1.$(MODULE_EXTENSION) $(PYTHON_LIB) getting_started1.o -L. -lboost_python + ln -s ../test/doctest.py ../example + python ../example/test_getting_started1.py -example1.o: ../example/example1.cpp +getting_started1.o: ../example/getting_started1.cpp como --pic $(INC) -o $*.o -c $< clean: diff --git a/build/gcc.mak b/build/gcc.mak index f71185e0..ce718f2b 100644 --- a/build/gcc.mak +++ b/build/gcc.mak @@ -1,5 +1,7 @@ # Revision History +# 17 Apr 01 include cross-module support, compile getting_started1 (R.W. Grosse-Kunstleve) +# 17 Apr 01 build shared library (patch provided by Dan Nuffer) # 04 Mar 01 Changed library name to libboost_python.a, various cleanups, # attempted Cygwin compatibility. Still needs testing on Linux # (David Abrahams) @@ -8,6 +10,7 @@ LIBSRC = \ classes.cpp \ conversions.cpp \ + cross_module.cpp \ extension_class.cpp \ functions.cpp \ init_function.cpp \ @@ -18,7 +21,7 @@ LIBSRC = \ LIBOBJ = $(LIBSRC:.cpp=.o) OBJ = $(LIBOBJ) -PYTHON_INC=$(ROOT)/usr/local/include/python2.0 +LIBNAME = libboost_python # libpython2.0.dll ifeq "$(OS)" "Windows_NT" @@ -26,13 +29,18 @@ ROOT=c:/cygnus INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -I$(PYTHON_INC) MODULE_EXTENSION=dll PYTHON_LIB=c:/cygnus/usr/local/lib/python2.0/config/libpython2.0.dll.a +SHARED_LIB = $(LIBNAME).dll else -INC = -I$(PYTHON_INC) +PYTHON_INC=$(ROOT)/usr/local/Python-2.0/include/python2.0 +BOOST_INC=../../.. +INC = -I$(BOOST_INC) -I$(PYTHON_INC) MODULE_EXTENSION=so +VERSION=1 +SHARED_LIB = $(LIBNAME).so.$(VERSION) endif %.o: ../src/%.cpp - g++ -fPIC -Wall -W $(INC) -o $*.o -c $< + g++ -fPIC -Wall -W $(INC) $(CXXFLAGS) -o $*.o -c $< %.d: ../src/%.cpp @echo creating $@ @@ -43,7 +51,9 @@ endif PYTHON = python -test: comprehensive.o libboost_python.a +all: test $(SHARED_LIB) getting_started1 + +test: comprehensive.o $(LIBNAME).a $(SHARED_LIB) g++ $(CXXFLAGS) -shared -o ../test/boost_python_test.$(MODULE_EXTENSION) comprehensive.o -L. -lboost_python $(PYTHON_LIB) $(PYTHON) ../test/comprehensive.py @@ -51,20 +61,24 @@ comprehensive.o: ../test/comprehensive.cpp g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $< -example1: example1.o libboost_python.a - g++ $(CXXFLAGS) -shared -o ../example/hellomodule.$(MODULE_EXTENSION) example1.o -L. -lboost_python $(PYTHON_LIB) - $(PYTHON) ../example/test_example1.py +getting_started1: getting_started1.o $(LIBNAME).a + g++ $(CXXFLAGS) -shared -o ../example/getting_started1.$(MODULE_EXTENSION) getting_started1.o -L. -lboost_python $(PYTHON_LIB) + ln -s ../test/doctest.py ../example + $(PYTHON) ../example/test_getting_started1.py -example1.o: ../example/example1.cpp +getting_started1.o: ../example/getting_started1.cpp g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $< clean: rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out -libboost_python.a: $(LIBOBJ) - rm -f libboost_python.a - ar cq libboost_python.a $(LIBOBJ) +$(LIBNAME).a: $(LIBOBJ) + rm -f $@ + ar cqs $@ $(LIBOBJ) + +$(SHARED_LIB): $(LIBOBJ) + g++ $(CXXFLAGS) -shared -o $@ -Wl,--soname=$(LIBNAME).$(MODULE_EXTENSION) DEP = $(OBJ:.o=.d) From 0c954dde270cb59e7a6093aee5ce36eb8fd7de55 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 19:42:35 +0000 Subject: [PATCH 0061/1042] moved from branch ralf_grosse_kunstleve to trunk [SVN r9820] --- build/filemgr.py | 135 ++++++++++++++++++++++++ build/irix_CC.mak | 165 ++++++++++++++++++++++++++++++ build/linux_gcc.mak | 191 +++++++++++++++++----------------- build/mingw32.mak | 242 +++++++++++++++++++++----------------------- build/tru64_cxx.mak | 186 ++++++++++++++++++---------------- build/vc60.mak | 133 ++++++++++++++++++++++++ 6 files changed, 740 insertions(+), 312 deletions(-) create mode 100644 build/filemgr.py create mode 100644 build/irix_CC.mak create mode 100644 build/vc60.mak diff --git a/build/filemgr.py b/build/filemgr.py new file mode 100644 index 00000000..fa674f18 --- /dev/null +++ b/build/filemgr.py @@ -0,0 +1,135 @@ +# Revision history: +# 12 Apr 01 use os.path, shutil +# Initial version: R.W. Grosse-Kunstleve + +bpl_src = "/libs/python/src" +bpl_tst = "/libs/python/test" +bpl_exa = "/libs/python/example" +files = ( +bpl_src + "/classes.cpp", +bpl_src + "/conversions.cpp", +bpl_src + "/extension_class.cpp", +bpl_src + "/functions.cpp", +bpl_src + "/init_function.cpp", +bpl_src + "/module_builder.cpp", +bpl_src + "/objects.cpp", +bpl_src + "/types.cpp", +bpl_src + "/cross_module.cpp", +bpl_tst + "/comprehensive.cpp", +bpl_tst + "/comprehensive.hpp", +bpl_tst + "/comprehensive.py", +bpl_tst + "/doctest.py", +bpl_exa + "/abstract.cpp", +bpl_exa + "/getting_started1.cpp", +bpl_exa + "/getting_started2.cpp", +bpl_exa + "/getting_started3.cpp", +bpl_exa + "/simple_vector.cpp", +bpl_exa + "/do_it_yourself_converters.cpp", +bpl_exa + "/pickle1.cpp", +bpl_exa + "/pickle2.cpp", +bpl_exa + "/pickle3.cpp", +bpl_exa + "/test_abstract.py", +bpl_exa + "/test_getting_started1.py", +bpl_exa + "/test_getting_started2.py", +bpl_exa + "/test_getting_started3.py", +bpl_exa + "/test_simple_vector.py", +bpl_exa + "/test_do_it_yourself_converters.py", +bpl_exa + "/test_pickle1.py", +bpl_exa + "/test_pickle2.py", +bpl_exa + "/test_pickle3.py", +bpl_exa + "/noncopyable.h", +bpl_exa + "/noncopyable_export.cpp", +bpl_exa + "/noncopyable_import.cpp", +bpl_exa + "/dvect.h", +bpl_exa + "/dvect.cpp", +bpl_exa + "/dvect_conversions.cpp", +bpl_exa + "/dvect_defs.cpp", +bpl_exa + "/ivect.h", +bpl_exa + "/ivect.cpp", +bpl_exa + "/ivect_conversions.cpp", +bpl_exa + "/ivect_defs.cpp", +bpl_exa + "/tst_noncopyable.py", +bpl_exa + "/tst_dvect1.py", +bpl_exa + "/tst_dvect2.py", +bpl_exa + "/tst_ivect1.py", +bpl_exa + "/tst_ivect2.py", +bpl_exa + "/test_cross_module.py", +) + +defs = ( +"boost_python_test", +"abstract", +"getting_started1", +"getting_started2", +"getting_started3", +"simple_vector", +"do_it_yourself_converters", +"pickle1", +"pickle2", +"pickle3", +"noncopyable_export", +"noncopyable_import", +"ivect", +"dvect", +) + +if (__name__ == "__main__"): + + import sys, os, shutil + + path = sys.argv[1] + mode = sys.argv[2] + if (not mode in ("softlinks", "unlink", "cp", "rm", "copy", "del")): + raise RuntimeError, \ + "usage: python filemgr.py path " + + if (mode in ("cp", "copy")): + for fn in files: + f = os.path.basename(fn) + print "Copying: " + f + shutil.copy(path + fn, ".") + + elif (mode == "softlinks"): + for fn in files: + f = os.path.basename(fn) + if (os.path.exists(f)): + print "File exists: " + f + else: + print "Linking: " + f + os.symlink(path + fn, f) + + elif (mode in ("rm", "del")): + for fn in files: + f = os.path.basename(fn) + if (os.path.exists(f)): + print "Removing: " + f + try: os.unlink(f) + except: pass + + elif (mode == "unlink"): + for fn in files: + f = os.path.basename(fn) + if (os.path.exists(f)): + if (os.path.islink(f)): + print "Unlinking: " + f + try: os.unlink(f) + except: pass + else: + print "Not a softlink: " + f + + if (mode in ("softlinks", "cp", "copy")): + for d in defs: + fn = d + ".def" + print "Creating: " + fn + f = open(fn, "w") + f.write("EXPORTS\n") + f.write("\tinit" + d + "\n") + f.close() + + if (mode in ("unlink", "rm", "del")): + for d in defs: + fn = d + ".def" + if (os.path.exists(fn)): + print "Removing: " + fn + try: os.unlink(fn) + except: pass diff --git a/build/irix_CC.mak b/build/irix_CC.mak new file mode 100644 index 00000000..88d374d8 --- /dev/null +++ b/build/irix_CC.mak @@ -0,0 +1,165 @@ +# Usage: +# +# Create a new empty directory anywhere (preferably not in the boost tree). +# Copy this Makefile to that new directory and rename it to "Makefile" +# Adjust the pathnames below. +# +# make softlinks Create softlinks to source code and tests +# make Compile all sources +# make test Run doctest tests +# make clean Remove all object files +# make unlink Remove softlinks +# +# Revision history: +# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) +# Initial version: R.W. Grosse-Kunstleve + +ROOT=$(HOME) +BOOST=$(ROOT)/boost + +PYEXE=/usr/local/Python-1.5.2/bin/python +PYINC=-I/usr/local/Python-1.5.2/include/python1.5 +#PYEXE=/usr/local/Python-2.0/bin/python +#PYINC=-I/usr/local/Python-2.0/include/python2.0 +STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers + +STDOPTS= +WARNOPTS=-woff 1001,1234,1682 +OPTOPTS=-g + +CPP=CC -LANG:std -n32 -mips4 +CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ + $(STDOPTS) $(WARNOPTS) $(OPTOPTS) +MAKEDEP=-M + +LD=CC -LANG:std -n32 -mips4 +LDOPTS=-shared + +OBJ=classes.o conversions.o extension_class.o functions.o \ + init_function.o module_builder.o \ + objects.o types.o cross_module.o +DEPOBJ=$(OBJ) \ + comprehensive.o \ + abstract.o \ + getting_started1.o getting_started2.o getting_started3.o \ + simple_vector.o \ + do_it_yourself_converters.o \ + pickle1.o pickle2.o pickle3.o \ + noncopyable_export.o noncopyable_import.o \ + ivect.o dvect.o + +.SUFFIXES: .o .cpp + +all: libboost_python.a \ + boost_python_test.so \ + abstract.so \ + getting_started1.so getting_started2.so getting_started3.so \ + simple_vector.so \ + do_it_yourself_converters.so \ + pickle1.so pickle2.so pickle3.so \ + noncopyable_export.so noncopyable_import.so \ + ivect.so dvect.so + +libboost_python.a: $(OBJ) + rm -f libboost_python.a + $(CPP) -ar -o libboost_python.a $(OBJ) + +boost_python_test.so: $(OBJ) comprehensive.o + $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm + +abstract.so: $(OBJ) abstract.o + $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so + +getting_started1.so: $(OBJ) getting_started1.o + $(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so + +getting_started2.so: $(OBJ) getting_started2.o + $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so + +getting_started3.so: $(OBJ) getting_started3.o + $(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so + +simple_vector.so: $(OBJ) simple_vector.o + $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so + +do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o + $(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so + +pickle1.so: $(OBJ) pickle1.o + $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so + +pickle2.so: $(OBJ) pickle2.o + $(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so + +pickle3.so: $(OBJ) pickle3.o + $(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so + +noncopyable_export.so: $(OBJ) noncopyable_export.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ + noncopyable_export.o -o noncopyable_export.so + +noncopyable_import.so: $(OBJ) noncopyable_import.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ + noncopyable_import.o -o noncopyable_import.so + +ivect.so: $(OBJ) ivect.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so + +dvect.so: $(OBJ) dvect.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so + +.cpp.o: + $(CPP) $(CPPOPTS) -c $*.cpp + +test: + $(PYEXE) comprehensive.py + $(PYEXE) test_abstract.py + $(PYEXE) test_getting_started1.py + $(PYEXE) test_getting_started2.py + $(PYEXE) test_getting_started3.py + $(PYEXE) test_simple_vector.py + $(PYEXE) test_do_it_yourself_converters.py + $(PYEXE) test_pickle1.py + $(PYEXE) test_pickle2.py + $(PYEXE) test_pickle3.py + $(PYEXE) test_cross_module.py + +clean: + rm -f $(OBJ) libboost_python.a libboost_python.a.input + rm -f comprehensive.o boost_python_test.so + rm -f abstract.o abstract.so + rm -f getting_started1.o getting_started1.so + rm -f getting_started2.o getting_started2.so + rm -f getting_started3.o getting_started3.so + rm -f simple_vector.o simple_vector.so + rm -f do_it_yourself_converters.o do_it_yourself_converters.so + rm -f pickle1.o pickle1.so + rm -f pickle2.o pickle2.so + rm -f pickle3.o pickle3.so + rm -f noncopyable_export.o noncopyable_export.so + rm -f noncopyable_import.o noncopyable_import.so + rm -f ivect.o ivect.so + rm -f dvect.o dvect.so + rm -f so_locations *.pyc + rm -rf ii_files + +softlinks: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks + +unlink: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink + +cp: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp + +rm: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm + +depend: + @ cat Makefile.nodepend; \ + for obj in $(DEPOBJ); \ + do \ + bn=`echo "$$obj" | cut -d. -f1`; \ + $(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \ + done + diff --git a/build/linux_gcc.mak b/build/linux_gcc.mak index a07bb5da..9be8f1cb 100644 --- a/build/linux_gcc.mak +++ b/build/linux_gcc.mak @@ -2,110 +2,64 @@ # # Create a new empty directory anywhere (preferably not in the boost tree). # Copy this Makefile to that new directory and rename it to "Makefile" -# Set the BOOST pathname below. +# Adjust the pathnames below. # # make softlinks Create softlinks to source code and tests # make Compile all sources # make test Run doctest tests # make clean Remove all object files # make unlink Remove softlinks +# +# Revision history: +# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) +# Initial version: R.W. Grosse-Kunstleve -BOOST= /net/cci/rwgk/boost +ROOT=$(HOME) +BOOST=$(ROOT)/boost -PYEXE= /usr/local/Python-1.5.2/bin/python -PYINC= -I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE= /usr/local/Python-2.0/bin/python -#PYINC= -I/usr/local/Python-2.0/include/python2.0 -#STLPORTINC= -I/usr/local/STLport-4.1b3/stlport -#STLPORTOPTS= \ -# -D__USE_STD_IOSTREAM \ -# -D__STL_NO_SGI_IOSTREAMS \ -# -D__STL_USE_NATIVE_STRING \ -# -D__STL_NO_NEW_C_HEADERS \ -# -D_RWSTD_COMPILE_INSTANTIATE=1 -#STLPORTINC= -I/usr/local/STLport-4.1b4/stlport -#STLPORTOPTS= -D__NO_USE_STD_IOSTREAM -D__STL_NO_SGI_IOSTREAMS -#STLPORTINC= -I/net/cci/xp/C++_C_headers +PYEXE=/usr/bin/python +PYINC=-I/usr/include/python1.5 +#PYEXE=/usr/local/Python-1.5.2/bin/python +#PYINC=-I/usr/local/Python-1.5.2/include/python1.5 +#PYEXE=/usr/local/Python-2.0/bin/python +#PYINC=-I/usr/local/Python-2.0/include/python2.0 -STDOPTS= -ftemplate-depth-21 +STDOPTS=-ftemplate-depth-21 WARNOPTS= -# use -msg_display_number to obtain integer tags for -msg_disable +OPTOPTS=-g -CPP= g++ -CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) -g -MAKEDEP= -M +CPP=g++ +CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ + $(STDOPTS) $(WARNOPTS) $(OPTOPTS) +MAKEDEP=-M -LD= g++ -LDOPTS= -shared +LD=g++ +LDOPTS=-shared -#HIDDEN= -hidden - -BPL_SRC = $(BOOST)/libs/python/src -BPL_TST = $(BOOST)/libs/python/test -BPL_EXA = $(BOOST)/libs/python/example -SOFTLINKS = \ -$(BPL_SRC)/classes.cpp \ -$(BPL_SRC)/conversions.cpp \ -$(BPL_SRC)/extension_class.cpp \ -$(BPL_SRC)/functions.cpp \ -$(BPL_SRC)/init_function.cpp \ -$(BPL_SRC)/module_builder.cpp \ -$(BPL_SRC)/objects.cpp \ -$(BPL_SRC)/types.cpp \ -$(BPL_TST)/comprehensive.cpp \ -$(BPL_TST)/comprehensive.hpp \ -$(BPL_TST)/comprehensive.py \ -$(BPL_TST)/doctest.py \ -$(BPL_EXA)/abstract.cpp \ -$(BPL_EXA)/getting_started1.cpp \ -$(BPL_EXA)/getting_started2.cpp \ -$(BPL_EXA)/getting_started3.cpp \ -$(BPL_EXA)/getting_started4.cpp \ -$(BPL_EXA)/getting_started5.cpp \ -$(BPL_EXA)/test_abstract.py \ -$(BPL_EXA)/test_getting_started1.py \ -$(BPL_EXA)/test_getting_started2.py \ -$(BPL_EXA)/test_getting_started3.py \ -$(BPL_EXA)/test_getting_started4.py \ -$(BPL_EXA)/test_getting_started5.py - -OBJ = classes.o conversions.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o -DEPOBJ= $(OBJ) comprehensive.o abstract.o \ - getting_started1.o getting_started2.o getting_started3.o \ - getting_started4.o getting_started5.o +OBJ=classes.o conversions.o extension_class.o functions.o \ + init_function.o module_builder.o \ + objects.o types.o cross_module.o +DEPOBJ=$(OBJ) \ + comprehensive.o \ + abstract.o \ + getting_started1.o getting_started2.o getting_started3.o \ + simple_vector.o \ + do_it_yourself_converters.o \ + pickle1.o pickle2.o pickle3.o \ + noncopyable_export.o noncopyable_import.o \ + ivect.o dvect.o .SUFFIXES: .o .cpp -all: libboost_python.a boost_python_test.so abstract.so \ +all: libboost_python.a \ + boost_python_test.so \ + abstract.so \ getting_started1.so getting_started2.so getting_started3.so \ - getting_started4.so getting_started5.so - -softlinks: - @ for pn in $(SOFTLINKS); \ - do \ - bn=`basename "$$pn"`; \ - if [ ! -e "$$bn" ]; then \ - echo "ln -s $$pn ."; \ - ln -s "$$pn" .; \ - else \ - echo "info: no softlink created (file exists): $$bn"; \ - fi; \ - done - -unlink: - @ for pn in $(SOFTLINKS); \ - do \ - bn=`basename "$$pn"`; \ - if [ -L "$$bn" ]; then \ - echo "rm $$bn"; \ - rm "$$bn"; \ - elif [ -e "$$bn" ]; then \ - echo "info: not a softlink: $$bn"; \ - fi; \ - done + simple_vector.so \ + do_it_yourself_converters.so \ + pickle1.so pickle2.so pickle3.so \ + noncopyable_export.so noncopyable_import.so \ + ivect.so dvect.so libboost_python.a: $(OBJ) rm -f libboost_python.a @@ -126,11 +80,34 @@ getting_started2.so: $(OBJ) getting_started2.o getting_started3.so: $(OBJ) getting_started3.o $(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so -getting_started4.so: $(OBJ) getting_started4.o - $(LD) $(LDOPTS) $(OBJ) getting_started4.o -o getting_started4.so +simple_vector.so: $(OBJ) simple_vector.o + $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so -getting_started5.so: $(OBJ) getting_started5.o - $(LD) $(LDOPTS) $(OBJ) getting_started5.o -o getting_started5.so +do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o + $(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so + +pickle1.so: $(OBJ) pickle1.o + $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so + +pickle2.so: $(OBJ) pickle2.o + $(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so + +pickle3.so: $(OBJ) pickle3.o + $(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so + +noncopyable_export.so: $(OBJ) noncopyable_export.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ + noncopyable_export.o -o noncopyable_export.so + +noncopyable_import.so: $(OBJ) noncopyable_import.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ + noncopyable_import.o -o noncopyable_import.so + +ivect.so: $(OBJ) ivect.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so + +dvect.so: $(OBJ) dvect.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so .cpp.o: $(CPP) $(CPPOPTS) -c $*.cpp @@ -141,8 +118,12 @@ test: $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py $(PYEXE) test_getting_started3.py - $(PYEXE) test_getting_started4.py - $(PYEXE) test_getting_started5.py + $(PYEXE) test_simple_vector.py + $(PYEXE) test_do_it_yourself_converters.py + $(PYEXE) test_pickle1.py + $(PYEXE) test_pickle2.py + $(PYEXE) test_pickle3.py + $(PYEXE) test_cross_module.py clean: rm -f $(OBJ) libboost_python.a libboost_python.a.input @@ -151,10 +132,28 @@ clean: rm -f getting_started1.o getting_started1.so rm -f getting_started2.o getting_started2.so rm -f getting_started3.o getting_started3.so - rm -f getting_started4.o getting_started4.so - rm -f getting_started5.o getting_started5.so + rm -f simple_vector.o simple_vector.so + rm -f do_it_yourself_converters.o do_it_yourself_converters.so + rm -f pickle1.o pickle1.so + rm -f pickle2.o pickle2.so + rm -f pickle3.o pickle3.so + rm -f noncopyable_export.o noncopyable_export.so + rm -f noncopyable_import.o noncopyable_import.so + rm -f ivect.o ivect.so + rm -f dvect.o dvect.so rm -f so_locations *.pyc - rm -rf cxx_repository + +softlinks: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks + +unlink: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink + +cp: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp + +rm: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm depend: @ cat Makefile.nodepend; \ diff --git a/build/mingw32.mak b/build/mingw32.mak index 014af132..98a26735 100644 --- a/build/mingw32.mak +++ b/build/mingw32.mak @@ -1,18 +1,14 @@ # Usage: # -# Create a new empty directory anywhere (preferably not in the boost tree). -# Copy this Makefile to that new directory and rename it to "Makefile" -# Set the BOOST_* pathnames below. +# make copy Copy the sources and tests +# make Compile all sources +# make test Run doctest tests +# make clean Remove all object files +# make del Remove the sources and tests # -# The idea is that the build directory is on a Unix filesystem that -# is mounted on a PC using SAMBA. Use this makefile under both Unix -# and Windows: -# -# Unix: make softlinks Create softlinks to source code and tests -# Win: make Compile all sources -# Win: make test Run doctest tests -# Unix: make clean Remove all object files -# Unix: make unlink Remove softlinks +# Revision history: +# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) +# Initial version: R.W. Grosse-Kunstleve # To install mingw32, follow instructions at: # http://starship.python.net/crew/kernr/mingw32/Notes.html @@ -31,117 +27,49 @@ # Could this be fixed with compiler options? # -fhuge-objects looks interesting, but requires recompiling the C++ library. # (what exactly does that mean?) -# -fvtable-thunks eliminates the compiler warning, -# but "import boost_python_test" still causes a crash. +# -fvtable-thunks eliminates the compiler warning, but +# "import boost_python_test" still causes a crash. -BOOST_UNIX= /net/cci/rwgk/boost -BOOST_WIN= "L:\boost" +ROOT=L: +BOOST_WIN="$(ROOT)\boost" +BOOST_UNIX=$(HOME)/boost -PYEXE= "C:\Program files\Python\python.exe" -PYINC= -I"C:\usr\include\python1.5" -PYLIB= "C:\usr\lib\libpython15.a" +PYEXE="C:\Program files\Python\python.exe" +PYINC=-I"C:\usr\include\python1.5" +PYLIB="C:\usr\lib\libpython15.a" -STDOPTS= -ftemplate-depth-21 +STDOPTS=-ftemplate-depth-21 WARNOPTS= +OPTOPTS=-g -CPP= g++ -CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) -g +CPP=g++ +CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \ + $(STDOPTS) $(WARNOPTS) $(OPTOPTS) -LD= g++ -LDOPTS= -shared +LD=g++ +LDOPTS=-shared -BPL_SRC = $(BOOST_UNIX)/libs/python/src -BPL_TST = $(BOOST_UNIX)/libs/python/test -BPL_EXA = $(BOOST_UNIX)/libs/python/example -SOFTLINKS = \ -$(BPL_SRC)/classes.cpp \ -$(BPL_SRC)/conversions.cpp \ -$(BPL_SRC)/extension_class.cpp \ -$(BPL_SRC)/functions.cpp \ -$(BPL_SRC)/init_function.cpp \ -$(BPL_SRC)/module_builder.cpp \ -$(BPL_SRC)/objects.cpp \ -$(BPL_SRC)/types.cpp \ -$(BPL_TST)/comprehensive.cpp \ -$(BPL_TST)/comprehensive.hpp \ -$(BPL_TST)/comprehensive.py \ -$(BPL_TST)/doctest.py \ -$(BPL_EXA)/abstract.cpp \ -$(BPL_EXA)/getting_started1.cpp \ -$(BPL_EXA)/getting_started2.cpp \ -$(BPL_EXA)/getting_started3.cpp \ -$(BPL_EXA)/getting_started4.cpp \ -$(BPL_EXA)/getting_started5.cpp \ -$(BPL_EXA)/passing_char.cpp \ -$(BPL_EXA)/test_abstract.py \ -$(BPL_EXA)/test_getting_started1.py \ -$(BPL_EXA)/test_getting_started2.py \ -$(BPL_EXA)/test_getting_started3.py \ -$(BPL_EXA)/test_getting_started4.py \ -$(BPL_EXA)/test_getting_started5.py - -DEFS= \ -boost_python_test \ -abstract \ -getting_started1 \ -getting_started2 \ -getting_started3 \ -getting_started4 \ -getting_started5 - -OBJ = classes.o conversions.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o +OBJ=classes.o conversions.o extension_class.o functions.o \ + init_function.o module_builder.o \ + objects.o types.o cross_module.o .SUFFIXES: .o .cpp -all: libboost_python.a boost_python_test.pyd abstract.pyd \ +all: libboost_python.a \ + abstract.pyd \ getting_started1.pyd getting_started2.pyd getting_started3.pyd \ - getting_started4.pyd getting_started5.pyd - -softlinks: defs - @ for pn in $(SOFTLINKS); \ - do \ - bn=`basename "$$pn"`; \ - if [ ! -e "$$bn" ]; then \ - echo "ln -s $$pn ."; \ - ln -s "$$pn" .; \ - else \ - echo "info: no softlink created (file exists): $$bn"; \ - fi; \ - done - -unlink: rmdefs - @ for pn in $(SOFTLINKS); \ - do \ - bn=`basename "$$pn"`; \ - if [ -L "$$bn" ]; then \ - echo "rm $$bn"; \ - rm "$$bn"; \ - elif [ -e "$$bn" ]; then \ - echo "info: not a softlink: $$bn"; \ - fi; \ - done - -defs: - @ for def in $(DEFS); \ - do \ - echo "EXPORTS\n\tinit$$def" > $$def.def; \ - done - -rmdefs: - @ for def in $(DEFS); \ - do \ - rm $$def.def; \ - done + simple_vector.pyd \ + do_it_yourself_converters.pyd \ + pickle1.pyd pickle2.pyd pickle3.pyd \ + noncopyable_export.pyd noncopyable_import.pyd \ + ivect.pyd dvect.pyd libboost_python.a: $(OBJ) del libboost_python.a ar r libboost_python.a $(OBJ) -DLLWRAPOPTS= -s --driver-name g++ -s - --entry _DllMainCRTStartup@12 --target=i386-mingw32 +DLLWRAPOPTS=-s --driver-name g++ -s \ + --entry _DllMainCRTStartup@12 --target=i386-mingw32 boost_python_test.pyd: $(OBJ) comprehensive.o dllwrap $(DLLWRAPOPTS) \ @@ -173,38 +101,96 @@ getting_started3.pyd: $(OBJ) getting_started3.o --def getting_started3.def \ $(OBJ) getting_started3.o $(PYLIB) -getting_started4.pyd: $(OBJ) getting_started4.o +simple_vector.pyd: $(OBJ) simple_vector.o dllwrap $(DLLWRAPOPTS) \ - --dllname getting_started4.pyd \ - --def getting_started4.def \ - $(OBJ) getting_started4.o $(PYLIB) + --dllname simple_vector.pyd \ + --def simple_vector.def \ + $(OBJ) simple_vector.o $(PYLIB) -getting_started5.pyd: $(OBJ) getting_started5.o +do_it_yourself_converters.pyd: $(OBJ) do_it_yourself_converters.o dllwrap $(DLLWRAPOPTS) \ - --dllname getting_started5.pyd \ - --def getting_started5.def \ - $(OBJ) getting_started5.o $(PYLIB) + --dllname do_it_yourself_converters.pyd \ + --def do_it_yourself_converters.def \ + $(OBJ) do_it_yourself_converters.o $(PYLIB) + +pickle1.pyd: $(OBJ) pickle1.o + dllwrap $(DLLWRAPOPTS) \ + --dllname pickle1.pyd \ + --def pickle1.def \ + $(OBJ) pickle1.o $(PYLIB) + +pickle2.pyd: $(OBJ) pickle2.o + dllwrap $(DLLWRAPOPTS) \ + --dllname pickle2.pyd \ + --def pickle2.def \ + $(OBJ) pickle2.o $(PYLIB) + +pickle3.pyd: $(OBJ) pickle3.o + dllwrap $(DLLWRAPOPTS) \ + --dllname pickle3.pyd \ + --def pickle3.def \ + $(OBJ) pickle3.o $(PYLIB) + +noncopyable_export.pyd: $(OBJ) noncopyable_export.o + dllwrap $(DLLWRAPOPTS) \ + --dllname noncopyable_export.pyd \ + --def noncopyable_export.def \ + $(OBJ) noncopyable_export.o $(PYLIB) + +noncopyable_import.pyd: $(OBJ) noncopyable_import.o + dllwrap $(DLLWRAPOPTS) \ + --dllname noncopyable_import.pyd \ + --def noncopyable_import.def \ + $(OBJ) noncopyable_import.o $(PYLIB) + +ivect.pyd: $(OBJ) ivect.o + dllwrap $(DLLWRAPOPTS) \ + --dllname ivect.pyd \ + --def ivect.def \ + $(OBJ) ivect.o $(PYLIB) + +dvect.pyd: $(OBJ) dvect.o + dllwrap $(DLLWRAPOPTS) \ + --dllname dvect.pyd \ + --def dvect.def \ + $(OBJ) dvect.o $(PYLIB) .cpp.o: $(CPP) $(CPPOPTS) -c $*.cpp test: - $(PYEXE) comprehensive.py +# $(PYEXE) comprehensive.py $(PYEXE) test_abstract.py $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py $(PYEXE) test_getting_started3.py - $(PYEXE) test_getting_started4.py - $(PYEXE) test_getting_started5.py + $(PYEXE) test_simple_vector.py + $(PYEXE) test_do_it_yourself_converters.py + $(PYEXE) test_pickle1.py + $(PYEXE) test_pickle2.py + $(PYEXE) test_pickle3.py + $(PYEXE) test_cross_module.py clean: - rm -f $(OBJ) libboost_python.a libboost_python.a.input - rm -f comprehensive.o boost_python_test.pyd - rm -f abstract.o abstract.pyd - rm -f getting_started1.o getting_started1.pyd - rm -f getting_started2.o getting_started2.pyd - rm -f getting_started3.o getting_started3.pyd - rm -f getting_started4.o getting_started4.pyd - rm -f getting_started5.o getting_started5.pyd - rm -f so_locations *.pyc - rm -rf cxx_repository + del *.o + del *.a + del *.pyd + del *.pyc + +softlinks: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks + +unlink: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink + +cp: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp + +rm: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm + +copy: + $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy + +del: + $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del diff --git a/build/tru64_cxx.mak b/build/tru64_cxx.mak index 3fd584b7..41f7a554 100644 --- a/build/tru64_cxx.mak +++ b/build/tru64_cxx.mak @@ -2,110 +2,74 @@ # # Create a new empty directory anywhere (preferably not in the boost tree). # Copy this Makefile to that new directory and rename it to "Makefile" -# Set the BOOST pathname below. +# Adjust the pathnames below. # # make softlinks Create softlinks to source code and tests # make Compile all sources # make test Run doctest tests # make clean Remove all object files # make unlink Remove softlinks +# +# Revision history: +# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) +# Initial version: R.W. Grosse-Kunstleve -BOOST= /net/cci/rwgk/boost +ROOT=$(HOME) +BOOST=$(ROOT)/boost -PYEXE= /usr/local/Python-1.5.2/bin/python -PYINC= -I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE= /usr/local/Python-2.0/bin/python -#PYINC= -I/usr/local/Python-2.0/include/python2.0 -#STLPORTINC= -I/usr/local/STLport-4.1b3/stlport +PYEXE=/usr/local/Python-1.5.2/bin/python +PYINC=-I/usr/local/Python-1.5.2/include/python1.5 +#PYEXE=/usr/local/Python-2.0/bin/python +#PYINC=-I/usr/local/Python-2.0/include/python2.0 +#STLPORTINC=-I/usr/local/STLport-4.1b3/stlport +#STLPORTINC=-I/usr/local/STLport-4.1b4/stlport #STLPORTOPTS= \ # -D__USE_STD_IOSTREAM \ # -D__STL_NO_SGI_IOSTREAMS \ # -D__STL_USE_NATIVE_STRING \ # -D__STL_NO_NEW_C_HEADERS \ # -D_RWSTD_COMPILE_INSTANTIATE=1 -#STLPORTINC= -I/usr/local/STLport-4.1b4/stlport -#STLPORTOPTS= -D__NO_USE_STD_IOSTREAM -D__STL_NO_SGI_IOSTREAMS -STLPORTINC= -I/net/cci/xp/C++_C_headers +STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers -STDOPTS= -std strict_ansi -WARNOPTS= -msg_disable 186,450,1115 +STDOPTS=-std strict_ansi # use -msg_display_number to obtain integer tags for -msg_disable +WARNOPTS=-msg_disable 186,450,1115 +OPTOPTS=-g -CPP= cxx -CPPOPTS= $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) -g -MAKEDEP= -Em +CPP=cxx +CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ + $(STDOPTS) $(WARNOPTS) $(OPTOPTS) +MAKEDEP=-Em -LD= cxx -LDOPTS= -shared -expect_unresolved 'Py*' -expect_unresolved '_Py*' +LD=cxx +LDOPTS=-shared -expect_unresolved 'Py*' -expect_unresolved '_Py*' -#HIDDEN= -hidden +#HIDDEN=-hidden -BPL_SRC = $(BOOST)/libs/python/src -BPL_TST = $(BOOST)/libs/python/test -BPL_EXA = $(BOOST)/libs/python/example -SOFTLINKS = \ -$(BPL_SRC)/classes.cpp \ -$(BPL_SRC)/conversions.cpp \ -$(BPL_SRC)/extension_class.cpp \ -$(BPL_SRC)/functions.cpp \ -$(BPL_SRC)/init_function.cpp \ -$(BPL_SRC)/module_builder.cpp \ -$(BPL_SRC)/objects.cpp \ -$(BPL_SRC)/types.cpp \ -$(BPL_TST)/comprehensive.cpp \ -$(BPL_TST)/comprehensive.hpp \ -$(BPL_TST)/comprehensive.py \ -$(BPL_TST)/doctest.py \ -$(BPL_EXA)/abstract.cpp \ -$(BPL_EXA)/getting_started1.cpp \ -$(BPL_EXA)/getting_started2.cpp \ -$(BPL_EXA)/getting_started3.cpp \ -$(BPL_EXA)/getting_started4.cpp \ -$(BPL_EXA)/getting_started5.cpp \ -$(BPL_EXA)/test_abstract.py \ -$(BPL_EXA)/test_getting_started1.py \ -$(BPL_EXA)/test_getting_started2.py \ -$(BPL_EXA)/test_getting_started3.py \ -$(BPL_EXA)/test_getting_started4.py \ -$(BPL_EXA)/test_getting_started5.py - -OBJ = classes.o conversions.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o -DEPOBJ= $(OBJ) comprehensive.o abstract.o \ - getting_started1.o getting_started2.o getting_started3.o \ - getting_started4.o getting_started5.o +OBJ=classes.o conversions.o extension_class.o functions.o \ + init_function.o module_builder.o \ + objects.o types.o cross_module.o +DEPOBJ=$(OBJ) \ + comprehensive.o \ + abstract.o \ + getting_started1.o getting_started2.o getting_started3.o \ + simple_vector.o \ + do_it_yourself_converters.o \ + pickle1.o pickle2.o pickle3.o \ + noncopyable_export.o noncopyable_import.o \ + ivect.o dvect.o .SUFFIXES: .o .cpp -all: libboost_python.a boost_python_test.so abstract.so \ +all: libboost_python.a \ + boost_python_test.so \ + abstract.so \ getting_started1.so getting_started2.so getting_started3.so \ - getting_started4.so getting_started5.so - -softlinks: - @ for pn in $(SOFTLINKS); \ - do \ - bn=`basename "$$pn"`; \ - if [ ! -e "$$bn" ]; then \ - echo "ln -s $$pn ."; \ - ln -s "$$pn" .; \ - else \ - echo "info: no softlink created (file exists): $$bn"; \ - fi; \ - done - -unlink: - @ for pn in $(SOFTLINKS); \ - do \ - bn=`basename "$$pn"`; \ - if [ -L "$$bn" ]; then \ - echo "rm $$bn"; \ - rm "$$bn"; \ - elif [ -e "$$bn" ]; then \ - echo "info: not a softlink: $$bn"; \ - fi; \ - done + simple_vector.so \ + do_it_yourself_converters.so \ + pickle1.so pickle2.so pickle3.so \ + noncopyable_export.so noncopyable_import.so \ + ivect.so dvect.so libboost_python.a: $(OBJ) rm -f libboost_python.a @@ -130,11 +94,34 @@ getting_started2.so: $(OBJ) getting_started2.o getting_started3.so: $(OBJ) getting_started3.o $(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so -getting_started4.so: $(OBJ) getting_started4.o - $(LD) $(LDOPTS) $(OBJ) getting_started4.o -o getting_started4.so +simple_vector.so: $(OBJ) simple_vector.o + $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so -getting_started5.so: $(OBJ) getting_started5.o - $(LD) $(LDOPTS) $(OBJ) getting_started5.o -o getting_started5.so +do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o + $(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so + +pickle1.so: $(OBJ) pickle1.o + $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so + +pickle2.so: $(OBJ) pickle2.o + $(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so + +pickle3.so: $(OBJ) pickle3.o + $(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so + +noncopyable_export.so: $(OBJ) noncopyable_export.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ + noncopyable_export.o -o noncopyable_export.so + +noncopyable_import.so: $(OBJ) noncopyable_import.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ + noncopyable_import.o -o noncopyable_import.so + +ivect.so: $(OBJ) ivect.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so + +dvect.so: $(OBJ) dvect.o + $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so .cpp.o: $(CPP) $(CPPOPTS) -c $*.cpp @@ -145,8 +132,12 @@ test: $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py $(PYEXE) test_getting_started3.py - $(PYEXE) test_getting_started4.py - $(PYEXE) test_getting_started5.py + $(PYEXE) test_simple_vector.py + $(PYEXE) test_do_it_yourself_converters.py + $(PYEXE) test_pickle1.py + $(PYEXE) test_pickle2.py + $(PYEXE) test_pickle3.py + $(PYEXE) test_cross_module.py clean: rm -f $(OBJ) libboost_python.a libboost_python.a.input @@ -155,11 +146,30 @@ clean: rm -f getting_started1.o getting_started1.so rm -f getting_started2.o getting_started2.so rm -f getting_started3.o getting_started3.so - rm -f getting_started4.o getting_started4.so - rm -f getting_started5.o getting_started5.so + rm -f simple_vector.o simple_vector.so + rm -f do_it_yourself_converters.o do_it_yourself_converters.so + rm -f pickle1.o pickle1.so + rm -f pickle2.o pickle2.so + rm -f pickle3.o pickle3.so + rm -f noncopyable_export.o noncopyable_export.so + rm -f noncopyable_import.o noncopyable_import.so + rm -f ivect.o ivect.so + rm -f dvect.o dvect.so rm -f so_locations *.pyc rm -rf cxx_repository +softlinks: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks + +unlink: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink + +cp: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp + +rm: + $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm + depend: @ cat Makefile.nodepend; \ for obj in $(DEPOBJ); \ diff --git a/build/vc60.mak b/build/vc60.mak new file mode 100644 index 00000000..64e0b9df --- /dev/null +++ b/build/vc60.mak @@ -0,0 +1,133 @@ +# Usage: +# +# make copy Copy the sources and tests +# make Compile all sources +# make test Run doctest tests +# make clean Remove all object files +# make del Remove the sources and tests +# +# Revision history: +# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) +# Initial version: R.W. Grosse-Kunstleve + +ROOT=L: +BOOST_WIN="$(ROOT)\boost" +BOOST_UNIX=$(HOME)/boost + +PYEXE="C:\Program files\Python\python.exe" +PYINC=/I"C:\Program files\Python\include" +PYLIB="C:\Program files\Python\libs\python15.lib" + +STDOPTS=/nologo /MD /GR /GX /Zm200 +WARNOPTS= +OPTOPTS= + +CPP=cl.exe +CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) /I$(BOOST_WIN) $(PYINC) \ + $(STDOPTS) $(WARNOPTS) $(OPTOPTS) + +LD=link.exe +LDOPTS=/nologo /dll /incremental:no + +OBJ=classes.obj conversions.obj extension_class.obj functions.obj \ + init_function.obj module_builder.obj \ + objects.obj types.obj cross_module.obj + +.SUFFIXES: .obj .cpp + +all: boost_python.lib \ + boost_python_test.pyd \ + abstract.pyd \ + getting_started1.pyd getting_started2.pyd getting_started3.pyd \ + simple_vector.pyd \ + do_it_yourself_converters.pyd \ + pickle1.pyd pickle2.pyd pickle3.pyd \ + noncopyable_export.pyd noncopyable_import.pyd \ + ivect.pyd dvect.pyd + +boost_python.lib: $(OBJ) + $(LD) -lib /nologo /out:boost_python.lib $(OBJ) + +boost_python_test.pyd: $(OBJ) comprehensive.obj + $(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) /export:initboost_python_test /out:"boost_python_test.pyd" + +abstract.pyd: $(OBJ) abstract.obj + $(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) /export:initabstract /out:"abstract.pyd" + +getting_started1.pyd: $(OBJ) getting_started1.obj + $(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) /export:initgetting_started1 /out:"getting_started1.pyd" + +getting_started2.pyd: $(OBJ) getting_started2.obj + $(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) /export:initgetting_started2 /out:"getting_started2.pyd" + +getting_started3.pyd: $(OBJ) getting_started3.obj + $(LD) $(LDOPTS) $(OBJ) getting_started3.obj $(PYLIB) /export:initgetting_started3 /out:"getting_started3.pyd" + +simple_vector.pyd: $(OBJ) simple_vector.obj + $(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) /export:initsimple_vector /out:"simple_vector.pyd" + +do_it_yourself_converters.pyd: $(OBJ) do_it_yourself_converters.obj + $(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.obj $(PYLIB) /export:initdo_it_yourself_converters /out:"do_it_yourself_converters.pyd" + +pickle1.pyd: $(OBJ) pickle1.obj + $(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) /export:initpickle1 /out:"pickle1.pyd" + +pickle2.pyd: $(OBJ) pickle2.obj + $(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) /export:initpickle2 /out:"pickle2.pyd" + +pickle3.pyd: $(OBJ) pickle3.obj + $(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) /export:initpickle3 /out:"pickle3.pyd" + +noncopyable_export.pyd: $(OBJ) noncopyable_export.obj + $(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) /export:initnoncopyable_export /out:"noncopyable_export.pyd" + +noncopyable_import.pyd: $(OBJ) noncopyable_import.obj + $(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) /export:initnoncopyable_import /out:"noncopyable_import.pyd" + +ivect.pyd: $(OBJ) ivect.obj + $(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) /export:initivect /out:"ivect.pyd" + +dvect.pyd: $(OBJ) dvect.obj + $(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) /export:initdvect /out:"dvect.pyd" + +.cpp.obj: + $(CPP) $(CPPOPTS) /c $*.cpp + +test: + $(PYEXE) comprehensive.py --broken-auto-ptr + $(PYEXE) test_abstract.py + $(PYEXE) test_getting_started1.py + $(PYEXE) test_getting_started2.py + $(PYEXE) test_getting_started3.py + $(PYEXE) test_simple_vector.py + $(PYEXE) test_do_it_yourself_converters.py + $(PYEXE) test_pickle1.py + $(PYEXE) test_pickle2.py + $(PYEXE) test_pickle3.py + $(PYEXE) test_cross_module.py --broken-auto-ptr + +clean: + del *.obj + del *.lib + del *.exp + del *.idb + del *.pyd + del *.pyc + +softlinks: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks + +unlink: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink + +cp: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp + +rm: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm + +copy: + $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy + +del: + $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del From fde432601aae5fc1ca29e1ba10b763622af6ab76 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 19:46:15 +0000 Subject: [PATCH 0062/1042] workaround for irix_CC problem. [SVN r9821] --- test/comprehensive.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 7699b01f..aa2d9886 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -15,6 +15,10 @@ #include // for pow() #include +#if defined(sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 +inline double pow(int x, int y) { return pow(static_cast(x), y); } +#endif + namespace bpl_test { FooCallback::FooCallback(PyObject* self, int x) From fa7b6591cf72da6d1d14d90dcb4b702cf9d325af Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 19:49:42 +0000 Subject: [PATCH 0063/1042] moved from branch ralf_grosse_kunstleve to trunk (was cross_module_dependencies.html) [SVN r9822] --- doc/cross_module.html | 336 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 doc/cross_module.html diff --git a/doc/cross_module.html b/doc/cross_module.html new file mode 100644 index 00000000..08c39bfe --- /dev/null +++ b/doc/cross_module.html @@ -0,0 +1,336 @@ + + +Cross-extension-module dependencies + +
      + +c++boost.gif (8819 bytes) + +
      +

      Cross-extension-module dependencies

      + +It is good programming practice to organize large projects as modules +that interact with each other via well defined interfaces. With +Boost.Python it is possible to reflect this organization at the C++ +level at the Python level. This is, each logical C++ module can be +organized as a separate Python extension module. + +

      +At first sight this might seem natural and straightforward. However, it +is a fairly complex problem to establish cross-extension-module +dependencies while maintaining the same ease of use Boost.Python +provides for classes that are wrapped in the same extension module. To +a large extent this complexity can be hidden from the author of a +Boost.Python extension module, but not entirely. + +


      +

      The recipe

      + +Suppose there is an extension module that exposes certain instances of +the C++ std::vector template library such that it can be used +from Python in the following manner: + +
      +import std_vector
      +v = std_vector.double([1, 2, 3, 4])
      +v.push_back(5)
      +v.size()
      +
      + +Suppose the std_vector module is done well and reflects all +C++ functions that are useful at the Python level, for all C++ built-in +data types (std_vector.int, std_vector.long, etc.). + +

      +Suppose further that there is statistic module with a C++ class that +has constructors or member functions that use or return a +std::vector. For example: + +

      +class xy {
      +  public:
      +    xy(const std::vector<double>& x, const std::vector<double>& y) : m_x(x), m_y(y) {}
      +    const std::vector<double>& x() const { return m_x; }
      +    const std::vector<double>& y() const { return m_y; }
      +    double correlation();
      +  private:
      +    std::vector<double> m_x;
      +    std::vector<double> m_y;
      +}
      +
      + +What is more natural than reusing the std_vector extension +module to expose these constructors or functions to Python? + +

      +Unfortunately, what seems natural needs a little work in both the +std_vector and the statistics module. + +

      +In the std_vector extension module, +std::vector<double> is exposed to Python in the usual +way with the class_builder<> template. To also enable the +automatic conversion of std::vector<double> function +arguments or return values in other Boost.Python C++ modules, the +converters that convert a std::vector<double> C++ object +to a Python object and vice versa (i.e. the to_python() and +from_python() template functions) have to be exported. For +example: + +

      +  #include <boost/python/cross_module.hpp>
      +  //...
      +  class_builder<std::vector<double> > v_double(std_vector_module, "double");
      +  export_converters(v_double);
      +
      + +In the extension module that wraps class xy we can now import +these converters with the import_converters<> template. +For example: + +
      +  #include <boost/python/cross_module.hpp>
      +  //...
      +  import_converters<std::vector<double> > v_double_converters("std_vector", "double");
      +
      + +That is all. All the attributes that are defined for +std_vector.double in the std_vector Boost.Python +module will be available for the returned objects of xy.x() +and xy.y(). Similarly, the constructor for xy will +accept objects that were created by the std_vectormodule. + +
      +

      Placement of import_converters<> template instantiations

      + +import_converts<> can be viewed as a drop-in replacement +for class_wrapper<>, and the recommendations for the +placement of class_wrapper<> template instantiations +also apply to to import_converts<>. In particular, it is +important that an instantiation of class_wrapper<> is +visible to any code which wraps a C++ function with a T, +T*, const T&, etc. parameter or return value. +Therefore you may want to group all class_wrapper<> and +import_converts<> instantiations at the top of your +module's init function, then def() the member functions later +to avoid problems with inter-class dependencies. + +
      +

      Non-copyable types

      + +export_converters() instantiates C++ template functions that +invoke the copy constructor of the wrapped type. For a type that is +non-copyable this will result in compile-time error messages. In such a +case, export_converters_noncopyable() can be used to export +the converters that do not involve the copy constructor of the wrapped +type. For example: + +
      +class_builder<store> py_store(your_module, "store");
      +export_converters_noncopyable(py_store);
      +
      + +The corresponding import_converters<> statement does not +need any special attention: + +
      +import_converters<store> py_store("noncopyable_export", "store");
      +
      + +
      +

      Python module search path

      + +The std_vector and statistics modules can now be used +in the following way: + +
      +import std_vector
      +import statistics
      +x = std_vector.double([1, 2, 3, 4])
      +y = std_vector.double([2, 4, 6, 8])
      +xy = statistics.xy(x, y)
      +xy.correlation()
      +
      + +In this example it is clear that Python has to be able to find both the +std_vector and the statistics extension module. In +other words, both extension modules need to be in the Python module +search path (sys.path). + +

      +The situation is not always this obvious. Suppose the +statistics module has a random() function that +returns a vector of random numbers with a given length: + +

      +import statistics
      +x = statistics.random(5)
      +y = statistics.random(5)
      +xy = statistics.xy(x, y)
      +xy.correlation()
      +
      + +A naive user will not easily anticipate that the std_vector +module is used to pass the x and y vectors around. If +the std_vector module is in the Python module search path, +this form of ignorance is of no harm. On the contrary, we are glad +that we do not have to bother the user with details like this. + +

      +If the std_vector module is not in the Python module search +path, a Python exception will be raised: + +

      +Traceback (innermost last):
      +  File "foo.py", line 2, in ?
      +    x = statistics.random(5)
      +ImportError: No module named std_vector
      +
      + +As is the case with any system of a non-trivial complexity, it is +important that the setup is consistent and complete. + +
      +

      Two-way module dependencies

      + +Boost.Python supports two-way module dependencies. This is best +illustrated by a simple example. + +

      +Suppose there is a module ivect that implements vectors of +integers, and a similar module dvect that implements vectors +of doubles. We want to be able do convert an integer vector to a double +vector and vice versa. For example: + +

      +import ivect
      +iv = ivect.ivect((1,2,3,4,5))
      +dv = iv.as_dvect()
      +
      + +The last expression will implicitly import the dvect module in +order to enable the conversion of the C++ representation of +dvect to a Python object. The analogous is possible for a +dvect: + +
      +import dvect
      +dv = dvect.dvect((1,2,3,4,5))
      +iv = dv.as_ivect()
      +
      + +Now the ivect module is imported implicitly. + +

      +Note that the two-way dependencies are possible because the +dependencies are resolved only when needed. This is, the initialization +of the ivect module does not rely on the dvect +module, and vice versa. Only if as_dvect() or +as_ivect() is actually invoked will the corresponding module +be implicitly imported. This also means that, for example, the +dvect module does not have to be available at all if +as_dvect() is never used. + +


      +

      Clarification of compile-time and link-time dependencies

      + +Boost.Python's support for resolving cross-module dependencies at +runtime does not imply that compile-time dependencies are eliminated. +For example, the statistics extension module in the example above will +need to #include <vector>. This is immediately obvious +from the definition of class xy. + +

      +If a library is wrapped that consists of both header files and compiled +components (e.g. libdvect.a, dvect.lib, etc.), both +the Boost.Python extension module with the +export_converters() statement and the module with the +import_converters<> statement need to be linked against +the object library. Ideally one would build a shared library (e.g. +libdvect.so, dvect.dll, etc.). However, this +introduces the issue of having to configure the search path for the +dynamic loading correctly. For small libraries it is therefore often +more convenient to ignore the fact that the object files are loaded +into memory more than once. + +


      +

      Summary of motivation for cross-module support

      + +The main purpose of Boost.Python's cross-module support is to allow for +a modular system layout. With this support it is straightforward to +reflect C++ code organization at the Python level. Without the +cross-module support, a multi-purpose module like std_vector +would be impractical because the entire wrapper code would somehow have +to be duplicated in all extension modules that use it, making them +harder to maintain and harder to build. + +

      +Another motivation for the cross-module support is that two extension +modules that wrap the same class cannot both be imported into Python. +For example, if there are two modules A and B that +both wrap a given class X, this will work: + +

      +import A
      +x = A.X()
      +
      + +This will also work: + +
      +import B
      +x = B.X()
      +
      + +However, this will fail: + +
      +import A
      +import B
      +python: /net/cci/rwgk/boost/boost/python/detail/extension_class.hpp:866:
      +static void boost::python::detail::class_registry<X>::register_class(boost::python::detail::extension_class_base *):
      +Assertion `static_class_object == 0' failed.
      +Abort
      +
      + +A good solution is to wrap class X only once. Depending on the +situation, this could be done by module A or B, or an +additional small extension module that only wraps and exports +class X. + +

      +Finally, there can be important psychological or political reasons for +using the cross-module support. If a group of classes is lumped +together with many others in a huge module, the authors will have +difficulties in being identified with their work. The situation is +much more transparent if the work is represented by a module with a +recognizable name. This is not just a question of strong egos, but also +of getting credit and funding. + +


      +

      Why not use export_converters() universally?

      + +There is some overhead associated with the Boost.Python cross-module +support. Depending on the platform, the size of the code generated by +export_converters() is roughly 10%-20% of that generated +by class_builder<>. For a large extension module with +many wrapped classes, this could mean a significant difference. +Therefore the general recommendation is to use +export_converters() only for classes that are likely to +be used as function arguments or return values in other modules. + +
      +© Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, +use, modify, sell and distribute this document is granted provided this +copyright notice appears in all copies. This document is provided "as +is" without express or implied warranty, and with no claim as to its +suitability for any purpose. + +

      +Updated: April 2001 + +

      From 38ac4fe84938e5a211d54b20fb912c1969f34aa3 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 19:51:30 +0000 Subject: [PATCH 0064/1042] cross-module mods [SVN r9823] --- doc/index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/index.html b/doc/index.html index c6e0722e..5ec32a6b 100644 --- a/doc/index.html +++ b/doc/index.html @@ -134,6 +134,8 @@ among others.
    • Pickle Support +
    • Cross-Extension-Module Dependencies +
    • Wrapping Enums
    • Pointers and Smart Pointers From 62b90206e842edce572c4ac10af9f9716a4f9173 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 19:52:44 +0000 Subject: [PATCH 0065/1042] More organized presentation. [SVN r9824] --- doc/building.html | 279 +++++++++++++++++++++++++--------------------- 1 file changed, 151 insertions(+), 128 deletions(-) diff --git a/doc/building.html b/doc/building.html index 2a8c9cae..f9458c42 100644 --- a/doc/building.html +++ b/doc/building.html @@ -5,153 +5,176 @@ Building an Extension Module
      -

      c++boost.gif (8819 bytes)Building an Extension Module

      The build process for Boost is currently undergoing some evolution, and, it is to be hoped, improvement. The following facts may help: +


      + Makefiles for various platforms and a Visual Studio project + reside in the Boost subdirectory libs/python/build. + Build targets include: +
        -
      • - Makefiles for various platforms reside in the Boost subdirectory - libs/python/build: +
      • The boost_python library for static linking with your + extension module. On the various Unices, this library will be + called libboost_python.a. When using Visual C++, the + library will be called boost_python.lib. -
          -
        • como.mak (Comeau C++ on Linux) +

          +

        • A comprehensive test of Boost.Python features. This test builds + a Boost.Python extension module, then runs Python to import the + module, and runs a series of tests on it using doctest. Source code for the module + and tests is available in the Boost subdirectory + libs/python/test. -
        • linux_gcc.mak (GCC on - Linux/Unix) +

          +

        • Various examples from the Boost subdirectory + libs/python/example. + All these examples include a doctest modeled + on the comprehensive test above. -
        • gcc.mak (older makefile for GCC - on Linux/Unix. Deprecated.) - -
        • mingw32.mak - (highly-specialized makefile for mingw32 (Win32-targeted) GCC. Read - the header comment). - -
        • tru64_cxx.mak (Compaq - Alpha). -
        -
        - -
      • - A project workspace for Microsoft Visual Studio is provided at libs/python/build/build.dsw. The - include paths for this project may need to be changed for your - installation. They currently assume that python has been installed at - c:\tools\python. Three configurations of all targets are - supported: - -
          -
        • Release (optimization, -DNDEBUG) - -
        • Debug (no optimization -D_DEBUG) - -
        • DebugPython (no optimization, -D_DEBUG - -DBOOST_DEBUG_PYTHON) -
        - -

        When extension modules are built with Visual C++ using - -D_DEBUG, Python defaults to force linking with a - special debugging version of the Python DLL. Since this debug DLL - isn't supplied with the default Python installation for Windows, - Boost.Python uses boost/python/detail/wrap_python.hpp - to temporarily undefine _DEBUG when Python.h is - #included. - -

        If you want the extra runtime checks available with the debugging - version of the library, #define BOOST_DEBUG_PYTHON to - re-enable library forcing, and link with the DebugPython version of - boost_python.lib. You'll need to get the debugging version - of the Python executable (python_d.exe) and DLL - (python20_d.dll or python15_d.dll). The Python - sources include project files for building these. If you download them, change the name of the - top-level directory to src, and install it under - c:\tools\python, the workspace supplied by Boost.Python will - be able to use it without modification. Just open - c:\tools\python\src\pcbuild\pcbuild.dsw and invoke "build - all" to generate all the debugging targets. - -

        If you do not #define BOOST_DEBUG_PYTHON, be sure that - any source files #include <boost/python/detail/wrap_python.hpp> - instead of the usual Python.h, or you will have link - incompatibilities.
        -
        - - -

      • - The makefiles and Visual Studio project can all build at least the - following: - -
          -
        • The boost_python library for static linking with your - extension module. On the various Unices, this library will be - called libboost_python.a. On Win32 platforms, the library - will be called boost_python.lib. - -
        • A comprehensive test of Boost.Python features. This test builds - a Boost.Python extension module, then runs Python to import the - module, and runs a series of tests on it using doctest. Source code for the module - and tests is available in the Boost subdirectory - libs/python/test.
          - - -
        • Various examples from the Boost subdirectory - libs/python/example. Which examples are built currently - depends on the platform. The most up-to-date examples are - getting_startedn.cpp from Ralf W. - Grosse-Kunstleve. All these examples include a doctest modeled - on the comprehensive test above.
          -
          - -
        - -
      • - If your platform isn't directly supported, you can build a static - library from the following source files (in the Boost subdirectory - libs/python/src), or compile them directly and link the - resulting objects into your extension module: - -
      -

      Next: Wrapping Enums Previous: + There is a group of makefiles with support for simultaneous + compilation on multiple platforms and a consistent set of + features that build the boost_python library for static + linking, the comprehensive test, and all examples in + libs/python/example: + +

      + Usage of these makefiles is described here. + +
      + There is another group of makefiles for GNU make. + These makefiles are less redundant than the makefiles + in the group above, + but the list of compilation targets is not as complete + and there is no support for simultaneous compilation + on multiple platforms. + + + +
      + A project workspace for Microsoft Visual Studio is provided at libs/python/build/build.dsw. The + include paths for this project may need to be changed for your + installation. They currently assume that python has been installed at + c:\tools\python. Three configurations of all targets are + supported: + +
        +
      • Release (optimization, -DNDEBUG) + +
      • Debug (no optimization -D_DEBUG) + +
      • DebugPython (no optimization, -D_DEBUG + -DBOOST_DEBUG_PYTHON) +
      + +

      When extension modules are built with Visual C++ using + -D_DEBUG, Python defaults to force linking with a + special debugging version of the Python DLL. Since this debug DLL + isn't supplied with the default Python installation for Windows, + Boost.Python uses boost/python/detail/wrap_python.hpp + to temporarily undefine _DEBUG when Python.h is + #included. + +

      If you want the extra runtime checks available with the debugging + version of the library, #define BOOST_DEBUG_PYTHON to + re-enable library forcing, and link with the DebugPython version of + boost_python.lib. You'll need to get the debugging version + of the Python executable (python_d.exe) and DLL + (python20_d.dll or python15_d.dll). The Python + sources include project files for building these. If you download them, change the name of the + top-level directory to src, and install it under + c:\tools\python, the workspace supplied by Boost.Python will + be able to use it without modification. Just open + c:\tools\python\src\pcbuild\pcbuild.dsw and invoke "build + all" to generate all the debugging targets. + +

      If you do not #define BOOST_DEBUG_PYTHON, be sure that + any source files #include <boost/python/detail/wrap_python.hpp> + instead of the usual Python.h, or you will have link + incompatibilities.
      + +


      + If your platform isn't directly supported, you can build a static + library from the following source files (in the Boost subdirectory + libs/python/src), or compile them directly and link the + resulting objects into your extension module: + + + +
      + Next: Wrapping Enums Previous: A Peek Under the Hood Up: Top +

      © Copyright David Abrahams 2000. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided ``as is'' without express or implied warranty, and with no claim as to its suitability for any purpose. -

      Updated: Mar 6, 2001 +

      Updated: Apr 17, 2001 (R.W. Grosse-Kunstleve)

      - From ad4b0fff565fb36c827f20357de54255dc365d3d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 19:55:11 +0000 Subject: [PATCH 0066/1042] moved from branch ralf_grosse_kunstleve to trunk [SVN r9825] --- doc/pickle.html | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/doc/pickle.html b/doc/pickle.html index 842112d3..994a78ab 100644 --- a/doc/pickle.html +++ b/doc/pickle.html @@ -227,11 +227,38 @@ Both __getinitargs__ and __getstate__ are not defined.

    -

    Example

    +

    Examples

    -An example that shows how to configure pickle support is available in the -boost/lib/python/example directory -(getting_started3.cpp). +There are three files in boost/libs/python/example that +show how so provide pickle support. + +

    pickle1.cpp

    + + The C++ class in this example can be fully restored by passing the + appropriate argument to the constructor. Therefore it is sufficient + to define the pickle interface method __getinitargs__. + +

    pickle2.cpp

    + + The C++ class in this example contains member data that cannot be + restored by any of the constructors. Therefore it is necessary to + provide the __getstate__/__setstate__ pair of + pickle interface methods. + +

    + For simplicity, the __dict__ is not included in the result + of __getstate__. This is not generally recommended, but a + valid approach if it is anticipated that the object's + __dict__ will always be empty. Note that the safety guards + will catch the cases where this assumption is violated. + +

    pickle3.cpp

    + + This example is similar to pickle2.cpp. However, the + object's __dict__ is included in the result of + __getstate__. This requires more code but is unavoidable + if the object's __dict__ is not always empty.
    © Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, @@ -241,5 +268,5 @@ is" without express or implied warranty, and with no claim as to its suitability for any purpose.

    -Updated: March 10, 2001 +Updated: March 21, 2001 From da83f20a283d943ed9fa42317109d3d0c3af14ec Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 20:02:20 +0000 Subject: [PATCH 0067/1042] stray getting_started3 references removed. [SVN r9826] --- build/filemgr.py | 3 --- build/irix_CC.mak | 9 ++------- build/linux_gcc.mak | 9 ++------- build/mingw32.mak | 9 +-------- build/tru64_cxx.mak | 9 ++------- build/vc60.mak | 6 +----- 6 files changed, 8 insertions(+), 37 deletions(-) diff --git a/build/filemgr.py b/build/filemgr.py index fa674f18..d8310f6d 100644 --- a/build/filemgr.py +++ b/build/filemgr.py @@ -22,7 +22,6 @@ bpl_tst + "/doctest.py", bpl_exa + "/abstract.cpp", bpl_exa + "/getting_started1.cpp", bpl_exa + "/getting_started2.cpp", -bpl_exa + "/getting_started3.cpp", bpl_exa + "/simple_vector.cpp", bpl_exa + "/do_it_yourself_converters.cpp", bpl_exa + "/pickle1.cpp", @@ -31,7 +30,6 @@ bpl_exa + "/pickle3.cpp", bpl_exa + "/test_abstract.py", bpl_exa + "/test_getting_started1.py", bpl_exa + "/test_getting_started2.py", -bpl_exa + "/test_getting_started3.py", bpl_exa + "/test_simple_vector.py", bpl_exa + "/test_do_it_yourself_converters.py", bpl_exa + "/test_pickle1.py", @@ -61,7 +59,6 @@ defs = ( "abstract", "getting_started1", "getting_started2", -"getting_started3", "simple_vector", "do_it_yourself_converters", "pickle1", diff --git a/build/irix_CC.mak b/build/irix_CC.mak index 88d374d8..5894ff51 100644 --- a/build/irix_CC.mak +++ b/build/irix_CC.mak @@ -41,7 +41,7 @@ OBJ=classes.o conversions.o extension_class.o functions.o \ DEPOBJ=$(OBJ) \ comprehensive.o \ abstract.o \ - getting_started1.o getting_started2.o getting_started3.o \ + getting_started1.o getting_started2.o \ simple_vector.o \ do_it_yourself_converters.o \ pickle1.o pickle2.o pickle3.o \ @@ -53,7 +53,7 @@ DEPOBJ=$(OBJ) \ all: libboost_python.a \ boost_python_test.so \ abstract.so \ - getting_started1.so getting_started2.so getting_started3.so \ + getting_started1.so getting_started2.so \ simple_vector.so \ do_it_yourself_converters.so \ pickle1.so pickle2.so pickle3.so \ @@ -76,9 +76,6 @@ getting_started1.so: $(OBJ) getting_started1.o getting_started2.so: $(OBJ) getting_started2.o $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so -getting_started3.so: $(OBJ) getting_started3.o - $(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so - simple_vector.so: $(OBJ) simple_vector.o $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so @@ -116,7 +113,6 @@ test: $(PYEXE) test_abstract.py $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py - $(PYEXE) test_getting_started3.py $(PYEXE) test_simple_vector.py $(PYEXE) test_do_it_yourself_converters.py $(PYEXE) test_pickle1.py @@ -130,7 +126,6 @@ clean: rm -f abstract.o abstract.so rm -f getting_started1.o getting_started1.so rm -f getting_started2.o getting_started2.so - rm -f getting_started3.o getting_started3.so rm -f simple_vector.o simple_vector.so rm -f do_it_yourself_converters.o do_it_yourself_converters.so rm -f pickle1.o pickle1.so diff --git a/build/linux_gcc.mak b/build/linux_gcc.mak index 9be8f1cb..9cd2b5de 100644 --- a/build/linux_gcc.mak +++ b/build/linux_gcc.mak @@ -42,7 +42,7 @@ OBJ=classes.o conversions.o extension_class.o functions.o \ DEPOBJ=$(OBJ) \ comprehensive.o \ abstract.o \ - getting_started1.o getting_started2.o getting_started3.o \ + getting_started1.o getting_started2.o \ simple_vector.o \ do_it_yourself_converters.o \ pickle1.o pickle2.o pickle3.o \ @@ -54,7 +54,7 @@ DEPOBJ=$(OBJ) \ all: libboost_python.a \ boost_python_test.so \ abstract.so \ - getting_started1.so getting_started2.so getting_started3.so \ + getting_started1.so getting_started2.so \ simple_vector.so \ do_it_yourself_converters.so \ pickle1.so pickle2.so pickle3.so \ @@ -77,9 +77,6 @@ getting_started1.so: $(OBJ) getting_started1.o getting_started2.so: $(OBJ) getting_started2.o $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so -getting_started3.so: $(OBJ) getting_started3.o - $(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so - simple_vector.so: $(OBJ) simple_vector.o $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so @@ -117,7 +114,6 @@ test: $(PYEXE) test_abstract.py $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py - $(PYEXE) test_getting_started3.py $(PYEXE) test_simple_vector.py $(PYEXE) test_do_it_yourself_converters.py $(PYEXE) test_pickle1.py @@ -131,7 +127,6 @@ clean: rm -f abstract.o abstract.so rm -f getting_started1.o getting_started1.so rm -f getting_started2.o getting_started2.so - rm -f getting_started3.o getting_started3.so rm -f simple_vector.o simple_vector.so rm -f do_it_yourself_converters.o do_it_yourself_converters.so rm -f pickle1.o pickle1.so diff --git a/build/mingw32.mak b/build/mingw32.mak index 98a26735..0a16f332 100644 --- a/build/mingw32.mak +++ b/build/mingw32.mak @@ -57,7 +57,7 @@ OBJ=classes.o conversions.o extension_class.o functions.o \ all: libboost_python.a \ abstract.pyd \ - getting_started1.pyd getting_started2.pyd getting_started3.pyd \ + getting_started1.pyd getting_started2.pyd \ simple_vector.pyd \ do_it_yourself_converters.pyd \ pickle1.pyd pickle2.pyd pickle3.pyd \ @@ -95,12 +95,6 @@ getting_started2.pyd: $(OBJ) getting_started2.o --def getting_started2.def \ $(OBJ) getting_started2.o $(PYLIB) -getting_started3.pyd: $(OBJ) getting_started3.o - dllwrap $(DLLWRAPOPTS) \ - --dllname getting_started3.pyd \ - --def getting_started3.def \ - $(OBJ) getting_started3.o $(PYLIB) - simple_vector.pyd: $(OBJ) simple_vector.o dllwrap $(DLLWRAPOPTS) \ --dllname simple_vector.pyd \ @@ -163,7 +157,6 @@ test: $(PYEXE) test_abstract.py $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py - $(PYEXE) test_getting_started3.py $(PYEXE) test_simple_vector.py $(PYEXE) test_do_it_yourself_converters.py $(PYEXE) test_pickle1.py diff --git a/build/tru64_cxx.mak b/build/tru64_cxx.mak index 41f7a554..21a8126e 100644 --- a/build/tru64_cxx.mak +++ b/build/tru64_cxx.mak @@ -52,7 +52,7 @@ OBJ=classes.o conversions.o extension_class.o functions.o \ DEPOBJ=$(OBJ) \ comprehensive.o \ abstract.o \ - getting_started1.o getting_started2.o getting_started3.o \ + getting_started1.o getting_started2.o \ simple_vector.o \ do_it_yourself_converters.o \ pickle1.o pickle2.o pickle3.o \ @@ -64,7 +64,7 @@ DEPOBJ=$(OBJ) \ all: libboost_python.a \ boost_python_test.so \ abstract.so \ - getting_started1.so getting_started2.so getting_started3.so \ + getting_started1.so getting_started2.so \ simple_vector.so \ do_it_yourself_converters.so \ pickle1.so pickle2.so pickle3.so \ @@ -91,9 +91,6 @@ getting_started1.so: $(OBJ) getting_started1.o getting_started2.so: $(OBJ) getting_started2.o $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so -getting_started3.so: $(OBJ) getting_started3.o - $(LD) $(LDOPTS) $(OBJ) getting_started3.o -o getting_started3.so - simple_vector.so: $(OBJ) simple_vector.o $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so @@ -131,7 +128,6 @@ test: $(PYEXE) test_abstract.py $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py - $(PYEXE) test_getting_started3.py $(PYEXE) test_simple_vector.py $(PYEXE) test_do_it_yourself_converters.py $(PYEXE) test_pickle1.py @@ -145,7 +141,6 @@ clean: rm -f abstract.o abstract.so rm -f getting_started1.o getting_started1.so rm -f getting_started2.o getting_started2.so - rm -f getting_started3.o getting_started3.so rm -f simple_vector.o simple_vector.so rm -f do_it_yourself_converters.o do_it_yourself_converters.so rm -f pickle1.o pickle1.so diff --git a/build/vc60.mak b/build/vc60.mak index 64e0b9df..f0016075 100644 --- a/build/vc60.mak +++ b/build/vc60.mak @@ -38,7 +38,7 @@ OBJ=classes.obj conversions.obj extension_class.obj functions.obj \ all: boost_python.lib \ boost_python_test.pyd \ abstract.pyd \ - getting_started1.pyd getting_started2.pyd getting_started3.pyd \ + getting_started1.pyd getting_started2.pyd \ simple_vector.pyd \ do_it_yourself_converters.pyd \ pickle1.pyd pickle2.pyd pickle3.pyd \ @@ -60,9 +60,6 @@ getting_started1.pyd: $(OBJ) getting_started1.obj getting_started2.pyd: $(OBJ) getting_started2.obj $(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) /export:initgetting_started2 /out:"getting_started2.pyd" -getting_started3.pyd: $(OBJ) getting_started3.obj - $(LD) $(LDOPTS) $(OBJ) getting_started3.obj $(PYLIB) /export:initgetting_started3 /out:"getting_started3.pyd" - simple_vector.pyd: $(OBJ) simple_vector.obj $(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) /export:initsimple_vector /out:"simple_vector.pyd" @@ -98,7 +95,6 @@ test: $(PYEXE) test_abstract.py $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py - $(PYEXE) test_getting_started3.py $(PYEXE) test_simple_vector.py $(PYEXE) test_do_it_yourself_converters.py $(PYEXE) test_pickle1.py From c3215d0ba5b3b75e2e6f42e37b5e8ad592fb57c3 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 17 Apr 2001 21:30:05 +0000 Subject: [PATCH 0068/1042] enhancement [SVN r9827] --- example/README | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/example/README b/example/README index 34b50d61..35d822d5 100644 --- a/example/README +++ b/example/README @@ -1,6 +1,24 @@ To get started with the Boost Python Library, use the examples -getting_started?.cpp and abstract.cpp. +getting_started1.cpp and getting_started2.cpp. + +Examples for providing pickle support can be found in: + pickle1.cpp + pickle2.cpp + pickle3.cpp +See also: libs/python/doc/pickle.html + +Other advanced concepts are introduced by: + abstract.cpp + simple_vector.cpp + do_it_yourself_converters.cpp + +Examples for the cross-module support are provided by: + noncopyable_export.cpp + noncopyable_import.cpp + dvect.cpp + ivect.cpp +See also: libs/python/doc/cross_module.html The files example1.cpp and rwgk1.cpp are obsolete. They are only -included because the makefiles in the build directory still refer to -them. This will be fixed later. +included because the Visual Studio project in the build directory still +refers to them. From ebb0145256b4247bf270d6442b669773153d487c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 18 Apr 2001 01:23:50 +0000 Subject: [PATCH 0069/1042] trying to clean cvs attic mess... [SVN r9828] --- example/simple_vector.cpp | 103 -------------------------------------- 1 file changed, 103 deletions(-) delete mode 100644 example/simple_vector.cpp diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp deleted file mode 100644 index 5ac0767b..00000000 --- a/example/simple_vector.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A wrapper is used to define additional constructors. - // - struct vector_double_wrapper: std::vector - { - // Tell the compiler how to convert a base class object to - // this wrapper object. - vector_double_wrapper(PyObject*, const std::vector& vd) - : std::vector(vd) {} - - vector_double_wrapper(PyObject* self) - : std::vector() {} - - vector_double_wrapper(PyObject* self, int n) - : std::vector(n) {} - - vector_double_wrapper(PyObject* self, python::tuple tuple) - : std::vector(tuple.size()) - { - std::vector::iterator vd = begin(); - for (int i = 0; i < tuple.size(); i++) - vd[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - python::type()); - } - }; - - double getitem(const std::vector& vd, std::size_t key) { - return vd[key]; - } - - void setitem(std::vector& vd, std::size_t key, double d) { - std::vector::iterator vditer = vd.begin(); - vditer[key] = d; - } - - void delitem(std::vector& vd, std::size_t key) { - std::vector::iterator vditer = vd.begin(); - vd.erase(&vditer[key]); - } - - // Convert vector_double to a regular Python tuple. - // - python::tuple as_tuple(const std::vector& vd) - { - python::tuple t(vd.size()); - for (int i = 0; i < vd.size(); i++) t.set_item(i, - python::ref(BOOST_PYTHON_CONVERSION::to_python(vd[i]))); - return t; - } - - // Function returning a vector_double object to Python. - // - std::vector foo(int n) - { - std::vector vd(n); - std::vector::iterator vditer = vd.begin(); - for (int i = 0; i < n; i++) vditer[i] = double(i); - return vd; - } - - // Same as foo(), but avoid copying on return. - // - std::auto_ptr > bar(int n) - { - std::auto_ptr > vdptr(new std::vector(n)); - std::vector::iterator vditer = vdptr->begin(); - for (int i = 0; i < n; i++) vditer[i] = double(10 * i); - return vdptr; - } -} - -BOOST_PYTHON_MODULE_INIT(simple_vector) -{ - try - { - python::module_builder this_module("simple_vector"); - - python::class_builder, vector_double_wrapper> - vector_double(this_module, "vector_double"); - - vector_double.def(python::constructor<>()); - vector_double.def(python::constructor()); - vector_double.def(python::constructor()); - vector_double.def(&std::vector::size, "__len__"); - vector_double.def(getitem, "__getitem__"); - vector_double.def(setitem, "__setitem__"); - vector_double.def(delitem, "__delitem__"); - vector_double.def(as_tuple, "as_tuple"); - - this_module.def(foo, "foo"); - this_module.def(bar, "bar"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} From 22024e7c1f8b7f8d2b92ad9ea0f2ce9307451e94 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 18 Apr 2001 01:24:34 +0000 Subject: [PATCH 0070/1042] trying to clean cvs attic mess... [SVN r9829] --- example/simple_vector.cpp | 103 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 example/simple_vector.cpp diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp new file mode 100644 index 00000000..5ac0767b --- /dev/null +++ b/example/simple_vector.cpp @@ -0,0 +1,103 @@ +// Example by Ralf W. Grosse-Kunstleve + +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A wrapper is used to define additional constructors. + // + struct vector_double_wrapper: std::vector + { + // Tell the compiler how to convert a base class object to + // this wrapper object. + vector_double_wrapper(PyObject*, const std::vector& vd) + : std::vector(vd) {} + + vector_double_wrapper(PyObject* self) + : std::vector() {} + + vector_double_wrapper(PyObject* self, int n) + : std::vector(n) {} + + vector_double_wrapper(PyObject* self, python::tuple tuple) + : std::vector(tuple.size()) + { + std::vector::iterator vd = begin(); + for (int i = 0; i < tuple.size(); i++) + vd[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + python::type()); + } + }; + + double getitem(const std::vector& vd, std::size_t key) { + return vd[key]; + } + + void setitem(std::vector& vd, std::size_t key, double d) { + std::vector::iterator vditer = vd.begin(); + vditer[key] = d; + } + + void delitem(std::vector& vd, std::size_t key) { + std::vector::iterator vditer = vd.begin(); + vd.erase(&vditer[key]); + } + + // Convert vector_double to a regular Python tuple. + // + python::tuple as_tuple(const std::vector& vd) + { + python::tuple t(vd.size()); + for (int i = 0; i < vd.size(); i++) t.set_item(i, + python::ref(BOOST_PYTHON_CONVERSION::to_python(vd[i]))); + return t; + } + + // Function returning a vector_double object to Python. + // + std::vector foo(int n) + { + std::vector vd(n); + std::vector::iterator vditer = vd.begin(); + for (int i = 0; i < n; i++) vditer[i] = double(i); + return vd; + } + + // Same as foo(), but avoid copying on return. + // + std::auto_ptr > bar(int n) + { + std::auto_ptr > vdptr(new std::vector(n)); + std::vector::iterator vditer = vdptr->begin(); + for (int i = 0; i < n; i++) vditer[i] = double(10 * i); + return vdptr; + } +} + +BOOST_PYTHON_MODULE_INIT(simple_vector) +{ + try + { + python::module_builder this_module("simple_vector"); + + python::class_builder, vector_double_wrapper> + vector_double(this_module, "vector_double"); + + vector_double.def(python::constructor<>()); + vector_double.def(python::constructor()); + vector_double.def(python::constructor()); + vector_double.def(&std::vector::size, "__len__"); + vector_double.def(getitem, "__getitem__"); + vector_double.def(setitem, "__setitem__"); + vector_double.def(delitem, "__delitem__"); + vector_double.def(as_tuple, "as_tuple"); + + this_module.def(foo, "foo"); + this_module.def(bar, "bar"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} From dc462cdc1f1fd22a97a69eda4b2a3cc97bb8bd7a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 18 Apr 2001 01:27:51 +0000 Subject: [PATCH 0071/1042] cleaning up cvs attic mess [SVN r9830] --- example/do_it_yourself_converters.cpp | 128 ---------------------- example/dvect.cpp | 45 -------- example/ivect.cpp | 45 -------- example/noncopyable_export.cpp | 25 ----- example/noncopyable_import.cpp | 42 -------- example/pickle1.cpp | 64 ----------- example/pickle2.cpp | 100 ----------------- example/pickle3.cpp | 150 -------------------------- example/tst_dvect1.py | 20 ---- example/tst_ivect1.py | 20 ---- example/tst_noncopyable.py | 16 --- 11 files changed, 655 deletions(-) delete mode 100644 example/do_it_yourself_converters.cpp delete mode 100644 example/dvect.cpp delete mode 100644 example/ivect.cpp delete mode 100644 example/noncopyable_export.cpp delete mode 100644 example/noncopyable_import.cpp delete mode 100644 example/pickle1.cpp delete mode 100644 example/pickle2.cpp delete mode 100644 example/pickle3.cpp delete mode 100644 example/tst_dvect1.py delete mode 100644 example/tst_ivect1.py delete mode 100644 example/tst_noncopyable.py diff --git a/example/do_it_yourself_converters.cpp b/example/do_it_yourself_converters.cpp deleted file mode 100644 index 6d2d2d6a..00000000 --- a/example/do_it_yourself_converters.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -/* - - This example shows how to convert a class from and to native - Python objects, such as tuples. - - We do not want to expose the helper class MillerIndex as an - Extension Class. However, in order to simplify the wrapper code, - we want to define from_python() and to_python() functions for - class MillerIndex. - - Consider the alternatives: - - - Expose MillerIndex as an Extension Class. - We need a constructor MillerIndex(python::tuple). - Python function calls become more complex: - foo(MillerIndex((1,2,3)) instead of foo((1,2,3)) - We need a method such as MillerIndex().as_tuple(). - - - Define a wrapper function for each function that we - want to expose, e.g.: - void add(const IndexingSet& ixset, const python::tuple PyMIx) - - The first alternative introduces a new type that the user has to - deal with. Other modules using Miller indices might organize them in - different ways, for example to increase runtime efficiency for - important procedures. This means, the user has to know how to - convert between the different kinds of Miller index representations. - This can quickly become a nuisance. Relying on native Python data - structures minimizes the number of special types the user has to - learn and convert. Of course, this argument is only valid for - small and relatively simply classes. - - If there are many member functions with MillerIndex arguments, the - second alternative is impractical, and concentrating the conversion - mechanism in one central place is essential for code - maintainability. An added benefit is that more convenient (smarter) - conversion functions can be provided without cluttering the rest of - the wrapper code. - - */ - -#include -#include -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // The helper class. - // - class MillerIndex { - public: - int v[3]; - }; - - // The main class. Imagine that there are MANY member functions - // like add() and get(). - // - class IndexingSet { - private: - std::vector VMIx; - public: - void add(const MillerIndex& MIx) { VMIx.push_back(MIx); } - MillerIndex get(std::size_t i) const { return VMIx[i]; } - }; -} - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - - // Convert a Python tuple to a MillerIndex object. - // - MillerIndex from_python(PyObject* p, python::type) - { - python::tuple tup - = python::tuple(python::ref(p, python::ref::increment_count)); - if (tup.size() != 3) { - PyErr_SetString(PyExc_ValueError, - "expecting exactly 3 values in tuple."); - throw python::error_already_set(); - } - MillerIndex result; - for (int i = 0; i < 3; i++) - result.v[i] = from_python(tup[i].get(), python::type()); - return result; - } - - // Similar conversion for MillerIndex objects passed by value. - // Not actually used, but included to show the principle. - // - MillerIndex from_python(PyObject* p, python::type) - { - return from_python(p, python::type()); - } - - // Convert a MillerIndex object to a Python tuple. - // - PyObject* to_python(const MillerIndex& hkl) - { - python::tuple result(3); - for (int i = 0; i < 3; i++) - result.set_item(i, python::ref(to_python(hkl.v[i]))); - return result.reference().release(); - } - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -BOOST_PYTHON_MODULE_INIT(do_it_yourself_converters) -{ - try - { - // Create an object representing this extension module. - python::module_builder this_module("do_it_yourself_converters"); - - // Create the Python type object for our extension class. - python::class_builder ixset_class(this_module, "IndexingSet"); - - // Add the __init__ function. - ixset_class.def(python::constructor<>()); - // Add the member functions. - ixset_class.def(&IndexingSet::add, "add"); - ixset_class.def(&IndexingSet::get, "get"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/dvect.cpp b/example/dvect.cpp deleted file mode 100644 index da6b35a3..00000000 --- a/example/dvect.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include "dvect.h" -#include "ivect.h" -#include -namespace python = boost::python; - -namespace { - -# include "dvect_conversions.cpp" -# include "ivect_conversions.cpp" - - vects::ivect dvect_as_ivect(const vects::dvect& dv) - { - vects::ivect iv(dv.size()); - vects::ivect::iterator iviter = iv.begin(); - for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); - return iv; - } -} - -BOOST_PYTHON_MODULE_INIT(dvect) -{ - try - { - python::module_builder this_module("dvect"); - - python::class_builder dvect_class(this_module, "dvect"); - python::export_converters(dvect_class); - - python::import_converters ivect_converters("ivect", "ivect"); - - dvect_class.def(python::constructor()); - dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); - dvect_class.def(dvect_as_ivect, "as_ivect"); - -# include "dvect_defs.cpp" -# include "ivect_defs.cpp" - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/ivect.cpp b/example/ivect.cpp deleted file mode 100644 index db1c0ec3..00000000 --- a/example/ivect.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include "dvect.h" -#include "ivect.h" -#include -namespace python = boost::python; - -namespace { - -# include "dvect_conversions.cpp" -# include "ivect_conversions.cpp" - - vects::dvect ivect_as_dvect(const vects::ivect& iv) - { - vects::dvect dv(iv.size()); - vects::dvect::iterator dviter = dv.begin(); - for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); - return dv; - } -} - -BOOST_PYTHON_MODULE_INIT(ivect) -{ - try - { - python::module_builder this_module("ivect"); - - python::class_builder ivect_class(this_module, "ivect"); - python::export_converters(ivect_class); - - python::import_converters dvect_converters("dvect", "dvect"); - - ivect_class.def(python::constructor()); - ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); - ivect_class.def(ivect_as_dvect, "as_dvect"); - -# include "dvect_defs.cpp" -# include "ivect_defs.cpp" - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp deleted file mode 100644 index 794b1200..00000000 --- a/example/noncopyable_export.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include -namespace python = boost::python; - -#include "noncopyable.h" - -BOOST_PYTHON_MODULE_INIT(noncopyable_export) -{ - try - { - python::module_builder this_module("noncopyable_export"); - - python::class_builder store_class(this_module, "store"); - python::export_converters_noncopyable(store_class); - - store_class.def(python::constructor()); - store_class.def(&store::recall, "recall"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp deleted file mode 100644 index ea2477be..00000000 --- a/example/noncopyable_import.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include -namespace python = boost::python; - -#include "noncopyable.h" - -namespace { // Avoid cluttering the global namespace. - - // A function with store objects as both input and output parameters. - // Because the copy constructor is disabled, we cannot pass a store - // object by value. Instead, we pass a smart pointer. - std::auto_ptr add_stores(const store& s1, const store& s2) - { - int sum = s1.recall() + s2.recall(); - std::auto_ptr ss = std::auto_ptr(new store(sum)); - return ss; - } -} - -BOOST_PYTHON_MODULE_INIT(noncopyable_import) -{ - try - { - python::module_builder this_module("noncopyable_import"); - - python::import_converters - dvect_converters("noncopyable_export", "store"); - - // Imagine all the additional classes with member functions - // that have store objects as input and output parameters. - // Lots and lots of them. - // However, to keep this example simple, we only define a - // module-level function. - this_module.def(add_stores, "add_stores"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/pickle1.cpp b/example/pickle1.cpp deleted file mode 100644 index cdd78989..00000000 --- a/example/pickle1.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below can be fully restored by passing the - appropriate argument to the constructor. Therefore it is sufficient - to define the pickle interface method __getinitargs__. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - private: - std::string country; - int secret_number; - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - }; - - // Support for pickle. - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); - } -} - -BOOST_PYTHON_MODULE_INIT(pickle1) -{ - try - { - // Create an object representing this extension module. - python::module_builder this_module("pickle1"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/pickle2.cpp b/example/pickle2.cpp deleted file mode 100644 index d6aa3201..00000000 --- a/example/pickle2.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below contains member data (secret_number) that - cannot be restored by any of the constructors. Therefore it is - necessary to provide the __getstate__/__setstate__ pair of pickle - interface methods. - - For simplicity, the __dict__ is not included in the result of - __getstate__. This is not generally recommended, but a valid - approach if it is anticipated that the object's __dict__ will - always be empty. Note that safety guard are provided to catch the - cases where this assumption is not true. - - pickle3.cpp shows how to include the object's __dict__ in the - result of __getstate__. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - private: - std::string country; - int secret_number; - }; - - // Support for pickle. - - using BOOST_PYTHON_CONVERSION::from_python; - - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); // returning the reference avoids the copying. - } - - python::ref world_getstate(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_secret_number()); - return result.reference(); // returning the reference avoids the copying. - } - - void world_setstate(world& w, python::tuple state) { - if (state.size() != 1) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); - throw python::error_already_set(); - } - int number = from_python(state[0].get(), python::type()); - if (number != 42) - w.set_secret_number(number); - } -} - -BOOST_PYTHON_MODULE_INIT(pickle2) -{ - try - { - // Create an object representing this extension module. - python::module_builder this_module("pickle2"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - world_class.def(&world::get_secret_number, "get_secret_number"); - world_class.def(&world::set_secret_number, "set_secret_number"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - world_class.def(world_getstate, "__getstate__"); - world_class.def(world_setstate, "__setstate__"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} diff --git a/example/pickle3.cpp b/example/pickle3.cpp deleted file mode 100644 index bfa7dc54..00000000 --- a/example/pickle3.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below contains member data (secret_number) that - cannot be restored by any of the constructors. Therefore it is - necessary to provide the __getstate__/__setstate__ pair of pickle - interface methods. - - The object's __dict__ is included in the result of __getstate__. - This requires more code (compare with pickle2.cpp), but is - unavoidable if the object's __dict__ is not always empty. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace boost { namespace python { - - ref getattr(PyObject* o, const std::string& attr_name) { - return ref(PyObject_GetAttrString(o, const_cast(attr_name.c_str()))); - } - ref getattr(const ref& r, const std::string& attr_name) { - return getattr(r.get(), attr_name); - } - -}} - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - private: - std::string country; - int secret_number; - }; - - // Support for pickle. - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); // returning the reference avoids the copying. - } - - python::ref world_getstate(python::tuple const & args, - python::dictionary const & keywords); - - PyObject* world_setstate(python::tuple const & args, - python::dictionary const & keywords); -} - -BOOST_PYTHON_MODULE_INIT(pickle3) -{ - try - { - // Create an object representing this extension module. - python::module_builder this_module("pickle3"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - world_class.def(&world::get_secret_number, "get_secret_number"); - world_class.def(&world::set_secret_number, "set_secret_number"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - world_class.def_raw(world_getstate, "__getstate__"); - world_class.def_raw(world_setstate, "__setstate__"); - world_class.getstate_manages_dict(); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } -} - -namespace { - - using BOOST_PYTHON_CONVERSION::from_python; - using boost::python::type; - using boost::python::ref; - using boost::python::tuple; - using boost::python::list; - using boost::python::dictionary; - using boost::python::getattr; - - ref world_getstate(tuple const & args, dictionary const & keywords) - { - if(args.size() != 1 || keywords.size() != 0) { - PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - throw boost::python::argument_error(); - } - const world& w = from_python(args[0].get(), type()); - ref mydict = getattr(args[0], "__dict__"); - tuple result(2); - // store the object's __dict__ - result.set_item(0, mydict); - // store the internal state of the C++ object - result.set_item(1, w.get_secret_number()); - return result.reference(); // returning the reference avoids the copying. - } - - PyObject* world_setstate(tuple const & args, dictionary const & keywords) - { - if(args.size() != 2 || keywords.size() != 0) { - PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - throw boost::python::argument_error(); - } - world& w = from_python(args[0].get(), type()); - ref mydict = getattr(args[0], "__dict__"); - tuple state = from_python(args[1].get(), type()); - if (state.size() != 2) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); - throw python::error_already_set(); - } - // restore the object's __dict__ - dictionary odict = from_python(mydict.get(), type()); - const dictionary& pdict = from_python(state[0].get(), type()); - list pkeys(pdict.keys()); - for (int i = 0; i < pkeys.size(); i++) { - ref k(pkeys[i]); - //odict[k] = pdict[k]; // XXX memory leak! - odict[k] = pdict.get_item(k); // this does not leak. - } - // restore the internal state of the C++ object - int number = from_python(state[1].get(), type()); - if (number != 42) - w.set_secret_number(number); - return python::detail::none(); - } -} diff --git a/example/tst_dvect1.py b/example/tst_dvect1.py deleted file mode 100644 index 22315528..00000000 --- a/example/tst_dvect1.py +++ /dev/null @@ -1,20 +0,0 @@ -def f(): - import dvect - dv = dvect.dvect((1,2,3,4,5)) - print dv.as_tuple() - iv = dv.as_ivect() - print iv.as_tuple() - print dvect.const_ivect_reference_as_tuple(iv) - aiv = dvect.ivect_as_auto_ptr(iv) - print dvect.const_ivect_reference_as_tuple(aiv) - siv = dvect.ivect_as_shared_ptr(iv) - print dvect.const_ivect_reference_as_tuple(siv) - print aiv.as_tuple() - print siv.as_tuple() - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() diff --git a/example/tst_ivect1.py b/example/tst_ivect1.py deleted file mode 100644 index 7369fdbf..00000000 --- a/example/tst_ivect1.py +++ /dev/null @@ -1,20 +0,0 @@ -def f(): - import ivect - iv = ivect.ivect((1,2,3,4,5)) - print iv.as_tuple() - dv = iv.as_dvect() - print dv.as_tuple() - print ivect.const_dvect_reference_as_tuple(dv) - adv = ivect.dvect_as_auto_ptr(dv) - print ivect.const_dvect_reference_as_tuple(adv) - sdv = ivect.dvect_as_shared_ptr(dv) - print ivect.const_dvect_reference_as_tuple(sdv) - print adv.as_tuple() - print sdv.as_tuple() - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py deleted file mode 100644 index 155910a5..00000000 --- a/example/tst_noncopyable.py +++ /dev/null @@ -1,16 +0,0 @@ -def f(): - import noncopyable_export - import noncopyable_import - s1 = noncopyable_export.store(1) - print s1.recall() - s2 = noncopyable_export.store(2) - print s2.recall() - s3 = noncopyable_import.add_stores(s1, s2) - print s3.recall() - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() From cbff11296bcbf7c486019db142cc9ba46560b20a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 18 Apr 2001 01:29:23 +0000 Subject: [PATCH 0072/1042] cleaning up cvs attic mess [SVN r9831] --- example/do_it_yourself_converters.cpp | 128 ++++++++++++++++++++++ example/dvect.cpp | 45 ++++++++ example/ivect.cpp | 45 ++++++++ example/noncopyable_export.cpp | 25 +++++ example/noncopyable_import.cpp | 42 ++++++++ example/pickle1.cpp | 64 +++++++++++ example/pickle2.cpp | 100 +++++++++++++++++ example/pickle3.cpp | 150 ++++++++++++++++++++++++++ example/tst_dvect1.py | 20 ++++ example/tst_ivect1.py | 20 ++++ example/tst_noncopyable.py | 16 +++ 11 files changed, 655 insertions(+) create mode 100644 example/do_it_yourself_converters.cpp create mode 100644 example/dvect.cpp create mode 100644 example/ivect.cpp create mode 100644 example/noncopyable_export.cpp create mode 100644 example/noncopyable_import.cpp create mode 100644 example/pickle1.cpp create mode 100644 example/pickle2.cpp create mode 100644 example/pickle3.cpp create mode 100644 example/tst_dvect1.py create mode 100644 example/tst_ivect1.py create mode 100644 example/tst_noncopyable.py diff --git a/example/do_it_yourself_converters.cpp b/example/do_it_yourself_converters.cpp new file mode 100644 index 00000000..6d2d2d6a --- /dev/null +++ b/example/do_it_yourself_converters.cpp @@ -0,0 +1,128 @@ +// Example by Ralf W. Grosse-Kunstleve +/* + + This example shows how to convert a class from and to native + Python objects, such as tuples. + + We do not want to expose the helper class MillerIndex as an + Extension Class. However, in order to simplify the wrapper code, + we want to define from_python() and to_python() functions for + class MillerIndex. + + Consider the alternatives: + + - Expose MillerIndex as an Extension Class. + We need a constructor MillerIndex(python::tuple). + Python function calls become more complex: + foo(MillerIndex((1,2,3)) instead of foo((1,2,3)) + We need a method such as MillerIndex().as_tuple(). + + - Define a wrapper function for each function that we + want to expose, e.g.: + void add(const IndexingSet& ixset, const python::tuple PyMIx) + + The first alternative introduces a new type that the user has to + deal with. Other modules using Miller indices might organize them in + different ways, for example to increase runtime efficiency for + important procedures. This means, the user has to know how to + convert between the different kinds of Miller index representations. + This can quickly become a nuisance. Relying on native Python data + structures minimizes the number of special types the user has to + learn and convert. Of course, this argument is only valid for + small and relatively simply classes. + + If there are many member functions with MillerIndex arguments, the + second alternative is impractical, and concentrating the conversion + mechanism in one central place is essential for code + maintainability. An added benefit is that more convenient (smarter) + conversion functions can be provided without cluttering the rest of + the wrapper code. + + */ + +#include +#include +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // The helper class. + // + class MillerIndex { + public: + int v[3]; + }; + + // The main class. Imagine that there are MANY member functions + // like add() and get(). + // + class IndexingSet { + private: + std::vector VMIx; + public: + void add(const MillerIndex& MIx) { VMIx.push_back(MIx); } + MillerIndex get(std::size_t i) const { return VMIx[i]; } + }; +} + +BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE + + // Convert a Python tuple to a MillerIndex object. + // + MillerIndex from_python(PyObject* p, python::type) + { + python::tuple tup + = python::tuple(python::ref(p, python::ref::increment_count)); + if (tup.size() != 3) { + PyErr_SetString(PyExc_ValueError, + "expecting exactly 3 values in tuple."); + throw python::error_already_set(); + } + MillerIndex result; + for (int i = 0; i < 3; i++) + result.v[i] = from_python(tup[i].get(), python::type()); + return result; + } + + // Similar conversion for MillerIndex objects passed by value. + // Not actually used, but included to show the principle. + // + MillerIndex from_python(PyObject* p, python::type) + { + return from_python(p, python::type()); + } + + // Convert a MillerIndex object to a Python tuple. + // + PyObject* to_python(const MillerIndex& hkl) + { + python::tuple result(3); + for (int i = 0; i < 3; i++) + result.set_item(i, python::ref(to_python(hkl.v[i]))); + return result.reference().release(); + } + +BOOST_PYTHON_END_CONVERSION_NAMESPACE + +BOOST_PYTHON_MODULE_INIT(do_it_yourself_converters) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("do_it_yourself_converters"); + + // Create the Python type object for our extension class. + python::class_builder ixset_class(this_module, "IndexingSet"); + + // Add the __init__ function. + ixset_class.def(python::constructor<>()); + // Add the member functions. + ixset_class.def(&IndexingSet::add, "add"); + ixset_class.def(&IndexingSet::get, "get"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/dvect.cpp b/example/dvect.cpp new file mode 100644 index 00000000..da6b35a3 --- /dev/null +++ b/example/dvect.cpp @@ -0,0 +1,45 @@ +// Example by Ralf W. Grosse-Kunstleve +// See root/libs/python/doc/cross_module.html for an introduction. + +#include "dvect.h" +#include "ivect.h" +#include +namespace python = boost::python; + +namespace { + +# include "dvect_conversions.cpp" +# include "ivect_conversions.cpp" + + vects::ivect dvect_as_ivect(const vects::dvect& dv) + { + vects::ivect iv(dv.size()); + vects::ivect::iterator iviter = iv.begin(); + for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); + return iv; + } +} + +BOOST_PYTHON_MODULE_INIT(dvect) +{ + try + { + python::module_builder this_module("dvect"); + + python::class_builder dvect_class(this_module, "dvect"); + python::export_converters(dvect_class); + + python::import_converters ivect_converters("ivect", "ivect"); + + dvect_class.def(python::constructor()); + dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); + dvect_class.def(dvect_as_ivect, "as_ivect"); + +# include "dvect_defs.cpp" +# include "ivect_defs.cpp" + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/ivect.cpp b/example/ivect.cpp new file mode 100644 index 00000000..db1c0ec3 --- /dev/null +++ b/example/ivect.cpp @@ -0,0 +1,45 @@ +// Example by Ralf W. Grosse-Kunstleve +// See root/libs/python/doc/cross_module.html for an introduction. + +#include "dvect.h" +#include "ivect.h" +#include +namespace python = boost::python; + +namespace { + +# include "dvect_conversions.cpp" +# include "ivect_conversions.cpp" + + vects::dvect ivect_as_dvect(const vects::ivect& iv) + { + vects::dvect dv(iv.size()); + vects::dvect::iterator dviter = dv.begin(); + for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); + return dv; + } +} + +BOOST_PYTHON_MODULE_INIT(ivect) +{ + try + { + python::module_builder this_module("ivect"); + + python::class_builder ivect_class(this_module, "ivect"); + python::export_converters(ivect_class); + + python::import_converters dvect_converters("dvect", "dvect"); + + ivect_class.def(python::constructor()); + ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); + ivect_class.def(ivect_as_dvect, "as_dvect"); + +# include "dvect_defs.cpp" +# include "ivect_defs.cpp" + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp new file mode 100644 index 00000000..794b1200 --- /dev/null +++ b/example/noncopyable_export.cpp @@ -0,0 +1,25 @@ +// Example by Ralf W. Grosse-Kunstleve +// See root/libs/python/doc/cross_module.html for an introduction. + +#include +namespace python = boost::python; + +#include "noncopyable.h" + +BOOST_PYTHON_MODULE_INIT(noncopyable_export) +{ + try + { + python::module_builder this_module("noncopyable_export"); + + python::class_builder store_class(this_module, "store"); + python::export_converters_noncopyable(store_class); + + store_class.def(python::constructor()); + store_class.def(&store::recall, "recall"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp new file mode 100644 index 00000000..ea2477be --- /dev/null +++ b/example/noncopyable_import.cpp @@ -0,0 +1,42 @@ +// Example by Ralf W. Grosse-Kunstleve +// See root/libs/python/doc/cross_module.html for an introduction. + +#include +namespace python = boost::python; + +#include "noncopyable.h" + +namespace { // Avoid cluttering the global namespace. + + // A function with store objects as both input and output parameters. + // Because the copy constructor is disabled, we cannot pass a store + // object by value. Instead, we pass a smart pointer. + std::auto_ptr add_stores(const store& s1, const store& s2) + { + int sum = s1.recall() + s2.recall(); + std::auto_ptr ss = std::auto_ptr(new store(sum)); + return ss; + } +} + +BOOST_PYTHON_MODULE_INIT(noncopyable_import) +{ + try + { + python::module_builder this_module("noncopyable_import"); + + python::import_converters + dvect_converters("noncopyable_export", "store"); + + // Imagine all the additional classes with member functions + // that have store objects as input and output parameters. + // Lots and lots of them. + // However, to keep this example simple, we only define a + // module-level function. + this_module.def(add_stores, "add_stores"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/pickle1.cpp b/example/pickle1.cpp new file mode 100644 index 00000000..cdd78989 --- /dev/null +++ b/example/pickle1.cpp @@ -0,0 +1,64 @@ +// Example by Ralf W. Grosse-Kunstleve + +/* + This example shows how to make an Extension Class "pickleable". + + The world class below can be fully restored by passing the + appropriate argument to the constructor. Therefore it is sufficient + to define the pickle interface method __getinitargs__. + + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include + +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + private: + std::string country; + int secret_number; + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + }; + + // Support for pickle. + python::ref world_getinitargs(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_country()); + return result.reference(); + } +} + +BOOST_PYTHON_MODULE_INIT(pickle1) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("pickle1"); + + // Create the Python type object for our extension class. + python::class_builder world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(python::constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + + // Support for pickle. + world_class.def(world_getinitargs, "__getinitargs__"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/pickle2.cpp b/example/pickle2.cpp new file mode 100644 index 00000000..d6aa3201 --- /dev/null +++ b/example/pickle2.cpp @@ -0,0 +1,100 @@ +// Example by Ralf W. Grosse-Kunstleve + +/* + This example shows how to make an Extension Class "pickleable". + + The world class below contains member data (secret_number) that + cannot be restored by any of the constructors. Therefore it is + necessary to provide the __getstate__/__setstate__ pair of pickle + interface methods. + + For simplicity, the __dict__ is not included in the result of + __getstate__. This is not generally recommended, but a valid + approach if it is anticipated that the object's __dict__ will + always be empty. Note that safety guard are provided to catch the + cases where this assumption is not true. + + pickle3.cpp shows how to include the object's __dict__ in the + result of __getstate__. + + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include + +#include +namespace python = boost::python; + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + void set_secret_number(int number) { secret_number = number; } + int get_secret_number() const { return secret_number; } + private: + std::string country; + int secret_number; + }; + + // Support for pickle. + + using BOOST_PYTHON_CONVERSION::from_python; + + python::ref world_getinitargs(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_country()); + return result.reference(); // returning the reference avoids the copying. + } + + python::ref world_getstate(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_secret_number()); + return result.reference(); // returning the reference avoids the copying. + } + + void world_setstate(world& w, python::tuple state) { + if (state.size() != 1) { + PyErr_SetString(PyExc_ValueError, + "Unexpected argument in call to __setstate__."); + throw python::error_already_set(); + } + int number = from_python(state[0].get(), python::type()); + if (number != 42) + w.set_secret_number(number); + } +} + +BOOST_PYTHON_MODULE_INIT(pickle2) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("pickle2"); + + // Create the Python type object for our extension class. + python::class_builder world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(python::constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + world_class.def(&world::get_secret_number, "get_secret_number"); + world_class.def(&world::set_secret_number, "set_secret_number"); + + // Support for pickle. + world_class.def(world_getinitargs, "__getinitargs__"); + world_class.def(world_getstate, "__getstate__"); + world_class.def(world_setstate, "__setstate__"); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} diff --git a/example/pickle3.cpp b/example/pickle3.cpp new file mode 100644 index 00000000..bfa7dc54 --- /dev/null +++ b/example/pickle3.cpp @@ -0,0 +1,150 @@ +// Example by Ralf W. Grosse-Kunstleve + +/* + This example shows how to make an Extension Class "pickleable". + + The world class below contains member data (secret_number) that + cannot be restored by any of the constructors. Therefore it is + necessary to provide the __getstate__/__setstate__ pair of pickle + interface methods. + + The object's __dict__ is included in the result of __getstate__. + This requires more code (compare with pickle2.cpp), but is + unavoidable if the object's __dict__ is not always empty. + + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include + +#include +namespace python = boost::python; + +namespace boost { namespace python { + + ref getattr(PyObject* o, const std::string& attr_name) { + return ref(PyObject_GetAttrString(o, const_cast(attr_name.c_str()))); + } + ref getattr(const ref& r, const std::string& attr_name) { + return getattr(r.get(), attr_name); + } + +}} + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + void set_secret_number(int number) { secret_number = number; } + int get_secret_number() const { return secret_number; } + private: + std::string country; + int secret_number; + }; + + // Support for pickle. + python::ref world_getinitargs(const world& w) { + python::tuple result(1); + result.set_item(0, w.get_country()); + return result.reference(); // returning the reference avoids the copying. + } + + python::ref world_getstate(python::tuple const & args, + python::dictionary const & keywords); + + PyObject* world_setstate(python::tuple const & args, + python::dictionary const & keywords); +} + +BOOST_PYTHON_MODULE_INIT(pickle3) +{ + try + { + // Create an object representing this extension module. + python::module_builder this_module("pickle3"); + + // Create the Python type object for our extension class. + python::class_builder world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(python::constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + world_class.def(&world::get_secret_number, "get_secret_number"); + world_class.def(&world::set_secret_number, "set_secret_number"); + + // Support for pickle. + world_class.def(world_getinitargs, "__getinitargs__"); + world_class.def_raw(world_getstate, "__getstate__"); + world_class.def_raw(world_setstate, "__setstate__"); + world_class.getstate_manages_dict(); + } + catch(...) + { + python::handle_exception(); // Deal with the exception for Python + } +} + +namespace { + + using BOOST_PYTHON_CONVERSION::from_python; + using boost::python::type; + using boost::python::ref; + using boost::python::tuple; + using boost::python::list; + using boost::python::dictionary; + using boost::python::getattr; + + ref world_getstate(tuple const & args, dictionary const & keywords) + { + if(args.size() != 1 || keywords.size() != 0) { + PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); + throw boost::python::argument_error(); + } + const world& w = from_python(args[0].get(), type()); + ref mydict = getattr(args[0], "__dict__"); + tuple result(2); + // store the object's __dict__ + result.set_item(0, mydict); + // store the internal state of the C++ object + result.set_item(1, w.get_secret_number()); + return result.reference(); // returning the reference avoids the copying. + } + + PyObject* world_setstate(tuple const & args, dictionary const & keywords) + { + if(args.size() != 2 || keywords.size() != 0) { + PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); + throw boost::python::argument_error(); + } + world& w = from_python(args[0].get(), type()); + ref mydict = getattr(args[0], "__dict__"); + tuple state = from_python(args[1].get(), type()); + if (state.size() != 2) { + PyErr_SetString(PyExc_ValueError, + "Unexpected argument in call to __setstate__."); + throw python::error_already_set(); + } + // restore the object's __dict__ + dictionary odict = from_python(mydict.get(), type()); + const dictionary& pdict = from_python(state[0].get(), type()); + list pkeys(pdict.keys()); + for (int i = 0; i < pkeys.size(); i++) { + ref k(pkeys[i]); + //odict[k] = pdict[k]; // XXX memory leak! + odict[k] = pdict.get_item(k); // this does not leak. + } + // restore the internal state of the C++ object + int number = from_python(state[1].get(), type()); + if (number != 42) + w.set_secret_number(number); + return python::detail::none(); + } +} diff --git a/example/tst_dvect1.py b/example/tst_dvect1.py new file mode 100644 index 00000000..22315528 --- /dev/null +++ b/example/tst_dvect1.py @@ -0,0 +1,20 @@ +def f(): + import dvect + dv = dvect.dvect((1,2,3,4,5)) + print dv.as_tuple() + iv = dv.as_ivect() + print iv.as_tuple() + print dvect.const_ivect_reference_as_tuple(iv) + aiv = dvect.ivect_as_auto_ptr(iv) + print dvect.const_ivect_reference_as_tuple(aiv) + siv = dvect.ivect_as_shared_ptr(iv) + print dvect.const_ivect_reference_as_tuple(siv) + print aiv.as_tuple() + print siv.as_tuple() + +if (__name__ == "__main__"): + import sys, string + n = 1 + if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) + for i in xrange(n): + f() diff --git a/example/tst_ivect1.py b/example/tst_ivect1.py new file mode 100644 index 00000000..7369fdbf --- /dev/null +++ b/example/tst_ivect1.py @@ -0,0 +1,20 @@ +def f(): + import ivect + iv = ivect.ivect((1,2,3,4,5)) + print iv.as_tuple() + dv = iv.as_dvect() + print dv.as_tuple() + print ivect.const_dvect_reference_as_tuple(dv) + adv = ivect.dvect_as_auto_ptr(dv) + print ivect.const_dvect_reference_as_tuple(adv) + sdv = ivect.dvect_as_shared_ptr(dv) + print ivect.const_dvect_reference_as_tuple(sdv) + print adv.as_tuple() + print sdv.as_tuple() + +if (__name__ == "__main__"): + import sys, string + n = 1 + if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) + for i in xrange(n): + f() diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py new file mode 100644 index 00000000..155910a5 --- /dev/null +++ b/example/tst_noncopyable.py @@ -0,0 +1,16 @@ +def f(): + import noncopyable_export + import noncopyable_import + s1 = noncopyable_export.store(1) + print s1.recall() + s2 = noncopyable_export.store(2) + print s2.recall() + s3 = noncopyable_import.add_stores(s1, s2) + print s3.recall() + +if (__name__ == "__main__"): + import sys, string + n = 1 + if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) + for i in xrange(n): + f() From 349b9bb2bf2f5dbc9b2365752b4d516d4ed62147 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 18 Apr 2001 19:13:11 +0000 Subject: [PATCH 0073/1042] use reserved symbol for detecting sgi [SVN r9835] --- test/comprehensive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index aa2d9886..410bd243 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -15,7 +15,7 @@ #include // for pow() #include -#if defined(sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 +#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 inline double pow(int x, int y) { return pow(static_cast(x), y); } #endif From fb8d9edfdfda1999bffd73c3e3dcb9cd626a039b Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Wed, 25 Apr 2001 00:24:50 +0000 Subject: [PATCH 0074/1042] Change all eGroups references to YahooGroups [SVN r9979] --- doc/index.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index 5ec32a6b..f636e7a8 100644 --- a/doc/index.html +++ b/doc/index.html @@ -1,6 +1,5 @@ - The Boost Python Library (Boost.Python) @@ -154,7 +153,7 @@ among others.

    Questions should be directed to the boost mailing list. + "http://www.yahoogroups.com/list/boost">the boost mailing list.

    © Copyright David Abrahams 2001. Permission to copy, use, modify, From 00b4f09e8abc953f106663bf316bad837af4ec82 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 5 May 2001 01:06:33 +0000 Subject: [PATCH 0075/1042] Check indices passed to __getitem__, __setitem__, __delitem__ [SVN r10009] --- build/irix_CC.mak | 2 +- example/simple_vector.cpp | 8 ++++++++ example/test_simple_vector.py | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/build/irix_CC.mak b/build/irix_CC.mak index 5894ff51..0436ef8a 100644 --- a/build/irix_CC.mak +++ b/build/irix_CC.mak @@ -24,7 +24,7 @@ PYINC=-I/usr/local/Python-1.5.2/include/python1.5 STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers STDOPTS= -WARNOPTS=-woff 1001,1234,1682 +WARNOPTS=-woff 1001,1183,1234,1682 OPTOPTS=-g CPP=CC -LANG:std -n32 -mips4 diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp index 5ac0767b..8f30121b 100644 --- a/example/simple_vector.cpp +++ b/example/simple_vector.cpp @@ -30,16 +30,24 @@ namespace { // Avoid cluttering the global namespace. } }; + void raise_vector_IndexError() { + PyErr_SetString(PyExc_IndexError, "IndexError: vector index out of range"); + throw python::error_already_set(); + } + double getitem(const std::vector& vd, std::size_t key) { + if (key < 0 || key >= vd.size()) raise_vector_IndexError(); return vd[key]; } void setitem(std::vector& vd, std::size_t key, double d) { + if (key < 0 || key >= vd.size()) raise_vector_IndexError(); std::vector::iterator vditer = vd.begin(); vditer[key] = d; } void delitem(std::vector& vd, std::size_t key) { + if (key < 0 || key >= vd.size()) raise_vector_IndexError(); std::vector::iterator vditer = vd.begin(); vd.erase(&vditer[key]); } diff --git a/example/test_simple_vector.py b/example/test_simple_vector.py index a19e205b..ca38d715 100644 --- a/example/test_simple_vector.py +++ b/example/test_simple_vector.py @@ -15,6 +15,11 @@ r'''>>> import simple_vector >>> v[1] = 40 >>> print v.as_tuple() (3.0, 40.0, 5.0) + >>> for e in v: + ... print e + 3.0 + 40.0 + 5.0 >>> del v[1] >>> print v.as_tuple() (3.0, 5.0) From 25320cd0e02bb14b058fa51fc2e2bc6e29000435 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 14 May 2001 21:43:34 +0000 Subject: [PATCH 0076/1042] Removed: unnecessary key < 0 test. [SVN r10113] --- build/irix_CC.mak | 2 +- example/simple_vector.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/irix_CC.mak b/build/irix_CC.mak index 0436ef8a..5894ff51 100644 --- a/build/irix_CC.mak +++ b/build/irix_CC.mak @@ -24,7 +24,7 @@ PYINC=-I/usr/local/Python-1.5.2/include/python1.5 STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers STDOPTS= -WARNOPTS=-woff 1001,1183,1234,1682 +WARNOPTS=-woff 1001,1234,1682 OPTOPTS=-g CPP=CC -LANG:std -n32 -mips4 diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp index 8f30121b..2b3aa290 100644 --- a/example/simple_vector.cpp +++ b/example/simple_vector.cpp @@ -31,23 +31,23 @@ namespace { // Avoid cluttering the global namespace. }; void raise_vector_IndexError() { - PyErr_SetString(PyExc_IndexError, "IndexError: vector index out of range"); + PyErr_SetString(PyExc_IndexError, "vector index out of range"); throw python::error_already_set(); } double getitem(const std::vector& vd, std::size_t key) { - if (key < 0 || key >= vd.size()) raise_vector_IndexError(); + if (key >= vd.size()) raise_vector_IndexError(); return vd[key]; } void setitem(std::vector& vd, std::size_t key, double d) { - if (key < 0 || key >= vd.size()) raise_vector_IndexError(); + if (key >= vd.size()) raise_vector_IndexError(); std::vector::iterator vditer = vd.begin(); vditer[key] = d; } void delitem(std::vector& vd, std::size_t key) { - if (key < 0 || key >= vd.size()) raise_vector_IndexError(); + if (key >= vd.size()) raise_vector_IndexError(); std::vector::iterator vditer = vd.begin(); vd.erase(&vditer[key]); } From d04f613c419c0b726d6f5d28b5e48d9ee3dff4e4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 18 May 2001 15:12:30 +0000 Subject: [PATCH 0077/1042] Fix up internal links [SVN r10122] --- doc/overriding.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/overriding.html b/doc/overriding.html index af458d79..02665be5 100644 --- a/doc/overriding.html +++ b/doc/overriding.html @@ -47,17 +47,17 @@ class hello PyObject* argument. The initial argument should be stored in the self data member described above. -

  • If the class being wrapped is ever returned by +
  • If the class being wrapped is ever returned by value from a wrapped function, be sure you do the same for the T's copy constructor: you'll need a constructor taking arguments (PyObject*, const T&). -
  • An implementation of each virtual function you may +
  • An implementation of each virtual function you may wish to override in Python which uses callback<return-type>::call_method(self, "name", args...) to call the Python override. -
  • For each non-pure virtual function meant to be +
  • For each non-pure virtual function meant to be overridable from Python, a static member function (or a free function) taking a reference or pointer to the T as the first parameter and which forwards any additional parameters neccessary to the default @@ -211,5 +211,5 @@ href="http://cs.calvin.edu/c++/C++Standard-Nov97/basic.html#basic.def.odr">ODR - Updated: Mar 6, 2001 + Updated: Mar 21, 2001 From 188597ecaf2968d6811d0272dc4cbc09e8d77023 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 24 May 2001 08:28:46 +0000 Subject: [PATCH 0078/1042] fixes tested with vc60, tru64cxx, irixCC, gcc2952 [SVN r10208] --- include/boost/python/callback.hpp | 440 ++++++++++++------------- include/boost/python/caller.hpp | 68 ++-- include/boost/python/detail/config.hpp | 23 +- 3 files changed, 264 insertions(+), 267 deletions(-) diff --git a/include/boost/python/callback.hpp b/include/boost/python/callback.hpp index 7240b5b7..b9e850c6 100644 --- a/include/boost/python/callback.hpp +++ b/include/boost/python/callback.hpp @@ -46,7 +46,7 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1) { - ref p1(to_python(a1)); + ref p1(to_python(search_namespace, a1)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(O)"), p1.get())); @@ -57,7 +57,7 @@ struct callback template static R call(PyObject* self, const A1& a1) { - ref p1(to_python(a1)); + ref p1(to_python(search_namespace, a1)); ref result(PyEval_CallFunction(self, const_cast("(O)"), p1.get())); detail::callback_adjust_refcount(result.get(), type()); @@ -67,8 +67,8 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OO)"), p1.get(), @@ -80,8 +80,8 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); ref result(PyEval_CallFunction(self, const_cast("(OO)"), p1.get(), p2.get())); @@ -92,9 +92,9 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOO)"), p1.get(), @@ -107,9 +107,9 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); ref result(PyEval_CallFunction(self, const_cast("(OOO)"), p1.get(), p2.get(), @@ -121,10 +121,10 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOO)"), p1.get(), @@ -138,10 +138,10 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); ref result(PyEval_CallFunction(self, const_cast("(OOOO)"), p1.get(), p2.get(), @@ -154,11 +154,11 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOO)"), p1.get(), @@ -173,11 +173,11 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); ref result(PyEval_CallFunction(self, const_cast("(OOOOO)"), p1.get(), p2.get(), @@ -191,12 +191,12 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOO)"), p1.get(), @@ -212,12 +212,12 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOO)"), p1.get(), p2.get(), @@ -232,13 +232,13 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOO)"), p1.get(), @@ -255,13 +255,13 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOO)"), p1.get(), p2.get(), @@ -277,14 +277,14 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOO)"), p1.get(), @@ -302,14 +302,14 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOO)"), p1.get(), p2.get(), @@ -326,15 +326,15 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); + ref p9(to_python(search_namespace, a9)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOOO)"), p1.get(), @@ -353,15 +353,15 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); + ref p9(to_python(search_namespace, a9)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOO)"), p1.get(), p2.get(), @@ -379,16 +379,16 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); + ref p9(to_python(search_namespace, a9)); + ref p10(to_python(search_namespace, a10)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOOOO)"), p1.get(), @@ -408,16 +408,16 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); + ref p9(to_python(search_namespace, a9)); + ref p10(to_python(search_namespace, a10)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOOO)"), p1.get(), p2.get(), @@ -455,7 +455,7 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1) { - ref p1(to_python(a1)); + ref p1(to_python(search_namespace, a1)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(O)"), p1.get())); @@ -464,7 +464,7 @@ struct callback template static void call(PyObject* self, const A1& a1) { - ref p1(to_python(a1)); + ref p1(to_python(search_namespace, a1)); ref result(PyEval_CallFunction(self, const_cast("(O)"), p1.get())); } @@ -472,8 +472,8 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OO)"), p1.get(), @@ -483,8 +483,8 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); ref result(PyEval_CallFunction(self, const_cast("(OO)"), p1.get(), p2.get())); @@ -493,9 +493,9 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOO)"), p1.get(), @@ -506,9 +506,9 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); ref result(PyEval_CallFunction(self, const_cast("(OOO)"), p1.get(), p2.get(), @@ -518,10 +518,10 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOO)"), p1.get(), @@ -533,10 +533,10 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); ref result(PyEval_CallFunction(self, const_cast("(OOOO)"), p1.get(), p2.get(), @@ -547,11 +547,11 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOO)"), p1.get(), @@ -564,11 +564,11 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); ref result(PyEval_CallFunction(self, const_cast("(OOOOO)"), p1.get(), p2.get(), @@ -580,12 +580,12 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOO)"), p1.get(), @@ -599,12 +599,12 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOO)"), p1.get(), p2.get(), @@ -617,13 +617,13 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOO)"), p1.get(), @@ -638,13 +638,13 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOO)"), p1.get(), p2.get(), @@ -658,14 +658,14 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOO)"), p1.get(), @@ -681,14 +681,14 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOO)"), p1.get(), p2.get(), @@ -703,15 +703,15 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); + ref p9(to_python(search_namespace, a9)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOOO)"), p1.get(), @@ -728,15 +728,15 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); + ref p9(to_python(search_namespace, a9)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOO)"), p1.get(), p2.get(), @@ -752,16 +752,16 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); + ref p9(to_python(search_namespace, a9)); + ref p10(to_python(search_namespace, a10)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOOOO)"), p1.get(), @@ -779,16 +779,16 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); + ref p1(to_python(search_namespace, a1)); + ref p2(to_python(search_namespace, a2)); + ref p3(to_python(search_namespace, a3)); + ref p4(to_python(search_namespace, a4)); + ref p5(to_python(search_namespace, a5)); + ref p6(to_python(search_namespace, a6)); + ref p7(to_python(search_namespace, a7)); + ref p8(to_python(search_namespace, a8)); + ref p9(to_python(search_namespace, a9)); + ref p10(to_python(search_namespace, a10)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOOO)"), p1.get(), p2.get(), diff --git a/include/boost/python/caller.hpp b/include/boost/python/caller.hpp index 35b2d618..86820233 100644 --- a/include/boost/python/caller.hpp +++ b/include/boost/python/caller.hpp @@ -30,7 +30,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("O"), &self)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)()); + return to_python(search_namespace, (target.*pmf)()); } template @@ -40,7 +40,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()))); + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()))); } template @@ -51,7 +51,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()))); } @@ -64,7 +64,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()))); } @@ -79,7 +79,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()))); @@ -96,7 +96,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -115,7 +115,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -136,7 +136,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -159,7 +159,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -184,7 +184,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -211,7 +211,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -230,7 +230,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("O"), &self)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)()); + return to_python(search_namespace, (target.*pmf)()); } template @@ -240,7 +240,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()))); + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()))); } template @@ -251,7 +251,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()))); } @@ -264,7 +264,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()))); } @@ -279,7 +279,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()))); @@ -296,7 +296,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -315,7 +315,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -336,7 +336,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -359,7 +359,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -384,7 +384,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -411,7 +411,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) return 0; T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), + return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -427,7 +427,7 @@ struct caller static PyObject* call(R (*f)(), PyObject* args, PyObject* /* keywords */ ) { if (!PyArg_ParseTuple(args, const_cast(""))) return 0; - return to_python(f()); + return to_python(search_namespace, f()); } template @@ -435,7 +435,7 @@ struct caller PyObject* a1; if (!PyArg_ParseTuple(args, const_cast("O"), &a1)) return 0; - return to_python(f(from_python(a1, type()))); + return to_python(search_namespace, f(from_python(a1, type()))); } template @@ -444,7 +444,7 @@ struct caller PyObject* a2; if (!PyArg_ParseTuple(args, const_cast("OO"), &a1, &a2)) return 0; - return to_python(f(from_python(a1, type()), + return to_python(search_namespace, f(from_python(a1, type()), from_python(a2, type()))); } @@ -455,7 +455,7 @@ struct caller PyObject* a3; if (!PyArg_ParseTuple(args, const_cast("OOO"), &a1, &a2, &a3)) return 0; - return to_python(f(from_python(a1, type()), + return to_python(search_namespace, f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()))); } @@ -468,7 +468,7 @@ struct caller PyObject* a4; if (!PyArg_ParseTuple(args, const_cast("OOOO"), &a1, &a2, &a3, &a4)) return 0; - return to_python(f(from_python(a1, type()), + return to_python(search_namespace, f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()))); @@ -483,7 +483,7 @@ struct caller PyObject* a5; if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &a1, &a2, &a3, &a4, &a5)) return 0; - return to_python(f(from_python(a1, type()), + return to_python(search_namespace, f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -500,7 +500,7 @@ struct caller PyObject* a6; if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6)) return 0; - return to_python(f(from_python(a1, type()), + return to_python(search_namespace, f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -519,7 +519,7 @@ struct caller PyObject* a7; if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7)) return 0; - return to_python(f(from_python(a1, type()), + return to_python(search_namespace, f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -540,7 +540,7 @@ struct caller PyObject* a8; if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) return 0; - return to_python(f(from_python(a1, type()), + return to_python(search_namespace, f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -563,7 +563,7 @@ struct caller PyObject* a9; if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) return 0; - return to_python(f(from_python(a1, type()), + return to_python(search_namespace, f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -588,7 +588,7 @@ struct caller PyObject* a10; if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) return 0; - return to_python(f(from_python(a1, type()), + return to_python(search_namespace, f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -615,7 +615,7 @@ struct caller PyObject* a11; if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11)) return 0; - return to_python(f(from_python(a1, type()), + return to_python(search_namespace, f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 9792695e..348bcc39 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -15,19 +15,6 @@ # include # include -# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE - // A gcc bug forces some symbols into the global namespace -# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -# define BOOST_PYTHON_END_CONVERSION_NAMESPACE -# define BOOST_PYTHON_CONVERSION -# define BOOST_PYTHON_IMPORT_CONVERSION(x) using ::x -# else -# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python { -# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python -# define BOOST_PYTHON_CONVERSION boost::python -# define BOOST_PYTHON_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';' -# endif - # if defined(BOOST_MSVC) # if _MSC_VER <= 1200 # define BOOST_MSVC6_OR_EARLIER 1 @@ -37,6 +24,16 @@ # endif +# if defined(BOOST_PYTHON_USE_FRIEND_KOENIG_LOOKUP) +// for compilers that support Koenig lookup +# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python { +# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python +# else +// for compilers that do not support Koenig lookup for friend functions +# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE +# define BOOST_PYTHON_END_CONVERSION_NAMESPACE +# endif + // Work around the broken library implementation/strict ansi checking on some // EDG-based compilers (e.g. alpha), which incorrectly warn that the result of // offsetof() is not an integer constant expression. From 294254efbb4539e93fb86249e7c92a5377191b88 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 24 May 2001 08:43:56 +0000 Subject: [PATCH 0079/1042] Fix accident: restore main version. [SVN r10209] --- include/boost/python/callback.hpp | 440 +++++++++++++++--------------- include/boost/python/caller.hpp | 68 ++--- 2 files changed, 254 insertions(+), 254 deletions(-) diff --git a/include/boost/python/callback.hpp b/include/boost/python/callback.hpp index b9e850c6..7240b5b7 100644 --- a/include/boost/python/callback.hpp +++ b/include/boost/python/callback.hpp @@ -46,7 +46,7 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1) { - ref p1(to_python(search_namespace, a1)); + ref p1(to_python(a1)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(O)"), p1.get())); @@ -57,7 +57,7 @@ struct callback template static R call(PyObject* self, const A1& a1) { - ref p1(to_python(search_namespace, a1)); + ref p1(to_python(a1)); ref result(PyEval_CallFunction(self, const_cast("(O)"), p1.get())); detail::callback_adjust_refcount(result.get(), type()); @@ -67,8 +67,8 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OO)"), p1.get(), @@ -80,8 +80,8 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); ref result(PyEval_CallFunction(self, const_cast("(OO)"), p1.get(), p2.get())); @@ -92,9 +92,9 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOO)"), p1.get(), @@ -107,9 +107,9 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); ref result(PyEval_CallFunction(self, const_cast("(OOO)"), p1.get(), p2.get(), @@ -121,10 +121,10 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOO)"), p1.get(), @@ -138,10 +138,10 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); ref result(PyEval_CallFunction(self, const_cast("(OOOO)"), p1.get(), p2.get(), @@ -154,11 +154,11 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOO)"), p1.get(), @@ -173,11 +173,11 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); ref result(PyEval_CallFunction(self, const_cast("(OOOOO)"), p1.get(), p2.get(), @@ -191,12 +191,12 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOO)"), p1.get(), @@ -212,12 +212,12 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOO)"), p1.get(), p2.get(), @@ -232,13 +232,13 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOO)"), p1.get(), @@ -255,13 +255,13 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOO)"), p1.get(), p2.get(), @@ -277,14 +277,14 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOO)"), p1.get(), @@ -302,14 +302,14 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOO)"), p1.get(), p2.get(), @@ -326,15 +326,15 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); - ref p9(to_python(search_namespace, a9)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); + ref p9(to_python(a9)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOOO)"), p1.get(), @@ -353,15 +353,15 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); - ref p9(to_python(search_namespace, a9)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); + ref p9(to_python(a9)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOO)"), p1.get(), p2.get(), @@ -379,16 +379,16 @@ struct callback template static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); - ref p9(to_python(search_namespace, a9)); - ref p10(to_python(search_namespace, a10)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); + ref p9(to_python(a9)); + ref p10(to_python(a10)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOOOO)"), p1.get(), @@ -408,16 +408,16 @@ struct callback template static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); - ref p9(to_python(search_namespace, a9)); - ref p10(to_python(search_namespace, a10)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); + ref p9(to_python(a9)); + ref p10(to_python(a10)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOOO)"), p1.get(), p2.get(), @@ -455,7 +455,7 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1) { - ref p1(to_python(search_namespace, a1)); + ref p1(to_python(a1)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(O)"), p1.get())); @@ -464,7 +464,7 @@ struct callback template static void call(PyObject* self, const A1& a1) { - ref p1(to_python(search_namespace, a1)); + ref p1(to_python(a1)); ref result(PyEval_CallFunction(self, const_cast("(O)"), p1.get())); } @@ -472,8 +472,8 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OO)"), p1.get(), @@ -483,8 +483,8 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); ref result(PyEval_CallFunction(self, const_cast("(OO)"), p1.get(), p2.get())); @@ -493,9 +493,9 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOO)"), p1.get(), @@ -506,9 +506,9 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); ref result(PyEval_CallFunction(self, const_cast("(OOO)"), p1.get(), p2.get(), @@ -518,10 +518,10 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOO)"), p1.get(), @@ -533,10 +533,10 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); ref result(PyEval_CallFunction(self, const_cast("(OOOO)"), p1.get(), p2.get(), @@ -547,11 +547,11 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOO)"), p1.get(), @@ -564,11 +564,11 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); ref result(PyEval_CallFunction(self, const_cast("(OOOOO)"), p1.get(), p2.get(), @@ -580,12 +580,12 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOO)"), p1.get(), @@ -599,12 +599,12 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOO)"), p1.get(), p2.get(), @@ -617,13 +617,13 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOO)"), p1.get(), @@ -638,13 +638,13 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOO)"), p1.get(), p2.get(), @@ -658,14 +658,14 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOO)"), p1.get(), @@ -681,14 +681,14 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOO)"), p1.get(), p2.get(), @@ -703,15 +703,15 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); - ref p9(to_python(search_namespace, a9)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); + ref p9(to_python(a9)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOOO)"), p1.get(), @@ -728,15 +728,15 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); - ref p9(to_python(search_namespace, a9)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); + ref p9(to_python(a9)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOO)"), p1.get(), p2.get(), @@ -752,16 +752,16 @@ struct callback template static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); - ref p9(to_python(search_namespace, a9)); - ref p10(to_python(search_namespace, a10)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); + ref p9(to_python(a9)); + ref p10(to_python(a10)); ref result(PyEval_CallMethod(self, const_cast(name), const_cast("(OOOOOOOOOO)"), p1.get(), @@ -779,16 +779,16 @@ struct callback template static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) { - ref p1(to_python(search_namespace, a1)); - ref p2(to_python(search_namespace, a2)); - ref p3(to_python(search_namespace, a3)); - ref p4(to_python(search_namespace, a4)); - ref p5(to_python(search_namespace, a5)); - ref p6(to_python(search_namespace, a6)); - ref p7(to_python(search_namespace, a7)); - ref p8(to_python(search_namespace, a8)); - ref p9(to_python(search_namespace, a9)); - ref p10(to_python(search_namespace, a10)); + ref p1(to_python(a1)); + ref p2(to_python(a2)); + ref p3(to_python(a3)); + ref p4(to_python(a4)); + ref p5(to_python(a5)); + ref p6(to_python(a6)); + ref p7(to_python(a7)); + ref p8(to_python(a8)); + ref p9(to_python(a9)); + ref p10(to_python(a10)); ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOOO)"), p1.get(), p2.get(), diff --git a/include/boost/python/caller.hpp b/include/boost/python/caller.hpp index 86820233..35b2d618 100644 --- a/include/boost/python/caller.hpp +++ b/include/boost/python/caller.hpp @@ -30,7 +30,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("O"), &self)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)()); + return to_python((target.*pmf)()); } template @@ -40,7 +40,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()))); + return to_python((target.*pmf)(from_python(a1, type()))); } template @@ -51,7 +51,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()))); } @@ -64,7 +64,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()))); } @@ -79,7 +79,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()))); @@ -96,7 +96,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -115,7 +115,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -136,7 +136,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -159,7 +159,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -184,7 +184,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -211,7 +211,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -230,7 +230,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("O"), &self)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)()); + return to_python((target.*pmf)()); } template @@ -240,7 +240,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()))); + return to_python((target.*pmf)(from_python(a1, type()))); } template @@ -251,7 +251,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()))); } @@ -264,7 +264,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()))); } @@ -279,7 +279,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()))); @@ -296,7 +296,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -315,7 +315,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -336,7 +336,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -359,7 +359,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -384,7 +384,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -411,7 +411,7 @@ struct caller if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) return 0; T& target = from_python(self, type()); - return to_python(search_namespace, (target.*pmf)(from_python(a1, type()), + return to_python((target.*pmf)(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -427,7 +427,7 @@ struct caller static PyObject* call(R (*f)(), PyObject* args, PyObject* /* keywords */ ) { if (!PyArg_ParseTuple(args, const_cast(""))) return 0; - return to_python(search_namespace, f()); + return to_python(f()); } template @@ -435,7 +435,7 @@ struct caller PyObject* a1; if (!PyArg_ParseTuple(args, const_cast("O"), &a1)) return 0; - return to_python(search_namespace, f(from_python(a1, type()))); + return to_python(f(from_python(a1, type()))); } template @@ -444,7 +444,7 @@ struct caller PyObject* a2; if (!PyArg_ParseTuple(args, const_cast("OO"), &a1, &a2)) return 0; - return to_python(search_namespace, f(from_python(a1, type()), + return to_python(f(from_python(a1, type()), from_python(a2, type()))); } @@ -455,7 +455,7 @@ struct caller PyObject* a3; if (!PyArg_ParseTuple(args, const_cast("OOO"), &a1, &a2, &a3)) return 0; - return to_python(search_namespace, f(from_python(a1, type()), + return to_python(f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()))); } @@ -468,7 +468,7 @@ struct caller PyObject* a4; if (!PyArg_ParseTuple(args, const_cast("OOOO"), &a1, &a2, &a3, &a4)) return 0; - return to_python(search_namespace, f(from_python(a1, type()), + return to_python(f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()))); @@ -483,7 +483,7 @@ struct caller PyObject* a5; if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &a1, &a2, &a3, &a4, &a5)) return 0; - return to_python(search_namespace, f(from_python(a1, type()), + return to_python(f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -500,7 +500,7 @@ struct caller PyObject* a6; if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6)) return 0; - return to_python(search_namespace, f(from_python(a1, type()), + return to_python(f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -519,7 +519,7 @@ struct caller PyObject* a7; if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7)) return 0; - return to_python(search_namespace, f(from_python(a1, type()), + return to_python(f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -540,7 +540,7 @@ struct caller PyObject* a8; if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) return 0; - return to_python(search_namespace, f(from_python(a1, type()), + return to_python(f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -563,7 +563,7 @@ struct caller PyObject* a9; if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) return 0; - return to_python(search_namespace, f(from_python(a1, type()), + return to_python(f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -588,7 +588,7 @@ struct caller PyObject* a10; if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) return 0; - return to_python(search_namespace, f(from_python(a1, type()), + return to_python(f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), @@ -615,7 +615,7 @@ struct caller PyObject* a11; if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11)) return 0; - return to_python(search_namespace, f(from_python(a1, type()), + return to_python(f(from_python(a1, type()), from_python(a2, type()), from_python(a3, type()), from_python(a4, type()), From 66da2339d4abfa1820d6a0320fc6f98e1bc92a5e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 24 May 2001 08:51:05 +0000 Subject: [PATCH 0080/1042] Fix accident: restore main version. [SVN r10210] --- include/boost/python/detail/config.hpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 348bcc39..9792695e 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -15,6 +15,19 @@ # include # include +# ifdef BOOST_NO_OPERATORS_IN_NAMESPACE + // A gcc bug forces some symbols into the global namespace +# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE +# define BOOST_PYTHON_END_CONVERSION_NAMESPACE +# define BOOST_PYTHON_CONVERSION +# define BOOST_PYTHON_IMPORT_CONVERSION(x) using ::x +# else +# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python { +# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python +# define BOOST_PYTHON_CONVERSION boost::python +# define BOOST_PYTHON_IMPORT_CONVERSION(x) void never_defined() // so we can follow the macro with a ';' +# endif + # if defined(BOOST_MSVC) # if _MSC_VER <= 1200 # define BOOST_MSVC6_OR_EARLIER 1 @@ -24,16 +37,6 @@ # endif -# if defined(BOOST_PYTHON_USE_FRIEND_KOENIG_LOOKUP) -// for compilers that support Koenig lookup -# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE namespace boost { namespace python { -# define BOOST_PYTHON_END_CONVERSION_NAMESPACE }} // namespace boost::python -# else -// for compilers that do not support Koenig lookup for friend functions -# define BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -# define BOOST_PYTHON_END_CONVERSION_NAMESPACE -# endif - // Work around the broken library implementation/strict ansi checking on some // EDG-based compilers (e.g. alpha), which incorrectly warn that the result of // offsetof() is not an integer constant expression. From 29a855813d307864ee96d5f45f63582d24d846ca Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 28 May 2001 20:14:25 +0000 Subject: [PATCH 0081/1042] fixed typo [SVN r10240] --- doc/pointers.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pointers.html b/doc/pointers.html index fdbee797..00f7bb41 100644 --- a/doc/pointers.html +++ b/doc/pointers.html @@ -85,7 +85,7 @@ code before the last Python reference to it disappears: BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround PyObject* to_python(Foo* p) { - return boost::python::python_extension_class_converters<Foo>::ptr_to_python(p); + return boost::python::python_extension_class_converters<Foo>::ptr_to_python(p); } PyObject* to_python(const Foo* p) From 7a71cea92a4ecbc59a4072b8d083f2fb9680942e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 18 Jun 2001 12:11:46 +0000 Subject: [PATCH 0082/1042] updated ILU links thanks to Scott Langley [SVN r10355] --- doc/comparisons.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/comparisons.html b/doc/comparisons.html index 6f082d51..57cec744 100644 --- a/doc/comparisons.html +++ b/doc/comparisons.html @@ -112,10 +112,10 @@ that.''
    -Paul Dubois

    ILU

    ILU + href="ftp://ftp.parc.xerox.com/pub/ilu/ilu.html">ILU is a very ambitious project which tries to describe a module's interface (types and functions) in terms of an Interface + href="ftp://ftp.parc.xerox.com/pub/ilu/2.0b1/manual-html/manual_2.html">Interface Specification Language (ISL) so that it can be uniformly interfaced to a wide range of computer languages, including Common Lisp, C++, C, Modula-3, and Python. ILU can parse the ISL to generate a C++ language From 91f0728b5598b144df3a87f236f6512c5dae459d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 21 Jun 2001 20:46:26 +0000 Subject: [PATCH 0083/1042] Minor fix, thanks to Jens Maurer. [SVN r10377] --- example/simple_vector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp index 2b3aa290..3499c8f7 100644 --- a/example/simple_vector.cpp +++ b/example/simple_vector.cpp @@ -49,7 +49,7 @@ namespace { // Avoid cluttering the global namespace. void delitem(std::vector& vd, std::size_t key) { if (key >= vd.size()) raise_vector_IndexError(); std::vector::iterator vditer = vd.begin(); - vd.erase(&vditer[key]); + vd.erase(vditer + key); } // Convert vector_double to a regular Python tuple. From 8b88e9f7272e8d0041deaca23b017193615cb849 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 21 Jun 2001 20:49:41 +0000 Subject: [PATCH 0084/1042] define changed to enable Silicon Graphics gcc compilation. [SVN r10378] --- test/comprehensive.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 410bd243..427ed2d8 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -15,7 +15,9 @@ #include // for pow() #include -#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 +#if defined(__sgi) \ + && ( (defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) \ + && !defined(__GNUC__)) inline double pow(int x, int y) { return pow(static_cast(x), y); } #endif From 7c33a46a76dc7174317644e90e0aabfd52718b59 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 21 Jun 2001 23:38:42 +0000 Subject: [PATCH 0085/1042] A small fix for Borland [SVN r10389] --- src/classes.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/classes.cpp b/src/classes.cpp index c609eeef..8755bb34 100644 --- a/src/classes.cpp +++ b/src/classes.cpp @@ -203,7 +203,8 @@ namespace detail { } if (!BOOST_CSTD_::strcmp(name, "__reduce__")) { - ref target(as_object(this), ref::increment_count); + PyObject* self = as_object(this); + ref target(self, ref::increment_count); return bound_function::create(target, global_class_reduce()); } @@ -808,7 +809,7 @@ namespace detail { // Enable the special handler for methods of the given name, if any. void enable_named_method(boost::python::detail::class_base* type_obj, const char* name) { - const std::size_t num_enablers = sizeof(enablers) / sizeof(enablers[0]); + const std::size_t num_enablers = PY_ARRAY_LENGTH(enablers); // Make sure this ends with "__" since we'll only compare the head of the // string. This is done to make the __getattr____/__setattr____ From 1364b97b881185c8ea231c146679fbce172532b1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 21 Jun 2001 23:39:30 +0000 Subject: [PATCH 0086/1042] A small Borland fix [SVN r10390] --- include/boost/python/detail/init_function.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/init_function.hpp b/include/boost/python/detail/init_function.hpp index f4b24fa6..c0c50272 100644 --- a/include/boost/python/detail/init_function.hpp +++ b/include/boost/python/detail/init_function.hpp @@ -73,7 +73,8 @@ namespace detail { struct parameter_traits { private: - typedef const_ref_selector::value> selector; + enum { is_ref = boost::is_reference::value }; + typedef const_ref_selector selector; public: typedef typename selector::template const_ref::type const_reference; }; From 081150b477dfbd5dce9d3a7faaa0d12fce9380e9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 21 Jun 2001 23:40:04 +0000 Subject: [PATCH 0087/1042] Quick Borland fix [SVN r10391] --- include/boost/python/detail/types.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/boost/python/detail/types.hpp b/include/boost/python/detail/types.hpp index ee33ce04..5f0c8f97 100644 --- a/include/boost/python/detail/types.hpp +++ b/include/boost/python/detail/types.hpp @@ -375,8 +375,12 @@ PyObject* reprable::instance_repr(PyObject* obj) const // This macro gets the length of an array as a compile-time constant, and will // fail to compile if the parameter is a pointer. +#ifdef __BORLANDC__ // smart implementation doesn't work for borland; maybe someone knows a workaround? +# define PY_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0])) +#else # define PY_ARRAY_LENGTH(a) \ (sizeof(::boost::python::detail::countof_validate(a, &(a))) ? sizeof(a) / sizeof((a)[0]) : 0) +#endif template inline void countof_validate(T* const, T* const*); From 88372000b5b4348610e4e5440de4e9a8d4b5f29d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 22 Jun 2001 00:49:58 +0000 Subject: [PATCH 0088/1042] fixes due to Jens Maurer (merged from branch boost_python_friend_fixes) [SVN r10395] --- build/linux_gcc.mak | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/linux_gcc.mak b/build/linux_gcc.mak index 9cd2b5de..5971ca61 100644 --- a/build/linux_gcc.mak +++ b/build/linux_gcc.mak @@ -17,14 +17,14 @@ ROOT=$(HOME) BOOST=$(ROOT)/boost -PYEXE=/usr/bin/python +PYEXE=PYTHONPATH=. /usr/bin/python PYINC=-I/usr/include/python1.5 #PYEXE=/usr/local/Python-1.5.2/bin/python #PYINC=-I/usr/local/Python-1.5.2/include/python1.5 #PYEXE=/usr/local/Python-2.0/bin/python #PYINC=-I/usr/local/Python-2.0/include/python2.0 -STDOPTS=-ftemplate-depth-21 +STDOPTS=-fPIC -ftemplate-depth-21 WARNOPTS= OPTOPTS=-g @@ -33,7 +33,7 @@ CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ $(STDOPTS) $(WARNOPTS) $(OPTOPTS) MAKEDEP=-M -LD=g++ +LD=$(CPP) LDOPTS=-shared OBJ=classes.o conversions.o extension_class.o functions.o \ From 4328ae1d8d86607807d5e649d4e0d9135a4d07bf Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 22 Jun 2001 22:36:00 +0000 Subject: [PATCH 0089/1042] Updates for Boost.Build [SVN r10403] --- example/test_abstract.py | 5 +++-- example/test_cross_module.py | 5 +++-- example/test_do_it_yourself_converters.py | 5 +++-- example/test_example1.py | 5 +++-- example/test_getting_started1.py | 5 +++-- example/test_getting_started2.py | 6 ++++-- example/test_pickle1.py | 6 ++++-- example/test_pickle2.py | 6 ++++-- example/test_pickle3.py | 5 +++-- example/test_rwgk1.py | 6 ++++-- example/test_simple_vector.py | 6 ++++-- test/comprehensive.py | 4 ++-- 12 files changed, 40 insertions(+), 24 deletions(-) diff --git a/example/test_abstract.py b/example/test_abstract.py index dda8aaa7..a48aff1b 100644 --- a/example/test_abstract.py +++ b/example/test_abstract.py @@ -17,7 +17,8 @@ def run(args = None): import sys sys.argv = args import doctest, test_abstract - doctest.testmod(test_abstract) + return doctest.testmod(test_abstract) if __name__ == '__main__': - run() + import sys + sys.exit(run()[0]) diff --git a/example/test_cross_module.py b/example/test_cross_module.py index 81057f23..86c1be0e 100644 --- a/example/test_cross_module.py +++ b/example/test_cross_module.py @@ -133,7 +133,8 @@ def run(args = None): import sys sys.argv = args import doctest, test_cross_module - doctest.testmod(test_cross_module) + return doctest.testmod(test_cross_module) if __name__ == '__main__': - run() + import sys + sys.exit(run()) diff --git a/example/test_do_it_yourself_converters.py b/example/test_do_it_yourself_converters.py index e256c614..17240750 100644 --- a/example/test_do_it_yourself_converters.py +++ b/example/test_do_it_yourself_converters.py @@ -16,7 +16,8 @@ def run(args = None): import sys sys.argv = args import doctest, test_do_it_yourself_converters - doctest.testmod(test_do_it_yourself_converters) + return doctest.testmod(test_do_it_yourself_converters) if __name__ == '__main__': - run() + import sys + sys.exit(run()[0]) diff --git a/example/test_example1.py b/example/test_example1.py index 0e3a9a18..3a30cb5b 100644 --- a/example/test_example1.py +++ b/example/test_example1.py @@ -44,7 +44,8 @@ def run(args = None): import sys sys.argv = args import doctest, test_example1 - doctest.testmod(test_example1) + return doctest.testmod(test_example1) if __name__ == '__main__': - run() + import sys + sys.exit(run()[0]) diff --git a/example/test_getting_started1.py b/example/test_getting_started1.py index 7daf65af..cd8fb59e 100644 --- a/example/test_getting_started1.py +++ b/example/test_getting_started1.py @@ -11,7 +11,8 @@ def run(args = None): import sys sys.argv = args import doctest, test_getting_started1 - doctest.testmod(test_getting_started1) + return doctest.testmod(test_getting_started1) if __name__ == '__main__': - run() + import sys + sys.exit(run()[0]) diff --git a/example/test_getting_started2.py b/example/test_getting_started2.py index 49cf765d..ccfaa4f1 100644 --- a/example/test_getting_started2.py +++ b/example/test_getting_started2.py @@ -23,7 +23,9 @@ def run(args = None): import sys sys.argv = args import doctest, test_getting_started2 - doctest.testmod(test_getting_started2) + return doctest.testmod(test_getting_started2) if __name__ == '__main__': - run() + import sys + sys.exit(run()[0]) + diff --git a/example/test_pickle1.py b/example/test_pickle1.py index 05696d4a..48c76a5f 100644 --- a/example/test_pickle1.py +++ b/example/test_pickle1.py @@ -25,7 +25,9 @@ def run(args = None): import sys sys.argv = args import doctest, test_pickle1 - doctest.testmod(test_pickle1) + return doctest.testmod(test_pickle1) if __name__ == '__main__': - run() + import sys + sys.exit(run()[0]) + diff --git a/example/test_pickle2.py b/example/test_pickle2.py index 463befa6..bafa9875 100644 --- a/example/test_pickle2.py +++ b/example/test_pickle2.py @@ -39,7 +39,9 @@ def run(args = None): import sys sys.argv = args import doctest, test_pickle2 - doctest.testmod(test_pickle2) + return doctest.testmod(test_pickle2) if __name__ == '__main__': - run() + import sys + sys.exit(run()[0]) + diff --git a/example/test_pickle3.py b/example/test_pickle3.py index b964f1a2..36da735d 100644 --- a/example/test_pickle3.py +++ b/example/test_pickle3.py @@ -32,7 +32,8 @@ def run(args = None): import sys sys.argv = args import doctest, test_pickle3 - doctest.testmod(test_pickle3) + return doctest.testmod(test_pickle3) if __name__ == '__main__': - run() + import sys + sys.exit(run()[0]) diff --git a/example/test_rwgk1.py b/example/test_rwgk1.py index 87298875..631eea3e 100644 --- a/example/test_rwgk1.py +++ b/example/test_rwgk1.py @@ -11,7 +11,9 @@ def run(args = None): import sys sys.argv = args import doctest, test_rwgk1 - doctest.testmod(test_rwgk1) + return doctest.testmod(test_rwgk1) if __name__ == '__main__': - run() + import sys + sys.exit(run()[0]) + diff --git a/example/test_simple_vector.py b/example/test_simple_vector.py index ca38d715..c6a2cd59 100644 --- a/example/test_simple_vector.py +++ b/example/test_simple_vector.py @@ -34,7 +34,9 @@ def run(args = None): import sys sys.argv = args import doctest, test_simple_vector - doctest.testmod(test_simple_vector) + return doctest.testmod(test_simple_vector) if __name__ == '__main__': - run() + import sys + sys.exit(run()[0]) + diff --git a/test/comprehensive.py b/test/comprehensive.py index c1424d25..06a191af 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -1188,7 +1188,7 @@ def run(args = None): if args is not None: sys.argv = args import doctest, comprehensive - doctest.testmod(comprehensive) + return doctest.testmod(comprehensive) if __name__ == '__main__': - run() + sys.exit(run()[0]) From ff2b37f6e374d6c9b594747ffa1eaa267b9ca952 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 29 Jun 2001 03:57:34 +0000 Subject: [PATCH 0090/1042] Fix so it compiles with Cygwin [SVN r10480] --- include/boost/python/detail/config.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 9792695e..b6075368 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -57,7 +57,7 @@ # define BOOST_CSTD_ std # endif -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) # define BOOST_PYTHON_MODULE_INIT(name) extern "C" __declspec(dllexport) void init##name() #else # define BOOST_PYTHON_MODULE_INIT(name) extern "C" void init##name() From a32dedd16c8998faad1aa7cd31f57de4d4e5ecee Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 29 Jun 2001 20:30:58 +0000 Subject: [PATCH 0091/1042] updates for Python2.1 [SVN r10485] --- test/comprehensive.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/test/comprehensive.py b/test/comprehensive.py index 06a191af..013fae96 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -19,10 +19,13 @@ Load up the extension module Automatic checking of the number and type of arguments. Foo's constructor takes a single long parameter. - >>> ext = Foo() - Traceback (innermost last): - File "", line 1, in ? - TypeError: function requires exactly 1 argument; 0 given + >>> try: + ... ext = Foo() + ... except TypeError, err: + ... assert re.match(r'function .* exactly 1 argument;? \(?0 given\)?', + ... str(err)) + ... else: + ... print 'no exception' >>> try: ext = Foo('foo') ... except TypeError, err: @@ -1014,9 +1017,12 @@ test inheritB2 -2 >>> str(i) '2' - >>> j = i/i - Traceback (innermost last): - TypeError: bad operand type(s) for / + >>> try: j = i/i + ... except TypeError, err: + ... assert re.match(r'(bad|unsupported) operand type\(s\) for /', + ... str(err)) + ... else: print 'no exception' + >>> j = abs(i) Traceback (innermost last): TypeError: bad operand type for abs() From 884b59a0b308f448b63f856ea6b56af7a99106c5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 2 Jul 2001 00:16:28 +0000 Subject: [PATCH 0092/1042] Added JIT debugging hooks [SVN r10507] --- example/dvect.cpp | 11 +++++++++++ example/ivect.cpp | 11 +++++++++++ example/noncopyable_export.cpp | 10 ++++++++++ example/noncopyable_import.cpp | 10 ++++++++++ 4 files changed, 42 insertions(+) diff --git a/example/dvect.cpp b/example/dvect.cpp index da6b35a3..4d109c96 100644 --- a/example/dvect.cpp +++ b/example/dvect.cpp @@ -20,6 +20,16 @@ namespace { } } +# ifdef BOOST_MSVC // fixes for JIT debugging +# include +extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) +{ + throw; +} +extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) + = _set_se_translator(structured_exception_translator); +# endif + BOOST_PYTHON_MODULE_INIT(dvect) { try @@ -43,3 +53,4 @@ BOOST_PYTHON_MODULE_INIT(dvect) python::handle_exception(); // Deal with the exception for Python } } + diff --git a/example/ivect.cpp b/example/ivect.cpp index db1c0ec3..848d693e 100644 --- a/example/ivect.cpp +++ b/example/ivect.cpp @@ -20,6 +20,16 @@ namespace { } } +# ifdef BOOST_MSVC // fixes for JIT debugging +# include +extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) +{ + throw; +} +extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) + = _set_se_translator(structured_exception_translator); +# endif + BOOST_PYTHON_MODULE_INIT(ivect) { try @@ -43,3 +53,4 @@ BOOST_PYTHON_MODULE_INIT(ivect) python::handle_exception(); // Deal with the exception for Python } } + diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp index 794b1200..b118abb8 100644 --- a/example/noncopyable_export.cpp +++ b/example/noncopyable_export.cpp @@ -6,6 +6,16 @@ namespace python = boost::python; #include "noncopyable.h" +# ifdef BOOST_MSVC // fixes for JIT debugging +# include +extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) +{ + throw; +} +extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) + = _set_se_translator(structured_exception_translator); +# endif + BOOST_PYTHON_MODULE_INIT(noncopyable_export) { try diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp index ea2477be..66c6457d 100644 --- a/example/noncopyable_import.cpp +++ b/example/noncopyable_import.cpp @@ -19,6 +19,16 @@ namespace { // Avoid cluttering the global namespace. } } +# ifdef BOOST_MSVC // fixes for JIT debugging +# include +extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) +{ + throw; +} +extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) + = _set_se_translator(structured_exception_translator); +# endif + BOOST_PYTHON_MODULE_INIT(noncopyable_import) { try From e504c3cd466326b11d40c363a67c89e356049db5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 2 Jul 2001 00:16:53 +0000 Subject: [PATCH 0093/1042] Made it a little more immune to command-line argument ordering [SVN r10508] --- example/tst_dvect2.py | 20 +++++++++++++------- example/tst_ivect2.py | 20 +++++++++++++------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/example/tst_dvect2.py b/example/tst_dvect2.py index 539e0b88..2e72bf8b 100644 --- a/example/tst_dvect2.py +++ b/example/tst_dvect2.py @@ -87,12 +87,18 @@ if (__name__ == "__main__"): import sys, string broken_auto_ptr = 0 n = 1 - if (len(sys.argv) > 1): - if (sys.argv[1] == "--broken-auto-ptr"): - broken_auto_ptr = 1 - if (len(sys.argv) > 2): - n = string.atoi(sys.argv[2]) - else: - n = string.atoi(sys.argv[1]) + + if len(sys.argv) > 1: + argv = [] + + for x in sys.argv: + if x != '--broken_auto_ptr': + argv.append(x) + broken_auto_ptr = argv != sys.argv + sys.argv = argv + + if len(sys.argv) > 1: + n = string.atoi(sys.argv[1]) + for i in xrange(n): f(broken_auto_ptr) diff --git a/example/tst_ivect2.py b/example/tst_ivect2.py index 6ffd2826..e7607151 100644 --- a/example/tst_ivect2.py +++ b/example/tst_ivect2.py @@ -87,12 +87,18 @@ if (__name__ == "__main__"): import sys, string broken_auto_ptr = 0 n = 1 - if (len(sys.argv) > 1): - if (sys.argv[1] == "--broken-auto-ptr"): - broken_auto_ptr = 1 - if (len(sys.argv) > 2): - n = string.atoi(sys.argv[2]) - else: - n = string.atoi(sys.argv[1]) + + if len(sys.argv) > 1: + argv = [] + + for x in sys.argv: + if x != '--broken_auto_ptr': + argv.append(x) + broken_auto_ptr = argv != sys.argv + sys.argv = argv + + if len(sys.argv) > 1: + n = string.atoi(sys.argv[1]) + for i in xrange(n): f(broken_auto_ptr) From 76c6adf1cfe57835c6fa264296820739cd1ef7b6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 3 Jul 2001 12:43:12 +0000 Subject: [PATCH 0094/1042] --broken_auto_ptr -> --broken-auto-ptr [SVN r10511] --- example/tst_dvect2.py | 2 +- example/tst_ivect2.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example/tst_dvect2.py b/example/tst_dvect2.py index 2e72bf8b..90d381a7 100644 --- a/example/tst_dvect2.py +++ b/example/tst_dvect2.py @@ -92,7 +92,7 @@ if (__name__ == "__main__"): argv = [] for x in sys.argv: - if x != '--broken_auto_ptr': + if x != '--broken-auto-ptr': argv.append(x) broken_auto_ptr = argv != sys.argv sys.argv = argv diff --git a/example/tst_ivect2.py b/example/tst_ivect2.py index e7607151..a9e6aeef 100644 --- a/example/tst_ivect2.py +++ b/example/tst_ivect2.py @@ -92,7 +92,7 @@ if (__name__ == "__main__"): argv = [] for x in sys.argv: - if x != '--broken_auto_ptr': + if x != '--broken-auto-ptr': argv.append(x) broken_auto_ptr = argv != sys.argv sys.argv = argv From 606898f5691a641a695d806941ad7c08d0a204f6 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 6 Jul 2001 07:31:39 +0000 Subject: [PATCH 0095/1042] tiny trivial fix. [SVN r10547] --- example/test_cross_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/test_cross_module.py b/example/test_cross_module.py index 86c1be0e..c5e2bef6 100644 --- a/example/test_cross_module.py +++ b/example/test_cross_module.py @@ -137,4 +137,4 @@ def run(args = None): if __name__ == '__main__': import sys - sys.exit(run()) + sys.exit(run()[0]) From 8ad7d06ec6fd2bce16011e5d3a0b7ade321f98ee Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 8 Jul 2001 22:30:12 +0000 Subject: [PATCH 0096/1042] fixed > -> > [SVN r10571] --- doc/pointers.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pointers.html b/doc/pointers.html index 00f7bb41..9085e152 100644 --- a/doc/pointers.html +++ b/doc/pointers.html @@ -85,7 +85,7 @@ code before the last Python reference to it disappears: BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround PyObject* to_python(Foo* p) { - return boost::python::python_extension_class_converters<Foo>::ptr_to_python(p); + return boost::python::python_extension_class_converters<Foo>::ptr_to_python(p); } PyObject* to_python(const Foo* p) From 819db1524fe330793593ea4efea395f20068381a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 9 Jul 2001 23:45:09 +0000 Subject: [PATCH 0097/1042] Integrate fix from Peter.Bienstman@rug.ac.be [SVN r10574] --- doc/enums.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/enums.html b/doc/enums.html index 32d61447..c58ca34d 100644 --- a/doc/enums.html +++ b/doc/enums.html @@ -91,8 +91,8 @@ initialization. These bind the corresponding enum values to the appropriate names so they can be used from Python:

    -mymodule.add(boost::python::to_python(enum_value_1), "enum_value_1");
    -mymodule.add(boost::python::to_python(enum_value_2), "enum_value_2");
    +mymodule.add(boost::python::make_ref(enum_value_1), "enum_value_1");
    +mymodule.add(boost::python::make_ref(enum_value_2), "enum_value_2");
     ...
     
    From 26aa8b69f96b7537652ba8b41e5ba10214e7a6dd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 10 Jul 2001 17:57:06 +0000 Subject: [PATCH 0098/1042] Integrate fix from Peter.Bienstman@rug.ac.be [SVN r10584] --- doc/pointers.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/pointers.html b/doc/pointers.html index 9085e152..11cfd8d9 100644 --- a/doc/pointers.html +++ b/doc/pointers.html @@ -85,7 +85,7 @@ code before the last Python reference to it disappears: BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround PyObject* to_python(Foo* p) { - return boost::python::python_extension_class_converters<Foo>::ptr_to_python(p); + return boost::python::python_extension_class_converters<Foo>::smart_ptr_to_python(p); } PyObject* to_python(const Foo* p) From 4f41a10fef7761fc571212659afa4639bf5816d4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 11 Jul 2001 11:53:46 +0000 Subject: [PATCH 0099/1042] fixed a comment [SVN r10588] --- include/boost/python/detail/base_object.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/base_object.hpp b/include/boost/python/detail/base_object.hpp index bf0faa7b..95a2805c 100644 --- a/include/boost/python/detail/base_object.hpp +++ b/include/boost/python/detail/base_object.hpp @@ -39,7 +39,7 @@ typedef base_object python_type; // -// class_t template member function implementations +// base_object member function implementations // template base_object::base_object(PyTypeObject* type_obj) From 24509a21d4fca7d6ae0a8f1250508af5f45a1b38 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Thu, 12 Jul 2001 15:31:15 +0000 Subject: [PATCH 0100/1042] Change absolute URL's to relative [SVN r10594] --- doc/under-the-hood.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/under-the-hood.html b/doc/under-the-hood.html index 733f0f54..e2a0ce2b 100644 --- a/doc/under-the-hood.html +++ b/doc/under-the-hood.html @@ -36,7 +36,7 @@ template defines a whole raft of these conversions (for T, T*, T&, std::auto_ptr<T>, etc.), using the same inline friend function technique employed by the boost operators + "file:///c:/boost/site/libs/utility/operators.htm">the boost operators library.

    Because the to_python and from_python functions From 08eb28f7b825de12a84f8e0eeb86309ba4d5c26d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 22 Jul 2001 17:03:15 +0000 Subject: [PATCH 0101/1042] move to main trunk [SVN r10690] --- build/Jamfile | 248 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 build/Jamfile diff --git a/build/Jamfile b/build/Jamfile new file mode 100644 index 00000000..fa31efc4 --- /dev/null +++ b/build/Jamfile @@ -0,0 +1,248 @@ +# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +# distribute this software is granted provided this copyright notice appears +# in all copies. This software is provided "as is" without express or implied +# warranty, and with no claim as to its suitability for any purpose. +# +# Boost.Python build and test Jamfile +# +# Declares the following targets: +# 1. libboost_python, a static link library to be linked with all +# Boost.Python modules +# +# 2. pairs of test targets of the form .test and .run +# .test runs the test when it is out-of-date, and the "all" target +# depends on it so that it it is built by default. .run runs +# a test unconditionally, and can be used to force a test to run.. Each +# test target builds one or more Boost.Python modules and runs a Python +# script to test them. The test names are: +# +# from ../test +# +# comprehensive - a comprehensive test of Boost.Python features +# +# from ../example: +# abstract - +# getting_started1 - +# getting_started2 - +# simple_vector - +# do_it_yourself_converters - +# pickle1 - +# pickle2 - +# pickle3 - +# +# dvect1 - +# dvect2 - +# ivect1 - +# ivect2 - +# noncopyable - +# +# subproject-specific environment/command-line variables: +# +# PYTHON_TEST_ARGS - specifies arguments to be passed to test scripts on +# the command line. "-v" can be useful if you want to +# see the output of successful tests. +# +# PYTHON_VECT_ITERATIONS - specifies the number of test iterations to use for +# the dvect and ivect tests above. + + +# declare the location of this subproject relative to the root +subproject libs/python/build ; + +# Do some OS-specific setup +if $(NT) +{ + PYTHON_ROOT ?= c:/tools/python ; + PYTHON_INCLUDES ?= $(PYTHON_ROOT)/include <*>/usr/include/python2.1 ; + PYTHON_LIBS ?= c:/cygnus/lib/python2.1/config/libpython2.1.dll.a ; + PYTHON_LIB_PATH = $(PYTHON_ROOT)/libs ; + + # common properties required for compiling any Python module. + PYTHON_PROPERTIES ?= + <*>SIZEOF_LONG=4 + <*>USE_DL_IMPORT + + # if you don't request multithreading, you can't get the DLL runtime, + # which is needed for the python modules to work right + <*>multi + ; + + SHELL_SET ?= "set " ; + SHELL_EXPORT ?= ; # shell variables are exported by default +} +else if $(UNIX) +{ + PYTHON_INCLUDES ?= /usr/include/python1.5 ; + PYTHON_LIBS ?= /usr/lib/python1.5/config/libpython1.5.a ; + SHELL_SET ?= "" ; + SHELL_EXPORT ?= "export " ; +} + +####################### + +# +# Declare the boost python static link library +# + +# standard include requirements for anything using Boost.Python +BOOST_PYTHON_INCLUDES = $(BOOST_ROOT) $(PYTHON_INCLUDES) ; + +# Base names of the source files for libboost_python +CPP_SOURCES = + classes conversions extension_class functions + init_function module_builder objects types cross_module ; + +lib libboost_python : ../src/$(CPP_SOURCES).cpp + # requirements + : $(BOOST_PYTHON_INCLUDES) + true + $(PYTHON_PROPERTIES) ; + +####################### + +# boost-python name : sources : requirements : default-BUILD +# +# Declare a boost python module. Return a list of the DLL files generated. +rule boost-python +{ + # declare a DLL; add the boost python library to sources + dll $(<) : libboost_python $(>) + + # Requirements + : $(3) # caller-specified requirements + + # standard requirements + $(BOOST_PYTHON_INCLUDES) + <*>$(PYTHON_LIB_PATH) + <*>$(PYTHON_LIBS) + $(PYTHON_PROPERTIES) + + : $(4) ; # pass on the default-BUILD, if any +} + +####################### + +# boost-python-test target : python-script sources : requirements : local-build : args +# +# declare two python module tests: $(<).test which builds when out-of-date, and +# $(<).run which builds unconditionally. +rule boost-python-test +{ + # tell Jam that the python script is relative to this directory + SEARCH on $(>[1]) = $(SEARCH_SOURCE) ; + + # required command-line args can be specified in argument 5 + # The user can add additional arguments in PYTHON_TEST_ARGS. + local gPYTHON_TEST_ARGS = $(5) $(PYTHON_TEST_ARGS) ; + + # declare the two subsidiary tests. + declare-local-target $(<:S=.test) : $(>) : $(PYTHON_PROPERTIES) : $(4) : PYTHON_TEST ; + declare-local-target $(<:S=.run) : $(>) : $(PYTHON_PROPERTIES) : $(4) : PYTHON_RUNTEST ; +} + +# how do we invoke python? +PYTHON ?= python ; + +# special rules for two new target types: PYTHON_TEST and PYTHON_RUNTEST. +# These are identical except that PYTHON_TEST runs the test when out-of-date, and +# PYTHON_RUNTEST runs the test unconditionally. These are used by boost-python-test. +SUFPYTHON_TEST = .test ; +gGENERATOR_FUNCTION(PYTHON_TEST) = python-test-target ; +rule python-test-target # test-target : sources : +{ + python-test-aux $(<) : $(>) ; + Clean clean : $(<) ; # remove the test-target as part of any clean operation + type-DEPENDS test : $(<) ; + MakeLocate $(<) : $(LOCATE_TARGET) ; +} +actions python-test-target +{ + $(SHELL_SET)PYTHONPATH=$(PYTHONPATH) + $(SHELL_EXPORT)PYTHONPATH + $(PYTHON) "$(>)" $(ARGS) > "$(<)" +} + +SUFPYTHON_RUNTEST = .run ; +gGENERATOR_FUNCTION(PYTHON_RUNTEST) = python-runtest-target ; +rule python-runtest-target # test-target : sources : +{ + python-test-aux $(<) : $(>) ; + NOTFILE $(<) ; + ALWAYS $(<) ; +} +actions python-runtest-target +{ + $(SHELL_SET)PYTHONPATH=$(PYTHONPATH) + $(SHELL_EXPORT)PYTHONPATH + $(PYTHON) "$(>)" $(ARGS) +} + +rule python-test-aux # target : sources +{ + DEPENDS $(<) : $(>) ; + + ARGS on $(<) += $(gPYTHON_TEST_ARGS) ; + + # Some tests need an extra command-line arg if built with + # msvc. Checking the target grist is a cheap way to + # find out. + switch $(<) + { + case <*\\\\msvc\\\\*>* : ARGS on $(<) += --broken-auto-ptr ; + } + + # compute the PYTHONPATH environment variable that will allow the test to + # find all of the modules on which it depends. + PYTHONPATH on $(<) = [ join + $(gLOCATE($(>[1]))) # location of python test file + $(gRUN_PATH($(<))) # location of module dependencies + [ join-path $(TOP) libs python test ] # location of doctest + $(PYTHONPATH) # base PYTHONPATH from environment + : $(SPLITPATH) ] ; # platform path separator +} + +############# comprehensive module and test ########### +boost-python boost_python_test : ../test/comprehensive.cpp ; +boost-python-test comprehensive : [ join-path $(DOTDOT) test comprehensive.py ] boost_python_test ; + +############# simple tests from ../example ############ + +rule boost-python-example-test +{ + boost-python $(<) : ../example/$(<).cpp ; + boost-python-test $(<) : [ join-path $(DOTDOT) example test_$(<).py ] $(<) ; +} + + +boost-python-example-test abstract ; +boost-python-example-test getting_started1 ; +boost-python-example-test getting_started2 ; +boost-python-example-test simple_vector ; +boost-python-example-test do_it_yourself_converters ; +boost-python-example-test pickle1 ; +boost-python-example-test pickle2 ; +boost-python-example-test pickle3 ; + + +boost-python ivect : ../example/ivect.cpp ; +boost-python dvect : ../example/dvect.cpp ; +boost-python noncopyable_export : ../example/noncopyable_export.cpp ; +boost-python noncopyable_import : ../example/noncopyable_import.cpp ; + +############## cross-module tests from ../example ########## + +# A simple rule to build a test which depends on multiple modules in the PYTHONPATH +rule boost-python-multi-example-test # test-name : python-file libs +{ + boost-python-test $(<) : ../example/tst_$(<).py $(>) : : : $(PYTHON_VECT_ITERATIONS) ; +} +PYTHON_VECT_ITERATIONS ?= 10 ; + +boost-python-multi-example-test dvect1 : ivect dvect ; +boost-python-multi-example-test dvect2 : ivect dvect ; + +boost-python-multi-example-test ivect1 : ivect dvect ; +boost-python-multi-example-test ivect2 : ivect dvect ; + +boost-python-multi-example-test noncopyable : noncopyable_import noncopyable_export ; + From 3c6a8d718fc5a7d198e1b089016b733eaaee4469 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 23 Jul 2001 03:34:37 +0000 Subject: [PATCH 0102/1042] build system update [SVN r10695] --- build/Jamfile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index fa31efc4..314b1440 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -61,10 +61,7 @@ if $(NT) PYTHON_PROPERTIES ?= <*>SIZEOF_LONG=4 <*>USE_DL_IMPORT - - # if you don't request multithreading, you can't get the DLL runtime, - # which is needed for the python modules to work right - <*>multi + dynamic ; SHELL_SET ?= "set " ; From f2e34d4836eab58dfd123b1aba294f5ed1d799fe Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 30 Jul 2001 13:31:23 +0000 Subject: [PATCH 0103/1042] MSVC doesn't like boost::dereferencable unless T has a default constructor, so operator-> must be defined by hand [SVN r10720] --- include/boost/python/detail/cast.hpp | 7 ++++++- include/boost/python/reference.hpp | 9 ++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/boost/python/detail/cast.hpp b/include/boost/python/detail/cast.hpp index a6f2f046..e047c0b3 100644 --- a/include/boost/python/detail/cast.hpp +++ b/include/boost/python/detail/cast.hpp @@ -51,7 +51,7 @@ inline PyObject* as_object(PyTypeObject* p) { return reinterpret_cast // If I didn't have to support stupid MSVC6 we could just use a simple template function: // template T* downcast(PyObject*). template -struct downcast : boost::dereferenceable, T*> +struct downcast { downcast(PyObject* p) : m_p(detail::downcast_traits::cast(detail::as_base_object((T*)0, p))) @@ -70,6 +70,11 @@ struct downcast : boost::dereferenceable, T*> {} operator T*() const { return m_p; } + + // MSVC doesn't like boost::dereferencable unless T has a default + // constructor, so operator-> must be defined by hand :( + T* operator->() const { return &**this; } + T* get() const { return m_p; } T& operator*() const { return *m_p; } private: diff --git a/include/boost/python/reference.hpp b/include/boost/python/reference.hpp index c633b9d7..a1585099 100644 --- a/include/boost/python/reference.hpp +++ b/include/boost/python/reference.hpp @@ -20,7 +20,7 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -template +template struct py_ptr_conversions : Base { inline friend T from_python(PyObject* x, boost::python::type) @@ -42,8 +42,7 @@ BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions); template class reference - : public py_ptr_conversions, T, - boost::dereferenceable, T*> > // supplies op-> + : public py_ptr_conversions, T> { public: typedef T value_type; @@ -117,6 +116,10 @@ public: T& operator*() const { return *m_p; } + // MSVC doesn't like boost::dereferencable unless T has a default + // constructor, so operator-> must be defined by hand :( + T* operator->() const { return &**this; } + T* get() const { return m_p; } T* release() From f1ae502b1f9b3c7a55782557774b4fb77171b32c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 31 Jul 2001 07:12:14 +0000 Subject: [PATCH 0104/1042] Merged from branch boost_python_richcmp. [SVN r10728] --- build/filemgr.py | 10 + build/irix_CC.mak | 25 ++- build/linux_gcc.mak | 25 ++- build/mingw32.mak | 34 +++- build/tru64_cxx.mak | 25 ++- build/vc60.mak | 30 ++- doc/richcmp.html | 106 +++++++++++ doc/special.html | 59 +++++- example/pickle3.cpp | 4 +- example/richcmp1.cpp | 87 +++++++++ example/richcmp2.cpp | 65 +++++++ example/richcmp3.cpp | 178 ++++++++++++++++++ example/test_pickle3.py | 12 +- example/test_richcmp1.py | 40 ++++ example/test_richcmp2.py | 41 ++++ example/test_richcmp3.py | 77 ++++++++ example/vector_wrapper.h | 117 ++++++++++++ include/boost/python/classes.hpp | 52 +++++ .../boost/python/detail/extension_class.hpp | 12 ++ include/boost/python/detail/types.hpp | 10 +- include/boost/python/operators.hpp | 14 +- src/classes.cpp | 36 ++++ src/gen_extclass.py | 21 +++ src/gen_init_function.py | 3 +- src/types.cpp | 70 ++++++- test/comprehensive.py | 8 +- 26 files changed, 1110 insertions(+), 51 deletions(-) create mode 100644 doc/richcmp.html create mode 100644 example/richcmp1.cpp create mode 100644 example/richcmp2.cpp create mode 100644 example/richcmp3.cpp create mode 100644 example/test_richcmp1.py create mode 100644 example/test_richcmp2.py create mode 100644 example/test_richcmp3.py create mode 100644 example/vector_wrapper.h diff --git a/build/filemgr.py b/build/filemgr.py index d8310f6d..5e32460e 100644 --- a/build/filemgr.py +++ b/build/filemgr.py @@ -52,6 +52,13 @@ bpl_exa + "/tst_dvect2.py", bpl_exa + "/tst_ivect1.py", bpl_exa + "/tst_ivect2.py", bpl_exa + "/test_cross_module.py", +bpl_exa + "/vector_wrapper.h", +bpl_exa + "/richcmp1.cpp", +bpl_exa + "/richcmp2.cpp", +bpl_exa + "/richcmp3.cpp", +bpl_exa + "/test_richcmp1.py", +bpl_exa + "/test_richcmp2.py", +bpl_exa + "/test_richcmp3.py", ) defs = ( @@ -68,6 +75,9 @@ defs = ( "noncopyable_import", "ivect", "dvect", +"richcmp1", +"richcmp2", +"richcmp3", ) if (__name__ == "__main__"): diff --git a/build/irix_CC.mak b/build/irix_CC.mak index 5894ff51..1fbe3388 100644 --- a/build/irix_CC.mak +++ b/build/irix_CC.mak @@ -19,8 +19,8 @@ BOOST=$(ROOT)/boost PYEXE=/usr/local/Python-1.5.2/bin/python PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE=/usr/local/Python-2.0/bin/python -#PYINC=-I/usr/local/Python-2.0/include/python2.0 +#PYEXE=/usr/local/Python-2.1/bin/python +#PYINC=-I/usr/local/Python-2.1/include/python2.1 STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers STDOPTS= @@ -46,7 +46,8 @@ DEPOBJ=$(OBJ) \ do_it_yourself_converters.o \ pickle1.o pickle2.o pickle3.o \ noncopyable_export.o noncopyable_import.o \ - ivect.o dvect.o + ivect.o dvect.o \ + richcmp1.o richcmp2.o richcmp3.o .SUFFIXES: .o .cpp @@ -58,7 +59,8 @@ all: libboost_python.a \ do_it_yourself_converters.so \ pickle1.so pickle2.so pickle3.so \ noncopyable_export.so noncopyable_import.so \ - ivect.so dvect.so + ivect.so dvect.so \ + richcmp1.so richcmp2.so richcmp3.so libboost_python.a: $(OBJ) rm -f libboost_python.a @@ -105,6 +107,15 @@ ivect.so: $(OBJ) ivect.o dvect.so: $(OBJ) dvect.o $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so +richcmp1.so: $(OBJ) richcmp1.o + $(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so + +richcmp2.so: $(OBJ) richcmp2.o + $(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so + +richcmp3.so: $(OBJ) richcmp3.o + $(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so + .cpp.o: $(CPP) $(CPPOPTS) -c $*.cpp @@ -119,6 +130,9 @@ test: $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py $(PYEXE) test_cross_module.py + $(PYEXE) test_richcmp1.py + $(PYEXE) test_richcmp2.py + $(PYEXE) test_richcmp3.py clean: rm -f $(OBJ) libboost_python.a libboost_python.a.input @@ -135,6 +149,9 @@ clean: rm -f noncopyable_import.o noncopyable_import.so rm -f ivect.o ivect.so rm -f dvect.o dvect.so + rm -f richcmp1.o richcmp1.so + rm -f richcmp2.o richcmp2.so + rm -f richcmp3.o richcmp3.so rm -f so_locations *.pyc rm -rf ii_files diff --git a/build/linux_gcc.mak b/build/linux_gcc.mak index 5971ca61..3fe407a0 100644 --- a/build/linux_gcc.mak +++ b/build/linux_gcc.mak @@ -21,8 +21,8 @@ PYEXE=PYTHONPATH=. /usr/bin/python PYINC=-I/usr/include/python1.5 #PYEXE=/usr/local/Python-1.5.2/bin/python #PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE=/usr/local/Python-2.0/bin/python -#PYINC=-I/usr/local/Python-2.0/include/python2.0 +#PYEXE=/usr/local/Python-2.1/bin/python +#PYINC=-I/usr/local/Python-2.1/include/python2.1 STDOPTS=-fPIC -ftemplate-depth-21 WARNOPTS= @@ -47,7 +47,8 @@ DEPOBJ=$(OBJ) \ do_it_yourself_converters.o \ pickle1.o pickle2.o pickle3.o \ noncopyable_export.o noncopyable_import.o \ - ivect.o dvect.o + ivect.o dvect.o \ + richcmp1.o richcmp2.o richcmp3.o .SUFFIXES: .o .cpp @@ -59,7 +60,8 @@ all: libboost_python.a \ do_it_yourself_converters.so \ pickle1.so pickle2.so pickle3.so \ noncopyable_export.so noncopyable_import.so \ - ivect.so dvect.so + ivect.so dvect.so \ + richcmp1.so richcmp2.so richcmp3.so libboost_python.a: $(OBJ) rm -f libboost_python.a @@ -106,6 +108,15 @@ ivect.so: $(OBJ) ivect.o dvect.so: $(OBJ) dvect.o $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so +richcmp1.so: $(OBJ) richcmp1.o + $(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so + +richcmp2.so: $(OBJ) richcmp2.o + $(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so + +richcmp3.so: $(OBJ) richcmp3.o + $(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so + .cpp.o: $(CPP) $(CPPOPTS) -c $*.cpp @@ -120,6 +131,9 @@ test: $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py $(PYEXE) test_cross_module.py + $(PYEXE) test_richcmp1.py + $(PYEXE) test_richcmp2.py + $(PYEXE) test_richcmp3.py clean: rm -f $(OBJ) libboost_python.a libboost_python.a.input @@ -136,6 +150,9 @@ clean: rm -f noncopyable_import.o noncopyable_import.so rm -f ivect.o ivect.so rm -f dvect.o dvect.so + rm -f richcmp1.o richcmp1.so + rm -f richcmp2.o richcmp2.so + rm -f richcmp3.o richcmp3.so rm -f so_locations *.pyc softlinks: diff --git a/build/mingw32.mak b/build/mingw32.mak index 0a16f332..6f192ce2 100644 --- a/build/mingw32.mak +++ b/build/mingw32.mak @@ -62,10 +62,11 @@ all: libboost_python.a \ do_it_yourself_converters.pyd \ pickle1.pyd pickle2.pyd pickle3.pyd \ noncopyable_export.pyd noncopyable_import.pyd \ - ivect.pyd dvect.pyd + ivect.pyd dvect.pyd \ + richcmp1.pyd richcmp2.pyd richcmp3.pyd libboost_python.a: $(OBJ) - del libboost_python.a + -del libboost_python.a ar r libboost_python.a $(OBJ) DLLWRAPOPTS=-s --driver-name g++ -s \ @@ -149,6 +150,24 @@ dvect.pyd: $(OBJ) dvect.o --def dvect.def \ $(OBJ) dvect.o $(PYLIB) +richcmp1.pyd: $(OBJ) richcmp1.o + dllwrap $(DLLWRAPOPTS) \ + --dllname richcmp1.pyd \ + --def richcmp1.def \ + $(OBJ) richcmp1.o $(PYLIB) + +richcmp2.pyd: $(OBJ) richcmp2.o + dllwrap $(DLLWRAPOPTS) \ + --dllname richcmp2.pyd \ + --def richcmp2.def \ + $(OBJ) richcmp2.o $(PYLIB) + +richcmp3.pyd: $(OBJ) richcmp3.o + dllwrap $(DLLWRAPOPTS) \ + --dllname richcmp3.pyd \ + --def richcmp3.def \ + $(OBJ) richcmp3.o $(PYLIB) + .cpp.o: $(CPP) $(CPPOPTS) -c $*.cpp @@ -163,12 +182,15 @@ test: $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py $(PYEXE) test_cross_module.py + $(PYEXE) test_richcmp1.py + $(PYEXE) test_richcmp2.py + $(PYEXE) test_richcmp3.py clean: - del *.o - del *.a - del *.pyd - del *.pyc + -del *.o + -del *.a + -del *.pyd + -del *.pyc softlinks: python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks diff --git a/build/tru64_cxx.mak b/build/tru64_cxx.mak index 21a8126e..8f3d3abf 100644 --- a/build/tru64_cxx.mak +++ b/build/tru64_cxx.mak @@ -19,8 +19,8 @@ BOOST=$(ROOT)/boost PYEXE=/usr/local/Python-1.5.2/bin/python PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE=/usr/local/Python-2.0/bin/python -#PYINC=-I/usr/local/Python-2.0/include/python2.0 +#PYEXE=/usr/local/Python-2.1/bin/python +#PYINC=-I/usr/local/Python-2.1/include/python2.1 #STLPORTINC=-I/usr/local/STLport-4.1b3/stlport #STLPORTINC=-I/usr/local/STLport-4.1b4/stlport #STLPORTOPTS= \ @@ -57,7 +57,8 @@ DEPOBJ=$(OBJ) \ do_it_yourself_converters.o \ pickle1.o pickle2.o pickle3.o \ noncopyable_export.o noncopyable_import.o \ - ivect.o dvect.o + ivect.o dvect.o \ + richcmp1.o richcmp2.o richcmp3.o .SUFFIXES: .o .cpp @@ -69,7 +70,8 @@ all: libboost_python.a \ do_it_yourself_converters.so \ pickle1.so pickle2.so pickle3.so \ noncopyable_export.so noncopyable_import.so \ - ivect.so dvect.so + ivect.so dvect.so \ + richcmp1.so richcmp2.so richcmp3.so libboost_python.a: $(OBJ) rm -f libboost_python.a @@ -120,6 +122,15 @@ ivect.so: $(OBJ) ivect.o dvect.so: $(OBJ) dvect.o $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so +richcmp1.so: $(OBJ) richcmp1.o + $(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so + +richcmp2.so: $(OBJ) richcmp2.o + $(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so + +richcmp3.so: $(OBJ) richcmp3.o + $(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so + .cpp.o: $(CPP) $(CPPOPTS) -c $*.cpp @@ -134,6 +145,9 @@ test: $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py $(PYEXE) test_cross_module.py + $(PYEXE) test_richcmp1.py + $(PYEXE) test_richcmp2.py + $(PYEXE) test_richcmp3.py clean: rm -f $(OBJ) libboost_python.a libboost_python.a.input @@ -150,6 +164,9 @@ clean: rm -f noncopyable_import.o noncopyable_import.so rm -f ivect.o ivect.so rm -f dvect.o dvect.so + rm -f richcmp1.o richcmp1.so + rm -f richcmp2.o richcmp2.so + rm -f richcmp3.o richcmp3.so rm -f so_locations *.pyc rm -rf cxx_repository diff --git a/build/vc60.mak b/build/vc60.mak index f0016075..f545015b 100644 --- a/build/vc60.mak +++ b/build/vc60.mak @@ -17,6 +17,9 @@ BOOST_UNIX=$(HOME)/boost PYEXE="C:\Program files\Python\python.exe" PYINC=/I"C:\Program files\Python\include" PYLIB="C:\Program files\Python\libs\python15.lib" +#PYEXE="C:\Python21\python.exe" +#PYINC=/I"C:\Python21\include" +#PYLIB="C:\Python21\libs\python21.lib" STDOPTS=/nologo /MD /GR /GX /Zm200 WARNOPTS= @@ -43,7 +46,8 @@ all: boost_python.lib \ do_it_yourself_converters.pyd \ pickle1.pyd pickle2.pyd pickle3.pyd \ noncopyable_export.pyd noncopyable_import.pyd \ - ivect.pyd dvect.pyd + ivect.pyd dvect.pyd \ + richcmp1.pyd richcmp2.pyd richcmp3.pyd boost_python.lib: $(OBJ) $(LD) -lib /nologo /out:boost_python.lib $(OBJ) @@ -87,6 +91,15 @@ ivect.pyd: $(OBJ) ivect.obj dvect.pyd: $(OBJ) dvect.obj $(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) /export:initdvect /out:"dvect.pyd" +richcmp1.pyd: $(OBJ) richcmp1.obj + $(LD) $(LDOPTS) $(OBJ) richcmp1.obj $(PYLIB) /export:initrichcmp1 /out:"richcmp1.pyd" + +richcmp2.pyd: $(OBJ) richcmp2.obj + $(LD) $(LDOPTS) $(OBJ) richcmp2.obj $(PYLIB) /export:initrichcmp2 /out:"richcmp2.pyd" + +richcmp3.pyd: $(OBJ) richcmp3.obj + $(LD) $(LDOPTS) $(OBJ) richcmp3.obj $(PYLIB) /export:initrichcmp3 /out:"richcmp3.pyd" + .cpp.obj: $(CPP) $(CPPOPTS) /c $*.cpp @@ -101,14 +114,17 @@ test: $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py $(PYEXE) test_cross_module.py --broken-auto-ptr + $(PYEXE) test_richcmp1.py + $(PYEXE) test_richcmp2.py + $(PYEXE) test_richcmp3.py clean: - del *.obj - del *.lib - del *.exp - del *.idb - del *.pyd - del *.pyc + -del *.obj + -del *.lib + -del *.exp + -del *.idb + -del *.pyd + -del *.pyc softlinks: python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks diff --git a/doc/richcmp.html b/doc/richcmp.html new file mode 100644 index 00000000..d9ab7044 --- /dev/null +++ b/doc/richcmp.html @@ -0,0 +1,106 @@ + + +Rich Comparisons + +

    + +c++boost.gif (8819 bytes) + +
    +

    Rich Comparisons

    + +
    +In Python versions up to and including Python 2.0, support for +implementing comparisons on user-defined classes and extension types +was quite simple. Classes could implement a __cmp__ method +that was given two instances of a class as arguments, and could only +return 0 if they were equal or +1 or -1 if +they were not. The method could not raise an exception or return +anything other than an integer value. +In Python 2.1, Rich Comparisons were added (see +PEP 207). +Python classes can now individually overload each of the <, <=, +>, >=, ==, and != operations. + +

    +For more detailed information, search for "rich comparison" +here. + +

    +Boost.Python supports both automatic overloading and manual overloading +of the Rich Comparison operators. The compile-time support is +independent of the Python version that is used when compiling +Boost.Python extension modules. That is, op_lt for example can +always be used, and the C++ operator< will always be bound +to the Python method __lt__. However, the run-time +behavior will depend on the Python version. + +

    +With Python versions before 2.1, the Rich Comparison operators will not +be called by Python when any of the six comparison operators +(<, <=, ==, !=, +>, >=) is used in an expression. The only way +to access the corresponding methods is to call them explicitly, e.g. +a.__lt__(b). Only with Python versions 2.1 or higher will +expressions like a < b work as expected. + +

    +To support Rich Comparisions, the Python C API was modified between +Python versions 2.0 and 2.1. A new slot was introduced in the +PyTypeObject structure: tp_richcompare. For backwards +compatibility, a flag (Py_TPFLAGS_HAVE_RICHCOMPARE) has to be +set to signal to the Python interpreter that Rich Comparisions are +supported by a particular type. +There is only one flag for all the six comparison operators. +When any of the six operators is wrapped automatically or +manually, Boost.Python will set this flag. Attempts to use comparison +operators at the Python level that are not defined at the C++ level +will then lead to an AttributeError when the Python 2.1 +(or higher) interpreter tries, e.g., a.__lt__(b). That +is, in general all six operators should be supplied. Automatically +wrapped operators and manually wrapped operators can be mixed. For +example:

    +    boost::python::class_builder<code> py_code(this_module, "code");
    +
    +    py_code.def(boost::python::constructor<>());
    +    py_code.def(boost::python::constructor<int>());
    +    py_code.def(boost::python::operators<(  boost::python::op_eq
    +                                          | boost::python::op_ne)>());
    +    py_code.def(NotImplemented, "__lt__");
    +    py_code.def(NotImplemented, "__le__");
    +    py_code.def(NotImplemented, "__gt__");
    +    py_code.def(NotImplemented, "__ge__");
    +
    + +NotImplemented is a simple free function that (currently) has +to be provided by the user. For example:
    +  boost::python::ref
    +  NotImplemented(const code&, const code&) {
    +    return
    +    boost::python::ref(Py_NotImplemented, boost::python::ref::increment_count);
    +  }
    +
    + +See also: + + +
    +© Copyright Nicholas K. Sauter & Ralf W. Grosse-Kunstleve 2001. +Permission to copy, use, modify, sell and distribute this document is +granted provided this copyright notice appears in all copies. This +document is provided "as is" without express or implied warranty, and +with no claim as to its suitability for any purpose. + +

    +Updated: July 2001 + +

    diff --git a/doc/special.html b/doc/special.html index 0caa1924..46ca0791 100644 --- a/doc/special.html +++ b/doc/special.html @@ -60,13 +60,27 @@ __str__(self)
    Create a string representation which is suitable for printing. +
    + __lt__(self, other) +
    + __le__(self, other) +
    + __eq__(self, other) +
    + __ne__(self, other) +
    + __gt__(self, other) +
    + __ge__(self, other) +
    + Rich Comparison methods. + New in Python 2.1. + See Rich Comparisons.
    __cmp__(self, other)
    - Three-way compare function, used to implement comparison operators - (< etc.) Should return a negative integer if self < other - , zero if self == other , a positive integer if - self > other . + Three-way compare function. + See Rich Comparisons.
    __hash__(self)
    @@ -544,17 +558,42 @@ Note that "__rrpow__" is an extension not present in plain Python. __cmp__, __rcmp__ cmp(left, right)
    - left < right
    - left <= right
    - left > right
    - left >= right
    - left == right
    - left != right +
    See Rich Comparisons. op_cmp cpp_left < cpp_right 
    cpp_right < cpp_left + + + __lt__ +
    __le__ +
    __eq__ +
    __ne__ +
    __gt__ +
    __ge__ + + left < right +
    left <= right +
    left == right +
    left != right +
    left > right +
    left >= right +
    See Rich Comparisons + + op_lt +
    op_le +
    op_eq +
    op_ne +
    op_gt +
    op_ge + + cpp_left < cpp_right  +
    cpp_left <= cpp_right  +
    cpp_left == cpp_right  +
    cpp_left != cpp_right  +
    cpp_left > cpp_right  +
    cpp_left >= cpp_right  diff --git a/example/pickle3.cpp b/example/pickle3.cpp index bfa7dc54..cb598ae6 100644 --- a/example/pickle3.cpp +++ b/example/pickle3.cpp @@ -106,7 +106,7 @@ namespace { { if(args.size() != 1 || keywords.size() != 0) { PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - throw boost::python::argument_error(); + throw boost::python::error_already_set(); } const world& w = from_python(args[0].get(), type()); ref mydict = getattr(args[0], "__dict__"); @@ -122,7 +122,7 @@ namespace { { if(args.size() != 2 || keywords.size() != 0) { PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - throw boost::python::argument_error(); + throw boost::python::error_already_set(); } world& w = from_python(args[0].get(), type()); ref mydict = getattr(args[0], "__dict__"); diff --git a/example/richcmp1.cpp b/example/richcmp1.cpp new file mode 100644 index 00000000..4dd74e1b --- /dev/null +++ b/example/richcmp1.cpp @@ -0,0 +1,87 @@ +// Example by Ralf W. Grosse-Kunstleve & Nicholas K. Sauter +// This example shows how to use rich comparisons for a vector type. +// It also shows how to template the entire wrapping of a std::vector. +// See vector_wrapper.h. + +#include +#include "vector_wrapper.h" + +namespace vects { + + struct dvect : public std::vector + { + dvect() : std::vector() {} + dvect(size_t n) : std::vector(n) {} + dvect(boost::python::tuple tuple) : std::vector(tuple.size()) + { + std::vector::iterator v_it = begin(); + for (std::size_t i = 0; i < tuple.size(); i++) + v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + + boost::python::tuple as_tuple() const + { + boost::python::tuple t(size()); + for (std::size_t i = 0; i < size(); i++) + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); + return t; + } + +# define DVECT_BINARY_OPERATORS(oper) \ + friend std::vector \ + operator##oper(const dvect& lhs, const dvect& rhs) \ + { \ + if (lhs.size() != rhs.size()) { \ + PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \ + throw boost::python::error_already_set(); \ + } \ + std::vector result(lhs.size()); \ + for (std::size_t i=0; i) + DVECT_BINARY_OPERATORS(>=) +# undef VECTOR_BINARY_OPERATORS + }; + +} // namespace + + +namespace { + + void init_module(boost::python::module_builder& this_module) + { + (void) example::wrap_vector(this_module, "vector_of_bool", bool()); + + boost::python::class_builder py_dvect(this_module, "dvect"); + + py_dvect.def(boost::python::constructor()); + py_dvect.def(&vects::dvect::as_tuple, "as_tuple"); + + const long + comp_operators = ( boost::python::op_lt | boost::python::op_le + | boost::python::op_eq | boost::python::op_ne + | boost::python::op_gt | boost::python::op_ge); + py_dvect.def(boost::python::operators()); + } + +} // namespace + +BOOST_PYTHON_MODULE_INIT(richcmp1) +{ + try { + boost::python::module_builder this_module("richcmp1"); + // The actual work is done in a separate function in order + // to suppress a bogus VC60 warning. + init_module(this_module); + } + catch (...) { boost::python::handle_exception(); } +} diff --git a/example/richcmp2.cpp b/example/richcmp2.cpp new file mode 100644 index 00000000..213852b3 --- /dev/null +++ b/example/richcmp2.cpp @@ -0,0 +1,65 @@ +// Example by Ralf W. Grosse-Kunstleve +// This example shows how to use rich comparisons for a type that +// does not support all six operators (<, <=, ==, !=, >, >=). +// To keep the example simple, we are using a "code" type does +// not really require rich comparisons. __cmp__ would be sufficient. +// However, with a more complicated type the main point of this +// example would be in danger of getting lost. + +#include + +namespace { + + // suppose operator< and operator> are not meaningful for code + class code { + public: + code(int c = 0) : m_code(c) {} + inline friend bool operator==(const code& lhs, const code& rhs) { + return lhs.m_code == rhs.m_code; + } + inline friend bool operator!=(const code& lhs, const code& rhs) { + return lhs.m_code != rhs.m_code; + } + private: + int m_code; + }; + +#if PYTHON_API_VERSION >= 1010 + boost::python::ref + NotImplemented(const code&, const code&) { + return + boost::python::ref(Py_NotImplemented, boost::python::ref::increment_count); + } +#endif +} + +namespace { + + void init_module(boost::python::module_builder& this_module) + { + boost::python::class_builder py_code(this_module, "code"); + + py_code.def(boost::python::constructor<>()); + py_code.def(boost::python::constructor()); + py_code.def(boost::python::operators<( boost::python::op_eq + | boost::python::op_ne)>()); +#if PYTHON_API_VERSION >= 1010 + py_code.def(NotImplemented, "__lt__"); + py_code.def(NotImplemented, "__le__"); + py_code.def(NotImplemented, "__gt__"); + py_code.def(NotImplemented, "__ge__"); +#endif + } + +} // namespace + +BOOST_PYTHON_MODULE_INIT(richcmp2) +{ + try { + boost::python::module_builder this_module("richcmp2"); + // The actual work is done in a separate function in order + // to suppress a bogus VC60 warning. + init_module(this_module); + } + catch (...) { boost::python::handle_exception(); } +} diff --git a/example/richcmp3.cpp b/example/richcmp3.cpp new file mode 100644 index 00000000..169e7f00 --- /dev/null +++ b/example/richcmp3.cpp @@ -0,0 +1,178 @@ +// Example by Ralf W. Grosse-Kunstleve & Nicholas K. Sauter. +// Comprehensive operator overloading for two vector types and scalars. + +#include +#include "vector_wrapper.h" +#include "dvect.h" +#include "ivect.h" + +#define VECT_VECT_OPERATORS(result_type, vect_type1, oper, vect_type2) \ +namespace vects { \ + result_type \ + operator##oper (const vect_type1& lhs, const vect_type2& rhs) { \ + if (lhs.size() != rhs.size()) { \ + PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \ + throw boost::python::error_already_set(); \ + } \ + result_type result(lhs.size()); \ + for (std::size_t i=0; i, vect_type1, <, vect_type2) \ + VECT_VECT_OPERATORS(std::vector, vect_type1, <=, vect_type2) \ + VECT_VECT_OPERATORS(std::vector, vect_type1, ==, vect_type2) \ + VECT_VECT_OPERATORS(std::vector, vect_type1, !=, vect_type2) \ + VECT_VECT_OPERATORS(std::vector, vect_type1, >, vect_type2) \ + VECT_VECT_OPERATORS(std::vector, vect_type1, >=, vect_type2) + +#define MATH_VECT_SCALAR_OPERATORS(result_type, vect_type, scalar_type) \ + VECT_SCALAR_OPERATORS(result_type, vect_type, +, scalar_type) \ + VECT_SCALAR_OPERATORS(result_type, vect_type, -, scalar_type) \ + VECT_SCALAR_OPERATORS(result_type, vect_type, *, scalar_type) \ + VECT_SCALAR_OPERATORS(result_type, vect_type, /, scalar_type) + +#define COMP_VECT_SCALAR_OPERATORS(vect_type, scalar_type) \ + VECT_SCALAR_OPERATORS(std::vector, vect_type, <, scalar_type) \ + VECT_SCALAR_OPERATORS(std::vector, vect_type, <=, scalar_type) \ + VECT_SCALAR_OPERATORS(std::vector, vect_type, ==, scalar_type) \ + VECT_SCALAR_OPERATORS(std::vector, vect_type, !=, scalar_type) \ + VECT_SCALAR_OPERATORS(std::vector, vect_type, >, scalar_type) \ + VECT_SCALAR_OPERATORS(std::vector, vect_type, >=, scalar_type) + +#define MATH_SCALAR_VECT_OPERATORS(result_type, scalar_type, vect_type) \ + SCALAR_VECT_OPERATORS(result_type, scalar_type, +, vect_type) \ + SCALAR_VECT_OPERATORS(result_type, scalar_type, -, vect_type) \ + SCALAR_VECT_OPERATORS(result_type, scalar_type, *, vect_type) \ + SCALAR_VECT_OPERATORS(result_type, scalar_type, /, vect_type) + +MATH_VECT_VECT_OPERATORS(dvect, dvect, dvect) +COMP_VECT_VECT_OPERATORS( dvect, dvect) +MATH_VECT_SCALAR_OPERATORS(dvect, dvect, double) +COMP_VECT_SCALAR_OPERATORS( dvect, double) +MATH_SCALAR_VECT_OPERATORS(dvect, double, dvect) +// comparison operators not needed since Python uses reflection + +MATH_VECT_VECT_OPERATORS(ivect, ivect, ivect) +COMP_VECT_VECT_OPERATORS( ivect, ivect) +MATH_VECT_SCALAR_OPERATORS(ivect, ivect, int) +COMP_VECT_SCALAR_OPERATORS( ivect, int) +MATH_SCALAR_VECT_OPERATORS(ivect, int, ivect) +// comparison operators not needed since Python uses reflection + +MATH_VECT_VECT_OPERATORS(dvect, dvect, ivect) +COMP_VECT_VECT_OPERATORS( dvect, ivect) +MATH_VECT_VECT_OPERATORS(dvect, ivect, dvect) +COMP_VECT_VECT_OPERATORS( ivect, dvect) + +#undef VECT_VECT_OPERATORS +#undef SCALAR_VECT_OPERATORS +#undef VECT_SCALAR_OPERATORS +#undef MATH_VECT_VECT_OPERATORS +#undef COMP_VECT_VECT_OPERATORS +#undef MATH_VECT_SCALAR_OPERATORS +#undef COMP_VECT_SCALAR_OPERATORS +#undef MATH_SCALAR_VECT_OPERATORS + +namespace { + + void init_module(boost::python::module_builder& this_module) + { + (void) example::wrap_vector(this_module, "vector_of_bool", bool()); + + const long + math_operators ( boost::python::op_mul | boost::python::op_add + | boost::python::op_div | boost::python::op_sub); + const long + comp_operators = ( boost::python::op_lt | boost::python::op_le + | boost::python::op_eq | boost::python::op_ne + | boost::python::op_gt | boost::python::op_ge); + + boost::python::class_builder + dvect_class(this_module, "dvect"); + boost::python::class_builder + ivect_class(this_module, "ivect"); + + dvect_class.def(boost::python::constructor()); + dvect_class.def(&vects::dvect::as_tuple,"as_tuple"); + + dvect_class.def(boost::python::operators()); + dvect_class.def(boost::python::operators(), + boost::python::right_operand() ); + dvect_class.def(boost::python::operators(), + boost::python::left_operand() ); + dvect_class.def(boost::python::operators(), + boost::python::right_operand() ); + + dvect_class.def(boost::python::operators()); + dvect_class.def(boost::python::operators(), + boost::python::right_operand() ); + // left_operand not needed since Python uses reflection + dvect_class.def(boost::python::operators(), + boost::python::right_operand() ); + + ivect_class.def(boost::python::constructor()); + ivect_class.def(&vects::ivect::as_tuple,"as_tuple"); + + ivect_class.def(boost::python::operators()); + ivect_class.def(boost::python::operators(), + boost::python::right_operand() ); + ivect_class.def(boost::python::operators(), + boost::python::left_operand() ); + ivect_class.def(boost::python::operators(), + boost::python::right_operand() ); + + ivect_class.def(boost::python::operators()); + ivect_class.def(boost::python::operators(), + boost::python::right_operand() ); + // left_operand not needed since Python uses reflection + ivect_class.def(boost::python::operators(), + boost::python::right_operand() ); + } + +} // namespace + +BOOST_PYTHON_MODULE_INIT(richcmp3) +{ + try { + boost::python::module_builder this_module("richcmp3"); + // The actual work is done in a separate function in order + // to suppress a bogus VC60 warning. + init_module(this_module); + } + catch (...) { boost::python::handle_exception(); } +} diff --git a/example/test_pickle3.py b/example/test_pickle3.py index 36da735d..6ac83b18 100644 --- a/example/test_pickle3.py +++ b/example/test_pickle3.py @@ -19,12 +19,12 @@ r'''>>> import pickle3 ... wd.z = 3. * number ... pstr = pickle.dumps(wd) ... wl = pickle.loads(pstr) - ... print wd.greet(), wd.get_secret_number(), wd.__dict__ - ... print wl.greet(), wl.get_secret_number(), wl.__dict__ - Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'} - Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'} - Hello from California! 42 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'} - Hello from California! 0 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'} + ... print wd.greet(), wd.get_secret_number(), wd.x, wd.y, wd.z + ... print wl.greet(), wl.get_secret_number(), wl.x, wl.y, wl.z + Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0 + Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0 + Hello from California! 42 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0 + Hello from California! 0 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0 ''' def run(args = None): diff --git a/example/test_richcmp1.py b/example/test_richcmp1.py new file mode 100644 index 00000000..d25fcc9c --- /dev/null +++ b/example/test_richcmp1.py @@ -0,0 +1,40 @@ +r'''>>> import richcmp1 + >>> d1 = richcmp1.dvect((0, 1, 3, 3, 6, 7)) + >>> d2 = richcmp1.dvect((1, 2, 3, 4, 5, 6)) + >>> print d1.as_tuple() + (0.0, 1.0, 3.0, 3.0, 6.0, 7.0) + >>> print d2.as_tuple() + (1.0, 2.0, 3.0, 4.0, 5.0, 6.0) + >>> print (d1 < d2).as_tuple() + (1, 1, 0, 1, 0, 0) + >>> print (d1 <= d2).as_tuple() + (1, 1, 1, 1, 0, 0) + >>> print (d1 == d2).as_tuple() + (0, 0, 1, 0, 0, 0) + >>> print (d1 != d2).as_tuple() + (1, 1, 0, 1, 1, 1) + >>> print (d1 > d2).as_tuple() + (0, 0, 0, 0, 1, 1) + >>> print (d1 >= d2).as_tuple() + (0, 0, 1, 0, 1, 1) + >>> try: d1 == richcmp1.dvect((1, 2, 3, 4, 5)) + ... except ValueError, e: print str(e) + ... + vectors have different sizes +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_richcmp1 + return doctest.testmod(test_richcmp1) + +if __name__ == '__main__': + import sys + if ( hasattr(sys, 'version_info') + and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1) + or sys.version_info[0] > 2)): + sys.exit(run()[0]) + else: + print "Python version 2.1 or higher required. Test skipped." diff --git a/example/test_richcmp2.py b/example/test_richcmp2.py new file mode 100644 index 00000000..859928c3 --- /dev/null +++ b/example/test_richcmp2.py @@ -0,0 +1,41 @@ +r'''>>> import richcmp2 + >>> c1 = richcmp2.code(1) + >>> c2 = richcmp2.code(2) + >>> c3 = richcmp2.code(2) + >>> print c1 == c2 + 0 + >>> print c1 != c2 + 1 + >>> print c2 == c3 + 1 + >>> print c2 != c3 + 0 + >>> print c1 < c2 + 1 + >>> print c1 <= c2 + 1 + >>> print c1 == c2 + 0 + >>> print c1 != c2 + 1 + >>> print c1 > c2 + 0 + >>> print c1 >= c2 + 0 +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_richcmp1 + return doctest.testmod(test_richcmp1) + +if __name__ == '__main__': + import sys + if ( hasattr(sys, 'version_info') + and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1) + or sys.version_info[0] > 2)): + sys.exit(run()[0]) + else: + print "Python version 2.1 or higher required. Test skipped." diff --git a/example/test_richcmp3.py b/example/test_richcmp3.py new file mode 100644 index 00000000..a769af17 --- /dev/null +++ b/example/test_richcmp3.py @@ -0,0 +1,77 @@ +r'''>>> import richcmp3 + >>> + >>> iv = richcmp3.ivect((1,2,3,4,5)) + >>> print iv.as_tuple() + (1, 2, 3, 4, 5) + >>> dv = richcmp3.dvect((2,-2,3,8,-5)) + >>> print dv.as_tuple() + (2.0, -2.0, 3.0, 8.0, -5.0) + >>> + >>> print (iv+dv).as_tuple() + (3.0, 0.0, 6.0, 12.0, 0.0) + >>> print (iv+3).as_tuple() + (4, 5, 6, 7, 8) + >>> print (3+iv).as_tuple() + (4, 5, 6, 7, 8) + >>> + >>> print "vect vs. vect Comparisons:" + vect vs. vect Comparisons: + >>> print (iv < dv).as_tuple() + (1, 0, 0, 1, 0) + >>> print (iv <= dv).as_tuple() + (1, 0, 1, 1, 0) + >>> print (iv == dv).as_tuple() + (0, 0, 1, 0, 0) + >>> print (iv != dv).as_tuple() + (1, 1, 0, 1, 1) + >>> print (iv > dv).as_tuple() + (0, 1, 0, 0, 1) + >>> print (iv >= dv).as_tuple() + (0, 1, 1, 0, 1) + >>> + >>> print "vect vs. scalar Comparisons:" + vect vs. scalar Comparisons: + >>> print (iv < 3).as_tuple() + (1, 1, 0, 0, 0) + >>> print (iv <= 3).as_tuple() + (1, 1, 1, 0, 0) + >>> print (iv == 3).as_tuple() + (0, 0, 1, 0, 0) + >>> print (iv != 3).as_tuple() + (1, 1, 0, 1, 1) + >>> print (iv > 3).as_tuple() + (0, 0, 0, 1, 1) + >>> print (iv >= 3).as_tuple() + (0, 0, 1, 1, 1) + >>> + >>> print "scalar vs. vect Comparisons:" + scalar vs. vect Comparisons: + >>> print (3 < iv).as_tuple() + (0, 0, 0, 1, 1) + >>> print (3 <= iv).as_tuple() + (0, 0, 1, 1, 1) + >>> print (3 == iv).as_tuple() + (0, 0, 1, 0, 0) + >>> print (3 != iv).as_tuple() + (1, 1, 0, 1, 1) + >>> print (3 > iv).as_tuple() + (1, 1, 0, 0, 0) + >>> print (3 >= iv).as_tuple() + (1, 1, 1, 0, 0) +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_richcmp3 + return doctest.testmod(test_richcmp3) + +if __name__ == '__main__': + import sys + if ( hasattr(sys, 'version_info') + and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1) + or sys.version_info[0] > 2)): + sys.exit(run()[0]) + else: + print "Python version 2.1 or higher required. Test skipped." diff --git a/example/vector_wrapper.h b/example/vector_wrapper.h new file mode 100644 index 00000000..d5bd7215 --- /dev/null +++ b/example/vector_wrapper.h @@ -0,0 +1,117 @@ +// Based on wrapVector.hh by Mike Owen and Jeff Johnson. +// http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/spheral/src/src/BPLWraps/CXXWraps/ + +#ifndef BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H +#define BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H + +#include + +namespace example { + + // A wrapper is used to define additional constructors. This wrapper + // is templated on the template parameter for its corresponding vector. + template + struct vector_wrapper: std::vector + { + // Tell the compiler how to convert a base class object to + // this wrapper object. + vector_wrapper(PyObject*, + const std::vector& vec): + std::vector(vec) {} + + vector_wrapper(PyObject* self): + std::vector() {} + + vector_wrapper(PyObject* self, + std::size_t n): + std::vector(n) {} + + vector_wrapper(PyObject* self, + boost::python::tuple tuple): + std::vector(tuple.size()) + { + std::vector::iterator vec = begin(); + for (std::size_t i = 0; i < tuple.size(); i++) + vec[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), + boost::python::type()); + } + }; + + void raise_vector_IndexError() { + PyErr_SetString(PyExc_IndexError, "vector index out of range"); + throw boost::python::error_already_set(); + } + + template + struct vector_access + { + static + T + getitem(const std::vector& vec, + std::size_t key) + { + if (key >= vec.size()) raise_vector_IndexError(); + return vec[key]; + } + + static + void + setitem(std::vector& vec, + std::size_t key, + const T &value) + { + if (key >= vec.size()) raise_vector_IndexError(); + vec[key] = value; + } + + static + void + delitem(std::vector& vec, + std::size_t key) + { + if (key >= vec.size()) raise_vector_IndexError(); + vec.erase(vec.begin() + key); + } + + // Convert vector to a regular Python tuple. + static + boost::python::tuple + as_tuple(const std::vector& vec) + { + // Create a python type of size vec.size(). + boost::python::tuple t(vec.size()); + for (std::size_t i = 0; i < vec.size(); i++) { + t.set_item(i, + boost::python::ref(BOOST_PYTHON_CONVERSION::to_python(vec[i]))); + } + return t; + } + }; + + // This function will build a vector and add it to the given + // module with the given name. + template + boost::python::class_builder, vector_wrapper > + wrap_vector(boost::python::module_builder& module, + const std::string& vector_name, + const T&) + { + // Add the vector to the module. + boost::python::class_builder, vector_wrapper > + py_vector(module, vector_name.c_str()); + + // Define constructors and methods for the vector. + py_vector.def(boost::python::constructor<>()); + py_vector.def(boost::python::constructor()); + py_vector.def(boost::python::constructor()); + py_vector.def(&std::vector::size, "__len__"); + py_vector.def(&vector_access::getitem, "__getitem__"); + py_vector.def(&vector_access::setitem, "__setitem__"); + py_vector.def(&vector_access::delitem, "__delitem__"); + py_vector.def(&vector_access::as_tuple, "as_tuple"); + + return py_vector; + } +} + +#endif // BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H diff --git a/include/boost/python/classes.hpp b/include/boost/python/classes.hpp index d38fbba5..2d69e81e 100644 --- a/include/boost/python/classes.hpp +++ b/include/boost/python/classes.hpp @@ -70,6 +70,14 @@ class instance PyObject* oct(); PyObject* hex(); + // Rich comparisons + PyObject* lt(PyObject* other); + PyObject* le(PyObject* other); + PyObject* eq(PyObject* other); + PyObject* ne(PyObject* other); + PyObject* gt(PyObject* other); + PyObject* ge(PyObject* other); + private: // noncopyable, without the size bloat instance(const instance&); void operator=(const instance&); @@ -169,6 +177,14 @@ class class_t PyObject* instance_number_float(PyObject*) const; PyObject* instance_number_oct(PyObject*) const; PyObject* instance_number_hex(PyObject*) const; + + private: // Implement rich comparisons + PyObject* instance_lt(PyObject*, PyObject*) const; + PyObject* instance_le(PyObject*, PyObject*) const; + PyObject* instance_eq(PyObject*, PyObject*) const; + PyObject* instance_ne(PyObject*, PyObject*) const; + PyObject* instance_gt(PyObject*, PyObject*) const; + PyObject* instance_ge(PyObject*, PyObject*) const; private: // Miscellaneous "special" methods PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* keywords) const; @@ -477,6 +493,42 @@ PyObject* class_t::instance_number_hex(PyObject* obj) const return downcast(obj)->hex(); } +template +PyObject* class_t::instance_lt(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->lt(other); +} + +template +PyObject* class_t::instance_le(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->le(other); +} + +template +PyObject* class_t::instance_eq(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->eq(other); +} + +template +PyObject* class_t::instance_ne(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->ne(other); +} + +template +PyObject* class_t::instance_gt(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->gt(other); +} + +template +PyObject* class_t::instance_ge(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->ge(other); +} + namespace detail { inline dictionary& class_base::dict() { diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 5c8e720a..d871ad6e 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -616,6 +616,12 @@ class extension_class choose_op<(which & op_and)>::template args::add(this); choose_op<(which & op_xor)>::template args::add(this); choose_op<(which & op_or)>::template args::add(this); + choose_op<(which & op_gt)>::template args::add(this); + choose_op<(which & op_ge)>::template args::add(this); + choose_op<(which & op_lt)>::template args::add(this); + choose_op<(which & op_le)>::template args::add(this); + choose_op<(which & op_eq)>::template args::add(this); + choose_op<(which & op_ne)>::template args::add(this); choose_unary_op<(which & op_neg)>::template args::add(this); choose_unary_op<(which & op_pos)>::template args::add(this); choose_unary_op<(which & op_abs)>::template args::add(this); @@ -645,6 +651,12 @@ class extension_class choose_op<(which & op_xor)>::template args::add(this); choose_op<(which & op_or)>::template args::add(this); choose_op<(which & op_cmp)>::template args::add(this); + choose_op<(which & op_gt)>::template args::add(this); + choose_op<(which & op_ge)>::template args::add(this); + choose_op<(which & op_lt)>::template args::add(this); + choose_op<(which & op_le)>::template args::add(this); + choose_op<(which & op_eq)>::template args::add(this); + choose_op<(which & op_ne)>::template args::add(this); } template diff --git a/include/boost/python/detail/types.hpp b/include/boost/python/detail/types.hpp index 5f0c8f97..2d0d0f6b 100644 --- a/include/boost/python/detail/types.hpp +++ b/include/boost/python/detail/types.hpp @@ -45,7 +45,7 @@ class type_object_base : public python_type public: enum capability { - hash, call, str, getattr, setattr, compare, repr, + hash, call, str, getattr, setattr, compare, repr, richcompare, mapping_length, mapping_subscript, mapping_ass_subscript, @@ -115,6 +115,14 @@ class type_object_base : public python_type virtual PyObject* instance_number_float(PyObject*) const; virtual PyObject* instance_number_oct(PyObject*) const; virtual PyObject* instance_number_hex(PyObject*) const; + + public: // Callbacks for rich comparisons + virtual PyObject* instance_lt(PyObject*, PyObject*) const; + virtual PyObject* instance_le(PyObject*, PyObject*) const; + virtual PyObject* instance_eq(PyObject*, PyObject*) const; + virtual PyObject* instance_ne(PyObject*, PyObject*) const; + virtual PyObject* instance_gt(PyObject*, PyObject*) const; + virtual PyObject* instance_ge(PyObject*, PyObject*) const; }; template diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp index da88ec6c..52e52eee 100644 --- a/include/boost/python/operators.hpp +++ b/include/boost/python/operators.hpp @@ -65,7 +65,13 @@ enum operator_id op_long = 0x20000, op_float = 0x40000, op_str = 0x80000, - op_cmp = 0x100000 + op_cmp = 0x100000, + op_gt = 0x200000, + op_ge = 0x400000, + op_lt = 0x800000, + op_le = 0x1000000, + op_eq = 0x2000000, + op_ne = 0x4000000 }; // Wrap the operators given by "which". Usage: @@ -301,6 +307,12 @@ namespace detail PY_DEFINE_BINARY_OPERATORS(and, &); PY_DEFINE_BINARY_OPERATORS(xor, ^); PY_DEFINE_BINARY_OPERATORS(or, |); + PY_DEFINE_BINARY_OPERATORS(gt, >); + PY_DEFINE_BINARY_OPERATORS(ge, >=); + PY_DEFINE_BINARY_OPERATORS(lt, <); + PY_DEFINE_BINARY_OPERATORS(le, <=); + PY_DEFINE_BINARY_OPERATORS(eq, ==); + PY_DEFINE_BINARY_OPERATORS(ne, !=); PY_DEFINE_UNARY_OPERATORS(neg, -); PY_DEFINE_UNARY_OPERATORS(pos, +); diff --git a/src/classes.cpp b/src/classes.cpp index 8755bb34..a44c3c0a 100644 --- a/src/classes.cpp +++ b/src/classes.cpp @@ -736,6 +736,36 @@ PyObject* instance::hex() return callback::call_method(this, "__hex__"); } +PyObject* instance::lt(PyObject* other) +{ + return callback::call_method(this, "__lt__", other); +} + +PyObject* instance::le(PyObject* other) +{ + return callback::call_method(this, "__le__", other); +} + +PyObject* instance::eq(PyObject* other) +{ + return callback::call_method(this, "__eq__", other); +} + +PyObject* instance::ne(PyObject* other) +{ + return callback::call_method(this, "__ne__", other); +} + +PyObject* instance::gt(PyObject* other) +{ + return callback::call_method(this, "__gt__", other); +} + +PyObject* instance::ge(PyObject* other) +{ + return callback::call_method(this, "__ge__", other); +} + namespace { struct named_capability { @@ -747,6 +777,12 @@ namespace { { { "__hash__", detail::type_object_base::hash }, { "__cmp__", detail::type_object_base::compare }, + { "__gt__", detail::type_object_base::richcompare }, + { "__ge__", detail::type_object_base::richcompare }, + { "__lt__", detail::type_object_base::richcompare }, + { "__le__", detail::type_object_base::richcompare }, + { "__eq__", detail::type_object_base::richcompare }, + { "__ne__", detail::type_object_base::richcompare }, { "__repr__", detail::type_object_base::repr }, { "__str__", detail::type_object_base::str }, { "__call__", detail::type_object_base::call }, diff --git a/src/gen_extclass.py b/src/gen_extclass.py index 8de8a1ae..57189a7d 100644 --- a/src/gen_extclass.py +++ b/src/gen_extclass.py @@ -15,6 +15,7 @@ def gen_extclass(args): // gen_extclass.python // Revision History: +// 17 Apr 01 Comment added with reference to cross_module.hpp (R.W. Grosse-Kunstleve) // 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted // to_python (Dave Abrahams) @@ -171,6 +172,14 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // and U. T is the class the user really intends to wrap. U is a class derived // from T with some virtual function overriding boilerplate, or if there are no // virtual functions, U = held_instance. +// +// A look-alike of this class in root/boost/python/cross_module.hpp +// is used for the implementation of the cross-module support +// (export_converters and import_converters). If from_python +// and to_python converters are added or removed from the class +// below, the class python_import_extension_class_converters has +// to be modified accordingly. +// template > class python_extension_class_converters { @@ -607,6 +616,12 @@ class extension_class choose_op<(which & op_and)>::template args::add(this); choose_op<(which & op_xor)>::template args::add(this); choose_op<(which & op_or)>::template args::add(this); + choose_op<(which & op_gt)>::template args::add(this); + choose_op<(which & op_ge)>::template args::add(this); + choose_op<(which & op_lt)>::template args::add(this); + choose_op<(which & op_le)>::template args::add(this); + choose_op<(which & op_eq)>::template args::add(this); + choose_op<(which & op_ne)>::template args::add(this); choose_unary_op<(which & op_neg)>::template args::add(this); choose_unary_op<(which & op_pos)>::template args::add(this); choose_unary_op<(which & op_abs)>::template args::add(this); @@ -636,6 +651,12 @@ class extension_class choose_op<(which & op_xor)>::template args::add(this); choose_op<(which & op_or)>::template args::add(this); choose_op<(which & op_cmp)>::template args::add(this); + choose_op<(which & op_gt)>::template args::add(this); + choose_op<(which & op_ge)>::template args::add(this); + choose_op<(which & op_lt)>::template args::add(this); + choose_op<(which & op_le)>::template args::add(this); + choose_op<(which & op_eq)>::template args::add(this); + choose_op<(which & op_ne)>::template args::add(this); } template diff --git a/src/gen_init_function.py b/src/gen_init_function.py index 69935230..80a9c199 100644 --- a/src/gen_init_function.py +++ b/src/gen_init_function.py @@ -79,7 +79,8 @@ namespace detail { struct parameter_traits { private: - typedef const_ref_selector::value> selector; + enum { is_ref = boost::is_reference::value }; + typedef const_ref_selector selector; public: typedef typename selector::template const_ref::type const_reference; }; diff --git a/src/types.cpp b/src/types.cpp index 7ba5840b..f8cf1ea6 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -159,6 +159,28 @@ static PyObject* do_instance_repr(PyObject* obj) return call(obj, &type_object_base::instance_repr); } +static PyObject* do_instance_richcompare(PyObject* obj, PyObject* other, int d) +{ +#if PYTHON_API_VERSION >= 1010 + switch(d) + { + case Py_LT: + return call(obj, &type_object_base::instance_lt, other); + case Py_LE: + return call(obj, &type_object_base::instance_le, other); + case Py_EQ: + return call(obj, &type_object_base::instance_eq, other); + case Py_NE: + return call(obj, &type_object_base::instance_ne, other); + case Py_GT: + return call(obj, &type_object_base::instance_gt, other); + case Py_GE: + return call(obj, &type_object_base::instance_ge, other); + } +#endif + return 0; +} + static int do_instance_compare(PyObject* obj, PyObject* other) { return call(obj, &type_object_base::instance_compare, other); @@ -406,7 +428,7 @@ namespace bool add_capability_general(type_object_base::capability capability, PyTypeObject* dest) { assert(dest != 0); - + switch(capability) { ENABLE_GENERAL_CAPABILITY(hash); @@ -435,6 +457,20 @@ void create_method_table_if_null(T*& table) } } +bool add_capability_richcompare(type_object_base::capability capability, PyTypeObject* dest) +{ + assert(dest != 0); + if (capability == type_object_base::richcompare) { +#if PYTHON_API_VERSION >= 1010 + dest->tp_richcompare = &do_instance_richcompare; + dest->tp_flags |= Py_TPFLAGS_HAVE_RICHCOMPARE; +#endif + return true; + } + + return false; +} + #define ENABLE_MAPPING_CAPABILITY(field) \ case type_object_base::mapping_##field: \ create_method_table_if_null(dest); \ @@ -548,6 +584,8 @@ namespace detail { { if(add_capability_general(capability, dest_)) return; + if(add_capability_richcompare(capability, dest_)) + return; if(add_capability_mapping(capability, dest_->tp_as_mapping)) return; if(add_capability_sequence(capability, dest_->tp_as_sequence)) @@ -975,6 +1013,36 @@ PyObject* type_object_base::instance_number_hex(PyObject*) const return unimplemented("instance_number_hex"); } +PyObject* type_object_base::instance_lt(PyObject*, PyObject*) const +{ + return unimplemented("instance_lt"); +} + +PyObject* type_object_base::instance_le(PyObject*, PyObject*) const +{ + return unimplemented("instance_le"); +} + +PyObject* type_object_base::instance_eq(PyObject*, PyObject*) const +{ + return unimplemented("instance_eq"); +} + +PyObject* type_object_base::instance_ne(PyObject*, PyObject*) const +{ + return unimplemented("instance_ne"); +} + +PyObject* type_object_base::instance_gt(PyObject*, PyObject*) const +{ + return unimplemented("instance_gt"); +} + +PyObject* type_object_base::instance_ge(PyObject*, PyObject*) const +{ + return unimplemented("instance_ge"); +} + }} // namespace boost::python #ifdef TYPE_OBJECT_BASE_STANDALONE_TEST diff --git a/test/comprehensive.py b/test/comprehensive.py index 013fae96..db4f8b73 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -422,7 +422,7 @@ Some simple overloading tests: >>> try: r = Range('yikes') ... except TypeError, e: ... assert re.match( - ... 'No overloaded functions match [(]Range, string[)]\. Candidates are:\n.*\n.*', + ... 'No overloaded functions match [(]Range, str[a-z]*[)]\. Candidates are:\n.*\n.*', ... str(e)) ... else: print 'no exception' @@ -632,7 +632,7 @@ Testing overloaded free functions 15 >>> try: overloaded(1, 'foo') ... except TypeError, err: - ... assert re.match("No overloaded functions match \(int, string\)\. Candidates are:", + ... assert re.match("No overloaded functions match \(int, str[a-z]*\)\. Candidates are:", ... str(err)) ... else: ... print 'no exception' @@ -662,7 +662,7 @@ Testing overloaded constructors 5 >>> try: over = OverloadTest(1, 'foo') ... except TypeError, err: - ... assert re.match("No overloaded functions match \(OverloadTest, int, string\)\. Candidates are:", + ... assert re.match("No overloaded functions match \(OverloadTest, int, str[a-z]*\)\. Candidates are:", ... str(err)) ... else: ... print 'no exception' @@ -684,7 +684,7 @@ Testing overloaded methods 5 >>> try: over.overloaded(1,'foo') ... except TypeError, err: - ... assert re.match("No overloaded functions match \(OverloadTest, int, string\)\. Candidates are:", + ... assert re.match("No overloaded functions match \(OverloadTest, int, str[a-z]*\)\. Candidates are:", ... str(err)) ... else: ... print 'no exception' From 801cae13ac53968a3f65556d855ea84f08835999 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 31 Jul 2001 07:39:05 +0000 Subject: [PATCH 0105/1042] Macintosh mods: do_it_yourself_converters -> do_it_yourself_convts [SVN r10729] --- build/Jamfile | 4 ++-- build/filemgr.py | 6 +++--- build/irix_CC.mak | 12 ++++++------ build/linux_gcc.mak | 12 ++++++------ build/mingw32.mak | 12 ++++++------ build/tru64_cxx.mak | 12 ++++++------ build/vc60.mak | 8 ++++---- example/README | 2 +- ...self_converters.cpp => do_it_yourself_convts.cpp} | 4 ++-- ...f_converters.py => test_do_it_yourself_convts.py} | 8 ++++---- 10 files changed, 40 insertions(+), 40 deletions(-) rename example/{do_it_yourself_converters.cpp => do_it_yourself_convts.cpp} (97%) rename example/{test_do_it_yourself_converters.py => test_do_it_yourself_convts.py} (63%) diff --git a/build/Jamfile b/build/Jamfile index 314b1440..562aca1e 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -25,7 +25,7 @@ # getting_started1 - # getting_started2 - # simple_vector - -# do_it_yourself_converters - +# do_it_yourself_convts - # pickle1 - # pickle2 - # pickle3 - @@ -215,7 +215,7 @@ boost-python-example-test abstract ; boost-python-example-test getting_started1 ; boost-python-example-test getting_started2 ; boost-python-example-test simple_vector ; -boost-python-example-test do_it_yourself_converters ; +boost-python-example-test do_it_yourself_convts ; boost-python-example-test pickle1 ; boost-python-example-test pickle2 ; boost-python-example-test pickle3 ; diff --git a/build/filemgr.py b/build/filemgr.py index 5e32460e..2ff163f0 100644 --- a/build/filemgr.py +++ b/build/filemgr.py @@ -23,7 +23,7 @@ bpl_exa + "/abstract.cpp", bpl_exa + "/getting_started1.cpp", bpl_exa + "/getting_started2.cpp", bpl_exa + "/simple_vector.cpp", -bpl_exa + "/do_it_yourself_converters.cpp", +bpl_exa + "/do_it_yourself_convts.cpp", bpl_exa + "/pickle1.cpp", bpl_exa + "/pickle2.cpp", bpl_exa + "/pickle3.cpp", @@ -31,7 +31,7 @@ bpl_exa + "/test_abstract.py", bpl_exa + "/test_getting_started1.py", bpl_exa + "/test_getting_started2.py", bpl_exa + "/test_simple_vector.py", -bpl_exa + "/test_do_it_yourself_converters.py", +bpl_exa + "/test_do_it_yourself_convts.py", bpl_exa + "/test_pickle1.py", bpl_exa + "/test_pickle2.py", bpl_exa + "/test_pickle3.py", @@ -67,7 +67,7 @@ defs = ( "getting_started1", "getting_started2", "simple_vector", -"do_it_yourself_converters", +"do_it_yourself_convts", "pickle1", "pickle2", "pickle3", diff --git a/build/irix_CC.mak b/build/irix_CC.mak index 1fbe3388..6e465b98 100644 --- a/build/irix_CC.mak +++ b/build/irix_CC.mak @@ -43,7 +43,7 @@ DEPOBJ=$(OBJ) \ abstract.o \ getting_started1.o getting_started2.o \ simple_vector.o \ - do_it_yourself_converters.o \ + do_it_yourself_convts.o \ pickle1.o pickle2.o pickle3.o \ noncopyable_export.o noncopyable_import.o \ ivect.o dvect.o \ @@ -56,7 +56,7 @@ all: libboost_python.a \ abstract.so \ getting_started1.so getting_started2.so \ simple_vector.so \ - do_it_yourself_converters.so \ + do_it_yourself_convts.so \ pickle1.so pickle2.so pickle3.so \ noncopyable_export.so noncopyable_import.so \ ivect.so dvect.so \ @@ -81,8 +81,8 @@ getting_started2.so: $(OBJ) getting_started2.o simple_vector.so: $(OBJ) simple_vector.o $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so -do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so +do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o + $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so pickle1.so: $(OBJ) pickle1.o $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so @@ -125,7 +125,7 @@ test: $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_converters.py + $(PYEXE) test_do_it_yourself_convts.py $(PYEXE) test_pickle1.py $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py @@ -141,7 +141,7 @@ clean: rm -f getting_started1.o getting_started1.so rm -f getting_started2.o getting_started2.so rm -f simple_vector.o simple_vector.so - rm -f do_it_yourself_converters.o do_it_yourself_converters.so + rm -f do_it_yourself_convts.o do_it_yourself_convts.so rm -f pickle1.o pickle1.so rm -f pickle2.o pickle2.so rm -f pickle3.o pickle3.so diff --git a/build/linux_gcc.mak b/build/linux_gcc.mak index 3fe407a0..2c977473 100644 --- a/build/linux_gcc.mak +++ b/build/linux_gcc.mak @@ -44,7 +44,7 @@ DEPOBJ=$(OBJ) \ abstract.o \ getting_started1.o getting_started2.o \ simple_vector.o \ - do_it_yourself_converters.o \ + do_it_yourself_convts.o \ pickle1.o pickle2.o pickle3.o \ noncopyable_export.o noncopyable_import.o \ ivect.o dvect.o \ @@ -57,7 +57,7 @@ all: libboost_python.a \ abstract.so \ getting_started1.so getting_started2.so \ simple_vector.so \ - do_it_yourself_converters.so \ + do_it_yourself_convts.so \ pickle1.so pickle2.so pickle3.so \ noncopyable_export.so noncopyable_import.so \ ivect.so dvect.so \ @@ -82,8 +82,8 @@ getting_started2.so: $(OBJ) getting_started2.o simple_vector.so: $(OBJ) simple_vector.o $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so -do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so +do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o + $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so pickle1.so: $(OBJ) pickle1.o $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so @@ -126,7 +126,7 @@ test: $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_converters.py + $(PYEXE) test_do_it_yourself_convts.py $(PYEXE) test_pickle1.py $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py @@ -142,7 +142,7 @@ clean: rm -f getting_started1.o getting_started1.so rm -f getting_started2.o getting_started2.so rm -f simple_vector.o simple_vector.so - rm -f do_it_yourself_converters.o do_it_yourself_converters.so + rm -f do_it_yourself_convts.o do_it_yourself_convts.so rm -f pickle1.o pickle1.so rm -f pickle2.o pickle2.so rm -f pickle3.o pickle3.so diff --git a/build/mingw32.mak b/build/mingw32.mak index 6f192ce2..e966f48a 100644 --- a/build/mingw32.mak +++ b/build/mingw32.mak @@ -59,7 +59,7 @@ all: libboost_python.a \ abstract.pyd \ getting_started1.pyd getting_started2.pyd \ simple_vector.pyd \ - do_it_yourself_converters.pyd \ + do_it_yourself_convts.pyd \ pickle1.pyd pickle2.pyd pickle3.pyd \ noncopyable_export.pyd noncopyable_import.pyd \ ivect.pyd dvect.pyd \ @@ -102,11 +102,11 @@ simple_vector.pyd: $(OBJ) simple_vector.o --def simple_vector.def \ $(OBJ) simple_vector.o $(PYLIB) -do_it_yourself_converters.pyd: $(OBJ) do_it_yourself_converters.o +do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.o dllwrap $(DLLWRAPOPTS) \ - --dllname do_it_yourself_converters.pyd \ - --def do_it_yourself_converters.def \ - $(OBJ) do_it_yourself_converters.o $(PYLIB) + --dllname do_it_yourself_convts.pyd \ + --def do_it_yourself_convts.def \ + $(OBJ) do_it_yourself_convts.o $(PYLIB) pickle1.pyd: $(OBJ) pickle1.o dllwrap $(DLLWRAPOPTS) \ @@ -177,7 +177,7 @@ test: $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_converters.py + $(PYEXE) test_do_it_yourself_convts.py $(PYEXE) test_pickle1.py $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py diff --git a/build/tru64_cxx.mak b/build/tru64_cxx.mak index 8f3d3abf..fba2bfe1 100644 --- a/build/tru64_cxx.mak +++ b/build/tru64_cxx.mak @@ -54,7 +54,7 @@ DEPOBJ=$(OBJ) \ abstract.o \ getting_started1.o getting_started2.o \ simple_vector.o \ - do_it_yourself_converters.o \ + do_it_yourself_convts.o \ pickle1.o pickle2.o pickle3.o \ noncopyable_export.o noncopyable_import.o \ ivect.o dvect.o \ @@ -67,7 +67,7 @@ all: libboost_python.a \ abstract.so \ getting_started1.so getting_started2.so \ simple_vector.so \ - do_it_yourself_converters.so \ + do_it_yourself_convts.so \ pickle1.so pickle2.so pickle3.so \ noncopyable_export.so noncopyable_import.so \ ivect.so dvect.so \ @@ -96,8 +96,8 @@ getting_started2.so: $(OBJ) getting_started2.o simple_vector.so: $(OBJ) simple_vector.o $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so -do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so +do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o + $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so pickle1.so: $(OBJ) pickle1.o $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so @@ -140,7 +140,7 @@ test: $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_converters.py + $(PYEXE) test_do_it_yourself_convts.py $(PYEXE) test_pickle1.py $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py @@ -156,7 +156,7 @@ clean: rm -f getting_started1.o getting_started1.so rm -f getting_started2.o getting_started2.so rm -f simple_vector.o simple_vector.so - rm -f do_it_yourself_converters.o do_it_yourself_converters.so + rm -f do_it_yourself_convts.o do_it_yourself_convts.so rm -f pickle1.o pickle1.so rm -f pickle2.o pickle2.so rm -f pickle3.o pickle3.so diff --git a/build/vc60.mak b/build/vc60.mak index f545015b..ae655c14 100644 --- a/build/vc60.mak +++ b/build/vc60.mak @@ -43,7 +43,7 @@ all: boost_python.lib \ abstract.pyd \ getting_started1.pyd getting_started2.pyd \ simple_vector.pyd \ - do_it_yourself_converters.pyd \ + do_it_yourself_convts.pyd \ pickle1.pyd pickle2.pyd pickle3.pyd \ noncopyable_export.pyd noncopyable_import.pyd \ ivect.pyd dvect.pyd \ @@ -67,8 +67,8 @@ getting_started2.pyd: $(OBJ) getting_started2.obj simple_vector.pyd: $(OBJ) simple_vector.obj $(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) /export:initsimple_vector /out:"simple_vector.pyd" -do_it_yourself_converters.pyd: $(OBJ) do_it_yourself_converters.obj - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.obj $(PYLIB) /export:initdo_it_yourself_converters /out:"do_it_yourself_converters.pyd" +do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.obj + $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.obj $(PYLIB) /export:initdo_it_yourself_convts /out:"do_it_yourself_convts.pyd" pickle1.pyd: $(OBJ) pickle1.obj $(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) /export:initpickle1 /out:"pickle1.pyd" @@ -109,7 +109,7 @@ test: $(PYEXE) test_getting_started1.py $(PYEXE) test_getting_started2.py $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_converters.py + $(PYEXE) test_do_it_yourself_convts.py $(PYEXE) test_pickle1.py $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py diff --git a/example/README b/example/README index 35d822d5..817facd0 100644 --- a/example/README +++ b/example/README @@ -10,7 +10,7 @@ See also: libs/python/doc/pickle.html Other advanced concepts are introduced by: abstract.cpp simple_vector.cpp - do_it_yourself_converters.cpp + do_it_yourself_convts.cpp Examples for the cross-module support are provided by: noncopyable_export.cpp diff --git a/example/do_it_yourself_converters.cpp b/example/do_it_yourself_convts.cpp similarity index 97% rename from example/do_it_yourself_converters.cpp rename to example/do_it_yourself_convts.cpp index 6d2d2d6a..4d9c1c89 100644 --- a/example/do_it_yourself_converters.cpp +++ b/example/do_it_yourself_convts.cpp @@ -105,12 +105,12 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE BOOST_PYTHON_END_CONVERSION_NAMESPACE -BOOST_PYTHON_MODULE_INIT(do_it_yourself_converters) +BOOST_PYTHON_MODULE_INIT(do_it_yourself_convts) { try { // Create an object representing this extension module. - python::module_builder this_module("do_it_yourself_converters"); + python::module_builder this_module("do_it_yourself_convts"); // Create the Python type object for our extension class. python::class_builder ixset_class(this_module, "IndexingSet"); diff --git a/example/test_do_it_yourself_converters.py b/example/test_do_it_yourself_convts.py similarity index 63% rename from example/test_do_it_yourself_converters.py rename to example/test_do_it_yourself_convts.py index 17240750..6f5fa5a0 100644 --- a/example/test_do_it_yourself_converters.py +++ b/example/test_do_it_yourself_convts.py @@ -1,5 +1,5 @@ -r'''>>> import do_it_yourself_converters - >>> ixset = do_it_yourself_converters.IndexingSet() +r'''>>> import do_it_yourself_convts + >>> ixset = do_it_yourself_convts.IndexingSet() >>> ixset.add((1,2,3)) >>> ixset.add((4,5,6)) >>> ixset.add((7,8,9)) @@ -15,8 +15,8 @@ def run(args = None): if args is not None: import sys sys.argv = args - import doctest, test_do_it_yourself_converters - return doctest.testmod(test_do_it_yourself_converters) + import doctest, test_do_it_yourself_convts + return doctest.testmod(test_do_it_yourself_convts) if __name__ == '__main__': import sys From f646975c3668bdb05376b3a14b62f59cd96c1b0e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 31 Jul 2001 08:10:05 +0000 Subject: [PATCH 0106/1042] convert int/double to complex [SVN r10730] --- include/boost/python/conversions.hpp | 5 +++++ test/comprehensive.py | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/boost/python/conversions.hpp b/include/boost/python/conversions.hpp index 47f80989..cf753e2d 100644 --- a/include/boost/python/conversions.hpp +++ b/include/boost/python/conversions.hpp @@ -7,6 +7,7 @@ // producing this work. // // Revision History: +// 31 Jul 01 convert int/double to complex (Peter Bienstman) // 04 Mar 01 Fixed std::complex<> stuff to work with MSVC (David Abrahams) // 03 Mar 01 added: converters for [plain] char and std::complex // (Ralf W. Grosse-Kunstleve) @@ -93,6 +94,10 @@ namespace detail { template std::complex complex_from_python(PyObject* p, boost::python::type) { + if (PyInt_Check(p)) return std::complex(PyInt_AS_LONG(p)); + if (PyLong_Check(p)) return std::complex(PyLong_AsDouble(p)); + if (PyFloat_Check(p)) return std::complex(PyFloat_AS_DOUBLE(p)); + expect_complex(p); return std::complex( diff --git a/test/comprehensive.py b/test/comprehensive.py index db4f8b73..4ff34b48 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -1175,6 +1175,18 @@ test methodologies for wrapping functions that return a pointer '2.94' >>> '%.3g' % (dreal(c)) '6.35' + >>> '%.3g' % (dreal(3)) + '3' + >>> '%.3g' % (dreal(3L)) + '3' + >>> '%.3g' % (dreal(3.)) + '3' + >>> '%.3g' % (freal(3)) + '3' + >>> '%.3g' % (freal(3L)) + '3' + >>> '%.3g' % (freal(3.)) + '3' ''' #' From 9f3cda0ac35cc752ab6928d8f7c8f7f1101eeef5 Mon Sep 17 00:00:00 2001 From: Darin Adler Date: Tue, 7 Aug 2001 17:22:02 +0000 Subject: [PATCH 0107/1042] Spell things consistently. Add some bits of Mac stuff to the tests. Use std::size_t where needed. [SVN r10800] --- example/dvect.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/dvect.h b/example/dvect.h index 8ffe7b50..d059f04d 100644 --- a/example/dvect.h +++ b/example/dvect.h @@ -9,7 +9,7 @@ namespace vects { struct dvect : public std::vector { dvect() : std::vector() {} - dvect(size_t n) : std::vector(n) {} + dvect(std::size_t n) : std::vector(n) {} dvect(boost::python::tuple tuple) : std::vector(tuple.size()) { std::vector::iterator v_it = begin(); From 6e6ae18aabefe93b2a8561effaa54877f5da983e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 15 Aug 2001 19:15:57 +0000 Subject: [PATCH 0108/1042] Missing "std::" added (std::size_t) [SVN r10872] --- example/ivect.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/ivect.h b/example/ivect.h index a0187307..b8d52246 100644 --- a/example/ivect.h +++ b/example/ivect.h @@ -9,7 +9,7 @@ namespace vects { struct ivect : public std::vector { ivect() : std::vector() {} - ivect(size_t n) : std::vector(n) {} + ivect(std::size_t n) : std::vector(n) {} ivect(boost::python::tuple tuple) : std::vector(tuple.size()) { std::vector::iterator v_it = begin(); From 37b6e2232147e655aadf79d0fbaa99d628abae5f Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Mon, 20 Aug 2001 13:04:43 +0000 Subject: [PATCH 0109/1042] Misc; mostly fix links to hard disk locations [SVN r10902] --- doc/under-the-hood.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/under-the-hood.html b/doc/under-the-hood.html index e2a0ce2b..ee0ecdfb 100644 --- a/doc/under-the-hood.html +++ b/doc/under-the-hood.html @@ -35,8 +35,7 @@ "example1.html#world_class">extension_class<T> template defines a whole raft of these conversions (for T, T*, T&, std::auto_ptr<T>, etc.), using the same inline - friend function technique employed by the boost operators + friend function technique employed by the boost operators library.

    Because the to_python and from_python functions From c7f1c5e29cb6437cff63601ac0f7f6751cdf41af Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 28 Aug 2001 02:02:27 +0000 Subject: [PATCH 0110/1042] New example: nested.cpp [SVN r10946] --- build/filemgr.py | 3 +++ build/irix_CC.mak | 7 +++++++ build/linux_gcc.mak | 7 +++++++ build/mingw32.mak | 13 ++++++++++++- build/tru64_cxx.mak | 7 +++++++ build/vc60.mak | 7 ++++++- example/nested.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++ example/test_nested.py | 23 ++++++++++++++++++++++ 8 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 example/nested.cpp create mode 100644 example/test_nested.py diff --git a/build/filemgr.py b/build/filemgr.py index 2ff163f0..99f4ca30 100644 --- a/build/filemgr.py +++ b/build/filemgr.py @@ -24,6 +24,7 @@ bpl_exa + "/getting_started1.cpp", bpl_exa + "/getting_started2.cpp", bpl_exa + "/simple_vector.cpp", bpl_exa + "/do_it_yourself_convts.cpp", +bpl_exa + "/nested.cpp", bpl_exa + "/pickle1.cpp", bpl_exa + "/pickle2.cpp", bpl_exa + "/pickle3.cpp", @@ -32,6 +33,7 @@ bpl_exa + "/test_getting_started1.py", bpl_exa + "/test_getting_started2.py", bpl_exa + "/test_simple_vector.py", bpl_exa + "/test_do_it_yourself_convts.py", +bpl_exa + "/test_nested.py", bpl_exa + "/test_pickle1.py", bpl_exa + "/test_pickle2.py", bpl_exa + "/test_pickle3.py", @@ -68,6 +70,7 @@ defs = ( "getting_started2", "simple_vector", "do_it_yourself_convts", +"nested", "pickle1", "pickle2", "pickle3", diff --git a/build/irix_CC.mak b/build/irix_CC.mak index 6e465b98..e3a97781 100644 --- a/build/irix_CC.mak +++ b/build/irix_CC.mak @@ -44,6 +44,7 @@ DEPOBJ=$(OBJ) \ getting_started1.o getting_started2.o \ simple_vector.o \ do_it_yourself_convts.o \ + nested.o \ pickle1.o pickle2.o pickle3.o \ noncopyable_export.o noncopyable_import.o \ ivect.o dvect.o \ @@ -57,6 +58,7 @@ all: libboost_python.a \ getting_started1.so getting_started2.so \ simple_vector.so \ do_it_yourself_convts.so \ + nested.so \ pickle1.so pickle2.so pickle3.so \ noncopyable_export.so noncopyable_import.so \ ivect.so dvect.so \ @@ -84,6 +86,9 @@ simple_vector.so: $(OBJ) simple_vector.o do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so +nested.so: $(OBJ) nested.o + $(LD) $(LDOPTS) $(OBJ) nested.o -o nested.so + pickle1.so: $(OBJ) pickle1.o $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so @@ -126,6 +131,7 @@ test: $(PYEXE) test_getting_started2.py $(PYEXE) test_simple_vector.py $(PYEXE) test_do_it_yourself_convts.py + $(PYEXE) test_nested.py $(PYEXE) test_pickle1.py $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py @@ -142,6 +148,7 @@ clean: rm -f getting_started2.o getting_started2.so rm -f simple_vector.o simple_vector.so rm -f do_it_yourself_convts.o do_it_yourself_convts.so + rm -f nested.o nested.so rm -f pickle1.o pickle1.so rm -f pickle2.o pickle2.so rm -f pickle3.o pickle3.so diff --git a/build/linux_gcc.mak b/build/linux_gcc.mak index 2c977473..64d61bab 100644 --- a/build/linux_gcc.mak +++ b/build/linux_gcc.mak @@ -45,6 +45,7 @@ DEPOBJ=$(OBJ) \ getting_started1.o getting_started2.o \ simple_vector.o \ do_it_yourself_convts.o \ + nested.o \ pickle1.o pickle2.o pickle3.o \ noncopyable_export.o noncopyable_import.o \ ivect.o dvect.o \ @@ -58,6 +59,7 @@ all: libboost_python.a \ getting_started1.so getting_started2.so \ simple_vector.so \ do_it_yourself_convts.so \ + nested.so \ pickle1.so pickle2.so pickle3.so \ noncopyable_export.so noncopyable_import.so \ ivect.so dvect.so \ @@ -85,6 +87,9 @@ simple_vector.so: $(OBJ) simple_vector.o do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so +nested.so: $(OBJ) nested.o + $(LD) $(LDOPTS) $(OBJ) nested.o -o nested.so + pickle1.so: $(OBJ) pickle1.o $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so @@ -127,6 +132,7 @@ test: $(PYEXE) test_getting_started2.py $(PYEXE) test_simple_vector.py $(PYEXE) test_do_it_yourself_convts.py + $(PYEXE) test_nested.py $(PYEXE) test_pickle1.py $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py @@ -143,6 +149,7 @@ clean: rm -f getting_started2.o getting_started2.so rm -f simple_vector.o simple_vector.so rm -f do_it_yourself_convts.o do_it_yourself_convts.so + rm -f nested.o nested.so rm -f pickle1.o pickle1.so rm -f pickle2.o pickle2.so rm -f pickle3.o pickle3.so diff --git a/build/mingw32.mak b/build/mingw32.mak index e966f48a..bf590409 100644 --- a/build/mingw32.mak +++ b/build/mingw32.mak @@ -30,13 +30,16 @@ # -fvtable-thunks eliminates the compiler warning, but # "import boost_python_test" still causes a crash. -ROOT=L: +ROOT=R: BOOST_WIN="$(ROOT)\boost" BOOST_UNIX=$(HOME)/boost PYEXE="C:\Program files\Python\python.exe" PYINC=-I"C:\usr\include\python1.5" PYLIB="C:\usr\lib\libpython15.a" +#PYEXE="C:\Python21\python.exe" +#PYINC=-I"C:\usr\include\python2.1" +#PYLIB="C:\usr\lib\libpython21.a" STDOPTS=-ftemplate-depth-21 WARNOPTS= @@ -60,6 +63,7 @@ all: libboost_python.a \ getting_started1.pyd getting_started2.pyd \ simple_vector.pyd \ do_it_yourself_convts.pyd \ + nested.pyd \ pickle1.pyd pickle2.pyd pickle3.pyd \ noncopyable_export.pyd noncopyable_import.pyd \ ivect.pyd dvect.pyd \ @@ -108,6 +112,12 @@ do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.o --def do_it_yourself_convts.def \ $(OBJ) do_it_yourself_convts.o $(PYLIB) +nested.pyd: $(OBJ) nested.o + dllwrap $(DLLWRAPOPTS) \ + --dllname nested.pyd \ + --def nested.def \ + $(OBJ) nested.o $(PYLIB) + pickle1.pyd: $(OBJ) pickle1.o dllwrap $(DLLWRAPOPTS) \ --dllname pickle1.pyd \ @@ -178,6 +188,7 @@ test: $(PYEXE) test_getting_started2.py $(PYEXE) test_simple_vector.py $(PYEXE) test_do_it_yourself_convts.py + $(PYEXE) test_nested.py $(PYEXE) test_pickle1.py $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py diff --git a/build/tru64_cxx.mak b/build/tru64_cxx.mak index fba2bfe1..d06f3372 100644 --- a/build/tru64_cxx.mak +++ b/build/tru64_cxx.mak @@ -55,6 +55,7 @@ DEPOBJ=$(OBJ) \ getting_started1.o getting_started2.o \ simple_vector.o \ do_it_yourself_convts.o \ + nested.o \ pickle1.o pickle2.o pickle3.o \ noncopyable_export.o noncopyable_import.o \ ivect.o dvect.o \ @@ -68,6 +69,7 @@ all: libboost_python.a \ getting_started1.so getting_started2.so \ simple_vector.so \ do_it_yourself_convts.so \ + nested.so \ pickle1.so pickle2.so pickle3.so \ noncopyable_export.so noncopyable_import.so \ ivect.so dvect.so \ @@ -99,6 +101,9 @@ simple_vector.so: $(OBJ) simple_vector.o do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so +nested.so: $(OBJ) nested.o + $(LD) $(LDOPTS) $(OBJ) nested.o -o nested.so + pickle1.so: $(OBJ) pickle1.o $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so @@ -141,6 +146,7 @@ test: $(PYEXE) test_getting_started2.py $(PYEXE) test_simple_vector.py $(PYEXE) test_do_it_yourself_convts.py + $(PYEXE) test_nested.py $(PYEXE) test_pickle1.py $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py @@ -157,6 +163,7 @@ clean: rm -f getting_started2.o getting_started2.so rm -f simple_vector.o simple_vector.so rm -f do_it_yourself_convts.o do_it_yourself_convts.so + rm -f nested.o nested.so rm -f pickle1.o pickle1.so rm -f pickle2.o pickle2.so rm -f pickle3.o pickle3.so diff --git a/build/vc60.mak b/build/vc60.mak index ae655c14..a348de54 100644 --- a/build/vc60.mak +++ b/build/vc60.mak @@ -10,7 +10,7 @@ # 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) # Initial version: R.W. Grosse-Kunstleve -ROOT=L: +ROOT=R: BOOST_WIN="$(ROOT)\boost" BOOST_UNIX=$(HOME)/boost @@ -44,6 +44,7 @@ all: boost_python.lib \ getting_started1.pyd getting_started2.pyd \ simple_vector.pyd \ do_it_yourself_convts.pyd \ + nested.pyd \ pickle1.pyd pickle2.pyd pickle3.pyd \ noncopyable_export.pyd noncopyable_import.pyd \ ivect.pyd dvect.pyd \ @@ -70,6 +71,9 @@ simple_vector.pyd: $(OBJ) simple_vector.obj do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.obj $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.obj $(PYLIB) /export:initdo_it_yourself_convts /out:"do_it_yourself_convts.pyd" +nested.pyd: $(OBJ) nested.obj + $(LD) $(LDOPTS) $(OBJ) nested.obj $(PYLIB) /export:initnested /out:"nested.pyd" + pickle1.pyd: $(OBJ) pickle1.obj $(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) /export:initpickle1 /out:"pickle1.pyd" @@ -110,6 +114,7 @@ test: $(PYEXE) test_getting_started2.py $(PYEXE) test_simple_vector.py $(PYEXE) test_do_it_yourself_convts.py + $(PYEXE) test_nested.py $(PYEXE) test_pickle1.py $(PYEXE) test_pickle2.py $(PYEXE) test_pickle3.py diff --git a/example/nested.cpp b/example/nested.cpp new file mode 100644 index 00000000..543754f7 --- /dev/null +++ b/example/nested.cpp @@ -0,0 +1,44 @@ +// Example by Ralf W. Grosse-Kunstleve + +/* + This example shows how convert a nested Python tuple. + */ + +#include +#include + +namespace { + + boost::python::list + show_nested_tuples(boost::python::tuple outer) + { + boost::python::list result; + for (int i = 0; i < outer.size(); i++) { + boost::python::tuple inner( + BOOST_PYTHON_CONVERSION::from_python(outer[i].get(), + boost::python::type())); + for (int j = 0; j < inner.size(); j++) { + double x = BOOST_PYTHON_CONVERSION::from_python(inner[j].get(), + boost::python::type()); + char buf[128]; + sprintf(buf, "(%d,%d) %.6g", i, j, x); + result.append(BOOST_PYTHON_CONVERSION::to_python(std::string(buf))); + } + } + return result; + } + +} + +BOOST_PYTHON_MODULE_INIT(nested) +{ + try + { + boost::python::module_builder this_module("nested"); + this_module.def(show_nested_tuples, "show_nested_tuples"); + } + catch(...) + { + boost::python::handle_exception(); + } +} diff --git a/example/test_nested.py b/example/test_nested.py new file mode 100644 index 00000000..e9abbf0f --- /dev/null +++ b/example/test_nested.py @@ -0,0 +1,23 @@ +r'''>>> import nested + >>> s = nested.show_nested_tuples(((1,2,3), (4,5,6,7))) + >>> for l in s: + ... print l + (0,0) 1 + (0,1) 2 + (0,2) 3 + (1,0) 4 + (1,1) 5 + (1,2) 6 + (1,3) 7 +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, test_nested + return doctest.testmod(test_nested) + +if __name__ == '__main__': + import sys + sys.exit(run()[0]) From e552607c95cf513a8f3e1f3c1ce123c909356fd1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 22 Sep 2001 17:51:10 +0000 Subject: [PATCH 0111/1042] const-ified list::size() and slice_proxy::size() [SVN r11212] --- include/boost/python/objects.hpp | 4 ++-- src/objects.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/objects.hpp b/include/boost/python/objects.hpp index 34052e1f..3b1a9094 100644 --- a/include/boost/python/objects.hpp +++ b/include/boost/python/objects.hpp @@ -101,7 +101,7 @@ class list : public object explicit list(std::size_t sz = 0); static PyTypeObject* type_obj(); static bool accepts(ref p); - std::size_t size(); + std::size_t size() const; ref operator[](std::size_t pos) const; proxy operator[](std::size_t pos); ref get_item(std::size_t pos) const; @@ -283,7 +283,7 @@ struct list::slice_proxy const list& operator=(const list& rhs); operator ref() const; operator list() const; - std::size_t size(); + std::size_t size() const; ref operator[](std::size_t pos) const; private: friend class list; diff --git a/src/objects.cpp b/src/objects.cpp index cc46b2ba..125a1eb8 100644 --- a/src/objects.cpp +++ b/src/objects.cpp @@ -362,7 +362,7 @@ bool list::accepts(ref p) return PyList_Check(p.get()); } -std::size_t list::size() +std::size_t list::size() const { return PyList_Size(get()); } @@ -467,7 +467,7 @@ list::slice_proxy::operator list() const return list(this->operator ref()); } -std::size_t list::slice_proxy::size() +std::size_t list::slice_proxy::size() const { return this->operator list().size(); } From e63451a9e7a545b7cac02e5756bd46e717251f0d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 6 Oct 2001 18:19:15 +0000 Subject: [PATCH 0112/1042] regex, threads, and python will all build from the top level. If you build the 'test' target from the top level, it will run all regressions. Jamfile: subincludes for thread, python libs, and status for regression tests Jamrules: Use the new path-global rule to establish BOOST_ROOT correctly for all subprojects libs/regex/build/Jamfile Take advantage of correct BOOST_ROOT setting libs/python/build/Jamfile Search for python executable; don't try to build anything if it can't be found. don't build tests by default improved comments, organization, and naming. status/Jamfile Fixed references to config test files Failed tests now leave their stdout results in .error instead of removing it No test targets are dependencies of 'all' anymore Added comments Reorganized tools/build/Jambase Meant to check this in long ago. tools/build/allyourbase.jam Fixed SHELL_EXPORT setting, added SHELL_SET removed 'test' from the dependencies of 'all'; tests no longer run by default. Fixed the direction of slashes for Windows when ALL_LOCATE_TARGET is used. Added path-global rule for declaring path variables which may be relative rule in-invocation-subdir returns true if the current subproject is the one from which Jam was invoked rule protect-subdir is now used to protect subproject variables rule tokens-to-simple-path converts path tokens to a simplified path. tools/build/boost-base.jam Fixed bugs tools/build/jam_src/makedebugjam.bat Fixed a bug which prevented a final debug build tools/build/jam_src/search.c Fixed a bug of mine which caused LOCATE to be ignored (!). [SVN r11348] --- build/Jamfile | 136 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 48 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index 562aca1e..d597d055 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -5,13 +5,16 @@ # # Boost.Python build and test Jamfile # +# To run all tests quietly: jam test +# To run all tests with verbose output: jam -sPYTHON_TEST_ARGS=-v test +# # Declares the following targets: # 1. libboost_python, a static link library to be linked with all # Boost.Python modules # # 2. pairs of test targets of the form .test and .run -# .test runs the test when it is out-of-date, and the "all" target -# depends on it so that it it is built by default. .run runs +# .test runs the test when it is out-of-date, and the "test" +# pseudotarget depends on it. .run runs # a test unconditionally, and can be used to force a test to run.. Each # test target builds one or more Boost.Python modules and runs a Python # script to test them. The test names are: @@ -38,6 +41,12 @@ # # subproject-specific environment/command-line variables: # +# PYTHON - How to invoke the Python interpreter. Defaults to "python" +# +# PYTHON_ROOT - Windows only: where Python is installed. Defaults to "c:/tools/python" +# +# PYTHON_VERSION - Version of Python. Defaults to "2.1" on Windows, "1.5" on Unix +# # PYTHON_TEST_ARGS - specifies arguments to be passed to test scripts on # the command line. "-v" can be useful if you want to # see the output of successful tests. @@ -49,12 +58,21 @@ # declare the location of this subproject relative to the root subproject libs/python/build ; +# grab variables from command-line or environment. +local PYTHON_VERSION = $(PYTHON_VERSION) ; +local PYTHON_ROOT = $(PYTHON_ROOT) ; +local PYTHON_INCLUDES = $(PYTHON_INCLUDES) ; +local PYTHON_LIBS = $(PYTHON_LIBS) ; +local PYTHON_LIB_PATH = $(PYTHON_LIB_PATH) ; +local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) ; + # Do some OS-specific setup if $(NT) { + PYTHON_VERSION ?= 2.1 ; PYTHON_ROOT ?= c:/tools/python ; - PYTHON_INCLUDES ?= $(PYTHON_ROOT)/include <*>/usr/include/python2.1 ; - PYTHON_LIBS ?= c:/cygnus/lib/python2.1/config/libpython2.1.dll.a ; + PYTHON_INCLUDES ?= $(PYTHON_ROOT)/include <*>/usr/include/python$(PYTHON_VERSION) ; + PYTHON_LIBS ?= c:/cygnus/lib/python$(PYTHON_VERSION)/config/libpython$(PYTHON_VERSION).dll.a ; PYTHON_LIB_PATH = $(PYTHON_ROOT)/libs ; # common properties required for compiling any Python module. @@ -64,17 +82,20 @@ if $(NT) dynamic ; - SHELL_SET ?= "set " ; - SHELL_EXPORT ?= ; # shell variables are exported by default } else if $(UNIX) { - PYTHON_INCLUDES ?= /usr/include/python1.5 ; - PYTHON_LIBS ?= /usr/lib/python1.5/config/libpython1.5.a ; - SHELL_SET ?= "" ; - SHELL_EXPORT ?= "export " ; + PYTHON_VERSION ?= 1.5 ; + PYTHON_INCLUDES ?= /usr/include/python$(PYTHON_VERSION) ; + PYTHON_LIBS ?= /usr/lib/python$(PYTHON_VERSION)/config/libpython$(PYTHON_VERSION).a ; } +# how do we invoke python? +local PYTHON = $(PYTHON) ; +PYTHON ?= python ; +PYTHON = [ FAppendSuffix $(PYTHON:G=) : $(SUFEXE) ] ; +SEARCH on $(PYTHON) = $(PATH) ; + ####################### # @@ -82,10 +103,10 @@ else if $(UNIX) # # standard include requirements for anything using Boost.Python -BOOST_PYTHON_INCLUDES = $(BOOST_ROOT) $(PYTHON_INCLUDES) ; +local BOOST_PYTHON_INCLUDES = $(BOOST_ROOT) $(PYTHON_INCLUDES) ; # Base names of the source files for libboost_python -CPP_SOURCES = +local CPP_SOURCES = classes conversions extension_class functions init_function module_builder objects types cross_module ; @@ -117,13 +138,25 @@ rule boost-python : $(4) ; # pass on the default-BUILD, if any } +# boost-python-test name : sources : requirements : default-BUILD +# +# Just like boost-python, but the result becomes part of the test pseudotarget +# instead of being built by 'all' +rule boost-python-test +{ + type-DEPENDS test : $(<) ; + + local gSUPPRESS_FAKE_TARGETS = true ; + boost-python $(1) : $(2) : $(3) : $(4) ; +} + ####################### -# boost-python-test target : python-script sources : requirements : local-build : args +# boost-python-runtest target : python-script sources : requirements : local-build : args # # declare two python module tests: $(<).test which builds when out-of-date, and # $(<).run which builds unconditionally. -rule boost-python-test +rule boost-python-runtest { # tell Jam that the python script is relative to this directory SEARCH on $(>[1]) = $(SEARCH_SOURCE) ; @@ -131,28 +164,25 @@ rule boost-python-test # required command-line args can be specified in argument 5 # The user can add additional arguments in PYTHON_TEST_ARGS. local gPYTHON_TEST_ARGS = $(5) $(PYTHON_TEST_ARGS) ; - + # declare the two subsidiary tests. declare-local-target $(<:S=.test) : $(>) : $(PYTHON_PROPERTIES) : $(4) : PYTHON_TEST ; declare-local-target $(<:S=.run) : $(>) : $(PYTHON_PROPERTIES) : $(4) : PYTHON_RUNTEST ; } -# how do we invoke python? -PYTHON ?= python ; - # special rules for two new target types: PYTHON_TEST and PYTHON_RUNTEST. # These are identical except that PYTHON_TEST runs the test when out-of-date, and -# PYTHON_RUNTEST runs the test unconditionally. These are used by boost-python-test. +# PYTHON_RUNTEST runs the test unconditionally. These are used by boost-python-runtest. SUFPYTHON_TEST = .test ; gGENERATOR_FUNCTION(PYTHON_TEST) = python-test-target ; rule python-test-target # test-target : sources : { - python-test-aux $(<) : $(>) ; + python-runtest-aux $(<) : $(>) ; Clean clean : $(<) ; # remove the test-target as part of any clean operation type-DEPENDS test : $(<) ; MakeLocate $(<) : $(LOCATE_TARGET) ; } -actions python-test-target +actions python-test-target bind PYTHON { $(SHELL_SET)PYTHONPATH=$(PYTHONPATH) $(SHELL_EXPORT)PYTHONPATH @@ -163,18 +193,18 @@ SUFPYTHON_RUNTEST = .run ; gGENERATOR_FUNCTION(PYTHON_RUNTEST) = python-runtest-target ; rule python-runtest-target # test-target : sources : { - python-test-aux $(<) : $(>) ; + python-runtest-aux $(<) : $(>) ; NOTFILE $(<) ; ALWAYS $(<) ; } -actions python-runtest-target +actions python-runtest-target bind PYTHON { $(SHELL_SET)PYTHONPATH=$(PYTHONPATH) $(SHELL_EXPORT)PYTHONPATH $(PYTHON) "$(>)" $(ARGS) } -rule python-test-aux # target : sources +rule python-runtest-aux # target : sources { DEPENDS $(<) : $(>) ; @@ -196,50 +226,60 @@ rule python-test-aux # target : sources [ join-path $(TOP) libs python test ] # location of doctest $(PYTHONPATH) # base PYTHONPATH from environment : $(SPLITPATH) ] ; # platform path separator + + PYTHON on $(<) = $(PYTHON) ; + DEPENDS $(<) : $(PYTHON) ; } ############# comprehensive module and test ########### -boost-python boost_python_test : ../test/comprehensive.cpp ; -boost-python-test comprehensive : [ join-path $(DOTDOT) test comprehensive.py ] boost_python_test ; +boost-python-test boost_python_test : ../test/comprehensive.cpp ; + +boost-python-runtest comprehensive + : [ join-path $(DOTDOT) test comprehensive.py ] + boost_python_test ; ############# simple tests from ../example ############ -rule boost-python-example-test +rule boost-python-example-runtest { - boost-python $(<) : ../example/$(<).cpp ; - boost-python-test $(<) : [ join-path $(DOTDOT) example test_$(<).py ] $(<) ; + boost-python-test $(<) : ../example/$(<).cpp ; + boost-python-runtest $(<) : [ join-path $(DOTDOT) example test_$(<).py ] $(<) ; } -boost-python-example-test abstract ; -boost-python-example-test getting_started1 ; -boost-python-example-test getting_started2 ; -boost-python-example-test simple_vector ; -boost-python-example-test do_it_yourself_convts ; -boost-python-example-test pickle1 ; -boost-python-example-test pickle2 ; -boost-python-example-test pickle3 ; +boost-python-example-runtest abstract ; +boost-python-example-runtest getting_started1 ; +boost-python-example-runtest getting_started2 ; +boost-python-example-runtest simple_vector ; +boost-python-example-runtest do_it_yourself_convts ; +boost-python-example-runtest pickle1 ; +boost-python-example-runtest pickle2 ; +boost-python-example-runtest pickle3 ; -boost-python ivect : ../example/ivect.cpp ; -boost-python dvect : ../example/dvect.cpp ; -boost-python noncopyable_export : ../example/noncopyable_export.cpp ; -boost-python noncopyable_import : ../example/noncopyable_import.cpp ; +boost-python-test ivect : ../example/ivect.cpp ; +boost-python-test dvect : ../example/dvect.cpp ; +boost-python-test noncopyable_export : ../example/noncopyable_export.cpp ; +boost-python-test noncopyable_import : ../example/noncopyable_import.cpp ; ############## cross-module tests from ../example ########## # A simple rule to build a test which depends on multiple modules in the PYTHONPATH -rule boost-python-multi-example-test # test-name : python-file libs +rule boost-python-multi-example-runtest # test-name : python-file libs { - boost-python-test $(<) : ../example/tst_$(<).py $(>) : : : $(PYTHON_VECT_ITERATIONS) ; + boost-python-runtest $(<) + : ../example/tst_$(<).py $(>) + : : : $(PYTHON_VECT_ITERATIONS) ; } + PYTHON_VECT_ITERATIONS ?= 10 ; -boost-python-multi-example-test dvect1 : ivect dvect ; -boost-python-multi-example-test dvect2 : ivect dvect ; +boost-python-multi-example-runtest dvect1 : ivect dvect ; +boost-python-multi-example-runtest dvect2 : ivect dvect ; -boost-python-multi-example-test ivect1 : ivect dvect ; -boost-python-multi-example-test ivect2 : ivect dvect ; +boost-python-multi-example-runtest ivect1 : ivect dvect ; +boost-python-multi-example-runtest ivect2 : ivect dvect ; -boost-python-multi-example-test noncopyable : noncopyable_import noncopyable_export ; +boost-python-multi-example-runtest + noncopyable : noncopyable_import noncopyable_export ; From a245bdbc2adcb44463b80b7a0d3f3003a3ec3b6e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 31 Oct 2001 19:14:07 +0000 Subject: [PATCH 0113/1042] Modified Files: boost/python/detail: base_object.hpp - Changed template parameter to MixedCase cast.hpp - Killed off unused downcast_traits<> functions.hpp - Added commentary libs/python/src functions.cpp, types.cpp - Added comments tools/build TODO.txt - updated allyourbase.jam - fixed a nasty typo which caused all kinds of bugs boost-base.jam - changes to support the use of command files intel-win32-tools.jam - A feeble attempt at allowing intel to work without prior tool setup. More work needed msvc-tools.jam - A first cut at command file support tools/build/jam_src jam.h - Fixed MAXLINE for NT [SVN r11489] --- include/boost/python/detail/base_object.hpp | 14 +++++++------- include/boost/python/detail/cast.hpp | 16 ++++------------ include/boost/python/detail/functions.hpp | 9 +++++++-- src/functions.cpp | 7 +++++++ src/types.cpp | 9 +++++++++ 5 files changed, 34 insertions(+), 21 deletions(-) diff --git a/include/boost/python/detail/base_object.hpp b/include/boost/python/detail/base_object.hpp index 95a2805c..cf6bb528 100644 --- a/include/boost/python/detail/base_object.hpp +++ b/include/boost/python/detail/base_object.hpp @@ -21,10 +21,10 @@ namespace boost { namespace python { namespace detail { // base_object - adds a constructor and non-virtual destructor to a // base Python type (e.g. PyObject, PyTypeObject). -template -struct base_object : python_type +template +struct base_object : PythonType { - typedef python_type base_python_type; + typedef PythonType base_python_type; // Initializes type and reference count. All other fields of base_python_type are 0 base_object(PyTypeObject* type_obj); @@ -41,8 +41,8 @@ typedef base_object python_type; // // base_object member function implementations // -template -base_object::base_object(PyTypeObject* type_obj) +template +base_object::base_object(PyTypeObject* type_obj) { base_python_type* bp = this; #if !defined(_MSC_VER) || defined(__STLPORT) @@ -53,8 +53,8 @@ base_object::base_object(PyTypeObject* type_obj) PyObject_INIT(bp, type_obj); } -template -inline base_object::~base_object() +template +inline base_object::~base_object() { Py_DECREF(ob_type); } diff --git a/include/boost/python/detail/cast.hpp b/include/boost/python/detail/cast.hpp index e047c0b3..67fe7b34 100644 --- a/include/boost/python/detail/cast.hpp +++ b/include/boost/python/detail/cast.hpp @@ -15,14 +15,6 @@ namespace boost { namespace python { namespace detail { - // The default way of converting a PyObject* or PyTypeObject* to a T* - template - struct downcast_traits - { - template - static T* cast(U* p) { return static_cast(p); } - }; - inline PyTypeObject* as_base_object(const PyTypeObject*, PyObject* p) { return reinterpret_cast(p); @@ -54,19 +46,19 @@ template struct downcast { downcast(PyObject* p) - : m_p(detail::downcast_traits::cast(detail::as_base_object((T*)0, p))) + : m_p(static_cast(detail::as_base_object((T*)0, p))) {} downcast(const PyObject* p) - : m_p(detail::downcast_traits::cast(detail::as_base_object((const T*)0, p))) + : m_p(static_cast(detail::as_base_object((const T*)0, p))) {} downcast(PyTypeObject* p) - : m_p(detail::downcast_traits::cast(p)) + : m_p(static_cast(p)) {} downcast(const PyTypeObject* p) - : m_p(detail::downcast_traits::cast(p)) + : m_p(static_cast(p)) {} operator T*() const { return m_p; } diff --git a/include/boost/python/detail/functions.hpp b/include/boost/python/detail/functions.hpp index 055255e7..16b8e16d 100644 --- a/include/boost/python/detail/functions.hpp +++ b/include/boost/python/detail/functions.hpp @@ -46,7 +46,7 @@ class function : public python_object private: struct type_object; private: - reference m_overloads; + reference m_overloads; // A linked list of the function overloads }; // wrapped_function_pointer<> -- @@ -66,7 +66,12 @@ struct wrapped_function_pointer : function private: PyObject* do_call(PyObject* args, PyObject* keywords) const - { return caller::call(m_pf, args, keywords); } + { + // This is where the boundary between the uniform Python function + // interface and the statically-checked C++ function interface is + // crossed. + return caller::call(m_pf, args, keywords); + } const char* description() const { return typeid(F).name(); } diff --git a/src/functions.cpp b/src/functions.cpp index 71b59136..a04e2e51 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -61,6 +61,8 @@ function::function() PyObject* function::call(PyObject* args, PyObject* keywords) const { + // Traverse the linked list of function overloads until we find one that + // matches. for (const function* f = this; f != 0; f = f->m_overloads.get()) { PyErr_Clear(); @@ -75,9 +77,14 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const } } + // If we get here, no overloads matched the arguments + + // Allow the single-function error-reporting to take effect unless there was + // an overload if (m_overloads.get() == 0) return 0; + // Synthesize a more-explicit error message PyErr_Clear(); string message("No overloaded functions match ("); tuple arguments(ref(args, ref::increment_count)); diff --git a/src/types.cpp b/src/types.cpp index f8cf1ea6..add0ebf0 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -24,6 +24,11 @@ namespace { using detail::type_object_base; + // Define a family of forwarding functions that can be calle from a + // PyTypeObject's slots. These functions dispatch through a (virtual) member + // function pointer in the type_object_base, and handle exceptions in a + // uniform way, preventing us from having to rewrite the dispatching code over + // and over. PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*) const) { try @@ -154,6 +159,10 @@ namespace { extern "C" { +// +// These functions actually go into the type object's slots, and dispatch to the +// "call" wrappers defined above. +// static PyObject* do_instance_repr(PyObject* obj) { return call(obj, &type_object_base::instance_repr); From 6cb4b790b9b328d99e8691704c2393fc96a6d703 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 1 Nov 2001 23:28:54 +0000 Subject: [PATCH 0114/1042] Python 2.2 pickle problems fixed. [SVN r11521] --- test/comprehensive.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/test/comprehensive.py b/test/comprehensive.py index 4ff34b48..2ac0704a 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -8,14 +8,11 @@ r''' // producing this work. // Revision History: +// 2001 Nov 01 Python 2.2 pickle problems fixed (rwgk) // 04 Mar 01 Changed name of extension module so it would work with DebugPython, // fixed exception message checking to work with Python 2.0 // (Dave Abrahams) -Load up the extension module - - >>> from boost_python_test import * - Automatic checking of the number and type of arguments. Foo's constructor takes a single long parameter. @@ -274,19 +271,12 @@ Pickle safety measures: ... except RuntimeError, err: print err[0] ... Incomplete pickle support (__dict_defines_state__ not set) - >>> class myrational(Rational): - ... __dict_defines_state__ = 1 # this is a lie but good enough for testing. - ... >>> r=myrational(3, 4) >>> r Rational(3, 4) >>> s=pickle.dumps(r) + >>> u=pickle.loads(s) - >>> class myworld(world): - ... def __init__(self): - ... world.__init__(self, 'anywhere') - ... self.x = 1 - ... >>> w = myworld() >>> w.greet() 'Hello from anywhere!' @@ -297,9 +287,6 @@ Pickle safety measures: ... Incomplete pickle support (__getstate_manages_dict__ not set) - >>> class myunsafeworld(myworld): - ... __getstate_manages_dict__ = 1 # this is a lie but good enough for testing. - ... >>> w = myunsafeworld() >>> w.greet() 'Hello from anywhere!' @@ -1191,6 +1178,23 @@ test methodologies for wrapping functions that return a pointer ''' #' +from boost_python_test import * + +# pickle requires these derived classes to be +# at the global scope of the module + +class myrational(Rational): + __dict_defines_state__ = 1 # this is a lie but good enough for testing. + +class myworld(world): + def __init__(self): + world.__init__(self, 'anywhere') + self.x = 1 + +class myunsafeworld(myworld): + __getstate_manages_dict__ = 1 # this is a lie but good enough for testing. + + def assert_integer_expected(err): """Handle a common error report which appears differently in Python 1.5.x and 2.0""" assert isinstance(err, TypeError) From b4a1a6c688d37d831fb7229feeb9f8c14a6015a4 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 2 Nov 2001 01:24:59 +0000 Subject: [PATCH 0115/1042] PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python [SVN r11523] --- build/irix_CC.mak | 4 ++-- build/linux_gcc.mak | 4 ++-- build/tru64_cxx.mak | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/irix_CC.mak b/build/irix_CC.mak index e3a97781..ec387746 100644 --- a/build/irix_CC.mak +++ b/build/irix_CC.mak @@ -17,9 +17,9 @@ ROOT=$(HOME) BOOST=$(ROOT)/boost -PYEXE=/usr/local/Python-1.5.2/bin/python +PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE=/usr/local/Python-2.1/bin/python +#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python #PYINC=-I/usr/local/Python-2.1/include/python2.1 STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers diff --git a/build/linux_gcc.mak b/build/linux_gcc.mak index 64d61bab..ef643991 100644 --- a/build/linux_gcc.mak +++ b/build/linux_gcc.mak @@ -19,9 +19,9 @@ BOOST=$(ROOT)/boost PYEXE=PYTHONPATH=. /usr/bin/python PYINC=-I/usr/include/python1.5 -#PYEXE=/usr/local/Python-1.5.2/bin/python +#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python #PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE=/usr/local/Python-2.1/bin/python +#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python #PYINC=-I/usr/local/Python-2.1/include/python2.1 STDOPTS=-fPIC -ftemplate-depth-21 diff --git a/build/tru64_cxx.mak b/build/tru64_cxx.mak index d06f3372..f996a0c1 100644 --- a/build/tru64_cxx.mak +++ b/build/tru64_cxx.mak @@ -17,9 +17,9 @@ ROOT=$(HOME) BOOST=$(ROOT)/boost -PYEXE=/usr/local/Python-1.5.2/bin/python +PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE=/usr/local/Python-2.1/bin/python +#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python #PYINC=-I/usr/local/Python-2.1/include/python2.1 #STLPORTINC=-I/usr/local/STLport-4.1b3/stlport #STLPORTINC=-I/usr/local/STLport-4.1b4/stlport From b211f8a096c8902442fb5e655ed01928816d5909 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 10 Nov 2001 22:16:01 +0000 Subject: [PATCH 0116/1042] Modified Files: index.htm - fixed reference to CVS repository libs/python/build/Jamfile - first stab at metrowerks Pro7 support status/Jamfile - added RUN_ALL_TESTS variables to force tests to run tools/build/boost-build.jam - fix BOOST_BUILD_INSTALLATION setting tools/build/metrowerks-tools.jam - command file support tools/build/msvc-tools.jam - permanent command file support tools/build/intel-win32-tools.jam - made it an extension of msvc-tools.jam tools/build/gcc-tools.jam - made FINDLIBS change submitted by Toon Knapen tools/build/jam_src/variable.c - changed command-line/env. variable interpretation so that surrounding them with quotes causes no breaking at spaces. These files were converted from tabs to spaces: boost/python/conversions.hpp boost/python/reference.hpp boost/python/detail/base_object.hpp boost/python/detail/functions.hpp boost/python/detail/wrap_python.hpp libs/python/test/comprehensive.cpp tools/build/boost-base.jam tools/build/como-tools.jam [SVN r11652] --- build/Jamfile | 1 + include/boost/python/conversions.hpp | 22 ++--- include/boost/python/detail/base_object.hpp | 2 +- include/boost/python/detail/functions.hpp | 30 +++---- include/boost/python/detail/wrap_python.hpp | 6 +- include/boost/python/reference.hpp | 98 ++++++++++----------- test/comprehensive.cpp | 2 +- 7 files changed, 83 insertions(+), 78 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index d597d055..eeb38d64 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -132,6 +132,7 @@ rule boost-python # standard requirements $(BOOST_PYTHON_INCLUDES) <*>$(PYTHON_LIB_PATH) + <*>$(PYTHON_LIB_PATH)/python22.lib <*>$(PYTHON_LIBS) $(PYTHON_PROPERTIES) diff --git a/include/boost/python/conversions.hpp b/include/boost/python/conversions.hpp index cf753e2d..c1a7d390 100644 --- a/include/boost/python/conversions.hpp +++ b/include/boost/python/conversions.hpp @@ -74,17 +74,17 @@ inline void xdecref_impl(PyObject* p) { Py_XDECREF(p); } template inline void decref(T* p) { - char* const raw_p = reinterpret_cast(p); - char* const p_base = raw_p - offsetof(PyObject, ob_refcnt); - decref_impl(reinterpret_cast(p_base)); + char* const raw_p = reinterpret_cast(p); + char* const p_base = raw_p - offsetof(PyObject, ob_refcnt); + decref_impl(reinterpret_cast(p_base)); } template inline void xdecref(T* p) { - char* const raw_p = reinterpret_cast(p); - char* const p_base = raw_p - offsetof(PyObject, ob_refcnt); - xdecref_impl(reinterpret_cast(p_base)); + char* const raw_p = reinterpret_cast(p); + char* const p_base = raw_p - offsetof(PyObject, ob_refcnt); + xdecref_impl(reinterpret_cast(p_base)); } namespace detail { @@ -294,22 +294,22 @@ inline PyObject* to_python(float f) inline PyObject* to_python(long l) { - return PyInt_FromLong(l); + return PyInt_FromLong(l); } inline PyObject* to_python(int x) { - return PyInt_FromLong(x); + return PyInt_FromLong(x); } inline PyObject* to_python(short x) { - return PyInt_FromLong(x); + return PyInt_FromLong(x); } inline PyObject* to_python(bool b) { - return PyInt_FromLong(b); + return PyInt_FromLong(b); } inline PyObject* to_python(void) @@ -319,7 +319,7 @@ inline PyObject* to_python(void) inline PyObject* to_python(const char* s) { - return PyString_FromString(s); + return PyString_FromString(s); } inline std::string from_python(PyObject* p, boost::python::type) diff --git a/include/boost/python/detail/base_object.hpp b/include/boost/python/detail/base_object.hpp index cf6bb528..19715876 100644 --- a/include/boost/python/detail/base_object.hpp +++ b/include/boost/python/detail/base_object.hpp @@ -48,7 +48,7 @@ base_object::base_object(PyTypeObject* type_obj) #if !defined(_MSC_VER) || defined(__STLPORT) std:: #endif - memset(bp, 0, sizeof(base_python_type)); + memset(bp, 0, sizeof(base_python_type)); Py_INCREF(type_obj); PyObject_INIT(bp, type_obj); } diff --git a/include/boost/python/detail/functions.hpp b/include/boost/python/detail/functions.hpp index 16b8e16d..eff05d65 100644 --- a/include/boost/python/detail/functions.hpp +++ b/include/boost/python/detail/functions.hpp @@ -59,13 +59,13 @@ class function : public python_object template struct wrapped_function_pointer : function { - typedef F ptr_fun; // pointer-to--function or pointer-to-member-function - - wrapped_function_pointer(ptr_fun pf) + typedef F ptr_fun; // pointer-to--function or pointer-to-member-function + + wrapped_function_pointer(ptr_fun pf) : m_pf(pf) {} private: - PyObject* do_call(PyObject* args, PyObject* keywords) const + PyObject* do_call(PyObject* args, PyObject* keywords) const { // This is where the boundary between the uniform Python function // interface and the statically-checked C++ function interface is @@ -77,7 +77,7 @@ struct wrapped_function_pointer : function { return typeid(F).name(); } private: - const ptr_fun m_pf; + const ptr_fun m_pf; }; // raw_arguments_function @@ -87,13 +87,13 @@ struct wrapped_function_pointer : function template struct raw_arguments_function : function { - typedef Ret (*ptr_fun)(Args, Keywords); - - raw_arguments_function(ptr_fun pf) + typedef Ret (*ptr_fun)(Args, Keywords); + + raw_arguments_function(ptr_fun pf) : m_pf(pf) {} private: - PyObject* do_call(PyObject* args, PyObject* keywords) const + PyObject* do_call(PyObject* args, PyObject* keywords) const { ref dict(keywords ? ref(keywords, ref::increment_count) : @@ -108,7 +108,7 @@ struct raw_arguments_function : function { return typeid(ptr_fun).name(); } private: - const ptr_fun m_pf; + const ptr_fun m_pf; }; // virtual_function<> -- @@ -127,19 +127,19 @@ template class virtual_function : public function { public: - virtual_function(V virtual_function_ptr, D default_implementation) + virtual_function(V virtual_function_ptr, D default_implementation) : m_virtual_function_ptr(virtual_function_ptr), m_default_implementation(default_implementation) {} private: - PyObject* do_call(PyObject* args, PyObject* keywords) const; + PyObject* do_call(PyObject* args, PyObject* keywords) const; const char* description() const { return typeid(V).name(); } private: - const V m_virtual_function_ptr; + const V m_virtual_function_ptr; const D m_default_implementation; }; @@ -160,7 +160,7 @@ template inline function* new_wrapped_function(F pmf) { // Deduce the return type and pass it off to the helper function above - return new_wrapped_function_aux(return_value(pmf), pmf); + return new_wrapped_function_aux(return_value(pmf), pmf); } template @@ -220,7 +220,7 @@ class bound_function : public python_object private: // data members for allocation/deallocation optimization bound_function* m_free_list_link; - static bound_function* free_list; + static bound_function* free_list; }; // Special functions designed to access data members of a wrapped C++ object. diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index b7a47513..373bbde4 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -90,5 +90,9 @@ typedef int pid_t; #if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2 # define PyObject_INIT(op, typeobj) \ - ( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) ) + ( (op)->ob_type = (typeobj), _Py_NewReference((PyObject *)(op)), (op) ) +#endif + +#ifdef __MWERKS__ +# pragma warn_possunwant off #endif diff --git a/include/boost/python/reference.hpp b/include/boost/python/reference.hpp index a1585099..4eb9ad51 100644 --- a/include/boost/python/reference.hpp +++ b/include/boost/python/reference.hpp @@ -42,31 +42,31 @@ BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions); template class reference - : public py_ptr_conversions, T> + : public py_ptr_conversions, T> { public: typedef T value_type; - reference(const reference& rhs) - : m_p(rhs.m_p) - { - Py_XINCREF(object()); - } + reference(const reference& rhs) + : m_p(rhs.m_p) + { + Py_XINCREF(object()); + } #if !defined(BOOST_MSVC6_OR_EARLIER) - template - reference(const reference& rhs) - : m_p(rhs.object()) - { - Py_XINCREF(object()); - } + template + reference(const reference& rhs) + : m_p(rhs.object()) + { + Py_XINCREF(object()); + } #endif - reference() : m_p(0) {} + reference() : m_p(0) {} // These are two ways of spelling the same thing, that we need to increment // the reference count on the pointer when we're initialized. - enum increment_count_t { increment_count }; + enum increment_count_t { increment_count }; enum allow_null { null_ok }; @@ -77,7 +77,7 @@ public: template reference(T2* x, increment_count_t) : m_p(expect_non_null(x)) { Py_INCREF(object()); } - + template reference(T2* x, allow_null) : m_p(x) {} @@ -85,49 +85,49 @@ public: template reference(T2* x, allow_null, increment_count_t) : m_p(x) { Py_XINCREF(object()); } - + template reference(T2* x, increment_count_t, allow_null) : m_p(x) { Py_XINCREF(object()); } - + #if !defined(BOOST_MSVC6_OR_EARLIER) - template - reference& operator=(const reference& rhs) - { - Py_XDECREF(object()); - m_p = rhs.m_p; - Py_XINCREF(object()); - return *this; - } + template + reference& operator=(const reference& rhs) + { + Py_XDECREF(object()); + m_p = rhs.m_p; + Py_XINCREF(object()); + return *this; + } #endif - reference& operator=(const reference& rhs) - { - Py_XINCREF(static_cast(rhs.m_p)); - Py_XDECREF(object()); - m_p = rhs.m_p; - return *this; - } + reference& operator=(const reference& rhs) + { + Py_XINCREF(static_cast(rhs.m_p)); + Py_XDECREF(object()); + m_p = rhs.m_p; + return *this; + } - ~reference() - { - Py_XDECREF(m_p); - } - - T& operator*() const { return *m_p; } + ~reference() + { + Py_XDECREF(m_p); + } + + T& operator*() const { return *m_p; } // MSVC doesn't like boost::dereferencable unless T has a default // constructor, so operator-> must be defined by hand :( T* operator->() const { return &**this; } - T* get() const { return m_p; } + T* get() const { return m_p; } - T* release() - { - T* p = m_p; - m_p = 0; - return p; - } + T* release() + { + T* p = m_p; + m_p = 0; + return p; + } void reset() { Py_XDECREF(m_p); m_p = 0; } @@ -139,7 +139,7 @@ public: template void reset(T2* x, increment_count_t) { Py_XDECREF(m_p); m_p = expect_non_null(x); Py_INCREF(object()); } - + template void reset(T2* x, allow_null) { Py_XDECREF(m_p); m_p = x;} @@ -147,11 +147,11 @@ public: template void reset(T2* x, allow_null, increment_count_t) { Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); } - + template void reset(T2* x, increment_count_t, allow_null) { Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); } - + #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) private: template friend class shared_ptr; @@ -160,7 +160,7 @@ private: inline PyObject* object() const { return as_object(m_p); } - T* m_p; + T* m_p; }; typedef reference ref; diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 427ed2d8..3571183e 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -157,7 +157,7 @@ int IntPairPythonClass::getattr(const IntPair& p, const std::string& s) PyErr_SetString(PyExc_AttributeError, s.c_str()); throw boost::python::error_already_set(); } -#if defined(__MWERKS__) && __MWERKS__ <= 0x2400 +#if defined(__MWERKS__) && __MWERKS__ <= 0x2405 return 0; #endif } From e38bc7cbcecc62e206ca9354cb09aa8beab21d89 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Nov 2001 17:26:11 +0000 Subject: [PATCH 0117/1042] Pro7 compatibility [SVN r11677] --- include/boost/python/cross_module.hpp | 3 +++ include/boost/python/detail/extension_class.hpp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/include/boost/python/cross_module.hpp b/include/boost/python/cross_module.hpp index 7c1fe507..dd1c47d2 100644 --- a/include/boost/python/cross_module.hpp +++ b/include/boost/python/cross_module.hpp @@ -169,6 +169,9 @@ struct export_converter_object_noncopyable : export_converter_object_base PyErr_SetString(PyExc_RuntimeError, "to_python(const T&) converter not exported"); throw import_error(); +#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 + return 0; +#endif } virtual T* from_python_Ts(PyObject* p, boost::python::type t) { diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index d871ad6e..f7be9afb 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -233,6 +233,9 @@ class python_extension_class_converters } boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); throw boost::python::argument_error(); +#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 + return 0; +#endif } // Convert to T* @@ -261,6 +264,9 @@ class python_extension_class_converters } boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); throw boost::python::argument_error(); +#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 + return *(PtrType*)0; +#endif } // Extract from obj a reference to the PtrType object which is holding a From e7904fa67a1fa41a8fc535b3fd911c13b8596ae1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Nov 2001 17:32:08 +0000 Subject: [PATCH 0118/1042] add _d targets for debugging [SVN r11678] --- build/Jamfile | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index eeb38d64..a76f372a 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -73,12 +73,13 @@ if $(NT) PYTHON_ROOT ?= c:/tools/python ; PYTHON_INCLUDES ?= $(PYTHON_ROOT)/include <*>/usr/include/python$(PYTHON_VERSION) ; PYTHON_LIBS ?= c:/cygnus/lib/python$(PYTHON_VERSION)/config/libpython$(PYTHON_VERSION).dll.a ; - PYTHON_LIB_PATH = $(PYTHON_ROOT)/libs ; + PYTHON_LIB_PATH ?= $(PYTHON_ROOT)/libs ; # common properties required for compiling any Python module. PYTHON_PROPERTIES ?= <*>SIZEOF_LONG=4 <*>USE_DL_IMPORT + _DEBUG dynamic ; @@ -90,6 +91,10 @@ else if $(UNIX) PYTHON_LIBS ?= /usr/lib/python$(PYTHON_VERSION)/config/libpython$(PYTHON_VERSION).a ; } +local PYTHON_VERSION_NODOT + = [ SUBST $(PYTHON_VERSION) ([0-9]*)\.([0-9]*) $1$2 ] + ; + # how do we invoke python? local PYTHON = $(PYTHON) ; PYTHON ?= python ; @@ -107,14 +112,22 @@ local BOOST_PYTHON_INCLUDES = $(BOOST_ROOT) $(PYTHON_INCLUDES) ; # Base names of the source files for libboost_python local CPP_SOURCES = - classes conversions extension_class functions - init_function module_builder objects types cross_module ; + types classes conversions extension_class functions + init_function module_builder objects cross_module ; lib libboost_python : ../src/$(CPP_SOURCES).cpp # requirements : $(BOOST_PYTHON_INCLUDES) true $(PYTHON_PROPERTIES) ; + +lib libboost_python_d : ../src/$(CPP_SOURCES).cpp + # requirements + : $(BOOST_PYTHON_INCLUDES) + true + $(PYTHON_PROPERTIES) + BOOST_DEBUG_PYTHON + ; ####################### @@ -123,8 +136,14 @@ lib libboost_python : ../src/$(CPP_SOURCES).cpp # Declare a boost python module. Return a list of the DLL files generated. rule boost-python { + local debug ; + if ( BOOST_DEBUG_PYTHON in $(3) ) || ( debug-python in $(BUILD) ) + { + debug = _d ; + } + # declare a DLL; add the boost python library to sources - dll $(<) : libboost_python $(>) + dll $(<) : libboost_python$(debug) $(>) # Requirements : $(3) # caller-specified requirements @@ -132,7 +151,7 @@ rule boost-python # standard requirements $(BOOST_PYTHON_INCLUDES) <*>$(PYTHON_LIB_PATH) - <*>$(PYTHON_LIB_PATH)/python22.lib + <*>$(PYTHON_LIB_PATH)/python$(PYTHON_VERSION_NODOT)$(debug).lib <*>$(PYTHON_LIBS) $(PYTHON_PROPERTIES) @@ -146,9 +165,12 @@ rule boost-python rule boost-python-test { type-DEPENDS test : $(<) ; + type-DEPENDS test_d : $(<)_d ; + NOTFILE test_d ; local gSUPPRESS_FAKE_TARGETS = true ; boost-python $(1) : $(2) : $(3) : $(4) ; + boost-python $(1)_d : $(2) : $(3) BOOST_DEBUG_PYTHON : $(4) ; } ####################### @@ -239,12 +261,17 @@ boost-python-runtest comprehensive : [ join-path $(DOTDOT) test comprehensive.py ] boost_python_test ; +boost-python-runtest comprehensive_d + : [ join-path $(DOTDOT) test comprehensive.py ] + boost_python_test_d ; + ############# simple tests from ../example ############ rule boost-python-example-runtest { boost-python-test $(<) : ../example/$(<).cpp ; boost-python-runtest $(<) : [ join-path $(DOTDOT) example test_$(<).py ] $(<) ; + boost-python-runtest $(<)_d : [ join-path $(DOTDOT) example test_$(<).py ] $(<)_d ; } From b7e10592272d61e90ca7c129109fa3576225aaba Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Nov 2001 17:35:18 +0000 Subject: [PATCH 0119/1042] initial checkin [SVN r11679] --- include/boost/python/detail/void_adaptor.hpp | 39 ++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 include/boost/python/detail/void_adaptor.hpp diff --git a/include/boost/python/detail/void_adaptor.hpp b/include/boost/python/detail/void_adaptor.hpp new file mode 100644 index 00000000..c2ecc2b0 --- /dev/null +++ b/include/boost/python/detail/void_adaptor.hpp @@ -0,0 +1,39 @@ +// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. + +#ifndef VOID_ADAPTOR_DWA20011112_HPP +# define VOID_ADAPTOR_DWA20011112_HPP + +namespace boost { namespace python { namespace detail { + + extern PyObject arbitrary_object; + + template + struct void_adaptor + { + typedef PyObject* result_type; + + void_adaptor(T const& f) + : m_f(f) + {} + + PyObject* operator()() const + { + m_f(); + return &arbitrary_object; + } + private: + T m_f; + }; + + template + void_adaptor make_void_adaptor(T const& f) + { + return void_adaptor(f); + } +}}} // namespace boost::python::detail + +#endif // VOID_ADAPTOR_DWA20011112_HPP + From 634d0848c894bcb3309209e62640105b6bab70c1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Nov 2001 17:37:07 +0000 Subject: [PATCH 0120/1042] got rid of the "rethrow error reporting" mechanism [SVN r11680] --- src/conversions.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/conversions.cpp b/src/conversions.cpp index 4bfe2011..c986f57b 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -14,6 +14,7 @@ // 03 Mar 01 added: converters for [plain] char (Ralf W. Grosse-Kunstleve) #include +#include #include #include #ifndef BOOST_NO_LIMITS @@ -23,15 +24,11 @@ namespace boost { namespace python { // IMPORTANT: this function may only be called from within a catch block! -void handle_exception() +PyObject* handle_exception_impl(object_functor_base const& f) { - try { - // re-toss the current exception so we can find out what type it is. - // NOTE: a heinous bug in MSVC6 causes exception objects re-thrown in - // this way to be double-destroyed. Thus, you must only use objects that - // can tolerate double-destruction with that compiler. Metrowerks - // Codewarrior doesn't suffer from this problem. - throw; + try + { + return f(); } catch(const boost::python::error_already_set&) { @@ -49,6 +46,13 @@ void handle_exception() { PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception"); } + return 0; +} + +void handle_exception(void (*f)()) +{ + handle_exception( + boost::python::detail::make_void_adaptor(f)); } namespace detail { @@ -116,7 +120,7 @@ T integer_from_python(PyObject* p, boost::python::type) PyErr_SetString(PyExc_ValueError, buffer); throw boost::python::argument_error(); } -#if defined(__MWERKS__) && __MWERKS__ <= 0x2400 +#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 return 0; // Not smart enough to know that the catch clause always rethrows #endif } From 6e7f1bc257f596090c0a8a01b9126beaad9c38df Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Nov 2001 17:41:17 +0000 Subject: [PATCH 0121/1042] Pro7 compatibility [SVN r11681] --- src/gen_extclass.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gen_extclass.py b/src/gen_extclass.py index 57189a7d..b794dc2c 100644 --- a/src/gen_extclass.py +++ b/src/gen_extclass.py @@ -238,6 +238,9 @@ class python_extension_class_converters } boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); throw boost::python::argument_error(); +#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 + return 0; +#endif } // Convert to T* @@ -266,6 +269,10 @@ class python_extension_class_converters } boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); throw boost::python::argument_error(); +#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 + PtrType x; + return x; +#endif } // Extract from obj a reference to the PtrType object which is holding a From aad05325a6e1426c508c68e126281cbf86edc759 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Nov 2001 19:50:35 +0000 Subject: [PATCH 0122/1042] Pro7 compatibility use the new "no-rethrow" way of handling exceptions. [SVN r11682] --- test/comprehensive.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 3571183e..8eaac025 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -157,7 +157,7 @@ int IntPairPythonClass::getattr(const IntPair& p, const std::string& s) PyErr_SetString(PyExc_AttributeError, s.c_str()); throw boost::python::error_already_set(); } -#if defined(__MWERKS__) && __MWERKS__ <= 0x2405 +#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 return 0; #endif } @@ -1139,12 +1139,7 @@ void init_module() BOOST_PYTHON_MODULE_INIT(boost_python_test) { - try { - bpl_test::init_module(); - } - catch(...) { - boost::python::handle_exception(); - } // Need a way to report other errors here + boost::python::handle_exception((void (*)())bpl_test::init_module); } CompareIntPairPythonClass::CompareIntPairPythonClass(boost::python::module_builder& m) From 5bec0d2d9817638ad63e4d6fa6ac40bd39e420b4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Nov 2001 20:06:18 +0000 Subject: [PATCH 0123/1042] fixes for intel [SVN r11690] --- build/Jamfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/Jamfile b/build/Jamfile index a76f372a..c4b9a9c3 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -151,6 +151,7 @@ rule boost-python # standard requirements $(BOOST_PYTHON_INCLUDES) <*>$(PYTHON_LIB_PATH) + <*>$(PYTHON_LIB_PATH) <*>$(PYTHON_LIB_PATH)/python$(PYTHON_VERSION_NODOT)$(debug).lib <*>$(PYTHON_LIBS) $(PYTHON_PROPERTIES) @@ -239,6 +240,7 @@ rule python-runtest-aux # target : sources switch $(<) { case <*\\\\msvc\\\\*>* : ARGS on $(<) += --broken-auto-ptr ; + case <*\\\\intel-win32\\\\*>* : ARGS on $(<) += --broken-auto-ptr ; } # compute the PYTHONPATH environment variable that will allow the test to From 7d6ff83760235f9cb23db61716c44635a6dfbd99 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Nov 2001 20:07:38 +0000 Subject: [PATCH 0124/1042] use the new "no-rethrow" way of handling exceptions. [SVN r11691] --- include/boost/python/errors.hpp | 39 ++++++++++++++++++++++++++++++++- src/extension_class.cpp | 16 +++++++++----- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp index a1cdbbb0..66f15587 100644 --- a/include/boost/python/errors.hpp +++ b/include/boost/python/errors.hpp @@ -9,13 +9,50 @@ #ifndef ERRORS_DWA052500_H_ # define ERRORS_DWA052500_H_ +# include + namespace boost { namespace python { struct error_already_set {}; struct argument_error : error_already_set {}; +struct object_functor_base +{ + typedef PyObject* result_type; + virtual PyObject* operator()() const = 0; + private: + static void* operator new(std::size_t); // don't allow dynamic allocation + void operator delete(void*); + void operator delete(void*, size_t); +}; + +template +struct object_functor : object_functor_base +{ + object_functor(T const& f) + : m_f(f) + { + } + + PyObject* operator()() const + { + return m_f(); + } + private: + T const& m_f; +}; + + // Handles exceptions caught just before returning to Python code. -void handle_exception(); +PyObject* handle_exception_impl(object_functor_base const& f); + +template +PyObject* handle_exception(T const& f) +{ + return handle_exception_impl(object_functor(f)); +} + +void handle_exception(void (*)()); template T* expect_non_null(T* x) diff --git a/src/extension_class.cpp b/src/extension_class.cpp index f71976b9..3815a19c 100644 --- a/src/extension_class.cpp +++ b/src/extension_class.cpp @@ -10,8 +10,9 @@ // 04 Mar 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) #include -#include #include +#include +#include namespace boost { namespace python { namespace detail { @@ -484,16 +485,19 @@ void operator_dispatcher_dealloc(PyObject* self) int operator_dispatcher_coerce(PyObject** l, PyObject** r) { Py_INCREF(*l); - try + PyObject* new_r = handle_exception( + bind(operator_dispatcher::create, + ref(*r, ref::increment_count), + ref())); + if (new_r) { - *r = operator_dispatcher::create(ref(*r, ref::increment_count), ref()); + *r = new_r; + return 0; } - catch(...) + else { - handle_exception(); return -1; } - return 0; } From 76768120d404e7ee532daecc8f5470736e5ad003 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Nov 2001 20:36:14 +0000 Subject: [PATCH 0125/1042] use the new "no-rethrow" way of handling exceptions. [SVN r11692] --- src/types.cpp | 256 ++++++++++++++++++++++++++++---------------------- 1 file changed, 143 insertions(+), 113 deletions(-) diff --git a/src/types.cpp b/src/types.cpp index add0ebf0..2e738c35 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -8,15 +8,18 @@ #include #include // for handle_exception() +#include #include #include +#include #include #include #include #include #include #include -#include +#include +#include namespace boost { namespace python { @@ -24,139 +27,169 @@ namespace { using detail::type_object_base; - // Define a family of forwarding functions that can be calle from a + // Define a family of forwarding functions that can be called from a // PyTypeObject's slots. These functions dispatch through a (virtual) member // function pointer in the type_object_base, and handle exceptions in a // uniform way, preventing us from having to rewrite the dispatching code over // and over. - PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*) const) + + + // Given a function object f with signature + // + // PyObject* f(PyTypeObject*,PyObject*) + // + // calls f inside of handle_exception, and returns the result. If an exception + // is thrown by f, returns 0. + template + PyObject* obj_call(PyObject* obj, F const& f) { - try - { - return (static_cast(obj->ob_type)->*f)(obj); - } - catch(...) - { - handle_exception(); - return 0; - } + return handle_exception( + boost::bind(f, static_cast(obj->ob_type), obj)); } - // Naming this differently allows us to use it for functions returning long on - // compilers without partial ordering - template - R int_call(PyObject* obj, R (type_object_base::*f)(PyObject*) const) + + // int_converter/value_holder + // + // A simple function object which converts its argument to a PyObject*. We + // need this because handle_exception needs to return a PyObject*, even if the + // function being called is supposed to return int. It has two parts... + + // holds the value actually returned by the underlying function + template + struct value_holder : PyObject { - try + value_holder() : is_set(false), value(-1) {} + + // Tricky constructor allows us to grab the result even if rhs == 0. + explicit value_holder(value_holder const* rhs) + : is_set(rhs ? rhs->is_set : false), value(rhs ? rhs->value : -1) {} + + // true if the function object was ever called (false if an exception occurred) + bool is_set; + + // The returned value + T value; + }; + + // The function object + template + struct int_converter + { + typedef PyObject* result_type; + + PyObject* operator()(R const& x) { - return (static_cast(obj->ob_type)->*f)(obj); - } - catch(...) - { - handle_exception(); - return -1; + m_holder.is_set = true; + m_holder.value = x; + return &m_holder; // returns } + + value_holder m_holder; + }; + + // Call the given int-returning function object inside of handle_exception, + // returning a value_holder. F is a function object with "signature" + // + // R F(PyTypeObject*, PyObject*) + // + // where R is an integer type. + template + typename value_holder int_call_holder(PyObject* obj, F f) + { + return value_holder( + + // The int_converter object containing the value_holder is valid + // through the life of the full-expression, so we can construct from + // the pointer + static_cast*>( + handle_exception( + + boost::bind( + // Add an int_converter back-end to f + int_converter() + // Bind the object's type and the object itself into f + , boost::bind(f, static_cast(obj->ob_type), obj) + ) + + ) + ) + ); + } + + // Just like int_call_holder (above), but returns the integer directly. If F + // throws an exception, returns -1 + template + R int_call(PyObject* obj, F f) + { + value_holder const v(int_call_holder(obj, f)); + return v.value; + } + + // Implemented in terms of obj_call, above + PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*) const) + { + return obj_call(obj, bind(f, _1, _2)); } // Implemented in terms of int_call, above int call(PyObject* obj, int (type_object_base::*f)(PyObject*) const) { - return int_call(obj, f); + return int_call(obj, bind(f, _1, _2)); } template PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*, A1) const, A1 a1) { - try - { - return (static_cast(obj->ob_type)->*f)(obj, a1); - } - catch(...) - { - handle_exception(); - return 0; - } + return obj_call(obj, bind(f, _1, _2, a1)); } template int call(PyObject* obj, int (type_object_base::*f)(PyObject*, A1) const, A1 a1) { - try - { - return (static_cast(obj->ob_type)->*f)(obj, a1); - } - catch(...) - { - handle_exception(); - return -1; - } + return int_call(obj, bind(f, _1, _2, a1)); } template PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*, A1, A2) const, A1 a1, A2 a2) { - try - { - return (static_cast(obj->ob_type)->*f)(obj, a1, a2); - } - catch(...) - { - handle_exception(); - return 0; - } + return obj_call(obj, bind(f, _1, _2, a1, a2)); } template int call(PyObject* obj, int (type_object_base::*f)(PyObject*, A1, A2) const, A1 a1, A2 a2) { - try - { - return (static_cast(obj->ob_type)->*f)(obj, a1, a2); - } - catch(...) - { - handle_exception(); - return -1; - } + return int_call(obj, bind(f, _1, _2, a1, a2)); } template int call(PyObject* obj, int (type_object_base::*f)(PyObject*, A1, A2, A3) const, A1 a1, A2 a2, A3 a3) { - try - { - return (static_cast(obj->ob_type)->*f)(obj, a1, a2, a3); - } - catch(...) - { - handle_exception(); - return -1; - } + return int_call(obj, bind(f, _1, _2, a1, a2, a3)); } int call_length_function(PyObject* obj, int (type_object_base::*f)(PyObject*) const) { - try + value_holder const r(int_call_holder(obj, bind(f, _1, _2))); + + if (!r.is_set) { - const int outcome = - (static_cast(obj->ob_type)->*f)(obj); - - if (outcome < 0) - { - PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0"); - return -1; - } - return outcome; - } - catch(...) - { - handle_exception(); return -1; } - } + + const int outcome = r.value; + if (outcome >= 0) + return outcome; + PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0"); + return -1; + } } // anonymous namespace +namespace detail { + // needed by void_adaptor (see void_adaptor.hpp) + PyObject arbitrary_object; +} + extern "C" { // @@ -202,7 +235,7 @@ static PyObject* do_instance_str(PyObject* obj) static long do_instance_hash(PyObject* obj) { - return int_call(obj, &type_object_base::instance_hash); + return int_call(obj, bind(&type_object_base::instance_hash, _1, _2)); } static PyObject* do_instance_call(PyObject* obj, PyObject* args, PyObject* keywords) @@ -212,15 +245,16 @@ static PyObject* do_instance_call(PyObject* obj, PyObject* args, PyObject* keywo static void do_instance_dealloc(PyObject* obj) { - try - { - static_cast(obj->ob_type) - ->instance_dealloc(obj); - } - catch(...) + PyObject* success = handle_exception( + // translate the void return value of instance_dealloc into a PyObject* + // that can indicate no error. + detail::make_void_adaptor( + bind(&type_object_base::instance_dealloc + , static_cast(obj->ob_type) + , obj))); + if (!success) { assert(!"exception during destruction!"); - handle_exception(); } } @@ -253,28 +287,22 @@ static PyObject* do_instance_mp_subscript(PyObject* obj, PyObject* index) static PyObject* do_instance_sq_item(PyObject* obj, int index) { - try + // This is an extension to standard class behavior. If sequence_length + // is implemented and n >= sequence_length(), raise an IndexError. That + // keeps users from having to worry about raising it themselves + const PyTypeObject* const type = obj->ob_type; + if (type->tp_as_sequence != 0 && type->tp_as_sequence->sq_length != 0 + && index >= type->tp_as_sequence->sq_length(obj)) { - const PyTypeObject* const type = obj->ob_type; - - // This is an extension to standard class behavior. If sequence_length - // is implemented and n >= sequence_length(), raise an IndexError. That - // keeps users from having to worry about raising it themselves - if (type->tp_as_sequence != 0 && type->tp_as_sequence->sq_length != 0 - && index >= type->tp_as_sequence->sq_length(obj)) - { - PyErr_SetString(PyExc_IndexError, type->tp_name); - return 0; - } - - return static_cast(obj->ob_type) - ->instance_sequence_item(obj, index); - } - catch(...) - { - handle_exception(); + PyErr_SetString(PyExc_IndexError, type->tp_name); return 0; } + + return handle_exception( + bind(&type_object_base::instance_sequence_item + , static_cast(obj->ob_type) + , obj + , index)); } static int do_instance_mp_ass_subscript(PyObject* obj, PyObject* index, PyObject* value) @@ -397,7 +425,10 @@ static PyObject* do_instance_nb_or(PyObject* obj, PyObject* other) static int do_instance_nb_coerce(PyObject**obj, PyObject**other) { - return call(*obj, &type_object_base::instance_number_coerce, obj, other); + // no call() overload for this oddball function, so we'll do it manually + return int_call( + *obj, bind( + &type_object_base::instance_number_coerce, _1, _2, obj, other)); } static PyObject* do_instance_nb_int(PyObject* obj) { @@ -1171,4 +1202,3 @@ int main() } #endif - From e6efa6e13e046dd7c412c92e4103085cc4098a98 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 15 Nov 2001 00:51:33 +0000 Subject: [PATCH 0126/1042] Fix minor gcc bug [SVN r11704] --- src/types.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.cpp b/src/types.cpp index 2e738c35..3367dba8 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -94,7 +94,7 @@ namespace { // // where R is an integer type. template - typename value_holder int_call_holder(PyObject* obj, F f) + value_holder int_call_holder(PyObject* obj, F f) { return value_holder( From 0dbb780a2f8b6e52100a201ff10e41ac9fa5db57 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 15 Nov 2001 05:29:22 +0000 Subject: [PATCH 0127/1042] * Updated to new handle_exception() idiom for boost::python * Made Cygwin archiving reliable, even when the user supplies a path with backslashes ---------------------------------------------------------------------- Modified Files: tools/build/gcc-tools.jam tools/build/new/boost-build.jam boost/python/detail/config.hpp libs/python/build/Jamfile libs/python/example/do_it_yourself_convts.cpp libs/python/example/dvect.cpp libs/python/example/example1.cpp libs/python/example/getting_started1.cpp libs/python/example/getting_started2.cpp libs/python/example/ivect.cpp libs/python/example/nested.cpp libs/python/example/noncopyable_export.cpp libs/python/example/noncopyable_import.cpp libs/python/example/pickle1.cpp libs/python/example/pickle2.cpp libs/python/example/pickle3.cpp libs/python/example/richcmp1.cpp libs/python/example/richcmp2.cpp libs/python/example/richcmp3.cpp libs/python/example/rwgk1.cpp libs/python/example/simple_vector.cpp libs/python/test/comprehensive.cpp Added Files: libs/python/example/rwgk2.cpp libs/python/example/rwgk3.cpp ---------------------------------------------------------------------- [SVN r11705] --- build/Jamfile | 7 +- example/do_it_yourself_convts.cpp | 7 -- example/dvect.cpp | 8 -- example/example1.cpp | 33 +++----- example/getting_started1.cpp | 7 -- example/getting_started2.cpp | 7 -- example/ivect.cpp | 7 -- example/nested.cpp | 7 -- example/noncopyable_export.cpp | 7 -- example/noncopyable_import.cpp | 7 -- example/pickle1.cpp | 7 -- example/pickle2.cpp | 7 -- example/pickle3.cpp | 7 -- example/richcmp1.cpp | 3 - example/richcmp2.cpp | 3 - example/richcmp3.cpp | 3 - example/rwgk1.cpp | 19 +---- example/rwgk2.cpp | 50 ++++++++++++ example/rwgk3.cpp | 101 +++++++++++++++++++++++++ example/simple_vector.cpp | 7 -- include/boost/python/detail/config.hpp | 4 +- test/comprehensive.cpp | 7 +- 22 files changed, 171 insertions(+), 144 deletions(-) create mode 100644 example/rwgk2.cpp create mode 100644 example/rwgk3.cpp diff --git a/build/Jamfile b/build/Jamfile index c4b9a9c3..05efd4a1 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -136,7 +136,7 @@ lib libboost_python_d : ../src/$(CPP_SOURCES).cpp # Declare a boost python module. Return a list of the DLL files generated. rule boost-python { - local debug ; + local debug = "" ; if ( BOOST_DEBUG_PYTHON in $(3) ) || ( debug-python in $(BUILD) ) { debug = _d ; @@ -203,7 +203,9 @@ rule python-test-target # test-target : sources : { python-runtest-aux $(<) : $(>) ; Clean clean : $(<) ; # remove the test-target as part of any clean operation - type-DEPENDS test : $(<) ; + local debug = [ SUBST $(<:B) (_d)$ $1 ] ; + debug ?= "" ; + type-DEPENDS test$(debug) : $(<) ; MakeLocate $(<) : $(LOCATE_TARGET) ; } actions python-test-target bind PYTHON @@ -249,6 +251,7 @@ rule python-runtest-aux # target : sources $(gLOCATE($(>[1]))) # location of python test file $(gRUN_PATH($(<))) # location of module dependencies [ join-path $(TOP) libs python test ] # location of doctest + $(>:D) # directory of python driver file(s) $(PYTHONPATH) # base PYTHONPATH from environment : $(SPLITPATH) ] ; # platform path separator diff --git a/example/do_it_yourself_convts.cpp b/example/do_it_yourself_convts.cpp index 4d9c1c89..01be6ef6 100644 --- a/example/do_it_yourself_convts.cpp +++ b/example/do_it_yourself_convts.cpp @@ -107,8 +107,6 @@ BOOST_PYTHON_END_CONVERSION_NAMESPACE BOOST_PYTHON_MODULE_INIT(do_it_yourself_convts) { - try - { // Create an object representing this extension module. python::module_builder this_module("do_it_yourself_convts"); @@ -120,9 +118,4 @@ BOOST_PYTHON_MODULE_INIT(do_it_yourself_convts) // Add the member functions. ixset_class.def(&IndexingSet::add, "add"); ixset_class.def(&IndexingSet::get, "get"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } diff --git a/example/dvect.cpp b/example/dvect.cpp index 4d109c96..fa1506fe 100644 --- a/example/dvect.cpp +++ b/example/dvect.cpp @@ -32,8 +32,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) BOOST_PYTHON_MODULE_INIT(dvect) { - try - { python::module_builder this_module("dvect"); python::class_builder dvect_class(this_module, "dvect"); @@ -47,10 +45,4 @@ BOOST_PYTHON_MODULE_INIT(dvect) # include "dvect_defs.cpp" # include "ivect_defs.cpp" - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } - diff --git a/example/example1.cpp b/example/example1.cpp index 467ac0dc..7bc5a1b7 100644 --- a/example/example1.cpp +++ b/example/example1.cpp @@ -16,32 +16,21 @@ namespace hello { // Python requires an exported function called init in every // extension module. This is where we build the module contents. -extern "C" -#ifdef _WIN32 -__declspec(dllexport) -#endif -void inithello() +BOOST_PYTHON_MODULE_INIT(hello) { - try - { - // create an object representing this extension module - boost::python::module_builder hello("hello"); + // create an object representing this extension module + boost::python::module_builder hello("hello"); - // Create the Python type object for our extension class - boost::python::class_builder world_class(hello, "world"); + // Create the Python type object for our extension class + boost::python::class_builder world_class(hello, "world"); - // Add the __init__ function - world_class.def(boost::python::constructor()); - // Add a regular member function - world_class.def(&hello::world::get, "get"); + // Add the __init__ function + world_class.def(boost::python::constructor()); + // Add a regular member function + world_class.def(&hello::world::get, "get"); - // Add a regular function to the module - hello.def(hello::length, "length"); - } - catch(...) - { - boost::python::handle_exception(); // Deal with the exception for Python - } + // Add a regular function to the module + hello.def(hello::length, "length"); } // Win32 DLL boilerplate diff --git a/example/getting_started1.cpp b/example/getting_started1.cpp index c6a77723..2f180633 100644 --- a/example/getting_started1.cpp +++ b/example/getting_started1.cpp @@ -16,17 +16,10 @@ namespace python = boost::python; // extension module. This is where we build the module contents. BOOST_PYTHON_MODULE_INIT(getting_started1) { - try - { // Create an object representing this extension module. python::module_builder this_module("getting_started1"); // Add regular functions to the module. this_module.def(greet, "greet"); this_module.def(square, "square"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } diff --git a/example/getting_started2.cpp b/example/getting_started2.cpp index 9121b1a0..04fbcc29 100644 --- a/example/getting_started2.cpp +++ b/example/getting_started2.cpp @@ -26,8 +26,6 @@ namespace python = boost::python; BOOST_PYTHON_MODULE_INIT(getting_started2) { - try - { // Create an object representing this extension module. python::module_builder this_module("getting_started2"); @@ -44,9 +42,4 @@ BOOST_PYTHON_MODULE_INIT(getting_started2) // Even better, invite() can also be made a member of hello_class!!! hello_class.def(invite, "invite"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } diff --git a/example/ivect.cpp b/example/ivect.cpp index 848d693e..35662b10 100644 --- a/example/ivect.cpp +++ b/example/ivect.cpp @@ -32,8 +32,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) BOOST_PYTHON_MODULE_INIT(ivect) { - try - { python::module_builder this_module("ivect"); python::class_builder ivect_class(this_module, "ivect"); @@ -47,10 +45,5 @@ BOOST_PYTHON_MODULE_INIT(ivect) # include "dvect_defs.cpp" # include "ivect_defs.cpp" - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } diff --git a/example/nested.cpp b/example/nested.cpp index 543754f7..a5632d16 100644 --- a/example/nested.cpp +++ b/example/nested.cpp @@ -32,13 +32,6 @@ namespace { BOOST_PYTHON_MODULE_INIT(nested) { - try - { boost::python::module_builder this_module("nested"); this_module.def(show_nested_tuples, "show_nested_tuples"); - } - catch(...) - { - boost::python::handle_exception(); - } } diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp index b118abb8..3a81db75 100644 --- a/example/noncopyable_export.cpp +++ b/example/noncopyable_export.cpp @@ -18,8 +18,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) BOOST_PYTHON_MODULE_INIT(noncopyable_export) { - try - { python::module_builder this_module("noncopyable_export"); python::class_builder store_class(this_module, "store"); @@ -27,9 +25,4 @@ BOOST_PYTHON_MODULE_INIT(noncopyable_export) store_class.def(python::constructor()); store_class.def(&store::recall, "recall"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp index 66c6457d..d4227642 100644 --- a/example/noncopyable_import.cpp +++ b/example/noncopyable_import.cpp @@ -31,8 +31,6 @@ extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) BOOST_PYTHON_MODULE_INIT(noncopyable_import) { - try - { python::module_builder this_module("noncopyable_import"); python::import_converters @@ -44,9 +42,4 @@ BOOST_PYTHON_MODULE_INIT(noncopyable_import) // However, to keep this example simple, we only define a // module-level function. this_module.def(add_stores, "add_stores"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } diff --git a/example/pickle1.cpp b/example/pickle1.cpp index cdd78989..af041e72 100644 --- a/example/pickle1.cpp +++ b/example/pickle1.cpp @@ -41,8 +41,6 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle1) { - try - { // Create an object representing this extension module. python::module_builder this_module("pickle1"); @@ -56,9 +54,4 @@ BOOST_PYTHON_MODULE_INIT(pickle1) // Support for pickle. world_class.def(world_getinitargs, "__getinitargs__"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } diff --git a/example/pickle2.cpp b/example/pickle2.cpp index d6aa3201..576180ee 100644 --- a/example/pickle2.cpp +++ b/example/pickle2.cpp @@ -73,8 +73,6 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle2) { - try - { // Create an object representing this extension module. python::module_builder this_module("pickle2"); @@ -92,9 +90,4 @@ BOOST_PYTHON_MODULE_INIT(pickle2) world_class.def(world_getinitargs, "__getinitargs__"); world_class.def(world_getstate, "__getstate__"); world_class.def(world_setstate, "__setstate__"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } diff --git a/example/pickle3.cpp b/example/pickle3.cpp index cb598ae6..664bed0b 100644 --- a/example/pickle3.cpp +++ b/example/pickle3.cpp @@ -65,8 +65,6 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle3) { - try - { // Create an object representing this extension module. python::module_builder this_module("pickle3"); @@ -85,11 +83,6 @@ BOOST_PYTHON_MODULE_INIT(pickle3) world_class.def_raw(world_getstate, "__getstate__"); world_class.def_raw(world_setstate, "__setstate__"); world_class.getstate_manages_dict(); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } namespace { diff --git a/example/richcmp1.cpp b/example/richcmp1.cpp index 4dd74e1b..f59aae65 100644 --- a/example/richcmp1.cpp +++ b/example/richcmp1.cpp @@ -77,11 +77,8 @@ namespace { BOOST_PYTHON_MODULE_INIT(richcmp1) { - try { boost::python::module_builder this_module("richcmp1"); // The actual work is done in a separate function in order // to suppress a bogus VC60 warning. init_module(this_module); - } - catch (...) { boost::python::handle_exception(); } } diff --git a/example/richcmp2.cpp b/example/richcmp2.cpp index 213852b3..993c6800 100644 --- a/example/richcmp2.cpp +++ b/example/richcmp2.cpp @@ -55,11 +55,8 @@ namespace { BOOST_PYTHON_MODULE_INIT(richcmp2) { - try { boost::python::module_builder this_module("richcmp2"); // The actual work is done in a separate function in order // to suppress a bogus VC60 warning. init_module(this_module); - } - catch (...) { boost::python::handle_exception(); } } diff --git a/example/richcmp3.cpp b/example/richcmp3.cpp index 169e7f00..4be48fee 100644 --- a/example/richcmp3.cpp +++ b/example/richcmp3.cpp @@ -168,11 +168,8 @@ namespace { BOOST_PYTHON_MODULE_INIT(richcmp3) { - try { boost::python::module_builder this_module("richcmp3"); // The actual work is done in a separate function in order // to suppress a bogus VC60 warning. init_module(this_module); - } - catch (...) { boost::python::handle_exception(); } } diff --git a/example/rwgk1.cpp b/example/rwgk1.cpp index b21ae4d1..ca8bd22f 100644 --- a/example/rwgk1.cpp +++ b/example/rwgk1.cpp @@ -13,29 +13,12 @@ namespace python = boost::python; // Python requires an exported function called init in every // extension module. This is where we build the module contents. -extern "C" -#ifdef _WIN32 -__declspec(dllexport) -#endif -void initrwgk1() +BOOST_PYTHON_MODULE_INIT(rwgk1) { - try - { // Create an object representing this extension module. python::module_builder this_module("rwgk1"); // Add regular functions to the module. this_module.def(greet, "greet"); this_module.def(square, "square"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } - -// Win32 DLL boilerplate -#if defined(_WIN32) -#include -extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; } -#endif // _WIN32 diff --git a/example/rwgk2.cpp b/example/rwgk2.cpp new file mode 100644 index 00000000..35dce88f --- /dev/null +++ b/example/rwgk2.cpp @@ -0,0 +1,50 @@ +#include +#include + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + private: + std::string country; + public: + world(const std::string& country) { this->country = country; } + std::string greet() const { return "Hello from " + country + "!"; } + }; + + // A function taking a world object as an argument. + std::string invite(const world& w) { + return w.greet() + " Please come soon!"; + } +} + +#include + +// Python requires an exported function called init in every +// extension module. This is where we build the module contents. +BOOST_PYTHON_MODULE_INIT(example2) +{ + // Create an object representing this extension module. + py::Module this_module("example2"); + + // Create the Python type object for our extension class. + py::ClassWrapper world_class(this_module, "world"); + + // Add the __init__ function. + world_class.def(py::Constructor()); + // Add a regular member function. + world_class.def(&world::greet, "greet"); + + // Add invite() as a regular function to the module. + this_module.def(invite, "invite"); + + // Even better, invite() can also be made a member of world_class!!! + world_class.def(invite, "invite"); +} + +// Win32 DLL boilerplate +#if defined(_WIN32) +#include +extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; } +#endif // _WIN32 diff --git a/example/rwgk3.cpp b/example/rwgk3.cpp new file mode 100644 index 00000000..df17b28e --- /dev/null +++ b/example/rwgk3.cpp @@ -0,0 +1,101 @@ +#include +#include + +#define rangei(n) for (int i = 0; i < n; i++) + +namespace { // Avoid cluttering the global namespace. + + // A wrapper is used to define additional constructors. + // + struct vector_double_wrapper: std::vector + { + // Tell the compiler how to convert a base class object to + // this wrapper object. + vector_double_wrapper(PyObject*, const std::vector& vd) + : std::vector(vd) {} + + vector_double_wrapper(PyObject* self) + : std::vector() {} + + vector_double_wrapper(PyObject* self, const int n) + : std::vector(n) {} + + vector_double_wrapper(PyObject* self, py::Tuple tuple) + : std::vector(tuple.size()) + { + std::vector::iterator vd = begin(); + rangei(tuple.size()) + vd[i] = from_python(tuple[i].get(), py::Type()); // GCC BUG + } + }; + + double getitem(const std::vector& vd, const std::size_t key) { + return vd[key]; + } + + void setitem(std::vector& vd, const std::size_t key, + const double &d) { + std::vector::iterator vditer = vd.begin(); + vditer[key] = d; + } + + void delitem(std::vector& vd, const std::size_t key) { + std::vector::iterator vditer = vd.begin(); + vd.erase(&vditer[key]); + } + + // Convert vector_double to a regular Python tuple. + // + py::Tuple as_tuple(const std::vector& vd) + { + py::Tuple t(vd.size()); + rangei(vd.size()) t.set_item(i, py::Ptr(py::to_python(vd[i]))); // GCC BUG + return t; + } + + // Function returning a vector_double object to Python. + // + std::vector foo(const int n) + { + std::vector vd(n); + std::vector::iterator vditer = vd.begin(); + rangei(n) vditer[i] = double(i); + return vd; + } + + // Same as foo(), but avoid copying on return. + // + std::auto_ptr > bar(const int n) + { + std::auto_ptr > vdptr(new std::vector(n)); + std::vector::iterator vditer = vdptr->begin(); + rangei(n) vditer[i] = double(10 * i); + return vdptr; + } +} + +BOOST_PYTHON_MODULE_INIT(example3) +{ + py::Module this_module("example3"); + + py::ClassWrapper, vector_double_wrapper> + vector_double(this_module, "vector_double"); + + vector_double.def(py::Constructor<>()); + vector_double.def(py::Constructor()); + vector_double.def(py::Constructor()); + vector_double.def(&std::vector::size, "__len__"); + vector_double.def(getitem, "__getitem__"); + vector_double.def(setitem, "__setitem__"); + vector_double.def(delitem, "__delitem__"); + vector_double.def(as_tuple, "as_tuple"); + + this_module.def(foo, "foo"); + this_module.def(bar, "bar"); +} + +// Win32 DLL boilerplate +#if defined(_WIN32) +#include +extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; } +#endif // _WIN32 diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp index 3499c8f7..8c7ee0ce 100644 --- a/example/simple_vector.cpp +++ b/example/simple_vector.cpp @@ -85,8 +85,6 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(simple_vector) { - try - { python::module_builder this_module("simple_vector"); python::class_builder, vector_double_wrapper> @@ -103,9 +101,4 @@ BOOST_PYTHON_MODULE_INIT(simple_vector) this_module.def(foo, "foo"); this_module.def(bar, "bar"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } } diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index b6075368..f814aba0 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -58,9 +58,9 @@ # endif #if defined(_WIN32) || defined(__CYGWIN__) -# define BOOST_PYTHON_MODULE_INIT(name) extern "C" __declspec(dllexport) void init##name() +# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name() #else -# define BOOST_PYTHON_MODULE_INIT(name) extern "C" void init##name() +# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name() #endif #endif // CONFIG_DWA052200_H_ diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 8eaac025..7cd7e0ce 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -1128,7 +1128,7 @@ PyObject* raw(const boost::python::tuple& args, const boost::python::dictionary& return BOOST_PYTHON_CONVERSION::to_python(first->i_ + second + third + fourth); } -void init_module() +BOOST_PYTHON_MODULE_INIT(boost_python_test) { boost::python::module_builder boost_python_test("boost_python_test"); init_module(boost_python_test); @@ -1137,11 +1137,6 @@ void init_module() boost_python_test.add(new boost::python::meta_class); } -BOOST_PYTHON_MODULE_INIT(boost_python_test) -{ - boost::python::handle_exception((void (*)())bpl_test::init_module); -} - CompareIntPairPythonClass::CompareIntPairPythonClass(boost::python::module_builder& m) : boost::python::class_builder(m, "CompareIntPair") { From 6a6084ed0ecf81134527ac066d629127a249d312 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 2 Dec 2001 17:43:45 +0000 Subject: [PATCH 0128/1042] Metrowerks needs BOOST_NO_STD_LOCALE in config to be able to compile regex regex test Jamfile updates so that some tests will actually run warning suppression for condition.cpp unit-test rule now accepts input files updated metrowerks and borland to properly set up path for running tests ---------------------------------------------------------------------- Modified Files: boost/config/compiler/metrowerks.hpp libs/python/src/gen_function.py libs/regex/test/Jamfile Tag: thread-initial libs/thread/src/condition.cpp No tag tools/build/boost-base.jam tools/build/borland-tools.jam tools/build/metrowerks-tools.jam ---------------------------------------------------------------------- [SVN r11853] --- src/gen_function.py | 106 ++++++++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 28 deletions(-) diff --git a/src/gen_function.py b/src/gen_function.py index bebbc818..ac24ac18 100644 --- a/src/gen_function.py +++ b/src/gen_function.py @@ -12,15 +12,31 @@ def _find(s, sub, start=0, end=None): else: return pos -def _gen_common_key(key, n, args): +def _raise_no_argument(key, n, args): + raise IndexError(str(key) + " extra arg(s) not passed to gen_function") + +def _gen_common_key(key, n, args, fill = _raise_no_argument): + # import sys + # print >> sys.stderr, "_gen_common_key(", repr(key), ",", repr(n), ',', repr(args), ',', fill, ')' + # sys.stderr.flush() if len(key) > 0 and key in '123456789': - return str(args[int(key) - 1]) - elif key == 'x': - return str(n) + index = int(key) - 1; + + if index >= len(args): + return fill(key, n, args) + + arg = args[index] + if callable(arg): + return str(arg(key, n, args)) + else: + return str(arg) + elif key in ('x','n','-','+'): + return str(n + {'-':-1,'+':+1,'x':0,'n':0}[key]) else: return key -def _gen_arg(template, n, args, delimiter = '%'): +def _gen_arg(template, n, args, delimiter = '%', fill = _raise_no_argument): + result = '' i = 0 while i < len(template): # until the template is consumed @@ -33,13 +49,13 @@ def _gen_arg(template, n, args, delimiter = '%'): key = template[start - 1 : start] # the key character. If there were no # delimiters left, key will be empty - if key == 'n': + if 0 and key == 'n': result = result + `n` - else: - result = result + _gen_common_key(key, n, args) + else: + result = result + _gen_common_key(key, n, args, fill) i = start - + return result def gen_function(template, n, *args, **keywords): @@ -52,19 +68,46 @@ def gen_function(template, n, *args, **keywords): Sections of the template between '%{', '%}' pairs are ommitted if n == 0. - %n is transformed into the string representation of 1..n for each repetition - of n. + %n is transformed into the string representation of 1..n for each + repetition within %(...%). Elsewhere, %n is transformed into the + string representation of n + + %- is transformed into the string representation of 0..n-1 for + each repetition within %(...%). Elsewhere, %- is transformed into the + string representation of n-1. + + %+ is transformed into the string representation of 2..n+1 for + each repetition within %(...%). Elsewhere, %- is transformed into the + string representation of n+1. + + %x is always transformed into the string representation of n + + %z, where z is a digit, selects the corresponding additional + argument. If that argument is callable, it is called with three + arguments: + key - the string representation of 'z' + n - the iteration number + args - a tuple consisting of all the additional arguments to + this function + otherwise, the selected argument is converted to a string representation - %x, where x is a digit, is transformed into the corresponding additional - argument. for example, - >>> gen_function('%1 abc(%(int a%n%:, %));%{ // all args are ints%}', 2, 'void') - 'void abc(int a1, int a2); // all args are ints' + >>> gen_function('%1 abc%x(%(int a%n%:, %));%{ // all args are ints%}', 2, 'void') + 'void abc2(int a1, int a2); // all args are ints' + >>> gen_function('%1 abc(%(int a%n%:, %));%{ // all args are ints%}', 0, 'x') 'x abc();' + >>> gen_function('%1 abc(%(int a%n%:, %));%{ // all args are ints%}', 0, lambda key, n, args: 'abcd'[n]) + 'a abc();' + + >>> gen_function('%2 %1 abc(%(int a%n%:, %));%{ // all args are ints%}', 0, 'x', fill = lambda key, n, args: 'const') + 'const x abc();' + + >>> gen_function('abc%[k%:v%]', 0, fill = lambda key, n, args, value = None: '<' + key + ',' + value + '>') + 'abc' >>> template = ''' template ... static PyObject* call( %1(T::*pmf)(%(A%n%:, %))%2, PyObject* args, PyObject* /* keywords */ ) { @@ -123,6 +166,7 @@ def gen_function(template, n, *args, **keywords): } """ delimiter = keywords.get('delimiter', '%') + fill = keywords.get('fill', _raise_no_argument); result = '' i = 0 while i < len(template): # until the template is consumed @@ -135,7 +179,7 @@ def gen_function(template, n, *args, **keywords): key = template[start - 1 : start] # the key character. If there were no # delimiters left, key will be empty - pairs = { '(':')', '{':'}' } + pairs = { '(':')', '{':'}', '[':']' } if key in pairs.keys(): end = string.find(template, delimiter + pairs[key], start) @@ -146,23 +190,27 @@ def gen_function(template, n, *args, **keywords): if n > 0: result = result + gen_function(template[start:end], n, args, delimiter) else: - separator_pos = _find(template, delimiter + ':', start, end) - separator = template[separator_pos+2 : end] - - for x in range(1, n + 1): - result = result + _gen_arg(template[start:separator_pos], x, args, - delimiter) - if x != n: - result = result + separator + separator_pos = _find(template, delimiter + ':', + start, end) + remainder = template[separator_pos+2 : end] + + if key == '(': + for x in range(1, n + 1): + result = result + _gen_arg(template[start:separator_pos], x, args, + delimiter) + if x != n: + result = result + remainder + else: + result = result + fill(template[start:separator_pos], n, args, value = remainder) else: - result = result + _gen_common_key(key, n, args) + result = result + _gen_common_key(key, n, args, fill) i = delimiter_pos + 2 return result -def gen_functions(template, n, *args): +def gen_functions(template, n, *args, **keywords): r"""gen_functions(template, n, [args...]) -> string Call gen_function repeatedly with from 0..n and the given optional @@ -174,11 +222,13 @@ def gen_functions(template, n, *args): void abc(int a1, int a2); // all args are ints """ + fill = keywords.get('fill', _raise_no_argument); result = '' for x in range(n + 1): - result = result + apply(gen_function, (template, x) + args) + result = result + apply(gen_function, (template, x) + args, keywords) return result if __name__ == '__main__': import doctest - doctest.testmod() + import sys + doctest.testmod(sys.modules.get(__name__)) From ccfd4acbda8bbe980ff24c52608bd6ff7e8234a9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 13 Dec 2001 18:17:38 +0000 Subject: [PATCH 0129/1042] factored out python.jam [SVN r12041] --- build/Jamfile | 220 +++++--------------------------------------------- 1 file changed, 22 insertions(+), 198 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index 05efd4a1..c56bf47c 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -54,52 +54,18 @@ # PYTHON_VECT_ITERATIONS - specifies the number of test iterations to use for # the dvect and ivect tests above. - # declare the location of this subproject relative to the root subproject libs/python/build ; -# grab variables from command-line or environment. -local PYTHON_VERSION = $(PYTHON_VERSION) ; -local PYTHON_ROOT = $(PYTHON_ROOT) ; -local PYTHON_INCLUDES = $(PYTHON_INCLUDES) ; -local PYTHON_LIBS = $(PYTHON_LIBS) ; -local PYTHON_LIB_PATH = $(PYTHON_LIB_PATH) ; -local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) ; +# bring in the rules for python +SEARCH on python.jam = $(BOOST_BUILD_PATH) ; +include python.jam ; -# Do some OS-specific setup -if $(NT) +####################### +local rule bpl-test ( test-name : sources + ) { - PYTHON_VERSION ?= 2.1 ; - PYTHON_ROOT ?= c:/tools/python ; - PYTHON_INCLUDES ?= $(PYTHON_ROOT)/include <*>/usr/include/python$(PYTHON_VERSION) ; - PYTHON_LIBS ?= c:/cygnus/lib/python$(PYTHON_VERSION)/config/libpython$(PYTHON_VERSION).dll.a ; - PYTHON_LIB_PATH ?= $(PYTHON_ROOT)/libs ; - - # common properties required for compiling any Python module. - PYTHON_PROPERTIES ?= - <*>SIZEOF_LONG=4 - <*>USE_DL_IMPORT - _DEBUG - dynamic - ; - + boost-python-test $(test-name) : $(sources) libboost_python ; } -else if $(UNIX) -{ - PYTHON_VERSION ?= 1.5 ; - PYTHON_INCLUDES ?= /usr/include/python$(PYTHON_VERSION) ; - PYTHON_LIBS ?= /usr/lib/python$(PYTHON_VERSION)/config/libpython$(PYTHON_VERSION).a ; -} - -local PYTHON_VERSION_NODOT - = [ SUBST $(PYTHON_VERSION) ([0-9]*)\.([0-9]*) $1$2 ] - ; - -# how do we invoke python? -local PYTHON = $(PYTHON) ; -PYTHON ?= python ; -PYTHON = [ FAppendSuffix $(PYTHON:G=) : $(SUFEXE) ] ; -SEARCH on $(PYTHON) = $(PATH) ; ####################### @@ -107,9 +73,6 @@ SEARCH on $(PYTHON) = $(PATH) ; # Declare the boost python static link library # -# standard include requirements for anything using Boost.Python -local BOOST_PYTHON_INCLUDES = $(BOOST_ROOT) $(PYTHON_INCLUDES) ; - # Base names of the source files for libboost_python local CPP_SOURCES = types classes conversions extension_class functions @@ -121,162 +84,23 @@ lib libboost_python : ../src/$(CPP_SOURCES).cpp true $(PYTHON_PROPERTIES) ; -lib libboost_python_d : ../src/$(CPP_SOURCES).cpp - # requirements - : $(BOOST_PYTHON_INCLUDES) - true - $(PYTHON_PROPERTIES) - BOOST_DEBUG_PYTHON - ; -####################### - -# boost-python name : sources : requirements : default-BUILD -# -# Declare a boost python module. Return a list of the DLL files generated. -rule boost-python -{ - local debug = "" ; - if ( BOOST_DEBUG_PYTHON in $(3) ) || ( debug-python in $(BUILD) ) - { - debug = _d ; - } - - # declare a DLL; add the boost python library to sources - dll $(<) : libboost_python$(debug) $(>) - - # Requirements - : $(3) # caller-specified requirements - - # standard requirements - $(BOOST_PYTHON_INCLUDES) - <*>$(PYTHON_LIB_PATH) - <*>$(PYTHON_LIB_PATH) - <*>$(PYTHON_LIB_PATH)/python$(PYTHON_VERSION_NODOT)$(debug).lib - <*>$(PYTHON_LIBS) - $(PYTHON_PROPERTIES) - - : $(4) ; # pass on the default-BUILD, if any -} - -# boost-python-test name : sources : requirements : default-BUILD -# -# Just like boost-python, but the result becomes part of the test pseudotarget -# instead of being built by 'all' -rule boost-python-test -{ - type-DEPENDS test : $(<) ; - type-DEPENDS test_d : $(<)_d ; - NOTFILE test_d ; - - local gSUPPRESS_FAKE_TARGETS = true ; - boost-python $(1) : $(2) : $(3) : $(4) ; - boost-python $(1)_d : $(2) : $(3) BOOST_DEBUG_PYTHON : $(4) ; -} - -####################### - -# boost-python-runtest target : python-script sources : requirements : local-build : args -# -# declare two python module tests: $(<).test which builds when out-of-date, and -# $(<).run which builds unconditionally. -rule boost-python-runtest -{ - # tell Jam that the python script is relative to this directory - SEARCH on $(>[1]) = $(SEARCH_SOURCE) ; - - # required command-line args can be specified in argument 5 - # The user can add additional arguments in PYTHON_TEST_ARGS. - local gPYTHON_TEST_ARGS = $(5) $(PYTHON_TEST_ARGS) ; - - # declare the two subsidiary tests. - declare-local-target $(<:S=.test) : $(>) : $(PYTHON_PROPERTIES) : $(4) : PYTHON_TEST ; - declare-local-target $(<:S=.run) : $(>) : $(PYTHON_PROPERTIES) : $(4) : PYTHON_RUNTEST ; -} - -# special rules for two new target types: PYTHON_TEST and PYTHON_RUNTEST. -# These are identical except that PYTHON_TEST runs the test when out-of-date, and -# PYTHON_RUNTEST runs the test unconditionally. These are used by boost-python-runtest. -SUFPYTHON_TEST = .test ; -gGENERATOR_FUNCTION(PYTHON_TEST) = python-test-target ; -rule python-test-target # test-target : sources : -{ - python-runtest-aux $(<) : $(>) ; - Clean clean : $(<) ; # remove the test-target as part of any clean operation - local debug = [ SUBST $(<:B) (_d)$ $1 ] ; - debug ?= "" ; - type-DEPENDS test$(debug) : $(<) ; - MakeLocate $(<) : $(LOCATE_TARGET) ; -} -actions python-test-target bind PYTHON -{ - $(SHELL_SET)PYTHONPATH=$(PYTHONPATH) - $(SHELL_EXPORT)PYTHONPATH - $(PYTHON) "$(>)" $(ARGS) > "$(<)" -} - -SUFPYTHON_RUNTEST = .run ; -gGENERATOR_FUNCTION(PYTHON_RUNTEST) = python-runtest-target ; -rule python-runtest-target # test-target : sources : -{ - python-runtest-aux $(<) : $(>) ; - NOTFILE $(<) ; - ALWAYS $(<) ; -} -actions python-runtest-target bind PYTHON -{ - $(SHELL_SET)PYTHONPATH=$(PYTHONPATH) - $(SHELL_EXPORT)PYTHONPATH - $(PYTHON) "$(>)" $(ARGS) -} - -rule python-runtest-aux # target : sources -{ - DEPENDS $(<) : $(>) ; - - ARGS on $(<) += $(gPYTHON_TEST_ARGS) ; - - # Some tests need an extra command-line arg if built with - # msvc. Checking the target grist is a cheap way to - # find out. - switch $(<) - { - case <*\\\\msvc\\\\*>* : ARGS on $(<) += --broken-auto-ptr ; - case <*\\\\intel-win32\\\\*>* : ARGS on $(<) += --broken-auto-ptr ; - } - - # compute the PYTHONPATH environment variable that will allow the test to - # find all of the modules on which it depends. - PYTHONPATH on $(<) = [ join - $(gLOCATE($(>[1]))) # location of python test file - $(gRUN_PATH($(<))) # location of module dependencies - [ join-path $(TOP) libs python test ] # location of doctest - $(>:D) # directory of python driver file(s) - $(PYTHONPATH) # base PYTHONPATH from environment - : $(SPLITPATH) ] ; # platform path separator - - PYTHON on $(<) = $(PYTHON) ; - DEPENDS $(<) : $(PYTHON) ; -} - ############# comprehensive module and test ########### -boost-python-test boost_python_test : ../test/comprehensive.cpp ; +bpl-test boost_python_test + : ../test/comprehensive.cpp ; boost-python-runtest comprehensive - : [ join-path $(DOTDOT) test comprehensive.py ] - boost_python_test ; - -boost-python-runtest comprehensive_d - : [ join-path $(DOTDOT) test comprehensive.py ] - boost_python_test_d ; + : ../test/comprehensive.py boost_python_test libboost_python ; ############# simple tests from ../example ############ -rule boost-python-example-runtest +local rule boost-python-example-runtest ( name ) { - boost-python-test $(<) : ../example/$(<).cpp ; - boost-python-runtest $(<) : [ join-path $(DOTDOT) example test_$(<).py ] $(<) ; - boost-python-runtest $(<)_d : [ join-path $(DOTDOT) example test_$(<).py ] $(<)_d ; + bpl-test $(name) + : ../example/$(name).cpp ; + + boost-python-runtest $(name) + : ../example/test_$(name).py $(name) ; } @@ -290,18 +114,18 @@ boost-python-example-runtest pickle2 ; boost-python-example-runtest pickle3 ; -boost-python-test ivect : ../example/ivect.cpp ; -boost-python-test dvect : ../example/dvect.cpp ; -boost-python-test noncopyable_export : ../example/noncopyable_export.cpp ; -boost-python-test noncopyable_import : ../example/noncopyable_import.cpp ; +bpl-test ivect : ../example/ivect.cpp ; +bpl-test dvect : ../example/dvect.cpp ; +bpl-test noncopyable_export : ../example/noncopyable_export.cpp ; +bpl-test noncopyable_import : ../example/noncopyable_import.cpp ; ############## cross-module tests from ../example ########## # A simple rule to build a test which depends on multiple modules in the PYTHONPATH -rule boost-python-multi-example-runtest # test-name : python-file libs +local rule boost-python-multi-example-runtest ( test-name : modules + ) { - boost-python-runtest $(<) - : ../example/tst_$(<).py $(>) + boost-python-runtest $(test-name) + : ../example/tst_$(test-name).py $(modules) libboost_python : : : $(PYTHON_VECT_ITERATIONS) ; } From d05cc7ccec6ceb8cf3153de04fa789e4d0e5b2f4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 13 Dec 2001 18:18:52 +0000 Subject: [PATCH 0130/1042] integrating scott snyder's changes [SVN r12042] --- doc/special.html | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/doc/special.html b/doc/special.html index 46ca0791..a72ec671 100644 --- a/doc/special.html +++ b/doc/special.html @@ -287,6 +287,35 @@ bignum_class.def(&rmod, "__rmod__"); found first (be it ``int`` or ``float'') will be used for either of the two types. +

    Inplace Operators

    +

    + Boost.Python can also be used to expose inplace numeric operations + (i.e., += and so forth). These operators must be wrapped + manually, as described in the previous section. For example, suppose + the class BigNum has an operator+=: + +

    +BigNum& operator+= (BigNum const& right);
    +
    + + This can be exposed by first writing a wrapper function: + +
    +BigNum& iadd (BigNum& self, const BigNum& right)
    +{
    +  return self += right;
    +}
    +
    + + and then exposing the wrapper with + +
    +bignum_class.def(&iadd, "__iadd__");
    +
    + + + +

    Coercion

    From 2f6e3cc09d5b588ecbca99879260c63d36eb2042 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 13 Dec 2001 18:22:03 +0000 Subject: [PATCH 0131/1042] Integrating scott snyder's inplace operator improvements [SVN r12043] --- src/types.cpp | 149 ++++++++++++++++++++++++++++++++++++++++- test/comprehensive.cpp | 48 ++++++++++++- 2 files changed, 194 insertions(+), 3 deletions(-) diff --git a/src/types.cpp b/src/types.cpp index 3367dba8..fe108225 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -455,6 +455,61 @@ static PyObject* do_instance_nb_hex(PyObject* obj) return call(obj, &type_object_base::instance_number_hex); } +static PyObject* do_instance_nb_inplace_add(PyObject* obj, PyObject* other) +{ + return call(obj, &type_object_base::instance_number_inplace_add, other); +} + +static PyObject* do_instance_nb_inplace_subtract(PyObject* obj, PyObject* other) +{ + return call(obj, &type_object_base::instance_number_inplace_subtract, other); +} + +static PyObject* do_instance_nb_inplace_multiply(PyObject* obj, PyObject* other) +{ + return call(obj, &type_object_base::instance_number_inplace_multiply, other); +} + +static PyObject* do_instance_nb_inplace_divide(PyObject* obj, PyObject* other) +{ + return call(obj, &type_object_base::instance_number_inplace_divide, other); +} + +static PyObject* do_instance_nb_inplace_remainder(PyObject* obj, PyObject* other) +{ + return call(obj, &type_object_base::instance_number_inplace_remainder, other); +} + +static PyObject* do_instance_nb_inplace_power(PyObject* obj, PyObject* exponent, PyObject* modulus) +{ + return call(obj, &type_object_base::instance_number_inplace_power, exponent, modulus); +} + +static PyObject* do_instance_nb_inplace_lshift(PyObject* obj, PyObject* other) +{ + return call(obj, &type_object_base::instance_number_inplace_lshift, other); +} + +static PyObject* do_instance_nb_inplace_rshift(PyObject* obj, PyObject* other) +{ + return call(obj, &type_object_base::instance_number_inplace_rshift, other); +} + +static PyObject* do_instance_nb_inplace_and(PyObject* obj, PyObject* other) +{ + return call(obj, &type_object_base::instance_number_inplace_and, other); +} + +static PyObject* do_instance_nb_inplace_or(PyObject* obj, PyObject* other) +{ + return call(obj, &type_object_base::instance_number_inplace_or, other); +} + +static PyObject* do_instance_nb_inplace_xor(PyObject* obj, PyObject* other) +{ + return call(obj, &type_object_base::instance_number_inplace_xor, other); +} + } // extern "C" namespace @@ -511,6 +566,41 @@ bool add_capability_richcompare(type_object_base::capability capability, PyTypeO return false; } +#if PYTHON_API_VERSION >= 1010 +# define ENABLE_INPLACE_CAPABILITY1 \ + dest->tp_flags |= Py_TPFLAGS_HAVE_INPLACEOPS; +#else +# define ENABLE_INPLACE_CAPABILITY1 +#endif +#define ENABLE_INPLACE_CAPABILITY(field) \ + case type_object_base::number_##field: \ + create_method_table_if_null(dest->tp_as_number); \ + dest->tp_as_number->nb_##field = &do_instance_nb_##field; \ + detail::shared_pod_manager::replace_if_equal(dest->tp_as_number); \ + ENABLE_INPLACE_CAPABILITY1 \ + return true + +bool add_capability_inplace(type_object_base::capability capability, PyTypeObject* dest) +{ + assert(dest != 0); + switch (capability) + { + ENABLE_INPLACE_CAPABILITY (inplace_add); + ENABLE_INPLACE_CAPABILITY (inplace_subtract); + ENABLE_INPLACE_CAPABILITY (inplace_multiply); + ENABLE_INPLACE_CAPABILITY (inplace_divide); + ENABLE_INPLACE_CAPABILITY (inplace_remainder); + ENABLE_INPLACE_CAPABILITY (inplace_power); + ENABLE_INPLACE_CAPABILITY (inplace_lshift); + ENABLE_INPLACE_CAPABILITY (inplace_rshift); + ENABLE_INPLACE_CAPABILITY (inplace_and); + ENABLE_INPLACE_CAPABILITY (inplace_or); + ENABLE_INPLACE_CAPABILITY (inplace_xor); + default: + return false; + } +} + #define ENABLE_MAPPING_CAPABILITY(field) \ case type_object_base::mapping_##field: \ create_method_table_if_null(dest); \ @@ -626,6 +716,8 @@ namespace detail { return; if(add_capability_richcompare(capability, dest_)) return; + if(add_capability_inplace(capability, dest_)) + return; if(add_capability_mapping(capability, dest_->tp_as_mapping)) return; if(add_capability_sequence(capability, dest_->tp_as_sequence)) @@ -970,7 +1062,7 @@ PyObject* type_object_base::instance_number_divmod(PyObject*, PyObject*) const PyObject* type_object_base::instance_number_power(PyObject*, PyObject*, PyObject*) const { - return unimplemented("instance_number_divmod"); + return unimplemented("instance_number_power"); } PyObject* type_object_base::instance_number_negative(PyObject*) const @@ -1053,6 +1145,61 @@ PyObject* type_object_base::instance_number_hex(PyObject*) const return unimplemented("instance_number_hex"); } +PyObject* type_object_base::instance_number_inplace_add(PyObject*, PyObject*) const +{ + return unimplemented("instance_number_inplace_add"); +} + +PyObject* type_object_base::instance_number_inplace_subtract(PyObject*, PyObject*) const +{ + return unimplemented("instance_number_inplace_subtract"); +} + +PyObject* type_object_base::instance_number_inplace_multiply(PyObject*, PyObject*) const +{ + return unimplemented("instance_number_inplace_multiply"); +} + +PyObject* type_object_base::instance_number_inplace_divide(PyObject*, PyObject*) const +{ + return unimplemented("instance_number_inplace_divide"); +} + +PyObject* type_object_base::instance_number_inplace_remainder(PyObject*, PyObject*) const +{ + return unimplemented("instance_number_inplace_remainder"); +} + +PyObject* type_object_base::instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const +{ + return unimplemented("instance_number_inplace_power"); +} + +PyObject* type_object_base::instance_number_inplace_lshift(PyObject*, PyObject*) const +{ + return unimplemented("instance_number_inplace_lshift"); +} + +PyObject* type_object_base::instance_number_inplace_rshift(PyObject*, PyObject*) const +{ + return unimplemented("instance_number_inplace_rshift"); +} + +PyObject* type_object_base::instance_number_inplace_and(PyObject*, PyObject*) const +{ + return unimplemented("instance_number_inplace_and"); +} + +PyObject* type_object_base::instance_number_inplace_or(PyObject*, PyObject*) const +{ + return unimplemented("instance_number_inplace_or"); +} + +PyObject* type_object_base::instance_number_inplace_xor(PyObject*, PyObject*) const +{ + return unimplemented("instance_number_inplace_xor"); +} + PyObject* type_object_base::instance_lt(PyObject*, PyObject*) const { return unimplemented("instance_lt"); diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 7cd7e0ce..61f56407 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -667,7 +667,7 @@ int total_Ints = 0; struct Int { - explicit Int(int i) : i_(i) { + explicit Int(int i) : i_(i), j_(0) { #ifndef NDEBUG ++total_Ints; #endif @@ -675,12 +675,29 @@ struct Int #ifndef NDEBUG ~Int() { --total_Ints; } - Int(const Int& rhs) : i_(rhs.i_) { ++total_Ints; } + Int(const Int& rhs) : i_(rhs.i_), j_(rhs.j_) { ++total_Ints; } #endif int i() const { return i_; } + int j() const { return j_; } int i_; + int j_; + + Int& operator +=(Int const& r) { ++j_; i_ += r.i_; return *this; } + Int& operator -=(Int const& r) { ++j_; i_ -= r.i_; return *this; } + Int& operator *=(Int const& r) { ++j_; i_ *= r.i_; return *this; } + Int& operator /=(Int const& r) { ++j_; i_ /= r.i_; return *this; } + Int& operator %=(Int const& r) { ++j_; i_ %= r.i_; return *this; } + Int& ipow (Int const& r) { ++j_; + int o=i_; + for (int k=1; k>=(Int const& r) { ++j_; i_ >>= r.i_; return *this; } + Int& operator &=(Int const& r) { ++j_; i_ &= r.i_; return *this; } + Int& operator |=(Int const& r) { ++j_; i_ |= r.i_; return *this; } + Int& operator ^=(Int const& r) { ++j_; i_ ^= r.i_; return *this; } }; Int operator+(Int const & l, Int const & r) { return Int(l.i_ + r.i_); } @@ -868,6 +885,19 @@ namespace bpl_test { double freal(const std::complex& c) { return c.real(); } double fimag(std::complex c) { return c.imag(); } + // Wrappers for inplace operators. + Int& int_iadd(Int& self, const Int& r) { self += r; return self; } + Int& int_isub(Int& self, const Int& r) { self -= r; return self; } + Int& int_imul(Int& self, const Int& r) { self *= r; return self; } + Int& int_idiv(Int& self, const Int& r) { self /= r; return self; } + Int& int_imod(Int& self, const Int& r) { self %= r; return self; } + Int& int_ipow(Int& self, const Int& r) { self.ipow (r); return self; } + Int& int_ilshift(Int& self, const Int& r) { self <<= r; return self; } + Int& int_irshift(Int& self, const Int& r) { self >>= r; return self; } + Int& int_iand(Int& self, const Int& r) { self &= r; return self; } + Int& int_ior(Int& self, const Int& r) { self |= r; return self; } + Int& int_ixor(Int& self, const Int& r) { self ^= r; return self; } + /************************************************************/ /* */ /* init the module */ @@ -1042,6 +1072,7 @@ void init_module(boost::python::module_builder& m) boost::python::class_builder int_class(m, "Int"); int_class.def(boost::python::constructor()); int_class.def(&Int::i, "i"); + int_class.def(&Int::j, "j"); // wrap homogeneous operators int_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub | boost::python::op_neg | @@ -1061,6 +1092,19 @@ void init_module(boost::python::module_builder& m) boost::python::left_operand()); // export non-operator function as heterogeneous reverse-argument operator int_class.def(&rmul, "__rmul__"); + + // inplace operators. + int_class.def(&int_iadd, "__iadd__"); + int_class.def(&int_isub, "__isub__"); + int_class.def(&int_imul, "__imul__"); + int_class.def(&int_idiv, "__idiv__"); + int_class.def(&int_imod, "__imod__"); + int_class.def(&int_ipow, "__ipow__"); + int_class.def(&int_ilshift, "__ilshift__"); + int_class.def(&int_irshift, "__irshift__"); + int_class.def(&int_iand, "__iand__"); + int_class.def(&int_ior, "__ior__"); + int_class.def(&int_ixor, "__ixor__"); boost::python::class_builder enum_owner(m, "EnumOwner"); From 160451b210d12071f378d8c0e13c2297dcb3ca19 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 13 Dec 2001 18:23:10 +0000 Subject: [PATCH 0132/1042] Integrating scott snyder's inplace operator improvements Fixed Python 2.2 incompatibility [SVN r12044] --- test/comprehensive.py | 64 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/test/comprehensive.py b/test/comprehensive.py index 2ac0704a..b4ae5679 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -318,26 +318,37 @@ Special member attributes. Tests courtesy of Barry Scott >> df = DerivedFromFoo() - >>> dir(df) - [] >>> dir(DerivedFromFoo) ['__del__', '__doc__', '__init__', '__module__', 'fred'] + + >>> df = DerivedFromFoo() >>> df.__dict__ {} - >>> df.fred.__doc__ 'Docs for DerivedFromFoo.fred' + >>> db = DerivedFromBase() - >>> dir(db) - [] - >>> dir(DerivedFromBase) - ['__doc__', '__module__', 'fred', 'i_am_derived_from_base'] >>> db.__dict__ {} >>> db.fred.__doc__ 'Docs for DerivedFromBase.fred' + >>> import sys + >>> if sys.version_info[0] < 2 or ( sys.version_info[0] == 2 and + ... sys.version_info[1] < 2 ): + ... assert dir(df) == [] + ... assert dir(db) == [] + ... assert dir(DerivedFromBase) == [ + ... '__doc__', '__module__', 'fred', 'i_am_derived_from_base'] + ... else: + ... assert dir(df) == [ + ... '__del__', '__doc__', '__init__', '__module__', 'add_len', + ... 'call_add_len', 'call_pure', 'fred', 'mumble', 'set'] + ... assert dir(db) == ['__doc__', '__module__', 'fred' + ... , 'i_am_base', 'i_am_derived_from_base'] + ... assert dir(DerivedFromBase) == [ + ... '__doc__', '__module__', 'fred', 'i_am_base', 'i_am_derived_from_base'] + Special member functions in action >>> del df Deleting DerivedFromFoo @@ -1058,6 +1069,43 @@ test inheritB2 Traceback (innermost last): TypeError: bad operand type(s) for pow() + >>> ii = Int(1) + >>> ii += Int(2) + >>> ii.i() + 3 + >>> ii -= Int(1) + >>> ii.i() + 2 + >>> ii *= Int(3) + >>> ii.i() + 6 + >>> ii /= Int(2) + >>> ii.i() + 3 + >>> ii <<= Int(2) + >>> ii.i() + 12 + >>> ii >>= Int(1) + >>> ii.i() + 6 + >>> ii &= Int(5) + >>> ii.i() + 4 + >>> ii |= Int(9) + >>> ii.i() + 13 + >>> ii ^= Int(7) + >>> ii.i() + 10 + >>> ii %= Int(4) + >>> ii.i() + 2 + >>> ii **= Int(3) + >>> ii.i() + 8 + >>> ii.j() + 11 + Test operator export to a subclass # force method table sharing From a365fa610936a312fdc9602c01afefb5f12cbb59 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 13 Dec 2001 19:43:35 +0000 Subject: [PATCH 0133/1042] many fixes [SVN r12054] --- include/boost/python/classes.hpp | 91 +++++++++++ include/boost/python/detail/types.hpp | 18 ++- include/boost/python/detail/wrap_python.hpp | 20 ++- src/classes.cpp | 69 ++++++++ src/gen_arg_tuple_size.py | 132 +++++++++++++++ src/gen_function.py | 171 ++++++++++---------- 6 files changed, 414 insertions(+), 87 deletions(-) create mode 100644 src/gen_arg_tuple_size.py diff --git a/include/boost/python/classes.hpp b/include/boost/python/classes.hpp index 2d69e81e..f88f1000 100644 --- a/include/boost/python/classes.hpp +++ b/include/boost/python/classes.hpp @@ -78,6 +78,19 @@ class instance PyObject* gt(PyObject* other); PyObject* ge(PyObject* other); + // Inplace operations. + PyObject* inplace_add(PyObject* other); + PyObject* inplace_subtract(PyObject* other); + PyObject* inplace_multiply(PyObject* other); + PyObject* inplace_divide(PyObject* other); + PyObject* inplace_remainder(PyObject* other); + PyObject* inplace_power(PyObject* exponent, PyObject* modulus); + PyObject* inplace_lshift(PyObject* other); + PyObject* inplace_rshift(PyObject* other); + PyObject* inplace_and(PyObject* other); + PyObject* inplace_or(PyObject* other); + PyObject* inplace_xor(PyObject* other); + private: // noncopyable, without the size bloat instance(const instance&); void operator=(const instance&); @@ -178,6 +191,18 @@ class class_t PyObject* instance_number_oct(PyObject*) const; PyObject* instance_number_hex(PyObject*) const; + PyObject* instance_number_inplace_add(PyObject*, PyObject*) const; + PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const; + PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const; + PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const; + PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const; + PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const; + PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const; + PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const; + PyObject* instance_number_inplace_and(PyObject*, PyObject*) const; + PyObject* instance_number_inplace_or(PyObject*, PyObject*) const; + PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const; + private: // Implement rich comparisons PyObject* instance_lt(PyObject*, PyObject*) const; PyObject* instance_le(PyObject*, PyObject*) const; @@ -493,6 +518,72 @@ PyObject* class_t::instance_number_hex(PyObject* obj) const return downcast(obj)->hex(); } +template +PyObject* class_t::instance_number_inplace_add(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->inplace_add(other); +} + +template +PyObject* class_t::instance_number_inplace_subtract(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->inplace_subtract(other); +} + +template +PyObject* class_t::instance_number_inplace_multiply(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->inplace_multiply(other); +} + +template +PyObject* class_t::instance_number_inplace_divide(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->inplace_divide(other); +} + +template +PyObject* class_t::instance_number_inplace_remainder(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->inplace_remainder(other); +} + +template +PyObject* class_t::instance_number_inplace_power(PyObject* obj, PyObject* exponent, PyObject* modulus) const +{ + return downcast(obj)->inplace_power(exponent, modulus); +} + +template +PyObject* class_t::instance_number_inplace_lshift(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->inplace_lshift(other); +} + +template +PyObject* class_t::instance_number_inplace_rshift(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->inplace_rshift(other); +} + +template +PyObject* class_t::instance_number_inplace_and(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->inplace_and(other); +} + +template +PyObject* class_t::instance_number_inplace_or(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->inplace_or(other); +} + +template +PyObject* class_t::instance_number_inplace_xor(PyObject* obj, PyObject* other) const +{ + return downcast(obj)->inplace_xor(other); +} + template PyObject* class_t::instance_lt(PyObject* obj, PyObject* other) const { diff --git a/include/boost/python/detail/types.hpp b/include/boost/python/detail/types.hpp index 2d0d0f6b..954e0213 100644 --- a/include/boost/python/detail/types.hpp +++ b/include/boost/python/detail/types.hpp @@ -57,7 +57,11 @@ class type_object_base : public python_type number_positive, number_absolute, number_nonzero, number_invert, number_lshift, number_rshift, number_and, number_xor, number_or, number_coerce, number_int, number_long, number_float, number_oct, - number_hex + number_hex, number_inplace_add, number_inplace_subtract, + number_inplace_multiply, number_inplace_divide, + number_inplace_remainder, number_inplace_power, + number_inplace_lshift, number_inplace_rshift, + number_inplace_and, number_inplace_or, number_inplace_xor }; void enable(capability); @@ -116,6 +120,18 @@ class type_object_base : public python_type virtual PyObject* instance_number_oct(PyObject*) const; virtual PyObject* instance_number_hex(PyObject*) const; + virtual PyObject* instance_number_inplace_add(PyObject*, PyObject*) const; + virtual PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const; + virtual PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const; + virtual PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const; + virtual PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const; + virtual PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const; + virtual PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const; + virtual PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const; + virtual PyObject* instance_number_inplace_and(PyObject*, PyObject*) const; + virtual PyObject* instance_number_inplace_or(PyObject*, PyObject*) const; + virtual PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const; + public: // Callbacks for rich comparisons virtual PyObject* instance_lt(PyObject*, PyObject*) const; virtual PyObject* instance_le(PyObject*, PyObject*) const; diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index 373bbde4..1ad88ab6 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -35,12 +35,13 @@ // than MSVC on Win32 // #if defined(_WIN32) -# ifdef __GNUC__ - +# if defined(__GNUC__) && defined(__CYGWIN__) +# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 typedef int pid_t; -# define WORD_BIT 32 -# define hypot _hypot -# include +# define WORD_BIT 32 +# define hypot _hypot +# include +# endif # if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2 # define HAVE_CLOCK # define HAVE_STRFTIME @@ -71,6 +72,13 @@ typedef int pid_t; # define _MSC_VER 900 # endif +# include +# undef hypot // undo the evil #define left by Python. + +# elif defined(__BORLANDC__) +# include +# undef HAVE_HYPOT +# define HAVE_HYPOT 1 # elif defined(_MSC_VER) # include // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX # endif @@ -95,4 +103,6 @@ typedef int pid_t; #ifdef __MWERKS__ # pragma warn_possunwant off +#elif _MSC_VER +# pragma warning(disable:4786) #endif diff --git a/src/classes.cpp b/src/classes.cpp index a44c3c0a..75f8a01a 100644 --- a/src/classes.cpp +++ b/src/classes.cpp @@ -766,6 +766,64 @@ PyObject* instance::ge(PyObject* other) return callback::call_method(this, "__ge__", other); } +PyObject* instance::inplace_add(PyObject* other) +{ + return callback::call_method(this, "__iadd__", other); +} + +PyObject* instance::inplace_subtract(PyObject* other) +{ + return callback::call_method(this, "__isub__", other); +} + +PyObject* instance::inplace_multiply(PyObject* other) +{ + return callback::call_method(this, "__imul__", other); +} + +PyObject* instance::inplace_divide(PyObject* other) +{ + return callback::call_method(this, "__idiv__", other); +} + +PyObject* instance::inplace_remainder(PyObject* other) +{ + return callback::call_method(this, "__imod__", other); +} + +PyObject* instance::inplace_power(PyObject* exponent, PyObject* modulus) +{ + if (modulus == Py_None) + return callback::call_method(this, "__ipow__", exponent); + else + return callback::call_method(this, "__ipow__", exponent, modulus); +} + +PyObject* instance::inplace_lshift(PyObject* other) +{ + return callback::call_method(this, "__ilshift__", other); +} + +PyObject* instance::inplace_rshift(PyObject* other) +{ + return callback::call_method(this, "__irshift__", other); +} + +PyObject* instance::inplace_and(PyObject* other) +{ + return callback::call_method(this, "__iand__", other); +} + +PyObject* instance::inplace_or(PyObject* other) +{ + return callback::call_method(this, "__ior__", other); +} + +PyObject* instance::inplace_xor(PyObject* other) +{ + return callback::call_method(this, "__ixor__", other); +} + namespace { struct named_capability { @@ -783,6 +841,17 @@ namespace { { "__le__", detail::type_object_base::richcompare }, { "__eq__", detail::type_object_base::richcompare }, { "__ne__", detail::type_object_base::richcompare }, + { "__iadd__", detail::type_object_base::number_inplace_add }, + { "__isub__", detail::type_object_base::number_inplace_subtract }, + { "__imul__", detail::type_object_base::number_inplace_multiply }, + { "__idiv__", detail::type_object_base::number_inplace_divide }, + { "__imod__", detail::type_object_base::number_inplace_remainder }, + { "__ipow__", detail::type_object_base::number_inplace_power }, + { "__ilshift__", detail::type_object_base::number_inplace_lshift }, + { "__irshift__", detail::type_object_base::number_inplace_rshift }, + { "__iand__", detail::type_object_base::number_inplace_and }, + { "__ixor__", detail::type_object_base::number_inplace_xor }, + { "__ior__", detail::type_object_base::number_inplace_or }, { "__repr__", detail::type_object_base::repr }, { "__str__", detail::type_object_base::str }, { "__call__", detail::type_object_base::call }, diff --git a/src/gen_arg_tuple_size.py b/src/gen_arg_tuple_size.py new file mode 100644 index 00000000..68e379cb --- /dev/null +++ b/src/gen_arg_tuple_size.py @@ -0,0 +1,132 @@ +# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +# distribute this software is granted provided this copyright notice appears +# in all copies. This software is provided "as is" without express or implied +# warranty, and with no claim as to its suitability for any purpose. +# +# This work was funded in part by Lawrence Berkeley National Labs + +from gen_function import * +import string + +header = '''// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// This work was funded in part by Lawrence Berkeley National Labs +// +// This file generated for %d-argument member functions and %d-argument free +// functions by gen_arg_tuple_size.python +''' + +_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') + +def gen_arg_tuple_size(member_function_args, free_function_args = None): + if free_function_args is None: + free_function_args = member_function_args + 1 + + return_none = '''; + return detail::none();''' + + return (header % (member_function_args, free_function_args) + + ''' +#ifndef ARG_TUPLE_SIZE_DWA20011201_HPP +# define ARG_TUPLE_SIZE_DWA20011201_HPP + +namespace boost { namespace python { namespace detail { + +// Computes (at compile-time) the number of elements that a Python +// argument tuple must have in order to be passed to a wrapped C++ +// (member) function of the given type. +template struct arg_tuple_size; + +# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__BORLANDC__) + +''' + + gen_functions( +'''template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = %n); +}; + +''', free_function_args) + + + '\n' + + gen_functions( +'''template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = %+); +}; + +''', member_function_args, '') + + +'''# else + +// We will use the "sizeof() trick" to work around the lack of +// partial specialization in MSVC6 and its broken-ness in borland. +// See http://opensource.adobe.com or +// http://groups.yahoo.com/group/boost/message/5441 for +// more examples + +// This little package is used to transmit the number of arguments +// from the helper functions below to the sizeof() expression below. +// Because we can never have an array of fewer than 1 element, we +// add 1 to n and then subtract 1 from the result of sizeof() below. +template +struct char_array +{ + char elements[n+1]; +}; + +// The following helper functions are never actually called, since +// they are only used within a sizeof() expression, but the type of +// their return value is used to discriminate between various free +// and member function pointers at compile-time. + +''' + + gen_functions( +'''template +char_array<%n> arg_tuple_size_helper(R (*)(%(A%+%:, %))); + +''', free_function_args) + + + reduce(lambda x,y: x+'\n'+y + , map( + lambda cv: gen_functions( +'''template +char_array<%+> arg_tuple_size_helper(R (A0::*)(%(A%+%:, %))%1); + +''', member_function_args, cv) + , _cv_qualifiers)) + + ''' +template +struct arg_tuple_size +{ + // The sizeof() magic happens here + BOOST_STATIC_CONSTANT(std::size_t, value + = sizeof(arg_tuple_size_helper(F(0)).elements) - 1); +}; +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +}}} // namespace boost::python::detail + +#endif // ARG_TUPLE_SIZE_DWA20011201_HPP +''') + +if __name__ == '__main__': + import sys + + if len(sys.argv) == 1: + member_function_args = 5 + free_function_args = 6 + else: + member_function_args = int(sys.argv[1]) + if len(sys.argv) > 2: + free_function_args = int(sys.argv[2]) + else: + free_function_args = member_function_args + + print gen_arg_tuple_size(member_function_args, free_function_args) + + diff --git a/src/gen_function.py b/src/gen_function.py index ac24ac18..dba53c3b 100644 --- a/src/gen_function.py +++ b/src/gen_function.py @@ -1,3 +1,60 @@ +r""" +>>> template = ''' template +... static PyObject* call( %1(T::*pmf)(%(A%+%:, %))%2, PyObject* args, PyObject* ) { +... PyObject* self; +... %( PyObject* a%+; +... %) if (!PyArg_ParseTuple(args, const_cast("O%(O%)"), &self%(, &a%+%))) +... return 0; +... T& target = from_python(self, type()); +... %3to_python((target.*pmf)(%( +... from_python(a%+, type())%:,%) +... ));%4 +... }''' + +>>> print gen_function(template, 0, 'R ', '', 'return ', '') + template + static PyObject* call( R (T::*pmf)(), PyObject* args, PyObject* ) { + PyObject* self; + if (!PyArg_ParseTuple(args, const_cast("O"), &self)) + return 0; + T& target = from_python(self, type()); + return to_python((target.*pmf)( + )); + } + +>>> print gen_function(template, 2, 'R ', '', 'return ', '') + template + static PyObject* call( R (T::*pmf)(A1, A2), PyObject* args, PyObject* ) { + PyObject* self; + PyObject* a1; + PyObject* a2; + if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) + return 0; + T& target = from_python(self, type()); + return to_python((target.*pmf)( + from_python(a1, type()), + from_python(a2, type()) + )); + } + +>>> print gen_function(template, 3, 'void ', ' const', '', '\n'+8*' ' + 'return none();') + template + static PyObject* call( void (T::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* ) { + PyObject* self; + PyObject* a1; + PyObject* a2; + PyObject* a3; + if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) + return 0; + T& target = from_python(self, type()); + to_python((target.*pmf)( + from_python(a1, type()), + from_python(a2, type()), + from_python(a3, type()) + )); + return none(); + } +""" import string def _find(s, sub, start=0, end=None): @@ -35,19 +92,19 @@ def _gen_common_key(key, n, args, fill = _raise_no_argument): else: return key -def _gen_arg(template, n, args, delimiter = '%', fill = _raise_no_argument): +def _gen_arg(template, n, args, fill = _raise_no_argument): result = '' i = 0 while i < len(template): # until the template is consumed - # consume everything up to the first delimiter - delimiter_pos = _find(template, delimiter, i) + # consume everything up to the first '%' + delimiter_pos = _find(template, '%', i) result = result + template[i:delimiter_pos] - # The start position of whatever comes after the delimiter+key + # The start position of whatever comes after the '%'+key start = delimiter_pos + 2 key = template[start - 1 : start] # the key character. If there were no - # delimiters left, key will be empty + # '%'s left, key will be empty if 0 and key == 'n': result = result + `n` @@ -64,7 +121,7 @@ def gen_function(template, n, *args, **keywords): Generate a function declaration based on the given template. Sections of the template between '%(', '%)' pairs are repeated n times. If '%:' - appears in the middle, it denotes the beginning of a delimiter. + appears in the middle, it denotes the beginning of a '%'. Sections of the template between '%{', '%}' pairs are ommitted if n == 0. @@ -95,7 +152,7 @@ def gen_function(template, n, *args, **keywords): for example, >>> gen_function('%1 abc%x(%(int a%n%:, %));%{ // all args are ints%}', 2, 'void') - 'void abc2(int a1, int a2); // all args are ints' + 'void abc2(int a0, int a1); // all args are ints' >>> gen_function('%1 abc(%(int a%n%:, %));%{ // all args are ints%}', 0, 'x') 'x abc();' @@ -109,102 +166,54 @@ def gen_function(template, n, *args, **keywords): >>> gen_function('abc%[k%:v%]', 0, fill = lambda key, n, args, value = None: '<' + key + ',' + value + '>') 'abc' - >>> template = ''' template - ... static PyObject* call( %1(T::*pmf)(%(A%n%:, %))%2, PyObject* args, PyObject* /* keywords */ ) { - ... PyObject* self; - ... %( PyObject* a%n; - ... %) if (!PyArg_ParseTuple(args, const_cast("O%(O%)"), &self%(, &a%n%))) - ... return 0; - ... T& target = from_python(self, type()); - ... %3to_python((target.*pmf)(%( - ... from_python(a%n, type())%:,%) - ... ));%4 - ... }''' - - >>> print gen_function(template, 0, 'R ', '', 'return ', '') - template - static PyObject* call( R (T::*pmf)(), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)( - )); - } - - >>> print gen_function(template, 2, 'R ', '', 'return ', '') - template - static PyObject* call( R (T::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)( - from_python(a1, type()), - from_python(a2, type()) - )); - } - - >>> print gen_function(template, 3, 'void ', ' const', '', '\n'+8*' ' + 'return none();') - template - static PyObject* call( void (T::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) - return 0; - T& target = from_python(self, type()); - to_python((target.*pmf)( - from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()) - )); - return none(); - } """ - delimiter = keywords.get('delimiter', '%') + expand = (lambda s, n = n: + apply(gen_function, (s, n) + args, keywords)) + fill = keywords.get('fill', _raise_no_argument); result = '' i = 0 while i < len(template): # until the template is consumed - # consume everything up to the first delimiter - delimiter_pos = _find(template, delimiter, i) + # consume everything up to the first '%' + delimiter_pos = _find(template, '%', i) result = result + template[i:delimiter_pos] - # The start position of whatever comes after the delimiter+key + # The start position of whatever comes after the '%'+key start = delimiter_pos + 2 key = template[start - 1 : start] # the key character. If there were no - # delimiters left, key will be empty + # '%'s left, key will be empty pairs = { '(':')', '{':'}', '[':']' } if key in pairs.keys(): - end = string.find(template, delimiter + pairs[key], start) - assert end >= 0, "Matching '" + delimiter + pairs[key] +"' not found!" + end = string.find(template, '%' + pairs[key], start) + assert end >= 0, "Matching '" + '%' + pairs[key] +"' not found!" delimiter_pos = end if key == '{': if n > 0: - result = result + gen_function(template[start:end], n, args, delimiter) + result = result + expand(template[start:end]) else: - separator_pos = _find(template, delimiter + ':', - start, end) + separator_pos = _find(template, '%:', start, end) remainder = template[separator_pos+2 : end] if key == '(': - for x in range(1, n + 1): - result = result + _gen_arg(template[start:separator_pos], x, args, - delimiter) - if x != n: - result = result + remainder + for x in range(n): + + iteration = expand( + template[start:separator_pos], x) + + result = result + expand(iteration, x) + + if x != n - 1: + result = result + expand(remainder, x) else: - result = result + fill(template[start:separator_pos], n, args, value = remainder) + function_result = fill( + template[start:separator_pos], n, args, value = remainder) + result = result + expand(function_result) else: - result = result + _gen_common_key(key, n, args, fill) + result = result + expand(_gen_common_key(key, n, args, fill)) i = delimiter_pos + 2 @@ -218,8 +227,8 @@ def gen_functions(template, n, *args, **keywords): >>> print gen_functions('%1 abc(%(int a%n%:, %));%{ // all args are ints%}\n', 2, 'void'), void abc(); - void abc(int a1); // all args are ints - void abc(int a1, int a2); // all args are ints + void abc(int a0); // all args are ints + void abc(int a0, int a1); // all args are ints """ fill = keywords.get('fill', _raise_no_argument); From c6fd3c47a4633221b41213ffb9f2249ee3f76b99 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 15 Dec 2001 04:57:18 +0000 Subject: [PATCH 0134/1042] Makefile and example setup batch file for Win32 Metrowerks Codewarrior 7. [SVN r12063] --- build/win32_mwcc.mak | 149 +++++++++++++++++++++++++++++++++++++ build/win32_mwcc_setup.bat | 2 + 2 files changed, 151 insertions(+) create mode 100755 build/win32_mwcc.mak create mode 100755 build/win32_mwcc_setup.bat diff --git a/build/win32_mwcc.mak b/build/win32_mwcc.mak new file mode 100755 index 00000000..ac054c07 --- /dev/null +++ b/build/win32_mwcc.mak @@ -0,0 +1,149 @@ +# Usage: +# +# make copy Copy the sources and tests +# make Compile all sources +# make test Run doctest tests +# make clean Remove all object files +# make del Remove the sources and tests +# +# Revision history: +# 14 Dec 01 derived from vc60.mak (R.W. Grosse-Kunstleve) + +ROOT=R: +BOOST_WIN="$(ROOT)\boostdev" +BOOST_UNIX=$(HOME)/boost + +#PYEXE="C:\Program files\Python\python.exe" +#PYINC=-I"C:\Program files\Python\include" +#PYLIB="C:\Program files\Python\libs\python15.lib" +PYEXE="C:\Python21\python.exe" +PYINC=-I"C:\Python21\include" +PYLIB="C:\Python21\libs\python21.lib" + +STDOPTS=-gccinc -prefix UseDLLPrefix.h +WARNOPTS=-warn on,nounusedexpr,nounused +OPTOPTS=-O + +CPP=mwcc +CPPOPTS=$(STDOPTS) $(WARNOPTS) $(OPTOPTS) \ + $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) + +LD=mwld +LDOPTS=-export dllexport -shared + +OBJ=classes.obj conversions.obj extension_class.obj functions.obj \ + init_function.obj module_builder.obj \ + objects.obj types.obj cross_module.obj + +.SUFFIXES: .obj .cpp + +all: libboost_python.lib \ + boost_python_test.pyd \ + abstract.pyd \ + getting_started1.pyd getting_started2.pyd \ + simple_vector.pyd \ + do_it_yourself_convts.pyd \ + nested.pyd \ + pickle1.pyd pickle2.pyd pickle3.pyd \ + noncopyable_export.pyd noncopyable_import.pyd \ + ivect.pyd dvect.pyd \ + richcmp1.pyd richcmp2.pyd richcmp3.pyd + +libboost_python.lib: $(OBJ) + $(LD) -library -o libboost_python.lib $(OBJ) + +boost_python_test.pyd: $(OBJ) comprehensive.obj + $(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) -o boost_python_test.pyd + +abstract.pyd: $(OBJ) abstract.obj + $(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) -o abstract.pyd + +getting_started1.pyd: $(OBJ) getting_started1.obj + $(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) -o getting_started1.pyd + +getting_started2.pyd: $(OBJ) getting_started2.obj + $(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) -o getting_started2.pyd + +simple_vector.pyd: $(OBJ) simple_vector.obj + $(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) -o simple_vector.pyd + +do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.obj + $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.obj $(PYLIB) -o do_it_yourself_convts.pyd + +nested.pyd: $(OBJ) nested.obj + $(LD) $(LDOPTS) $(OBJ) nested.obj $(PYLIB) -o nested.pyd + +pickle1.pyd: $(OBJ) pickle1.obj + $(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) -o pickle1.pyd + +pickle2.pyd: $(OBJ) pickle2.obj + $(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) -o pickle2.pyd + +pickle3.pyd: $(OBJ) pickle3.obj + $(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) -o pickle3.pyd + +noncopyable_export.pyd: $(OBJ) noncopyable_export.obj + $(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) -o noncopyable_export.pyd + +noncopyable_import.pyd: $(OBJ) noncopyable_import.obj + $(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) -o noncopyable_import.pyd + +ivect.pyd: $(OBJ) ivect.obj + $(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) -o ivect.pyd + +dvect.pyd: $(OBJ) dvect.obj + $(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) -o dvect.pyd + +richcmp1.pyd: $(OBJ) richcmp1.obj + $(LD) $(LDOPTS) $(OBJ) richcmp1.obj $(PYLIB) -o richcmp1.pyd + +richcmp2.pyd: $(OBJ) richcmp2.obj + $(LD) $(LDOPTS) $(OBJ) richcmp2.obj $(PYLIB) -o richcmp2.pyd + +richcmp3.pyd: $(OBJ) richcmp3.obj + $(LD) $(LDOPTS) $(OBJ) richcmp3.obj $(PYLIB) -o richcmp3.pyd + +.cpp.obj: + $(CPP) $(CPPOPTS) -c $*.cpp + +test: + $(PYEXE) comprehensive.py + $(PYEXE) test_abstract.py + $(PYEXE) test_getting_started1.py + $(PYEXE) test_getting_started2.py + $(PYEXE) test_simple_vector.py + $(PYEXE) test_do_it_yourself_convts.py + $(PYEXE) test_nested.py + $(PYEXE) test_pickle1.py + $(PYEXE) test_pickle2.py + $(PYEXE) test_pickle3.py + $(PYEXE) test_cross_module.py + $(PYEXE) test_richcmp1.py + $(PYEXE) test_richcmp2.py + $(PYEXE) test_richcmp3.py + +clean: + -del *.obj + -del *.lib + -del *.exp + -del *.idb + -del *.pyd + -del *.pyc + +softlinks: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks + +unlink: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink + +cp: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp + +rm: + python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm + +copy: + $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy + +del: + $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del diff --git a/build/win32_mwcc_setup.bat b/build/win32_mwcc_setup.bat new file mode 100755 index 00000000..d42a60cf --- /dev/null +++ b/build/win32_mwcc_setup.bat @@ -0,0 +1,2 @@ +"c:\program files\metrowerks\codewarrior\other metrowerks tools\command line tools\cwenv.bat" +set MWWinx86LibraryFiles=MSL_All-DLL_x86.lib;gdi32.lib;user32.lib;kernel32.lib From 3a86a69964fb3d53f7672861c4ac7d160ae78342 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 15 Dec 2001 04:59:11 +0000 Subject: [PATCH 0135/1042] Restore Python <2.2 compatibility (config.h, pyconfig.h). [SVN r12064] --- include/boost/python/detail/wrap_python.hpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index 1ad88ab6..b6e23b66 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -72,11 +72,19 @@ typedef int pid_t; # define _MSC_VER 900 # endif -# include +# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 +# include +# else +# include +# endif # undef hypot // undo the evil #define left by Python. # elif defined(__BORLANDC__) -# include +# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 +# include +# else +# include +# endif # undef HAVE_HYPOT # define HAVE_HYPOT 1 # elif defined(_MSC_VER) From 5134fb2ec18a96bd9735c39873b0ba670627f1e2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 15 Dec 2001 22:59:48 +0000 Subject: [PATCH 0136/1042] scott snyder's fixes to maintain 1.5.2 compatibility [SVN r12065] --- src/types.cpp | 10 ++---- test/comprehensive.py | 84 +++++++++++++++++++++++-------------------- 2 files changed, 49 insertions(+), 45 deletions(-) diff --git a/src/types.cpp b/src/types.cpp index fe108225..c7e1f167 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -566,18 +566,12 @@ bool add_capability_richcompare(type_object_base::capability capability, PyTypeO return false; } -#if PYTHON_API_VERSION >= 1010 -# define ENABLE_INPLACE_CAPABILITY1 \ - dest->tp_flags |= Py_TPFLAGS_HAVE_INPLACEOPS; -#else -# define ENABLE_INPLACE_CAPABILITY1 -#endif #define ENABLE_INPLACE_CAPABILITY(field) \ case type_object_base::number_##field: \ create_method_table_if_null(dest->tp_as_number); \ dest->tp_as_number->nb_##field = &do_instance_nb_##field; \ detail::shared_pod_manager::replace_if_equal(dest->tp_as_number); \ - ENABLE_INPLACE_CAPABILITY1 \ + dest->tp_flags |= Py_TPFLAGS_HAVE_INPLACEOPS; \ return true bool add_capability_inplace(type_object_base::capability capability, PyTypeObject* dest) @@ -585,6 +579,7 @@ bool add_capability_inplace(type_object_base::capability capability, PyTypeObjec assert(dest != 0); switch (capability) { +#if PYTHON_API_VERSION >= 1010 ENABLE_INPLACE_CAPABILITY (inplace_add); ENABLE_INPLACE_CAPABILITY (inplace_subtract); ENABLE_INPLACE_CAPABILITY (inplace_multiply); @@ -596,6 +591,7 @@ bool add_capability_inplace(type_object_base::capability capability, PyTypeObjec ENABLE_INPLACE_CAPABILITY (inplace_and); ENABLE_INPLACE_CAPABILITY (inplace_or); ENABLE_INPLACE_CAPABILITY (inplace_xor); +#endif default: return false; } diff --git a/test/comprehensive.py b/test/comprehensive.py index b4ae5679..c49a4add 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -334,7 +334,8 @@ Special member attributes. Tests courtesy of Barry Scott >> import sys - >>> if sys.version_info[0] < 2 or ( sys.version_info[0] == 2 and + >>> if not sys.__dict__.has_key('version_info') or \ + ... sys.version_info[0] < 2 or ( sys.version_info[0] == 2 and ... sys.version_info[1] < 2 ): ... assert dir(df) == [] ... assert dir(db) == [] @@ -1069,43 +1070,6 @@ test inheritB2 Traceback (innermost last): TypeError: bad operand type(s) for pow() - >>> ii = Int(1) - >>> ii += Int(2) - >>> ii.i() - 3 - >>> ii -= Int(1) - >>> ii.i() - 2 - >>> ii *= Int(3) - >>> ii.i() - 6 - >>> ii /= Int(2) - >>> ii.i() - 3 - >>> ii <<= Int(2) - >>> ii.i() - 12 - >>> ii >>= Int(1) - >>> ii.i() - 6 - >>> ii &= Int(5) - >>> ii.i() - 4 - >>> ii |= Int(9) - >>> ii.i() - 13 - >>> ii ^= Int(7) - >>> ii.i() - 10 - >>> ii %= Int(4) - >>> ii.i() - 2 - >>> ii **= Int(3) - >>> ii.i() - 8 - >>> ii.j() - 11 - Test operator export to a subclass # force method table sharing @@ -1226,6 +1190,50 @@ test methodologies for wrapping functions that return a pointer ''' #' +__test__ = {} +import sys + +# Inplace ops only exist in python 2.1 or later. +if sys.hexversion >= 0x02010000: + __test__['inplacetests'] = r''' + >>> ii = Int(1) + >>> ii += Int(2) + >>> ii.i() + 3 + >>> ii -= Int(1) + >>> ii.i() + 2 + >>> ii *= Int(3) + >>> ii.i() + 6 + >>> ii /= Int(2) + >>> ii.i() + 3 + >>> ii <<= Int(2) + >>> ii.i() + 12 + >>> ii >>= Int(1) + >>> ii.i() + 6 + >>> ii &= Int(5) + >>> ii.i() + 4 + >>> ii |= Int(9) + >>> ii.i() + 13 + >>> ii ^= Int(7) + >>> ii.i() + 10 + >>> ii %= Int(4) + >>> ii.i() + 2 + >>> ii **= Int(3) + >>> ii.i() + 8 + >>> ii.j() + 11 +''' + from boost_python_test import * # pickle requires these derived classes to be From f9e6933840ffe0af5049eae3dcb73633ec8cce33 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 16 Dec 2001 06:00:03 +0000 Subject: [PATCH 0137/1042] Use "call", otherwise the "set" command is not executed. [SVN r12066] --- build/win32_mwcc_setup.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/win32_mwcc_setup.bat b/build/win32_mwcc_setup.bat index d42a60cf..30f84be8 100755 --- a/build/win32_mwcc_setup.bat +++ b/build/win32_mwcc_setup.bat @@ -1,2 +1,2 @@ -"c:\program files\metrowerks\codewarrior\other metrowerks tools\command line tools\cwenv.bat" -set MWWinx86LibraryFiles=MSL_All-DLL_x86.lib;gdi32.lib;user32.lib;kernel32.lib +call "c:\program files\metrowerks\codewarrior\other metrowerks tools\command line tools\cwenv.bat" +set MWWinx86LibraryFiles=MSL_All-DLL_x86.lib;gdi32.lib;user32.lib;kernel32.lib From e65ca4ccac7bfa510f10d011d85502c108b1b64d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 16 Dec 2001 17:58:23 +0000 Subject: [PATCH 0138/1042] Python 1.5 compatibility fixes [SVN r12072] --- test/comprehensive.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 61f56407..d25b131a 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -1093,6 +1093,7 @@ void init_module(boost::python::module_builder& m) // export non-operator function as heterogeneous reverse-argument operator int_class.def(&rmul, "__rmul__"); +#if PYTHON_API_VERSION >= 1010 // inplace operators. int_class.def(&int_iadd, "__iadd__"); int_class.def(&int_isub, "__isub__"); @@ -1105,6 +1106,7 @@ void init_module(boost::python::module_builder& m) int_class.def(&int_iand, "__iand__"); int_class.def(&int_ior, "__ior__"); int_class.def(&int_ixor, "__ixor__"); +#endif boost::python::class_builder enum_owner(m, "EnumOwner"); From bed2c8a371b2e181c5215604629abb641b9751df Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 16 Dec 2001 18:20:26 +0000 Subject: [PATCH 0139/1042] no message [SVN r12076] --- include/boost/python/detail/config.hpp | 12 +++++++----- include/boost/python/detail/wrap_python.hpp | 8 +++++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index f814aba0..ff22e78e 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -57,10 +57,12 @@ # define BOOST_CSTD_ std # endif -#if defined(_WIN32) || defined(__CYGWIN__) -# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name() -#else -# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name() -#endif +# ifndef BOOST_PYTHON_MODULE_INIT +# if defined(_WIN32) || defined(__CYGWIN__) +# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name() +# else +# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name() +# endif +# endif #endif // CONFIG_DWA052200_H_ diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index b6e23b66..34a9c2b5 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -72,7 +72,7 @@ typedef int pid_t; # define _MSC_VER 900 # endif -# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 +# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2 # include # else # include @@ -80,7 +80,7 @@ typedef int pid_t; # undef hypot // undo the evil #define left by Python. # elif defined(__BORLANDC__) -# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 +# if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2 # include # else # include @@ -88,7 +88,9 @@ typedef int pid_t; # undef HAVE_HYPOT # define HAVE_HYPOT 1 # elif defined(_MSC_VER) -# include // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX +# ifdef __cplusplus +# include // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX +# endif # endif #endif // _WIN32 From 291c36df05902fd1d73cd6131ba42c17f592b4fe Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 17 Dec 2001 05:49:24 +0000 Subject: [PATCH 0140/1042] Integrated Scott Snyder's nested class patch [SVN r12080] --- doc/exporting_classes.html | 6 ++++++ include/boost/python/class_builder.hpp | 16 ++++++++++++++++ test/comprehensive.cpp | 20 ++++++++++++++++++++ test/comprehensive.hpp | 4 ++++ test/comprehensive.py | 10 +++++++++- 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/doc/exporting_classes.html b/doc/exporting_classes.html index e5932e70..61c5ef88 100644 --- a/doc/exporting_classes.html +++ b/doc/exporting_classes.html @@ -98,6 +98,12 @@ Notes:
    • Any function added to a class whose initial argument matches the class (or any base) will act like a member function in Python. + +
    • To define a nested class, just pass the enclosing +class_builder (instead of a module_builder) as the +first argument to the nested class_builder's constructor. + +

    We can even make a subclass of hello.world: diff --git a/include/boost/python/class_builder.hpp b/include/boost/python/class_builder.hpp index 4a9ec1b2..fe2a7b74 100644 --- a/include/boost/python/class_builder.hpp +++ b/include/boost/python/class_builder.hpp @@ -25,6 +25,22 @@ class class_builder module.add(ref(as_object(m_class.get()), ref::increment_count), name); } + template + class_builder(class_builder& cls, const char* name) + : m_class(new detail::extension_class(name)) + { + cls.add(ref(as_object(m_class.get()), ref::increment_count), name); + } + + template + class_builder(detail::extension_class* cls, + const char* name) + : m_class(new detail::extension_class(name)) + { + cls->set_attribute(name, + ref(as_object(m_class.get()), ref::increment_count)); + } + ~class_builder() {} diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index d25b131a..6c7cc4d3 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -67,6 +67,16 @@ Foo::PythonClass::PythonClass(boost::python::module_builder& m) def(&Foo::add_len, "add_len", &FooCallback::default_add_len); // Since pure() is pure virtual, we are leaving it undefined. + + // And the nested classes. + boost::python::class_builder foo_a(*this, "Foo_A"); + foo_a.def(boost::python::constructor<>()); + foo_a.def(&Foo::Foo_A::mumble, "mumble"); + + boost::python::class_builder foo_b(get_extension_class(), + "Foo_B"); + foo_b.def(boost::python::constructor<>()); + foo_b.def(&Foo::Foo_B::mumble, "mumble"); } BarPythonClass::BarPythonClass(boost::python::module_builder& m) @@ -223,6 +233,16 @@ const char* Foo::mumble() return "mumble"; } +const char* Foo::Foo_A::mumble() +{ + return "mumble a"; +} + +const char* Foo::Foo_B::mumble() +{ + return "mumble b"; +} + void Foo::set(long x) { m_x = x; diff --git a/test/comprehensive.hpp b/test/comprehensive.hpp index ed90f061..deb68a88 100644 --- a/test/comprehensive.hpp +++ b/test/comprehensive.hpp @@ -42,6 +42,10 @@ class Foo // prohibit copying, proving that it doesn't choke std::string call_pure(); // call a pure virtual fuction int call_add_len(const char* s) const; // virtual function with a default implementation + // A couple nested classs. + struct Foo_A { const char* mumble(); }; + struct Foo_B { const char* mumble(); }; + private: // by default, sum the held value and the length of s virtual int add_len(const char* s) const; diff --git a/test/comprehensive.py b/test/comprehensive.py index c49a4add..7d0bec79 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -230,6 +230,14 @@ Polymorphism also works: >>> baz.get_foo_value(polymorphic_foo) 1000 +Simple nested class test: + >>> foo_a = Foo.Foo_A() + >>> foo_a.mumble() + 'mumble a' + >>> foo_b = Foo.Foo_B() + >>> foo_b.mumble() + 'mumble b' + Pickling tests: >>> world.__module__ @@ -343,7 +351,7 @@ Special member attributes. Tests courtesy of Barry Scott Date: Mon, 17 Dec 2001 16:59:54 +0000 Subject: [PATCH 0141/1042] Integrating Andreas Zieringer's shared library implementation. Modified Files: classes.hpp conversions.hpp cross_module.hpp errors.hpp module_builder.hpp objects.hpp operators.hpp detail/config.hpp detail/extension_class.hpp detail/functions.hpp detail/init_function.hpp detail/signatures.hpp detail/singleton.hpp detail/types.hpp detail/void_adaptor.hpp [SVN r12083] --- include/boost/python/detail/config.hpp | 64 +++++++++++++++++++ .../boost/python/detail/extension_class.hpp | 22 +++---- include/boost/python/detail/functions.hpp | 4 +- include/boost/python/detail/init_function.hpp | 2 +- include/boost/python/detail/signatures.hpp | 2 +- include/boost/python/detail/singleton.hpp | 2 +- include/boost/python/detail/types.hpp | 6 +- include/boost/python/detail/void_adaptor.hpp | 2 +- 8 files changed, 84 insertions(+), 20 deletions(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index ff22e78e..0fc1093a 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -65,4 +65,68 @@ # endif # endif +/***************************************************************************** + * + * Set up dll import/export options: + * + ****************************************************************************/ + +// backwards compatibility: +#ifdef BOOST_RE_STATIC_LIB +# define BOOST_PYTHON_STATIC_LINK +#endif + +#if defined(BOOST_MSVC) && defined(_DLL) +# define BOOST_PYTHON_HAS_DLL_RUNTIME +#endif + +#if defined(__BORLANDC__) && defined(_RTLDLL) +# define BOOST_PYTHON_HAS_DLL_RUNTIME +#endif + +#if defined(__ICL) && defined(_DLL) +# define BOOST_PYTHON_HAS_DLL_RUNTIME +#endif + +#if defined(BOOST_PYTHON_HAS_DLL_RUNTIME) && !defined(BOOST_PYTHON_STATIC_LINK) +# if defined(BOOST_PYTHON_SOURCE) +# define BOOST_PYTHON_DECL __declspec(dllexport) +# define BOOST_PYTHON_BUILD_DLL +# else +# define BOOST_PYTHON_DECL __declspec(dllimport) +# endif +#endif + +#ifndef BOOST_PYTHON_DECL +# define BOOST_PYTHON_DECL +#endif + +#if (defined(BOOST_MSVC) || defined(__BORLANDC__)) && !defined(BOOST_PYTHON_NO_LIB) && !defined(BOOST_PYTHON_SOURCE) +# include +#endif + +// Borland C++ Fix/error check: +#if defined(__BORLANDC__) +# if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551) + // problems with std::basic_string and dll RTL: +# if defined(_RTLDLL) && defined(_RWSTD_COMPILE_INSTANTIATE) +# ifdef BOOST_PYTHON_BUILD_DLL +# error _RWSTD_COMPILE_INSTANTIATE must not be defined when building regex++ as a DLL +# else +# pragma warn defining _RWSTD_COMPILE_INSTANTIATE when linking to the DLL version of the RTL may produce memory corruption problems in std::basic_string, as a result of separate versions of basic_string's static data in the RTL and you're exe/dll: be warned!! +# endif +# endif +# ifndef _RTLDLL + // this is harmless for a staic link: +# define _RWSTD_COMPILE_INSTANTIATE +# endif +# endif + // + // VCL support: + // if we're building a console app then there can't be any VCL (can there?) +# if !defined(__CONSOLE__) && !defined(_NO_VCL) +# define BOOST_PYTHON_USE_VCL +# endif +#endif + #endif // CONFIG_DWA052200_H_ diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index f7be9afb..00f9b6b4 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -52,12 +52,12 @@ template struct operand_select; template struct choose_unary_op; template struct define_operator; -meta_class* extension_meta_class(); -extension_instance* get_extension_instance(PyObject* p); -void report_missing_instance_data(extension_instance*, class_t*, const std::type_info&); -void report_missing_ptr_data(extension_instance*, class_t*, const std::type_info&); -void report_missing_class_object(const std::type_info&); -void report_released_smart_pointer(const std::type_info&); +BOOST_PYTHON_DECL meta_class* extension_meta_class(); +BOOST_PYTHON_DECL extension_instance* get_extension_instance(PyObject* p); +BOOST_PYTHON_DECL void report_missing_instance_data(extension_instance*, class_t*, const std::type_info&); +BOOST_PYTHON_DECL void report_missing_ptr_data(extension_instance*, class_t*, const std::type_info&); +BOOST_PYTHON_DECL void report_missing_class_object(const std::type_info&); +BOOST_PYTHON_DECL void report_released_smart_pointer(const std::type_info&); template T* check_non_null(T* p) @@ -71,7 +71,7 @@ template class held_instance; typedef void* (*conversion_function_ptr)(void*); -struct base_class_info +struct BOOST_PYTHON_DECL base_class_info { base_class_info(extension_class_base* t, conversion_function_ptr f) :class_object(t), convert(f) @@ -85,7 +85,7 @@ typedef base_class_info derived_class_info; struct add_operator_base; -class extension_class_base : public class_t +class BOOST_PYTHON_DECL extension_class_base : public class_t { public: extension_class_base(const char* name); @@ -378,7 +378,7 @@ namespace detail { template class instance_holder; -class read_only_setattr_function : public function +class BOOST_PYTHON_DECL read_only_setattr_function : public function { public: read_only_setattr_function(const char* name); @@ -725,7 +725,7 @@ public: // Abstract base class for all obj holders. Base for template class // instance_holder<>, below. -class instance_holder_base +class BOOST_PYTHON_DECL instance_holder_base { public: virtual ~instance_holder_base() {} @@ -813,7 +813,7 @@ class instance_ptr_holder : public instance_holder PtrType m_ptr; }; -class extension_instance : public instance +class BOOST_PYTHON_DECL extension_instance : public instance { public: extension_instance(PyTypeObject* class_); diff --git a/include/boost/python/detail/functions.hpp b/include/boost/python/detail/functions.hpp index eff05d65..486d73f9 100644 --- a/include/boost/python/detail/functions.hpp +++ b/include/boost/python/detail/functions.hpp @@ -29,7 +29,7 @@ class extension_instance; // function -- // the common base class for all overloadable function and method objects // supplied by the library. -class function : public python_object +class BOOST_PYTHON_DECL function : public python_object { public: function(); @@ -201,7 +201,7 @@ inline function* new_virtual_function( // the expression a.b where a is an instance or extension_instance object and b // is a callable object not found in the obj namespace but on its class or // a base class. -class bound_function : public python_object +class BOOST_PYTHON_DECL bound_function : public python_object { public: static bound_function* create(const ref& target, const ref& fn); diff --git a/include/boost/python/detail/init_function.hpp b/include/boost/python/detail/init_function.hpp index c0c50272..69df703d 100644 --- a/include/boost/python/detail/init_function.hpp +++ b/include/boost/python/detail/init_function.hpp @@ -230,7 +230,7 @@ struct init_function } }; -class init : public function +class BOOST_PYTHON_DECL init : public function { private: // override function hook PyObject* do_call(PyObject* args, PyObject* keywords) const; diff --git a/include/boost/python/detail/signatures.hpp b/include/boost/python/detail/signatures.hpp index 2be75b52..e216f688 100644 --- a/include/boost/python/detail/signatures.hpp +++ b/include/boost/python/detail/signatures.hpp @@ -17,7 +17,7 @@ namespace boost { namespace python { namespace detail { // A stand-in for the built-in void. This one can be passed to functions and // (under MSVC, which has a bug, be used as a default template type parameter). -struct void_t {}; +struct BOOST_PYTHON_DECL void_t {}; } // An envelope in which type information can be delivered for the purposes diff --git a/include/boost/python/detail/singleton.hpp b/include/boost/python/detail/singleton.hpp index 07d794ac..3e7d91af 100644 --- a/include/boost/python/detail/singleton.hpp +++ b/include/boost/python/detail/singleton.hpp @@ -13,7 +13,7 @@ namespace boost { namespace python { namespace detail { -struct empty {}; +struct BOOST_PYTHON_DECL empty {}; template struct singleton : Base { diff --git a/include/boost/python/detail/types.hpp b/include/boost/python/detail/types.hpp index 954e0213..f4e62f88 100644 --- a/include/boost/python/detail/types.hpp +++ b/include/boost/python/detail/types.hpp @@ -37,7 +37,7 @@ namespace detail { class instance_holder_base; -class type_object_base : public python_type +class BOOST_PYTHON_DECL type_object_base : public python_type { public: explicit type_object_base(PyTypeObject* type_type); @@ -327,7 +327,7 @@ PyObject* reprable::instance_repr(PyObject* obj) const // memory. Reference counting is used to free unused memory. // This is useful because method tables of related extension classes tend // to be identical, so less memory is needed for them. - class shared_pod_manager + class BOOST_PYTHON_DECL shared_pod_manager { typedef std::pair holder; typedef std::vector storage; @@ -394,7 +394,7 @@ PyObject* reprable::instance_repr(PyObject* obj) const }; - void add_capability(type_object_base::capability capability, + BOOST_PYTHON_DECL void add_capability(type_object_base::capability capability, PyTypeObject* dest); // This macro gets the length of an array as a compile-time constant, and will diff --git a/include/boost/python/detail/void_adaptor.hpp b/include/boost/python/detail/void_adaptor.hpp index c2ecc2b0..3d60e4bf 100644 --- a/include/boost/python/detail/void_adaptor.hpp +++ b/include/boost/python/detail/void_adaptor.hpp @@ -8,7 +8,7 @@ namespace boost { namespace python { namespace detail { - extern PyObject arbitrary_object; + BOOST_PYTHON_DECL extern PyObject arbitrary_object; template struct void_adaptor From d4b215a66b1e2c6f18df61ae2e5d79ce66a146f0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 17 Dec 2001 17:00:53 +0000 Subject: [PATCH 0142/1042] Integrating Andreas Zieringer's shared lib changes Modified Files: build/Jamfile build/win32_mwcc_setup.bat src/classes.cpp src/conversions.cpp src/cross_module.cpp src/extension_class.cpp src/functions.cpp src/init_function.cpp src/module_builder.cpp src/objects.cpp src/types.cpp [SVN r12084] --- build/Jamfile | 8 +++++++- src/classes.cpp | 2 ++ src/conversions.cpp | 2 ++ src/cross_module.cpp | 2 ++ src/extension_class.cpp | 2 ++ src/functions.cpp | 2 ++ src/init_function.cpp | 2 ++ src/module_builder.cpp | 2 ++ src/objects.cpp | 2 ++ src/types.cpp | 2 ++ 10 files changed, 25 insertions(+), 1 deletion(-) diff --git a/build/Jamfile b/build/Jamfile index c56bf47c..78d1e84a 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -84,7 +84,13 @@ lib libboost_python : ../src/$(CPP_SOURCES).cpp true $(PYTHON_PROPERTIES) ; - +dll libboost_python$(SUFDLL[1]) : ../src/$(CPP_SOURCES).cpp + # requirements + : $(BOOST_PYTHON_INCLUDES) + true + BOOST_RE_BUILD_DLL=1 + $(PYTHON_PROPERTIES) ; + ############# comprehensive module and test ########### bpl-test boost_python_test : ../test/comprehensive.cpp ; diff --git a/src/classes.cpp b/src/classes.cpp index 75f8a01a..c721ef5c 100644 --- a/src/classes.cpp +++ b/src/classes.cpp @@ -11,6 +11,8 @@ // 03 Mar 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve) // 03 Mar 01 bug fix: use bound_function::create() (instead of new bound_function) +#define BOOST_PYTHON_SOURCE + #include #include #include diff --git a/src/conversions.cpp b/src/conversions.cpp index c986f57b..f1534dd9 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -13,6 +13,8 @@ // 04 Mar 01 std::complex<> fixes for MSVC (Dave Abrahams) // 03 Mar 01 added: converters for [plain] char (Ralf W. Grosse-Kunstleve) +#define BOOST_PYTHON_SOURCE + #include #include #include diff --git a/src/cross_module.cpp b/src/cross_module.cpp index ea5a08de..5949be4d 100644 --- a/src/cross_module.cpp +++ b/src/cross_module.cpp @@ -8,6 +8,8 @@ 17 Apr 01 merged into boost CVS trunk (Ralf W. Grosse-Kunstleve) */ +#define BOOST_PYTHON_SOURCE + # include namespace python = boost::python; # include // MSVC6.0SP4 does not know std::fprintf diff --git a/src/extension_class.cpp b/src/extension_class.cpp index 3815a19c..e9183c82 100644 --- a/src/extension_class.cpp +++ b/src/extension_class.cpp @@ -9,6 +9,8 @@ // Revision History: // 04 Mar 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) +#define BOOST_PYTHON_SOURCE + #include #include #include diff --git a/src/functions.cpp b/src/functions.cpp index a04e2e51..ecbacf4e 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -9,6 +9,8 @@ // Revision History: // Mar 01 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) +#define BOOST_PYTHON_SOURCE + #include #include #include diff --git a/src/init_function.cpp b/src/init_function.cpp index 1667724c..1ebfa501 100644 --- a/src/init_function.cpp +++ b/src/init_function.cpp @@ -6,6 +6,8 @@ // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +#define BOOST_PYTHON_SOURCE + #include #include #include diff --git a/src/module_builder.cpp b/src/module_builder.cpp index 57eec75f..bd04a89c 100644 --- a/src/module_builder.cpp +++ b/src/module_builder.cpp @@ -6,6 +6,8 @@ // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +#define BOOST_PYTHON_SOURCE + #include namespace boost { namespace python { diff --git a/src/objects.cpp b/src/objects.cpp index 125a1eb8..70257388 100644 --- a/src/objects.cpp +++ b/src/objects.cpp @@ -8,6 +8,8 @@ // TODO: Move inline implementations from objects.cpp here +#define BOOST_PYTHON_SOURCE + #include #include diff --git a/src/types.cpp b/src/types.cpp index c7e1f167..f411aa42 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -6,6 +6,8 @@ // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +#define BOOST_PYTHON_SOURCE + #include #include // for handle_exception() #include From 460f3aebe9a68918fae1e328b85712cbea91ce3a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 17 Dec 2001 17:24:41 +0000 Subject: [PATCH 0143/1042] inital checkin [SVN r12086] --- .../python/detail/python_library_include.hpp | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 include/boost/python/detail/python_library_include.hpp diff --git a/include/boost/python/detail/python_library_include.hpp b/include/boost/python/detail/python_library_include.hpp new file mode 100644 index 00000000..903f02be --- /dev/null +++ b/include/boost/python/detail/python_library_include.hpp @@ -0,0 +1,182 @@ +/* + * + * Copyright (c) 1998-2000 + * Dr John Maddock + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Dr John Maddock makes no representations + * about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE regex_libary_include.hpp + * VERSION see + * DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers. + * Note this is an internal header file included + * by regex.hpp, do not include on its own. + */ + + +#ifndef BOOST_REGEX_LIBRARY_INCLUDE_HPP +#define BOOST_REGEX_LIBRARY_INCLUDE_HPP +#ifndef BOOST_REGEX_NO_LIB + +#if defined(BOOST_MSVC) && !defined(BOOST_REGEX_BUILD_DLL) +#ifdef __SGI_STL_PORT + #ifdef _DLL + // All these are multithreaded: + #if defined(_DEBUG) && defined(__STL_DEBUG) + #pragma comment(lib, "vc6-stlport-re300ddl.lib") + #elif defined(_DEBUG) + #pragma comment(lib, "vc6-stlport-re300dl.lib") + #elif defined(BOOST_REGEX_STATIC_LINK) + // static regex lib, dll runtime + #pragma comment(lib, "vc6-stlport-re300ls.lib") + #else // DEBUG + #pragma comment(lib, "vc6-stlport-re300l.lib") + #endif // _DEBUG + #else // _DLL + #ifdef _MT + #if defined(_DEBUG) && defined(__STL_DEBUG) + #pragma comment(lib, "vc6-stlport-re300ddm.lib") + #elif defined(_DEBUG) + #pragma comment(lib, "vc6-stlport-re300dm.lib") + #else //_DEBUG + #pragma comment(lib, "vc6-stlport-re300m.lib") + #endif //_DEBUG + #else //_MT + // STLPort does not support single threaded builds: + #error STLPort does not support single threaded builds + #endif //_MT + #endif //_DLL +#elif _MSC_VER < 1300 + #ifdef _DLL + // All these are multithreaded: + #ifdef _DEBUG + #pragma comment(lib, "vc6-re300dl.lib") + #elif defined(BOOST_REGEX_STATIC_LINK) + // static regex lib, dll runtime + #pragma comment(lib, "vc6-re300ls.lib") + #else // DEBUG + #pragma comment(lib, "vc6-re300l.lib") + #endif // _DEBUG + #else // _DLL + #ifdef _MT + #ifdef _DEBUG + #pragma comment(lib, "vc6-re300dm.lib") + #else //_DEBUG + #pragma comment(lib, "vc6-re300m.lib") + #endif //_DEBUG + #else //_MT + #ifdef _DEBUG + #pragma comment(lib, "vc6-re300d.lib") + #else //_DEBUG + #pragma comment(lib, "vc6-re300.lib") + #endif //_DEBUG + #endif //_MT + #endif //_DLL +#else + #ifdef _DLL + // All these are multithreaded: + #ifdef _DEBUG + #pragma comment(lib, "vc7-re300dl.lib") + #elif defined(BOOST_REGEX_STATIC_LINK) + // static regex lib, dll runtime + #pragma comment(lib, "vc7-re300ls.lib") + #else // DEBUG + #pragma comment(lib, "vc7-re300l.lib") + #endif // _DEBUG + #else // _DLL + #ifdef _MT + #ifdef _DEBUG + #pragma comment(lib, "vc7-re300dm.lib") + #else //_DEBUG + #pragma comment(lib, "vc7-re300m.lib") + #endif //_DEBUG + #else //_MT + #ifdef _DEBUG + #pragma comment(lib, "vc7-re300d.lib") + #else //_DEBUG + #pragma comment(lib, "vc7-re300.lib") + #endif //_DEBUG + #endif //_MT + #endif //_DLL +#endif // __SGI_STL_PORT +#endif //BOOST_MSVC + + +#if defined(__BORLANDC__) && !defined(BOOST_REGEX_BUILD_DLL) + + #if __BORLANDC__ < 0x550 + + #ifdef BOOST_REGEX_USE_VCL + + #ifdef _RTLDLL + #pragma comment(lib, "bcb4re300lv.lib") + #else + #pragma comment(lib, "bcb4re300v.lib") + #endif + + #else // VCL + + #ifdef _RTLDLL + #ifdef __MT__ + #pragma comment(lib, "bcb4re300lm.lib") + #else // __MT__ + #pragma comment(lib, "bcb4re300l.lib") + #endif // __MT__ + #else //_RTLDLL + #ifdef __MT__ + #pragma comment(lib, "bcb4re300m.lib") + #else // __MT__ + #pragma comment(lib, "bcb4re300.lib") + #endif // __MT__ + #endif // _RTLDLL + + #endif // VCL + + #else // C++ Builder 5: + + #ifdef BOOST_REGEX_USE_VCL + + #ifdef _RTLDLL + #pragma comment(lib, "bcb5re300lv.lib") + #else + #pragma comment(lib, "bcb5re300v.lib") + #endif + + #else // VCL + + #ifdef _RTLDLL + #ifdef __MT__ + #pragma comment(lib, "bcb5re300lm.lib") + #else // __MT__ + #pragma comment(lib, "bcb5re300l.lib") + #endif // __MT__ + #else //_RTLDLL + #ifdef __MT__ + #pragma comment(lib, "bcb5re300m.lib") + #else // __MT__ + #pragma comment(lib, "bcb5re300.lib") + #endif // __MT__ + #endif // _RTLDLL + + #endif // VCL + + #endif + +#endif //__BORLANDC__ + +#endif //BOOST_REGEX_NO_LIB + +#endif // BOOST_REGEX_LIBRARY_INCLUDE_HPP + + + + From c494649ddef5160217f8a2aa5ba3134130e136c9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 18 Dec 2001 21:00:07 +0000 Subject: [PATCH 0144/1042] fix a bug with instance::power reported by Scott Snyder. [SVN r12119] --- src/classes.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/classes.cpp b/src/classes.cpp index c721ef5c..f51d1a2f 100644 --- a/src/classes.cpp +++ b/src/classes.cpp @@ -11,8 +11,6 @@ // 03 Mar 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve) // 03 Mar 01 bug fix: use bound_function::create() (instead of new bound_function) -#define BOOST_PYTHON_SOURCE - #include #include #include @@ -645,7 +643,7 @@ PyObject* instance::divmod(PyObject* other) PyObject* instance::power(PyObject* exponent, PyObject* modulus) { - if (as_object(modulus->ob_type) == Py_None) + if (as_object(modulus) == Py_None) return callback::call_method(this, "__pow__", exponent); else return callback::call_method(this, "__pow__", exponent, modulus); From 1f78c7408592a4ce634bc7268c5a910b6e0c6b05 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 24 Dec 2001 19:27:39 +0000 Subject: [PATCH 0145/1042] fixes [SVN r12146] --- Jamfile | 39 + build/Jamfile | 22 +- doc/new-conversions.html | 326 +++++++ doc/new-conversions.txt | 111 +++ example/simple_vector.cpp | 2 +- include/boost/python/call.hpp | 210 +++++ include/boost/python/classes.hpp | 6 +- include/boost/python/conversions.hpp | 53 +- include/boost/python/convert.hpp | 84 ++ include/boost/python/converter/body.hpp | 68 ++ include/boost/python/converter/class.hpp | 56 ++ include/boost/python/converter/handle.hpp | 91 ++ .../boost/python/converter/registration.hpp | 83 ++ include/boost/python/converter/registry.hpp | 74 ++ include/boost/python/converter/source.hpp | 80 ++ .../boost/python/converter/source_holder.hpp | 24 + include/boost/python/converter/target.hpp | 173 ++++ include/boost/python/converter/type_id.hpp | 200 +++++ include/boost/python/converter/unwrap.hpp | 192 ++++ include/boost/python/converter/unwrapper.hpp | 53 ++ .../boost/python/converter/unwrapper_base.hpp | 25 + include/boost/python/converter/wrap.hpp | 145 +++ include/boost/python/converter/wrapper.hpp | 69 ++ include/boost/python/cross_module.hpp | 110 +-- .../boost/python/detail/arg_tuple_size.hpp | 233 +++++ include/boost/python/detail/base_object.hpp | 6 +- include/boost/python/detail/call_object.hpp | 66 ++ include/boost/python/detail/caller.hpp | 27 + include/boost/python/detail/config.hpp | 18 +- .../python/detail/python_library_include.hpp | 1 + include/boost/python/detail/returning.hpp | 846 ++++++++++++++++++ include/boost/python/detail/types.hpp | 4 - include/boost/python/detail/void_adaptor.hpp | 2 +- include/boost/python/detail/wrap_python.hpp | 46 +- include/boost/python/errors.hpp | 42 +- include/boost/python/export.hpp | 20 + include/boost/python/make_function.hpp | 40 + include/boost/python/module.hpp | 12 + include/boost/python/module_builder.hpp | 39 +- include/boost/python/object/class.hpp | 103 +++ .../boost/python/object/class_unwrapper.hpp | 40 + include/boost/python/object/construct.hpp | 24 + include/boost/python/object/forward.hpp | 33 + include/boost/python/object/function.hpp | 36 + include/boost/python/object/make_holder.hpp | 124 +++ include/boost/python/object/value_holder.hpp | 80 ++ include/boost/python/objects.hpp | 223 +++-- include/boost/python/operators.hpp | 2 +- src/classes.cpp | 4 +- src/conversions.cpp | 99 +- src/converter/body.cpp | 18 + src/converter/handle.cpp | 35 + src/converter/registry.cpp | 177 ++++ src/converter/type_id.cpp | 67 ++ src/converter/unwrap.cpp | 35 + src/converter/unwrapper.cpp | 24 + src/converter/wrapper.cpp | 30 + src/cross_module.cpp | 117 +-- src/errors.cpp | 68 ++ src/extension_class.cpp | 25 +- src/gen_call.py | 82 ++ src/gen_returning.py | 191 ++++ src/module_builder.cpp | 16 +- src/object/class.cpp | 165 ++++ src/object/function.cpp | 95 ++ src/objects.cpp | 126 +-- src/types.cpp | 126 +-- test/complicated.hpp | 39 + test/m1.cpp | 281 ++++++ test/m2.cpp | 197 ++++ test/module_tail.cpp | 39 + test/newtest.py | 95 ++ test/simple_type.hpp | 14 + 73 files changed, 5947 insertions(+), 581 deletions(-) create mode 100644 Jamfile create mode 100644 doc/new-conversions.html create mode 100644 doc/new-conversions.txt create mode 100644 include/boost/python/call.hpp create mode 100644 include/boost/python/convert.hpp create mode 100644 include/boost/python/converter/body.hpp create mode 100644 include/boost/python/converter/class.hpp create mode 100644 include/boost/python/converter/handle.hpp create mode 100644 include/boost/python/converter/registration.hpp create mode 100644 include/boost/python/converter/registry.hpp create mode 100644 include/boost/python/converter/source.hpp create mode 100644 include/boost/python/converter/source_holder.hpp create mode 100644 include/boost/python/converter/target.hpp create mode 100644 include/boost/python/converter/type_id.hpp create mode 100644 include/boost/python/converter/unwrap.hpp create mode 100644 include/boost/python/converter/unwrapper.hpp create mode 100644 include/boost/python/converter/unwrapper_base.hpp create mode 100644 include/boost/python/converter/wrap.hpp create mode 100644 include/boost/python/converter/wrapper.hpp create mode 100644 include/boost/python/detail/arg_tuple_size.hpp create mode 100644 include/boost/python/detail/call_object.hpp create mode 100644 include/boost/python/detail/caller.hpp create mode 100644 include/boost/python/detail/returning.hpp create mode 100644 include/boost/python/export.hpp create mode 100644 include/boost/python/make_function.hpp create mode 100644 include/boost/python/module.hpp create mode 100644 include/boost/python/object/class.hpp create mode 100644 include/boost/python/object/class_unwrapper.hpp create mode 100644 include/boost/python/object/construct.hpp create mode 100644 include/boost/python/object/forward.hpp create mode 100644 include/boost/python/object/function.hpp create mode 100644 include/boost/python/object/make_holder.hpp create mode 100644 include/boost/python/object/value_holder.hpp create mode 100644 src/converter/body.cpp create mode 100644 src/converter/handle.cpp create mode 100644 src/converter/registry.cpp create mode 100644 src/converter/type_id.cpp create mode 100644 src/converter/unwrap.cpp create mode 100644 src/converter/unwrapper.cpp create mode 100644 src/converter/wrapper.cpp create mode 100644 src/errors.cpp create mode 100644 src/gen_call.py create mode 100644 src/gen_returning.py create mode 100644 src/object/class.cpp create mode 100644 src/object/function.cpp create mode 100644 test/complicated.hpp create mode 100644 test/m1.cpp create mode 100644 test/m2.cpp create mode 100644 test/module_tail.cpp create mode 100644 test/newtest.py create mode 100644 test/simple_type.hpp diff --git a/Jamfile b/Jamfile new file mode 100644 index 00000000..18372684 --- /dev/null +++ b/Jamfile @@ -0,0 +1,39 @@ +subproject libs/python ; + +# bring in the rules for python +SEARCH on python.jam = $(BOOST_BUILD_PATH) ; +include python.jam ; + +PYTHON_PROPERTIES + += <*>"-inline deferred" + <*>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers + BOOST_PYTHON_DYNAMIC_LIB + ; + + +dll bpl + : + src/converter/body.cpp + src/converter/handle.cpp + src/converter/registry.cpp + src/converter/wrapper.cpp + src/converter/unwrap.cpp + src/converter/unwrapper.cpp + src/converter/type_id.cpp + src/object/class.cpp + src/object/function.cpp + src/errors.cpp + : + $(PYTHON_PROPERTIES) + BOOST_PYTHON_SOURCE + ; + +extension m1 : test/m1.cpp bpl # BOOST_PYTHON_TRACE + : + : debug-python ; + +extension m2 : test/m2.cpp bpl # BOOST_PYTHON_TRACE + : + : debug-python ; + +boost-python-runtest try : test/newtest.py m1 m2 : : debug-python ; \ No newline at end of file diff --git a/build/Jamfile b/build/Jamfile index 78d1e84a..7fd8c285 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -61,6 +61,8 @@ subproject libs/python/build ; SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; +local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_DYNAMIC_LIB ; + ####################### local rule bpl-test ( test-name : sources + ) { @@ -75,21 +77,27 @@ local rule bpl-test ( test-name : sources + ) # Base names of the source files for libboost_python local CPP_SOURCES = - types classes conversions extension_class functions - init_function module_builder objects cross_module ; + types classes conversions extension_class functions + init_function module_builder objects cross_module errors + ; -lib libboost_python : ../src/$(CPP_SOURCES).cpp +lib libboost_python_static : ../src/$(CPP_SOURCES).cpp # requirements : $(BOOST_PYTHON_INCLUDES) true + BOOST_PYTHON_STATIC_LIB=1 $(PYTHON_PROPERTIES) ; -dll libboost_python$(SUFDLL[1]) : ../src/$(CPP_SOURCES).cpp +dll libboost_python + # $(SUFDLL[1]) + : ../src/$(CPP_SOURCES).cpp # requirements - : $(BOOST_PYTHON_INCLUDES) + : $(BOOST_PYTHON_INCLUDES) true - BOOST_RE_BUILD_DLL=1 - $(PYTHON_PROPERTIES) ; + dynamic + BOOST_PYTHON_HAS_DLL_RUNTIME=1 + $(PYTHON_PROPERTIES) + ; ############# comprehensive module and test ########### bpl-test boost_python_test diff --git a/doc/new-conversions.html b/doc/new-conversions.html new file mode 100644 index 00000000..cd8a5b19 --- /dev/null +++ b/doc/new-conversions.html @@ -0,0 +1,326 @@ + + + + +A New Type Conversion Mechanism for Boost.Python + + + + +

    + +

    A New Type Conversion Mechanism for Boost.Python

    + +

    By David Abrahams. + +

    Introduction

    + +This document describes a redesign of the mechanism for automatically +converting objects between C++ and Python. The current implementation +uses two functions for any type T: + +
    +U from_python(PyObject*, type<T>);
    +void to_python(V);
    +
    + +where U is convertible to T and T is convertible to V. These functions +are at the heart of C++/Python interoperability in Boost.Python, so +why would we want to change them? There are many reasons: + +

    Bugs

    +

    Firstly, the current mechanism relies on a common C++ compiler +bug. This is not just embarrassing: as compilers get to be more +conformant, the library stops working. The issue, in detail, is the +use of inline friend functions in templates to generate +conversions. It is a very powerful, and legal technique as long as +it's used correctly: + +

    +template <class Derived>
    +struct add_some_functions
    +{
    +     friend return-type some_function1(..., Derived cv-*-&-opt, ...);
    +     friend return-type some_function2(..., Derived cv-*-&-opt, ...);
    +};
    +
    +template <class T>
    +struct some_template : add_some_functions<some_template<T> >
    +{
    +};
    +
    + +The add_some_functions template generates free functions +which operate on Derived, or on related types. Strictly +speaking the related types are not just cv-qualified Derived +values, pointers and/or references. Section 3.4.2 in the standard +describes exactly which types you must use as parameters to these +functions if you want the functions to be found +(there is also a less-technical description in section 11.5.1 of +C++PL3 [1]). Suffice it to say that +with the current design, the from_python and +to_python functions are not supposed to be callable under any +conditions! + +

    Compilation and Linking Time

    + +The conversion functions generated for each wrapped class using the +above technique are not function templates, but regular functions. The +upshot is that they must all be generated regardless of whether +they are actually used. Generating all of those functions can slow +down module compilation, and resolving the references can slow down +linking. + +

    Efficiency

    + +The conversion functions are primarily used in (member) function +wrappers to convert the arguments and return values. Being functions, +converters have no interface which allows us to ask "will the +conversion succeed?" without calling the function. Since the +return value of the function must be the object to be passed as an +argument, Boost.Python currently uses C++ exception-handling to detect +an unsuccessful conversion. It's not a particularly good use of +exception-handling, since the failure is not handled very far from +where it occurred. More importantly, it means that C++ exceptions are +thrown during overload resolution as we seek an overload that matches +the arguments passed. Depending on the implementation, this approach +can result in significant slowdowns. + +

    It is also unclear that the current library generates a minimal +amount of code for any type conversion. Many of the conversion +functions are nontrivial, and partly because of compiler limitations, +they are declared inline. Also, we could have done a better +job separating the type-specific conversion code from the code which +is type-independent. + +

    Cross-module Support

    + +The current strategy requires every module to contain the definition +of conversions it uses. In general, a new module can never supply +conversion code which is used by another module. Ralf Grosse-Kunstleve +designed a clever system which imports conversions directly from one +library into another using some explicit declarations, but it has some +disadvantages also: + +
      +
    1. The system Ullrich Koethe designed for implicit conversion between +wrapped classes related through inheritance does not currently work if +the classes are defined in separate modules. + +
    2. The writer of the importing module is required to know the name of +the module supplying the imported conversions. + +
    3. There can be only one way to extract any given C++ type from a +Python object in a given module. +
    + +The first item might be addressed by moving Boost.Python into a shared +library, but the other two cannot. Ralf turned the limitation in item +two into a feature: the required module is loaded implicitly when a +conversion it defines is invoked. We will probably want to provide +that functionality anyway, but it's not clear that we should require +the declaration of all such conversions. The final item is a more +serious limitation. If, for example, new numeric types are defined in +separate modules, and these types can all be converted to +doubles, we have to choose just one conversion method. + +

    Ease-of-use

    + +One persistent source of confusion for users of Boost.Python has been +the fact that conversions for a class are not be visible at +compile-time until the declaration of that class has been seen. When +the user tries to expose a (member) function operating on or returning +an instance of the class in question, compilation fails...even though +the user goes on to expose the class in the same translation unit! + +

    +The new system lifts all compile-time checks for the existence of +particular type conversions and replaces them with runtime checks, in +true Pythonic style. While this might seem cavalier, the compile-time +checks are actually not much use in the current system if many classes +are wrapped in separate modules, since the checks are based only on +the user's declaration that the conversions exist. + +

    The New Design

    + +

    Motivation

    + +The new design was heavily influenced by a desire to generate as +little code as possible in extension modules. Some of Boost.Python's +clients are enormous projects where link time is proportional to the +amount of object code, and there are many Python extension modules. As +such, we try to keep type-specific conversion code out of modules +other than the one the converters are defined in, and rely as much as +possible on centralized control through a shared library. + +

    The Basics

    + +The library contains a registry which maps runtime type +identifiers (actually an extension of std::type_info which +preserves references and constness) to entries containing type +converters. An entry can contain only one converter from C++ to Python +(wrapper), but many converters from Python to C++ +(unwrappers). What should happen if +multiple modules try to register wrappers for the same type?. Wrappers +and unwrappers are known as body objects, and are accessed +by the user and the library (in its function-wrapping code) through +corresponding handle (wrap<T> and +unwrap<T>) objects. The handle objects are +extremely lightweight, and delegate all of their operations to +the corresponding body. + +

    +When a handle object is constructed, it accesses the +registry to find a corresponding body that can convert the +handle's constructor argument. Actually the registry record for any +type +Tused in a module is looked up only once and stored in a +static registration<T> object for efficiency. For +example, if the handle is an unwrap<Foo&> object, +the entry for Foo& is looked up in the +registry, and each unwrapper it contains is queried +to determine if it can convert the +PyObject* with which the unwrap was constructed. If +a body object which can perform the conversion is found, a pointer to +it is stored in the handle. A body object may at any point store +additional data in the handle to speed up the conversion process. + +

    +Now that the handle has been constructed, the user can ask it whether +the conversion can be performed. All handles can be tested as though +they were convertible to bool; a true value +indicates success. If the user forges ahead and tries to do the +conversion without checking when no conversion is possible, an +exception will be thrown as usual. The conversion itself is performed +by the body object. + +

    Handling complex conversions

    + +

    Some conversions may require a dynamic allocation. For example, +when a Python tuple is converted to a std::vector<double> +const&, we need some storage into which to construct the +vector so that a reference to it can be formed. Furthermore, multiple +conversions of the same type may need to be "active" +simultaneously, so we can't keep a single copy of the storage +anywhere. We could keep the storage in the body object, and +have the body clone itself in case the storage is used, but in that +case the storage in the body which lives in the registry is never +used. If the storage was actually an object of the target type (the +safest way in C++), we'd have to find a way to construct one for the +body in the registry, since it may not have a default constructor. + +

    +The most obvious way out of this quagmire is to allocate the object using a +new-expression, and store a pointer to it in the handle. Since +the body object knows everything about the data it needs to +allocate (if any), it is also given responsibility for destroying that +data. When the handle is destroyed it asks the body +object to tear down any data it may have stored there. In many ways, +you can think of the body as a "dynamically-determined +vtable" for the handle. + +

    Eliminating Redundancy

    + +If you look at the current Boost.Python code, you'll see that there +are an enormous number of conversion functions generated for each +wrapped class. For a given class T, functions are generated +to extract the following types from_python: + +
    +T*
    +T const*
    +T const* const&
    +T* const&
    +T&
    +T const&
    +T
    +std::auto_ptr<T>&
    +std::auto_ptr<T>
    +std::auto_ptr<T> const&
    +boost::shared_ptr<T>&
    +boost::shared_ptr<T>
    +boost::shared_ptr<T> const&
    +
    + +Most of these are implemented in terms of just a few conversions, and +if you're lucky, they will be inlined and cause no extra +overhead. In the new system, however, a significant amount of data +will be associated with each type that needs to be converted. We +certainly don't want to register a separate unwrapper object for all +of the above types. + +

    Fortunately, much of the redundancy can be eliminated. For example, +if we generate an unwrapper for T&, we don't need an +unwrapper for T const& or T. Accordingly, the user's +request to wrap/unwrap a given type is translated at compile-time into +a request which helps to eliminate redundancy. The rules used to +unwrap a type are: + +

      +
    1. Treat built-in types specially: when unwrapping a value or + constant reference to one of these, use a value for the target + type. It will bind to a const reference if neccessary, and more + importantly, avoids having to dynamically allocate room for + an lvalue of types which can be cheaply copied. +
    2. + Reduce everything else to a reference to an un-cv-qualified type + where possible. Since cv-qualification is lost on Python + anyway, there's no point in trying to convert to a + const&. What about conversions + to values like the tuple->vector example above? It seems to me + that we don't want to make a vector<double>& + (non-const) converter available for that case. We may need to + rethink this slightly. +
    + +

    To handle the problem described above in item 2, we modify the +procedure slightly. To unwrap any non-scalar T, we seek an +unwrapper for add_reference<T>::type. Unwrappers for +T const& always return T&, and are +registered under both T & and +T const&. + +

    For compilers not supporting partial specialization, unwrappers for +T const& must return T const& +(since constness can't be stripped), but a separate unwrapper object +need to be registered for T & and +T const& anyway, for the same reasons. + +We may want to make it possible to compile as +though partial specialization were unavailable even on compilers where +it is available, in case modules could be compiled by different +compilers with compatible ABIs (e.g. Intel C++ and MSVC6). + +

    Efficient Argument Conversion

    + +Since type conversions are primarily used in function wrappers, an +optimization is provided for the case where a group of conversions are +used together. Each handle class has a corresponding +"_more" class which does the same job, but has a +trivial destructor. Instead of asking each "_more" +handle to destroy its own body, it is linked into an endogenous list +managed by the first (ordinary) handle. The wrap and +unwrap destructors are responsible for traversing that list +and asking each body class to tear down its +handle. This mechanism is also used to determine if all of +the argument/return-value conversions can succeed with a single +function call in the function wrapping code. We +might need to handle return values in a separate step for Python +callbacks, since the availablility of a conversion won't be known +until the result object is retrieved. + +
    +
    +

    References

    + +

    [1]B. Stroustrup, The C++ Programming Language +Special Edition Addison-Wesley, ISBN 0-201-70073-5. + +


    +

    Revised 19 December 2001

    +

    © Copyright David Abrahams, 2001

    + + + + diff --git a/doc/new-conversions.txt b/doc/new-conversions.txt new file mode 100644 index 00000000..1540e199 --- /dev/null +++ b/doc/new-conversions.txt @@ -0,0 +1,111 @@ +This hierarchy contains converter handle classes. + + + +-------------+ + | noncopyable | + +-------------+ + ^ + | A common base class used so that + +--------+--------+ conversions can be linked into a + | conversion_base | chain for efficient argument + +-----------------+ conversion + ^ + | + +---------+-----------+ + | | ++-----------+----+ +------+-------+ only used for +| unwrap_more | | wrap_more | chaining, and don't manage any ++----------------+ +--------------+ resources. + ^ ^ + | | + +-----+-----+ +-------+-+ These converters are what users + | unwrap | | wrap | actually touch, but they do so + +-----------+ +---------+ through a type generator which + minimizes the number of converters + that must be generated, so they + + +Each unwrap, unwrap_more, wrap, wrap_more converter holds +a reference to an appropriate converter object + +This hierarchy contains converter body classes + + Exposes use/release which + are needed in case the converter + +-----------+ in the registry needs to be + | converter | cloned. That occurs when a + +-----------+ unwrap target type is not + ^ contained within the Python object. + | + +------------------+-----+ + | | + +--------+-------+ Exposes | + | unwrapper_base | convertible() | + +----------------+ | + ^ | + | | + +--------+----+ +-----+-----+ + | unwrapper| | wrapper| + +-------------+ +-----------+ + Exposes T convert(PyObject*) Exposes PyObject* convert(T) + + +unwrap: + + constructed with a PyObject*, whose reference count is + incremented. + + find the registry entry for the target type + + look in the collection of converters for one which claims to be + able to convert the PyObject to the target type. + + stick a pointer to the unwrapper in the unwrap object + + when unwrap is queried for convertibility, it checks to see + if it has a pointer to an unwrapper. + + on conversion, the unwrapper is asked to allocate an + implementation if the unwrap object isn't already holding + one. The unwrap object "takes ownership" of the unwrapper's + implementation. No memory allocation will actually take place + unless this is a value conversion. + + on destruction, the unwrapper is asked to free any implementation + held by the unwrap object. No memory deallocation actually + takes place unless this is a value conversion + + on destruction, the reference count on the held PyObject is + decremented. + + We need to make sure that by default, you can't instantiate + callback<> for reference and pointer return types: although the + unwrappers may exist, they may convert by-value, which would cause + the referent to be destroyed upon return. + +wrap: + + find the registry entry for the source type + + see if there is a converter. If found, stick a pointer to it in + the wrap object. + + when queried for convertibility, it checks to see if it has a + pointer to a converter. + + on conversion, a reference to the target PyObject is held by the + converter. Generally, the PyObject will have been created by the + converter, but in certain cases it may be a pre-existing object, + whose reference count will have been incremented. + + when a wrap x is used to return from a C++ function, + x.release() is returned so that x no longer holds a reference to + the PyObject when destroyed. + + Otherwise, on destruction, any PyObject still held has its + reference-count decremented. + + +When a converter is created by the user, the appropriate element must +be added to the registry; when it is destroyed, it must be removed +from the registry. diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp index 8c7ee0ce..e0f9e85e 100644 --- a/example/simple_vector.cpp +++ b/example/simple_vector.cpp @@ -91,7 +91,7 @@ BOOST_PYTHON_MODULE_INIT(simple_vector) vector_double(this_module, "vector_double"); vector_double.def(python::constructor<>()); - vector_double.def(python::constructor()); + vector_double.def(python::constructor()); vector_double.def(python::constructor()); vector_double.def(&std::vector::size, "__len__"); vector_double.def(getitem, "__getitem__"); diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp new file mode 100644 index 00000000..bdda879d --- /dev/null +++ b/include/boost/python/call.hpp @@ -0,0 +1,210 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// +// This work was funded in part by Lawrence Berkeley National Labs +// +// This file generated for 5-argument member functions and 6-argument free +// functions by gen_call.py + +#ifndef CALL_DWA20011214_HPP +# define CALL_DWA20011214_HPP + +# include + +namespace boost { namespace python { + +template +PyObject* call(R (*f)(), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (*f)(A0), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (*f)(A0, A1), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +// Member functions +template +PyObject* call(R (A0::*f)(), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)() const, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)() volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +template +PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + + +}} // namespace boost::python + +#endif // CALL_DWA20011214_HPP + diff --git a/include/boost/python/classes.hpp b/include/boost/python/classes.hpp index f88f1000..548a57db 100644 --- a/include/boost/python/classes.hpp +++ b/include/boost/python/classes.hpp @@ -20,7 +20,7 @@ namespace boost { namespace python { // A simple type which acts something like a built-in Python class obj. -class instance +class BOOST_PYTHON_DECL instance : public boost::python::detail::python_object { public: @@ -105,7 +105,7 @@ class instance template class meta_class; namespace detail { - class class_base : public type_object_base + class BOOST_PYTHON_DECL class_base : public type_object_base { public: class_base(PyTypeObject* meta_class_obj, string name, tuple bases, const dictionary& name_space); @@ -344,7 +344,7 @@ int class_t::instance_mapping_ass_subscript(PyObject* obj, PyObject* key, PyO return 0; } -void adjust_slice_indices(PyObject* obj, int& start, int& finish); +void BOOST_PYTHON_DECL adjust_slice_indices(PyObject* obj, int& start, int& finish); template PyObject* class_t::instance_sequence_slice(PyObject* obj, int start, int finish) const diff --git a/include/boost/python/conversions.hpp b/include/boost/python/conversions.hpp index c1a7d390..aa07547f 100644 --- a/include/boost/python/conversions.hpp +++ b/include/boost/python/conversions.hpp @@ -122,61 +122,68 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // Converters // PyObject* to_python(long); -long from_python(PyObject* p, boost::python::type); +BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type); long from_python(PyObject* p, boost::python::type); -PyObject* to_python(unsigned long); -unsigned long from_python(PyObject* p, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(unsigned long); +BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type); unsigned long from_python(PyObject* p, boost::python::type); PyObject* to_python(int); -int from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL int from_python(PyObject*, boost::python::type); int from_python(PyObject*, boost::python::type); -PyObject* to_python(unsigned int); -unsigned int from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(unsigned int); +BOOST_PYTHON_DECL unsigned int from_python(PyObject*, boost::python::type); unsigned int from_python(PyObject*, boost::python::type); PyObject* to_python(short); -short from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL short from_python(PyObject*, boost::python::type); short from_python(PyObject*, boost::python::type); -PyObject* to_python(unsigned short); -unsigned short from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(unsigned short); +BOOST_PYTHON_DECL unsigned short from_python(PyObject*, boost::python::type); unsigned short from_python(PyObject*, boost::python::type); -PyObject* to_python(char); -char from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(char); +BOOST_PYTHON_DECL char from_python(PyObject*, boost::python::type); char from_python(PyObject*, boost::python::type); -PyObject* to_python(signed char); -signed char from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(signed char); +BOOST_PYTHON_DECL signed char from_python(PyObject*, boost::python::type); signed char from_python(PyObject*, boost::python::type); -PyObject* to_python(unsigned char); -unsigned char from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(unsigned char); +BOOST_PYTHON_DECL unsigned char from_python(PyObject*, boost::python::type); unsigned char from_python(PyObject*, boost::python::type); +# ifndef BOOST_MSVC6_OR_EARLIER PyObject* to_python(float); float from_python(PyObject*, boost::python::type); -float from_python(PyObject*, boost::python::type); - PyObject* to_python(double); double from_python(PyObject*, boost::python::type); +# else +BOOST_PYTHON_DECL PyObject* to_python(float); +BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(double); +BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type); +# endif +float from_python(PyObject*, boost::python::type); + double from_python(PyObject*, boost::python::type); PyObject* to_python(bool); -bool from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL bool from_python(PyObject*, boost::python::type); bool from_python(PyObject*, boost::python::type); -PyObject* to_python(void); -void from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(void); +BOOST_PYTHON_DECL void from_python(PyObject*, boost::python::type); PyObject* to_python(const char* s); -const char* from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL const char* from_python(PyObject*, boost::python::type); -PyObject* to_python(const std::string& s); -std::string from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(const std::string& s); +BOOST_PYTHON_DECL std::string from_python(PyObject*, boost::python::type); std::string from_python(PyObject*, boost::python::type); inline PyObject* to_python(const std::complex& x) diff --git a/include/boost/python/convert.hpp b/include/boost/python/convert.hpp new file mode 100644 index 00000000..5614bd3b --- /dev/null +++ b/include/boost/python/convert.hpp @@ -0,0 +1,84 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CONVERT_DWA20011129_HPP +# define CONVERT_DWA20011129_HPP + +# include +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + template + struct converter_gen + { + typedef T value_type; + typedef typename converter::source::type source_t; + typedef converter::wrap_ wrap_t; + typedef converter::wrap_more_ wrap_more_t; + + typedef typename converter::target::type target_t; + typedef converter::unwrap_ unwrap_t; + typedef converter::unwrap_more_ unwrap_more_t; + }; +} + +template +struct wrap : detail::converter_gen::wrap_t +{ + typedef typename detail::converter_gen::wrap_t base_t; + typedef typename detail::converter_gen::source_t source_t; +}; + +template +struct wrap_more : detail::converter_gen::wrap_more_t +{ + typedef typename detail::converter_gen::wrap_more_t base_t; + typedef typename detail::converter_gen::source_t source_t; + wrap_more(converter::handle& prev); +}; + +template +struct unwrap : detail::converter_gen::unwrap_t +{ + typedef typename detail::converter_gen::unwrap_t base_t; + unwrap(PyObject*); +}; + +template +struct unwrap_more : detail::converter_gen::unwrap_more_t +{ + typedef typename detail::converter_gen::unwrap_more_t base_t; + unwrap_more(PyObject*, converter::handle& prev); +}; + +// +// implementations +// +template +inline wrap_more::wrap_more(converter::handle& prev) + : base_t(prev) +{ +} + +template +inline unwrap::unwrap(PyObject* source) + : base_t(source) +{ +} + +template +inline unwrap_more::unwrap_more(PyObject* source, converter::handle& prev) + : base_t(source, prev) +{ +} + +}} // namespace boost::python + +#endif // CONVERT_DWA20011129_HPP diff --git a/include/boost/python/converter/body.hpp b/include/boost/python/converter/body.hpp new file mode 100644 index 00000000..c8d932a0 --- /dev/null +++ b/include/boost/python/converter/body.hpp @@ -0,0 +1,68 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BODY_DWA2001127_HPP +# define BODY_DWA2001127_HPP +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +struct BOOST_PYTHON_EXPORT handle; + +namespace registry +{ + class entry; +} + +struct BOOST_PYTHON_EXPORT body +{ + public: + body(type_id_t key); + virtual ~body() {} + + // default implementation is a no-op + virtual void destroy_handle(handle*) const; + + type_id_t key() const; + + protected: + // true iff the registry is still alive + bool can_unregister() const; + + private: + // called when the registry is destroyed, to prevent it from being + // unregistered. + void do_not_unregister(); + friend class registry::entry; + + private: + type_id_t m_key; + bool m_can_unregister; +}; + +// +// implementations +// +inline body::body(type_id_t key) + : m_key(key) + , m_can_unregister(true) +{ +} + +inline type_id_t body::key() const +{ + return m_key; +} + +inline bool body::can_unregister() const +{ + return m_can_unregister; +} + +}}} // namespace boost::python::converter + +#endif // BODY_DWA2001127_HPP diff --git a/include/boost/python/converter/class.hpp b/include/boost/python/converter/class.hpp new file mode 100644 index 00000000..305ec448 --- /dev/null +++ b/include/boost/python/converter/class.hpp @@ -0,0 +1,56 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CLASS_DWA20011215_HPP +# define CLASS_DWA20011215_HPP + +# include +# include + +namespace boost { namespace python { namespace converter { + +struct class_unwrapper_base +{ + class_unwrapper_base(type_id_t sought_type); + void* +}; + +template +struct class_unwrapper +{ + struct ref_unwrapper : unwrapper + { + bool convertible(PyObject* p) const + { + return p->ob_type == &SimpleType; + } + + simple const& convert(PyObject* p, void*&) const + { + return static_cast(p)->x; + } + + }; + +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + struct const_ref_unwrapper : unwrapper + { + bool convertible(PyObject* p) const + { + return p->ob_type == &SimpleType; + } + + simple const& convert(PyObject* p, void*&) const + { + return static_cast(p)->x; + } + + }; +# endif +}; + +}}} // namespace boost::python::converter + +#endif // CLASS_DWA20011215_HPP diff --git a/include/boost/python/converter/handle.hpp b/include/boost/python/converter/handle.hpp new file mode 100644 index 00000000..16a50b38 --- /dev/null +++ b/include/boost/python/converter/handle.hpp @@ -0,0 +1,91 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef HANDLE_DWA20011130_HPP +# define HANDLE_DWA20011130_HPP +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +struct BOOST_PYTHON_EXPORT body; + +// The common base class for unwrap_ and wrap_ handle objects. They +// share a common base so that handles can be linked into a chain +// within a function wrapper which is managed by a single object. +struct BOOST_PYTHON_EXPORT handle : boost::noncopyable +{ + public: // member functions + + // All constructors take a body* passed from the derived class. + // + // Constructors taking a handle links this into a chain of + // handles, for more efficient management in function wrappers + handle(body* body); + handle(body* body, handle& prev); + + // returns true iff all handles in the chain can convert their + // arguments + bool convertible() const; + + // safe_bool idiom from Peter Dimov: provides handles to/from + // bool without enabling handles to integer types/void*. + private: + struct dummy { inline void nonnull() {} }; + typedef void (dummy::*safe_bool)(); + public: + inline operator safe_bool() const; + inline safe_bool operator!() const; + + protected: // member functions for derived classes + // Get the body we hold + inline body* get_body() const; + + // Release all bodies in the chain, in reverse order of + // initialization. Only actually called for the head of the chain. + void destroy(); + + private: + // Holds implementation + body* m_body; + + // handle for next argument, if any. + handle* m_next; +}; + +// +// implementations +// +inline handle::handle(body* body, handle& prev) + : m_body(body), m_next(0) +{ + prev.m_next = this; +} + +inline handle::handle(body* body) + : m_body(body), m_next(0) +{ +} + +inline handle::operator handle::safe_bool() const +{ + return convertible() ? &dummy::nonnull : 0; +} + +inline handle::safe_bool handle::operator!() const +{ + return convertible() ? 0 : &dummy::nonnull; +} + +inline body* handle::get_body() const +{ + return m_body; +} + +}}} // namespace boost::python::converter + +#endif // HANDLE_DWA20011130_HPP diff --git a/include/boost/python/converter/registration.hpp b/include/boost/python/converter/registration.hpp new file mode 100644 index 00000000..0d85d1d7 --- /dev/null +++ b/include/boost/python/converter/registration.hpp @@ -0,0 +1,83 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef REGISTRATION_DWA20011130_HPP +# define REGISTRATION_DWA20011130_HPP +# include +# include +# include +# include +# ifdef BOOST_PYTHON_TRACE +# include +# endif + +namespace boost { namespace python { namespace converter { + +struct BOOST_PYTHON_EXPORT wrapper_base; +struct BOOST_PYTHON_EXPORT unwrapper_base; + +// This class is really sort of a "templated namespace". It manages a +// static data member which refers to the registry entry for T. This +// reference is acquired once to reduce the burden of multiple +// dictionary lookups at runtime. +template +struct registration +{ + public: // member functions + // Return a converter which can convert the given Python object to + // T, or 0 if no such converter exists + static unwrapper_base* unwrapper(PyObject*); + + // Return a converter which can convert T to a Python object, or 0 + // if no such converter exists + static wrapper_base* wrapper(); + + private: // helper functions + static registry::entry* entry(); + static registry::entry* find_entry(); + + private: // data members + static registry::entry* m_registry_entry; +}; + +// because this is static POD data it will be initialized to zero +template +registry::entry* registration::m_registry_entry; + +template +registry::entry* registration::find_entry() +{ + return registry::find(type_id()); +} + +template +inline registry::entry* registration::entry() +{ + if (!m_registry_entry) + m_registry_entry = find_entry(); + return m_registry_entry; +} + +template +unwrapper_base* registration::unwrapper(PyObject* p) +{ +# ifdef BOOST_PYTHON_TRACE + std::cout << "retrieving unwrapper for " << type_id() << std::endl; +# endif + return entry()->unwrapper(p); +} + +template +wrapper_base* registration::wrapper() +{ +# ifdef BOOST_PYTHON_TRACE + std::cout << "retrieving wrapper for " << type_id() << std::endl; +# endif + return entry()->wrapper(); +} + +}}} // namespace boost::python::converter + +#endif // REGISTRATION_DWA20011130_HPP diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp new file mode 100644 index 00000000..30eeba8d --- /dev/null +++ b/include/boost/python/converter/registry.hpp @@ -0,0 +1,74 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef REGISTRY_DWA20011127_HPP +# define REGISTRY_DWA20011127_HPP +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +struct BOOST_PYTHON_EXPORT wrapper_base; +struct BOOST_PYTHON_EXPORT unwrapper_base; + +// This namespace acts as a sort of singleton +namespace registry +{ + // These are the elements stored in the registry + class BOOST_PYTHON_EXPORT entry + { + public: // member functions + entry(); + ~entry(); + + // Return a converter appropriate for converting the given + // Python object from_python to the C++ type with which this + // converter is associated in the registry, or 0 if no such + // converter exists. + unwrapper_base* unwrapper(PyObject*) const; + + // Return a converter appropriate for converting a C++ object + // whose type this entry is associated with in the registry to a + // Python object, or 0 if no such converter exists. + wrapper_base* wrapper() const; + + // Conversion classes use these functions to register + // themselves. + void insert(wrapper_base&); + void remove(wrapper_base&); + + void insert(unwrapper_base&); + void remove(unwrapper_base&); + + private: // types + typedef std::list unwrappers; + + private: // helper functions + unwrappers::iterator find(unwrapper_base const&); + + private: // data members + + // The collection of from_python converters for the associated + // C++ type. + unwrappers m_unwrappers; + + // The unique to_python converter for the associated C++ type. + converter::wrapper_base* m_wrapper; + }; + + BOOST_PYTHON_EXPORT entry* find(type_id_t); + + BOOST_PYTHON_EXPORT void insert(wrapper_base& x); + BOOST_PYTHON_EXPORT void insert(unwrapper_base& x); + BOOST_PYTHON_EXPORT void remove(wrapper_base& x); + BOOST_PYTHON_EXPORT void remove(unwrapper_base& x); +} + +}}} // namespace boost::python::converter + +#endif // REGISTRY_DWA20011127_HPP diff --git a/include/boost/python/converter/source.hpp b/include/boost/python/converter/source.hpp new file mode 100644 index 00000000..9af1cf49 --- /dev/null +++ b/include/boost/python/converter/source.hpp @@ -0,0 +1,80 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef SOURCE_DWA20011119_HPP +# define SOURCE_DWA20011119_HPP +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +// source -- +// +// This type generator (see +// ../../../more/generic_programming.html#type_generator) is used +// to select the argument type to use when converting T to a PyObject* + +template struct source; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +// Since for some strange reason temporaries can't be bound to const +// volatile references (8.5.3/5 in the C++ standard), we cannot use a +// const volatile reference as the standard for values and references. +template +struct source +{ + typedef T const& type; +}; + +// This will handle the following: +// T const volatile& -> T const volatile& +// T volatile& -> T const volatile& +// T const& -> T const& +// T& -> T const& +template +struct source +{ + typedef T const& type; +}; + +template +struct source +{ + typedef T const* type; +}; + +template +struct source +{ + typedef T const* type; +}; + +// Deal with references to pointers +template +struct source +{ + typedef T const* type; +}; + +template +struct source +{ + typedef T const* type; +}; +# else +template +struct source +{ + typedef typename add_reference< + typename add_const::type + >::type type; +}; +# endif + +}}} // namespace boost::python::converter + +#endif // SOURCE_DWA20011119_HPP diff --git a/include/boost/python/converter/source_holder.hpp b/include/boost/python/converter/source_holder.hpp new file mode 100644 index 00000000..f2c774f9 --- /dev/null +++ b/include/boost/python/converter/source_holder.hpp @@ -0,0 +1,24 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef SOURCE_HOLDER_DWA20011215_HPP +# define SOURCE_HOLDER_DWA20011215_HPP + +namespace boost { namespace python { namespace converter { + +struct source_holder_base +{ +}; + +template +struct source_holder : source_holder_base +{ + source_holder(T x) : value(x) {} + T value; +}; + +}}} // namespace boost::python::converter + +#endif // SOURCE_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/converter/target.hpp b/include/boost/python/converter/target.hpp new file mode 100644 index 00000000..6effb996 --- /dev/null +++ b/include/boost/python/converter/target.hpp @@ -0,0 +1,173 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#ifndef TARGET_DWA20011119_HPP +# define TARGET_DWA20011119_HPP +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +// target -- +// +// This type generator (see +// ../../../more/generic_programming.html#type_generator) is used +// to select the return type of the appropriate converter for +// unwrapping a given type. + +// Strategy: +// +// 1. reduce everything to a common, un-cv-qualified reference +// type where possible. This will save on registering many different +// converter types. +// +// 2. Treat built-in types specially: when unwrapping a value or +// constant reference to one of these, use a value for the target +// type. It will bind to a const reference if neccessary, and more +// importantly, avoids having to dynamically allocate room for +// an lvalue of types which can be cheaply copied. +// +// In the tables below, "cv" stands for the set of all possible +// cv-qualifications. + +// Target Source +// int int +// int const& int +// int& int& +// int volatile& int volatile& +// int const volatile& int const volatile& + +// On compilers supporting partial specialization: +// +// Target Source +// T T& +// T cv& T& +// T cv* T* +// T cv*const& T* +// T cv*& T*& <- should this be legal? +// T cv*volatile& T*& <- should this be legal? +// T cv*const volatile& T*& <- should this be legal? + +// On others: +// +// Target Source +// T T& +// T cv& T cv& +// T cv* T cv* +// T cv*cv& T cv*cv& + +// As you can see, in order to handle the same range of types without +// partial specialization, more converters need to be registered. + +template +struct target +{ + // Some pointer types are handled in a more sophisticated way on + // compilers supporting partial specialization. + BOOST_STATIC_CONSTANT(bool, use_identity = (::boost::is_scalar::value)); + + typedef typename mpl::select_type< + use_identity + , T + , typename add_reference::type>::type + >::type type; +}; + +// When partial specialization is not present, we'll simply need to +// register many more converters. +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +template +struct target +{ + typedef typename remove_cv::type& type; +}; + +template +struct target +{ + typedef typename remove_cv::type* type; +}; + +// Handle T*-cv for completeness. Function arguments in a signature +// are never actually cv-qualified, but who knows how these converters +// might be used, or whether compiler bugs lurk which make it seem +// otherwise? +template +struct target +{ + typedef typename remove_cv::type* type; +}; + +template +struct target +{ + typedef typename remove_cv::type* type; +}; + +template +struct target +{ + typedef typename remove_cv::type* type; +}; + +// non-const references to pointers should be handled by the +// specialization for T&, above. +template +struct target +{ + typedef typename remove_cv::type* type; +}; +# endif + +// Fortunately, we can handle T const& where T is an arithmetic type +// by explicit specialization. These specializations will cause value +// and const& arguments to be converted to values, rather than to +// references. +# define BOOST_PYTHON_UNWRAP_VALUE(T) \ +template <> \ +struct target \ +{ \ + typedef T type; \ +}; \ +template <> \ +struct target \ +{ \ + typedef T type; \ +}; \ +template <> \ +struct target \ +{ \ + typedef T type; \ +}; \ +template <> \ +struct target \ +{ \ + typedef T type; \ +}; \ +template <> \ +struct target \ +{ \ + typedef T type; \ +} + +BOOST_PYTHON_UNWRAP_VALUE(char); +BOOST_PYTHON_UNWRAP_VALUE(unsigned char); +BOOST_PYTHON_UNWRAP_VALUE(signed char); +BOOST_PYTHON_UNWRAP_VALUE(unsigned int); +BOOST_PYTHON_UNWRAP_VALUE(signed int); +BOOST_PYTHON_UNWRAP_VALUE(unsigned short); +BOOST_PYTHON_UNWRAP_VALUE(signed short); +BOOST_PYTHON_UNWRAP_VALUE(unsigned long); +BOOST_PYTHON_UNWRAP_VALUE(signed long); +BOOST_PYTHON_UNWRAP_VALUE(char const*); + +}}} // namespace boost::python::converter + +#endif // TARGET_DWA20011119_HPP diff --git a/include/boost/python/converter/type_id.hpp b/include/boost/python/converter/type_id.hpp new file mode 100644 index 00000000..ddc04266 --- /dev/null +++ b/include/boost/python/converter/type_id.hpp @@ -0,0 +1,200 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TYPE_ID_DWA20011127_HPP +# define TYPE_ID_DWA20011127_HPP +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + + +namespace boost { namespace python { namespace converter { + +// a portable mechanism for identifying types at runtime across modules. + +namespace detail +{ + template class dummy; +} + +// for this compiler at least, cross-shared-library type_info +// comparisons don't work, so use typeid(x).name() instead. It's not +// yet clear what the best default strategy is. +# if defined(__GNUC__) && __GNUC__ >= 3 +# define BOOST_PYTHON_TYPE_ID_NAME +# endif + +# if 1 +struct type_id_t : totally_ordered +{ + enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 }; + +# ifdef BOOST_PYTHON_TYPE_ID_NAME +typedef char const* base_id_t; +# else +typedef std::type_info const* base_id_t; +# endif + + type_id_t(base_id_t, decoration decoration); + + bool operator<(type_id_t const& rhs) const; + bool operator==(type_id_t const& rhs) const; + friend BOOST_PYTHON_EXPORT std::ostream& operator<<(std::ostream&, type_id_t const&); + + private: + decoration m_decoration; + base_id_t m_base_type; +}; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct is_reference_to_const +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_reference_to_const +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template +struct is_reference_to_volatile +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_reference_to_volatile +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; +# else +template +struct is_const_help +{ + typedef typename mpl::select_type< + is_const::value + , type_traits::yes_type + , type_traits::no_type + >::type type; +}; + +template +struct is_volatile_help +{ + typedef typename mpl::select_type< + is_volatile::value + , type_traits::yes_type + , type_traits::no_type + >::type type; +}; + +template +typename is_const_help::type reference_to_const_helper(V&); + +type_traits::no_type +reference_to_const_helper(...); + +template +struct is_reference_to_const +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_const_helper(t)) == sizeof(type_traits::yes_type)); +}; + +template +typename is_volatile_help::type reference_to_volatile_helper(V&); +type_traits::no_type reference_to_volatile_helper(...); + +template +struct is_reference_to_volatile +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_volatile_helper(t)) == sizeof(type_traits::yes_type)); +}; +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +template +inline type_id_t type_id(detail::dummy* = 0) +{ + return type_id_t( +# ifdef BOOST_PYTHON_TYPE_ID_NAME + typeid(T).name() +# else + &typeid(T) +# endif + , type_id_t::decoration( + (is_const::value || is_reference_to_const::value + ? type_id_t::const_ : 0) + | (is_volatile::value || is_reference_to_volatile::value + ? type_id_t::volatile_ : 0) + | (is_reference::value ? type_id_t::reference : 0) + ) + ); +} + +inline type_id_t::type_id_t(base_id_t base_t, decoration decoration) + : m_decoration(decoration) + , m_base_type(base_t) +{ +} + +inline bool type_id_t::operator<(type_id_t const& rhs) const +{ + return m_decoration < rhs.m_decoration + || m_decoration == rhs.m_decoration +# ifdef BOOST_PYTHON_TYPE_ID_NAME + && std::strcmp(m_base_type, rhs.m_base_type) < 0; +# else + && m_base_type->before(*rhs.m_base_type); +# endif +} + +inline bool type_id_t::operator==(type_id_t const& rhs) const +{ + return m_decoration == rhs.m_decoration +# ifdef BOOST_PYTHON_TYPE_ID_NAME + && !std::strcmp(m_base_type, rhs.m_base_type); +# else + && *m_base_type == *rhs.m_base_type; +# endif +} + +# else +// This is the type which is used to identify a type +typedef char const* type_id_t; + +// This is a workaround for a silly MSVC bug +// Converts a compile-time type to its corresponding runtime identifier. +template +type_id_t type_id(detail::dummy* = 0) +{ + return typeid(T).name(); +} +# endif + +struct BOOST_PYTHON_EXPORT type_id_before +{ + bool operator()(type_id_t const& x, type_id_t const& y) const; +}; + +BOOST_PYTHON_EXPORT std::ostream& operator<<(std::ostream&, type_id_t const&); + +}}} // namespace boost::python::converter + +#endif // TYPE_ID_DWA20011127_HPP diff --git a/include/boost/python/converter/unwrap.hpp b/include/boost/python/converter/unwrap.hpp new file mode 100644 index 00000000..6dda61fb --- /dev/null +++ b/include/boost/python/converter/unwrap.hpp @@ -0,0 +1,192 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef UNWRAP_BASE_DWA20011130_HPP +# define UNWRAP_BASE_DWA20011130_HPP + +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +template struct unwrapper; +struct BOOST_PYTHON_EXPORT body; + +struct BOOST_PYTHON_EXPORT unwrap_base : handle +{ + public: // member functions + inline unwrap_base(PyObject* source, body*, handle& prev); + inline unwrap_base(PyObject* source, body*); + inline PyObject* source() const; + + private: // data members + PyObject* m_source; +}; + +// These converters will be used by the function wrappers. They don't +// manage any resources, but are instead linked into a chain which is +// managed by an instance of unwrap_ or wrap_. +template +struct unwrap_more_ : unwrap_base +{ + public: // member functions + // Construction + unwrap_more_(PyObject* source, handle& prev); + + // invoke the conversion or throw an exception if unsuccessful + T operator*(); + + protected: // constructor + // this constructor is only for the use of unwrap_ + unwrap_more_(PyObject* source); + + private: // helper functions + // Return the unwrapper which will convert the given Python object + // to T, or 0 if no such converter exists + static unwrapper_base* lookup(PyObject*); + + private: + // unspecified storage which may be allocated by the unwrapper to + // do value conversions. + mutable void* m_storage; + friend class unwrapper; +}; + +// specialization for PyObject* +template <> +struct unwrap_more_ + : unwrap_base +{ + public: // member functions + // Construction + unwrap_more_(PyObject* source, handle& prev) + : unwrap_base(source, m_unwrapper, prev) + { + } + + + // invoke the conversion or throw an exception if unsuccessful + PyObject* operator*() + { + return source(); + } + + bool convertible(PyObject*) const + { + return true; + } + + protected: // constructor + // this constructor is only for the use of unwrap_ + unwrap_more_(PyObject* source) + : unwrap_base(source, m_unwrapper) + + { + } + private: + static BOOST_PYTHON_EXPORT unwrapper_base* m_unwrapper; +}; + +template +struct unwrap_ : unwrap_more_ +{ + unwrap_(PyObject* source); + ~unwrap_(); +}; + +// +// implementations +// +inline unwrap_base::unwrap_base(PyObject* source, body* body, handle& prev) + : handle(body, prev) + , m_source(source) +{ +} + +inline unwrap_base::unwrap_base(PyObject* source, body* body) + : handle(body) + , m_source(source) +{ +} + +inline PyObject* unwrap_base::source() const +{ + return m_source; +} + +template +inline unwrapper_base* unwrap_more_::lookup(PyObject* source) +{ + // Find the converters registered for T and get a unwrapper + // appropriate for the source object + return registration::unwrapper(source); +} + +template +unwrap_more_::unwrap_more_(PyObject* source, handle& prev) + : unwrap_base(source, lookup(source), prev) + , m_storage(0) +{ +} + +template +unwrap_more_::unwrap_more_(PyObject* source) + : unwrap_base(source, lookup(source)) + , m_storage(0) +{ +} + +# if 0 +template <> +inline unwrap_more_::unwrap_more_(PyObject* source, handle& prev) + : unwrap_base(source, m_unwrapper, prev) +{ +} + +template <> +inline unwrap_more_::unwrap_more_(PyObject* source) + : unwrap_base(source, m_unwrapper) + +{ +} + +template <> +inline PyObject* unwrap_more_::operator*() +{ + return source(); +} + +template <> +inline bool unwrap_more_::convertible(PyObject*) const +{ + return true; +} +# endif +template +inline unwrap_::unwrap_(PyObject* source) + : unwrap_more_(source) +{ +} + +template +T unwrap_more_::operator*() +{ + return static_cast*>( + get_body())->do_conversion(this); +} + +template +unwrap_::~unwrap_() +{ + destroy(); +} + +}}} // namespace boost::python::converter + +#endif // UNWRAP_BASE_DWA20011130_HPP diff --git a/include/boost/python/converter/unwrapper.hpp b/include/boost/python/converter/unwrapper.hpp new file mode 100644 index 00000000..a30ff522 --- /dev/null +++ b/include/boost/python/converter/unwrapper.hpp @@ -0,0 +1,53 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef UNWRAPPER_DWA2001127_HPP +# define UNWRAPPER_DWA2001127_HPP + +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +template struct unwrap_more_; + +// Abstract base for all unwrappers of Ts +template +struct unwrapper : unwrapper_base +{ + public: + unwrapper(); + + T do_conversion(unwrap_more_ const* handle) const; + + private: + virtual T convert(PyObject*, void*&) const = 0; + + private: // body required interface implementation + void destroy_handle(handle*) const {} +}; + +// +// implementations +// +template +unwrapper::unwrapper() + : unwrapper_base(type_id()) +{ +} + +// We could think about making this virtual in an effort to get its +// code generated in the module where the unwrapper is defined, but +// it's not clear that it's a good tradeoff. +template +T unwrapper::do_conversion(unwrap_more_ const* handle) const +{ + return convert(handle->source(), handle->m_storage); +} + +}}} // namespace boost::python::converter + +#endif // UNWRAPPER_DWA2001127_HPP diff --git a/include/boost/python/converter/unwrapper_base.hpp b/include/boost/python/converter/unwrapper_base.hpp new file mode 100644 index 00000000..54e2e54c --- /dev/null +++ b/include/boost/python/converter/unwrapper_base.hpp @@ -0,0 +1,25 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef UNWRAPPER_BASE_DWA20011215_HPP +# define UNWRAPPER_BASE_DWA20011215_HPP +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +struct BOOST_PYTHON_EXPORT unwrapper_base : body +{ + public: + unwrapper_base(type_id_t); // registers + ~unwrapper_base(); // unregisters + virtual bool convertible(PyObject*) const = 0; +}; + +}}} // namespace boost::python::converter + +#endif // UNWRAPPER_BASE_DWA20011215_HPP diff --git a/include/boost/python/converter/wrap.hpp b/include/boost/python/converter/wrap.hpp new file mode 100644 index 00000000..91c9de86 --- /dev/null +++ b/include/boost/python/converter/wrap.hpp @@ -0,0 +1,145 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef WRAP_DWA2001127_HPP +# define WRAP_DWA2001127_HPP +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +struct BOOST_PYTHON_EXPORT wrapper_base; + +template struct wrapper; + +struct wrap_base : handle +{ + public: // member functions + wrap_base(body*, handle& prev); + wrap_base(body*); + PyObject* release(); + + public: // accessor, really only for wrappers + PyObject*& target() const; + + protected: + void hold_result(PyObject*) const; + + private: + mutable PyObject* m_target; +}; + +template +struct wrap_more_ : wrap_base +{ + protected: + typedef T source_t; + + public: // member functions + wrap_more_(handle& prev); + + PyObject* operator()(source_t) const; + + protected: // constructor for wrap_, below + wrap_more_(); + + private: // helper functions + static wrapper_base* lookup(); + + private: + friend class wrapper; +}; + +template +struct wrap_ : wrap_more_ +{ + typedef typename wrap_more_::source_t source_t; + public: // member functions + wrap_(); + ~wrap_(); +}; + +// +// implementations +// + +inline wrap_base::wrap_base(body* body, handle& prev) + : handle(body, prev), + m_target(0) +{ +} + +inline wrap_base::wrap_base(body* body) + : handle(body), + m_target(0) +{ +} + +inline PyObject*& wrap_base::target() const +{ + return m_target; +} + +inline void wrap_base::hold_result(PyObject* p) const +{ + assert(m_target == 0); + m_target = p; +} + +inline PyObject* wrap_base::release() +{ + PyObject* result = m_target; + m_target = 0; + return result; +} + +template +inline wrapper_base* wrap_more_::lookup() +{ + // Find the converters registered for T and get a wrapper + // appropriate for the source object + return registration::wrapper(); +} + +template +inline wrap_more_::wrap_more_(handle& prev) + : wrap_base(lookup(), prev) +{ + +} + +template +PyObject* wrap_more_::operator()(source_t x) const +{ + return static_cast*>( + get_body())->do_conversion(*this, source_holder(x)); +} + +template +wrap_more_::wrap_more_() + : wrap_base(lookup()) +{ +} + +template +wrap_::wrap_() + : wrap_more_() +{ +} + +template +wrap_::~wrap_() +{ + destroy(); +} + +}}} // namespace boost::python::converter + +#endif // WRAP_DWA2001127_HPP diff --git a/include/boost/python/converter/wrapper.hpp b/include/boost/python/converter/wrapper.hpp new file mode 100644 index 00000000..ada5e8cb --- /dev/null +++ b/include/boost/python/converter/wrapper.hpp @@ -0,0 +1,69 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef WRAPPER_DWA2001127_HPP +# define WRAPPER_DWA2001127_HPP +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +struct source_holder_base; +struct wrap_base; +template struct wrap_more_; + +struct BOOST_PYTHON_EXPORT wrapper_base : body +{ + public: + wrapper_base(type_id_t); // registers + ~wrapper_base(); // unregisters + + virtual PyObject* do_conversion(wrap_base const&, source_holder_base const&) const = 0; +}; + +template +struct wrapper : wrapper_base +{ + public: + wrapper(); + + PyObject* do_conversion(wrap_base const&, source_holder_base const&) const; + + // This does the actual conversion + virtual PyObject* convert(T source) const = 0; +}; + +// +// implementations +// + +template +wrapper::wrapper() + : wrapper_base(type_id()) +{ +} + + +template +PyObject* wrapper::do_conversion(wrap_base const& handle_, source_holder_base const& data_) const +{ + // Casting pointers instead of references suppresses a CWPro7 bug. + wrap_more_ const& handle = *static_cast const*>(&handle_); + source_holder const& data = *static_cast const*>(&data_); + if (handle.target() == 0) + { + handle.hold_result(convert(data.value)); + } + return handle.target(); +} + +}}} // namespace boost::python::converter + +#endif // WRAPPER_DWA2001127_HPP diff --git a/include/boost/python/cross_module.hpp b/include/boost/python/cross_module.hpp index dd1c47d2..f5ca315d 100644 --- a/include/boost/python/cross_module.hpp +++ b/include/boost/python/cross_module.hpp @@ -18,26 +18,28 @@ # include namespace boost { namespace python { - struct import_error : error_already_set {}; - struct export_error : error_already_set {}; -}} + struct BOOST_PYTHON_DECL import_error: error_already_set {}; + struct BOOST_PYTHON_DECL export_error : error_already_set {}; -namespace boost { namespace python { namespace detail { +namespace detail +{ // Concept: throw exception if api_major is changed // show warning on stderr if api_minor is changed -const int export_converters_api_major = 4; -const int export_converters_api_minor = 1; -extern const char* converters_attribute_name; -void* import_converter_object(const std::string& module_name, - const std::string& py_class_name, - const std::string& attribute_name); -void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor); + const int export_converters_api_major = 4; + const int export_converters_api_minor = 1; + extern BOOST_PYTHON_DECL const char* converters_attribute_name; + BOOST_PYTHON_DECL void* import_converter_object(const std::string& module_name, + const std::string& py_class_name, + const std::string& attribute_name); + BOOST_PYTHON_DECL void check_export_converters_api(const int importing_major, + const int importing_minor, + const int imported_major, + const int imported_minor); -}}} +} + +}} // namespace boost::python // forward declaration namespace boost { namespace python { namespace detail { @@ -232,56 +234,56 @@ struct export_converter_object : export_converter_object_noncopyable } }; -namespace detail { +namespace detail +{ /* This class template is instantiated by import_converters. Its purpose is to import the converter_object via the Python API. The actual import is only done once. The pointer to the imported converter object is kept in the static data member imported_converters. - */ -template -class import_extension_class - : public python_import_extension_class_converters -{ - public: - inline import_extension_class(const char* module, const char* py_class) { - m_module = module; - m_py_class = py_class; - } +*/ + template + class import_extension_class + : public python_import_extension_class_converters + { + public: + inline import_extension_class(const char* module, const char* py_class) { + m_module = module; + m_py_class = py_class; + } - static boost::python::export_converter_object_base* get_converters(); + static boost::python::export_converter_object_base* get_converters(); - private: - static std::string m_module; - static std::string m_py_class; - static boost::python::export_converter_object_base* imported_converters; -}; + private: + static std::string m_module; + static std::string m_py_class; + static boost::python::export_converter_object_base* imported_converters; + }; -template std::string import_extension_class::m_module; -template std::string import_extension_class::m_py_class; -template -boost::python::export_converter_object_base* -import_extension_class::imported_converters = 0; + template std::string import_extension_class::m_module; + template std::string import_extension_class::m_py_class; + template + boost::python::export_converter_object_base* + import_extension_class::imported_converters = 0; -template -boost::python::export_converter_object_base* -import_extension_class::get_converters() { - if (imported_converters == 0) { - void* cobject - = import_converter_object(m_module, m_py_class, - converters_attribute_name); - imported_converters - = static_cast*>(cobject); - check_export_converters_api( - export_converters_api_major, - export_converters_api_minor, - imported_converters->get_api_major(), - imported_converters->get_api_minor()); + template + boost::python::export_converter_object_base* + import_extension_class::get_converters() { + if (imported_converters == 0) { + void* cobject + = import_converter_object(m_module, m_py_class, + converters_attribute_name); + imported_converters + = static_cast*>(cobject); + check_export_converters_api( + export_converters_api_major, + export_converters_api_minor, + imported_converters->get_api_major(), + imported_converters->get_api_minor()); + } + return imported_converters; } - return imported_converters; -} - }}} // namespace boost::python::detail namespace boost { namespace python { diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp new file mode 100644 index 00000000..e6b6ccc1 --- /dev/null +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -0,0 +1,233 @@ +// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// This work was funded in part by Lawrence Berkeley National Labs +// +// This file generated for 5-argument member functions and 6-argument free +// functions by gen_arg_tuple_size.python + +#ifndef ARG_TUPLE_SIZE_DWA20011201_HPP +# define ARG_TUPLE_SIZE_DWA20011201_HPP + +namespace boost { namespace python { namespace detail { + +// Computes (at compile-time) the number of elements that a Python +// argument tuple must have in order to be passed to a wrapped C++ +// (member) function of the given type. +template struct arg_tuple_size; + +# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__BORLANDC__) + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 0); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 1); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 2); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 3); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 4); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 5); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 6); +}; + + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 1); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 2); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 3); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 4); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 5); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 6); +}; + +# else + +// We will use the "sizeof() trick" to work around the lack of +// partial specialization in MSVC6 and its broken-ness in borland. +// See http://opensource.adobe.com or +// http://groups.yahoo.com/group/boost/message/5441 for +// more examples + +// This little package is used to transmit the number of arguments +// from the helper functions below to the sizeof() expression below. +// Because we can never have an array of fewer than 1 element, we +// add 1 to n and then subtract 1 from the result of sizeof() below. +template +struct char_array +{ + char elements[n+1]; +}; + +// The following helper functions are never actually called, since +// they are only used within a sizeof() expression, but the type of +// their return value is used to discriminate between various free +// and member function pointers at compile-time. + +template +char_array<0> arg_tuple_size_helper(R (*)()); + +template +char_array<1> arg_tuple_size_helper(R (*)(A1)); + +template +char_array<2> arg_tuple_size_helper(R (*)(A1, A2)); + +template +char_array<3> arg_tuple_size_helper(R (*)(A1, A2, A3)); + +template +char_array<4> arg_tuple_size_helper(R (*)(A1, A2, A3, A4)); + +template +char_array<5> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5)); + +template +char_array<6> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5, A6)); + +template +char_array<1> arg_tuple_size_helper(R (A0::*)()); + +template +char_array<2> arg_tuple_size_helper(R (A0::*)(A1)); + +template +char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2)); + +template +char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3)); + +template +char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4)); + +template +char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5)); + + +template +char_array<1> arg_tuple_size_helper(R (A0::*)() const); + +template +char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const); + +template +char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const); + +template +char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const); + +template +char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const); + +template +char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const); + + +template +char_array<1> arg_tuple_size_helper(R (A0::*)() volatile); + +template +char_array<2> arg_tuple_size_helper(R (A0::*)(A1) volatile); + +template +char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) volatile); + +template +char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) volatile); + +template +char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) volatile); + +template +char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) volatile); + + +template +char_array<1> arg_tuple_size_helper(R (A0::*)() const volatile); + +template +char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const volatile); + +template +char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const volatile); + +template +char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const volatile); + +template +char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const volatile); + +template +char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const volatile); + + +template +struct arg_tuple_size +{ + // The sizeof() magic happens here + BOOST_STATIC_CONSTANT(std::size_t, value + = sizeof(arg_tuple_size_helper(F(0)).elements) - 1); +}; +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +}}} // namespace boost::python::detail + +#endif // ARG_TUPLE_SIZE_DWA20011201_HPP + diff --git a/include/boost/python/detail/base_object.hpp b/include/boost/python/detail/base_object.hpp index 19715876..d92b3972 100644 --- a/include/boost/python/detail/base_object.hpp +++ b/include/boost/python/detail/base_object.hpp @@ -13,7 +13,6 @@ # define BASE_OBJECT_DWA051600_H_ # include -# include // really just for type<> # include # include @@ -45,10 +44,7 @@ template base_object::base_object(PyTypeObject* type_obj) { base_python_type* bp = this; -#if !defined(_MSC_VER) || defined(__STLPORT) - std:: -#endif - memset(bp, 0, sizeof(base_python_type)); + BOOST_CSTD_::memset(bp, 0, sizeof(base_python_type)); Py_INCREF(type_obj); PyObject_INIT(bp, type_obj); } diff --git a/include/boost/python/detail/call_object.hpp b/include/boost/python/detail/call_object.hpp new file mode 100644 index 00000000..5595e5c0 --- /dev/null +++ b/include/boost/python/detail/call_object.hpp @@ -0,0 +1,66 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CALL_OBJECT_DWA20011222_HPP +# define CALL_OBJECT_DWA20011222_HPP +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + // A function object adaptor which turns a function returning R into + // an "equivalent" function returning void, but taking an R& in + // which the adapted function's result is stored. + template + struct return_by_reference + { + typedef void return_type; + + return_by_reference(R& result, F f) + : m_result(result) + , m_f(f) + { + } + + void operator()() const + { + m_result = m_f(); + } + + R& m_result; + F m_f; + }; + + // An object generator for the above adaptors + template + return_by_reference bind_return(R& result, F f) + { + return return_by_reference(result, f); + } + + // Given a function object f with signature + // + // R f(PyTypeObject*,PyObject*) + // + // calls f inside of handle_exception_impl, placing f's result in + // ret. Returns true iff an exception is thrown by f, leaving ret + // unmodified. + template + bool call_object(R& ret, PyObject* obj, F f) + { + return handle_exception( + detail::bind_return( + ret + , boost::bind( + f, static_cast(obj->ob_type), obj))); + } +} // namespace detail + +}} // namespace boost::python + +#endif // CALL_OBJECT_DWA20011222_HPP diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp new file mode 100644 index 00000000..95c6dc7a --- /dev/null +++ b/include/boost/python/detail/caller.hpp @@ -0,0 +1,27 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CALLER_DWA20011214_HPP +# define CALLER_DWA20011214_HPP + +# include +# include + +namespace boost { namespace python { namespace detail { + +struct caller +{ + typedef PyObject* result_type; + + template + PyObject* operator()(F f, PyObject* args, PyObject* keywords) + { + return call(f, args, keywords); + } +}; + +}}} // namespace boost::python::detail + +#endif // CALLER_DWA20011214_HPP diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 0fc1093a..498fa07a 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -59,9 +59,9 @@ # ifndef BOOST_PYTHON_MODULE_INIT # if defined(_WIN32) || defined(__CYGWIN__) -# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name() +# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name() # else -# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(init_module_##name); } void init_module_##name() +# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name() # endif # endif @@ -72,23 +72,23 @@ ****************************************************************************/ // backwards compatibility: -#ifdef BOOST_RE_STATIC_LIB +#ifdef BOOST_PYTHON_STATIC_LIB # define BOOST_PYTHON_STATIC_LINK #endif -#if defined(BOOST_MSVC) && defined(_DLL) +#if defined(BOOST_MSVC) && defined(_DLL) && !defined(BOOST_PYTHON_HAS_DLL_RUNTIME) # define BOOST_PYTHON_HAS_DLL_RUNTIME #endif -#if defined(__BORLANDC__) && defined(_RTLDLL) +#if defined(__BORLANDC__) && defined(_RTLDLL) && !defined(BOOST_PYTHON_HAS_DLL_RUNTIME) # define BOOST_PYTHON_HAS_DLL_RUNTIME #endif -#if defined(__ICL) && defined(_DLL) +#if defined(__ICL) && defined(_DLL) && !defined(BOOST_PYTHON_HAS_DLL_RUNTIME) # define BOOST_PYTHON_HAS_DLL_RUNTIME #endif -#if defined(BOOST_PYTHON_HAS_DLL_RUNTIME) && !defined(BOOST_PYTHON_STATIC_LINK) +#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32) // && !defined(BOOST_PYTHON_STATIC_LINK) # if defined(BOOST_PYTHON_SOURCE) # define BOOST_PYTHON_DECL __declspec(dllexport) # define BOOST_PYTHON_BUILD_DLL @@ -102,7 +102,7 @@ #endif #if (defined(BOOST_MSVC) || defined(__BORLANDC__)) && !defined(BOOST_PYTHON_NO_LIB) && !defined(BOOST_PYTHON_SOURCE) -# include +// # include #endif // Borland C++ Fix/error check: @@ -117,7 +117,7 @@ # endif # endif # ifndef _RTLDLL - // this is harmless for a staic link: + // this is harmless for a static link: # define _RWSTD_COMPILE_INSTANTIATE # endif # endif diff --git a/include/boost/python/detail/python_library_include.hpp b/include/boost/python/detail/python_library_include.hpp index 903f02be..d2b78c6e 100644 --- a/include/boost/python/detail/python_library_include.hpp +++ b/include/boost/python/detail/python_library_include.hpp @@ -1,3 +1,4 @@ +#error obsolete /* * * Copyright (c) 1998-2000 diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp new file mode 100644 index 00000000..28f1846e --- /dev/null +++ b/include/boost/python/detail/returning.hpp @@ -0,0 +1,846 @@ +// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// This work was funded in part by Lawrence Berkeley National Labs +// +// This file generated for 5-argument member functions and 6-argument free +// functions by gen_returning.py + +#ifndef RETURNING_DWA20011201_HPP +# define RETURNING_DWA20011201_HPP + +//# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +// Calling C++ from Python +template +struct returning +{ + template + static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + + // find the result converter + wrap_more r(c0); + if (!c0) return 0; + return r( ((*c0).*pmf)() ); + }; + template + static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + + // find the result converter + wrap_more r(c1); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + + // find the result converter + wrap_more r(c2); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + + // find the result converter + wrap_more r(c3); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + + // find the result converter + wrap_more r(c4); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + + // find the result converter + wrap_more r(c5); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); + }; + + template + static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + + // find the result converter + wrap_more r(c0); + if (!c0) return 0; + return r( ((*c0).*pmf)() ); + }; + template + static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + + // find the result converter + wrap_more r(c1); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + + // find the result converter + wrap_more r(c2); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + + // find the result converter + wrap_more r(c3); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + + // find the result converter + wrap_more r(c4); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + + // find the result converter + wrap_more r(c5); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); + }; + + template + static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + + // find the result converter + wrap_more r(c0); + if (!c0) return 0; + return r( ((*c0).*pmf)() ); + }; + template + static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + + // find the result converter + wrap_more r(c1); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + + // find the result converter + wrap_more r(c2); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + + // find the result converter + wrap_more r(c3); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + + // find the result converter + wrap_more r(c4); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + + // find the result converter + wrap_more r(c5); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); + }; + + +// missing const volatile type traits +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + + // find the result converter + wrap_more r(c0); + if (!c0) return 0; + return r( ((*c0).*pmf)() ); + }; + template + static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + + // find the result converter + wrap_more r(c1); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + + // find the result converter + wrap_more r(c2); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + + // find the result converter + wrap_more r(c3); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + + // find the result converter + wrap_more r(c4); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + + // find the result converter + wrap_more r(c5); + if (!c0) return 0; + return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); + }; + +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + static PyObject* call(R (*pf)(), PyObject*, PyObject* /* keywords */ ) + { + // find the result converter + wrap r; + return r( (*pf)() ); + }; + template + static PyObject* call(R (*pf)(A0), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + + // find the result converter + wrap_more r(c0); + if (!c0) return 0; + return r( (*pf)(*c0) ); + }; + template + static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + + // find the result converter + wrap_more r(c1); + if (!c0) return 0; + return r( (*pf)(*c0, *c1) ); + }; + template + static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + + // find the result converter + wrap_more r(c2); + if (!c0) return 0; + return r( (*pf)(*c0, *c1, *c2) ); + }; + template + static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + + // find the result converter + wrap_more r(c3); + if (!c0) return 0; + return r( (*pf)(*c0, *c1, *c2, *c3) ); + }; + template + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + + // find the result converter + wrap_more r(c4); + if (!c0) return 0; + return r( (*pf)(*c0, *c1, *c2, *c3, *c4) ); + }; + template + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + + // find the result converter + wrap_more r(c5); + if (!c0) return 0; + return r( (*pf)(*c0, *c1, *c2, *c3, *c4, *c5) ); + }; +}; + +template <> +struct returning +{ + typedef void R; + template + static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + + if (!c0) return 0; + ((*c0).*pmf)(); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + + if (!c0) return 0; + ((*c0).*pmf)(*c1); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3, *c4); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); + return detail::none(); + }; + + template + static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + + if (!c0) return 0; + ((*c0).*pmf)(); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + + if (!c0) return 0; + ((*c0).*pmf)(*c1); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3, *c4); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); + return detail::none(); + }; + + template + static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + + if (!c0) return 0; + ((*c0).*pmf)(); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + + if (!c0) return 0; + ((*c0).*pmf)(*c1); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3, *c4); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); + return detail::none(); + }; + + +// missing const volatile type traits +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + + if (!c0) return 0; + ((*c0).*pmf)(); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + + if (!c0) return 0; + ((*c0).*pmf)(*c1); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3, *c4); + return detail::none(); + }; + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + + if (!c0) return 0; + ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); + return detail::none(); + }; + +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + static PyObject* call(R (*pf)(), PyObject*, PyObject* /* keywords */ ) + { + (*pf)(); + return detail::none(); + }; + template + static PyObject* call(R (*pf)(A0), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + + if (!c0) return 0; + (*pf)(*c0); + return detail::none(); + }; + template + static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + + if (!c0) return 0; + (*pf)(*c0, *c1); + return detail::none(); + }; + template + static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + + if (!c0) return 0; + (*pf)(*c0, *c1, *c2); + return detail::none(); + }; + template + static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + + if (!c0) return 0; + (*pf)(*c0, *c1, *c2, *c3); + return detail::none(); + }; + template + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + + if (!c0) return 0; + (*pf)(*c0, *c1, *c2, *c3, *c4); + return detail::none(); + }; + template + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); + unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + + if (!c0) return 0; + (*pf)(*c0, *c1, *c2, *c3, *c4, *c5); + return detail::none(); + }; +}; + +}}} // namespace boost::python::detail + +#endif // RETURNING_DWA20011201_HPP + diff --git a/include/boost/python/detail/types.hpp b/include/boost/python/detail/types.hpp index f4e62f88..2e69d24e 100644 --- a/include/boost/python/detail/types.hpp +++ b/include/boost/python/detail/types.hpp @@ -31,12 +31,8 @@ namespace boost { namespace python { -class string; - namespace detail { -class instance_holder_base; - class BOOST_PYTHON_DECL type_object_base : public python_type { public: diff --git a/include/boost/python/detail/void_adaptor.hpp b/include/boost/python/detail/void_adaptor.hpp index 3d60e4bf..3b4b2124 100644 --- a/include/boost/python/detail/void_adaptor.hpp +++ b/include/boost/python/detail/void_adaptor.hpp @@ -8,7 +8,7 @@ namespace boost { namespace python { namespace detail { - BOOST_PYTHON_DECL extern PyObject arbitrary_object; + extern BOOST_PYTHON_DECL PyObject arbitrary_object; template struct void_adaptor diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index 34a9c2b5..d0ad5dd2 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -34,36 +34,36 @@ // Some things we need in order to get Python.h to work with compilers other // than MSVC on Win32 // -#if defined(_WIN32) +#if defined(_WIN32) || defined(__CYGWIN__) # if defined(__GNUC__) && defined(__CYGWIN__) # if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 typedef int pid_t; # define WORD_BIT 32 # define hypot _hypot # include +# if PY_MAJOR_VERSION < 2 +# define HAVE_CLOCK +# define HAVE_STRFTIME +# define HAVE_STRERROR +# endif +# define NT_THREADS +# define WITH_THREAD +# ifndef NETSCAPE_PI +# define USE_SOCKET +# endif + +# ifdef USE_DL_IMPORT +# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE +# endif + +# ifdef USE_DL_EXPORT +# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE +# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE +# endif + +# define HAVE_LONG_LONG 1 +# define LONG_LONG long long # endif -# if !defined(PY_MAJOR_VERSION) || PY_MAJOR_VERSION < 2 -# define HAVE_CLOCK -# define HAVE_STRFTIME -# define HAVE_STRERROR -# endif -# define NT_THREADS -# define WITH_THREAD -# ifndef NETSCAPE_PI -# define USE_SOCKET -# endif - -# ifdef USE_DL_IMPORT -# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE -# endif - -# ifdef USE_DL_EXPORT -# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE -# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE -# endif - -# define HAVE_LONG_LONG 1 -# define LONG_LONG long long # elif defined(__MWERKS__) diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp index 66f15587..b9eb4363 100644 --- a/include/boost/python/errors.hpp +++ b/include/boost/python/errors.hpp @@ -9,57 +9,31 @@ #ifndef ERRORS_DWA052500_H_ # define ERRORS_DWA052500_H_ +# include # include +# include namespace boost { namespace python { struct error_already_set {}; struct argument_error : error_already_set {}; -struct object_functor_base -{ - typedef PyObject* result_type; - virtual PyObject* operator()() const = 0; - private: - static void* operator new(std::size_t); // don't allow dynamic allocation - void operator delete(void*); - void operator delete(void*, size_t); -}; - -template -struct object_functor : object_functor_base -{ - object_functor(T const& f) - : m_f(f) - { - } - - PyObject* operator()() const - { - return m_f(); - } - private: - T const& m_f; -}; - - // Handles exceptions caught just before returning to Python code. -PyObject* handle_exception_impl(object_functor_base const& f); +// Returns true iff an exception was caught. +BOOST_PYTHON_DECL bool handle_exception_impl(function0); template -PyObject* handle_exception(T const& f) +bool handle_exception(T f) { - return handle_exception_impl(object_functor(f)); + return handle_exception_impl(function0(boost::ref(f))); } -void handle_exception(void (*)()); +BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x); template T* expect_non_null(T* x) { - if (x == 0) - throw error_already_set(); - return x; + return (T*)expect_non_null((PyObject*)x); } }} // namespace boost::python diff --git a/include/boost/python/export.hpp b/include/boost/python/export.hpp new file mode 100644 index 00000000..1229dffe --- /dev/null +++ b/include/boost/python/export.hpp @@ -0,0 +1,20 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef EXPORT_DWA20011220_HPP +# define EXPORT_DWA20011220_HPP + +# include +# ifdef _WIN32 +# ifdef BOOST_PYTHON_SOURCE +# define BOOST_PYTHON_EXPORT __declspec(dllexport) +# else +# define BOOST_PYTHON_EXPORT __declspec(dllimport) +# endif +# else +# define BOOST_PYTHON_EXPORT +# endif + +#endif // EXPORT_DWA20011220_HPP diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp new file mode 100644 index 00000000..d824c0a4 --- /dev/null +++ b/include/boost/python/make_function.hpp @@ -0,0 +1,40 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MAKE_FUNCTION_DWA20011221_HPP +# define MAKE_FUNCTION_DWA20011221_HPP + +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +template +PyObject* make_function(F f) +{ + return new object::function( + object::py_function( + bind(detail::caller(), f, _1, _2))); +} + +template +PyObject* make_constructor(T* = 0, ArgList* = 0, Generator* = 0) +{ + enum { nargs = mpl::size::value }; + return new object::function( + object::py_function( + bind(detail::caller(), + object::make_holder + ::template apply::execute + , _1, _2))); +} + +}} // namespace boost::python + +#endif // MAKE_FUNCTION_DWA20011221_HPP diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp new file mode 100644 index 00000000..c20279c3 --- /dev/null +++ b/include/boost/python/module.hpp @@ -0,0 +1,12 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MODULE_DWA2001128_HPP +# define MODULE_DWA2001128_HPP + +# include +# include + +#endif // MODULE_DWA20011221_HPP diff --git a/include/boost/python/module_builder.hpp b/include/boost/python/module_builder.hpp index 6a8a9b4b..180a6200 100644 --- a/include/boost/python/module_builder.hpp +++ b/include/boost/python/module_builder.hpp @@ -16,30 +16,18 @@ namespace boost { namespace python { -class module_builder +class BOOST_PYTHON_DECL module_builder_base { public: // Create a module. REQUIRES: only one module_builder is created per module. - module_builder(const char* name); - ~module_builder(); + module_builder_base(const char* name); + ~module_builder_base(); // Add elements to the module void add(detail::function* x, const char* name); void add(PyTypeObject* x, const char* name = 0); void add(ref x, const char*name); - template - void def_raw(Fn fn, const char* name) - { - add(detail::new_raw_arguments_function(fn), name); - } - - template - void def(Fn fn, const char* name) - { - add(detail::new_wrapped_function(fn), name); - } - // Return true iff a module is currently being built. static bool initializing(); @@ -55,10 +43,29 @@ class module_builder static PyMethodDef initial_methods[1]; }; +class module_builder : public module_builder_base +{ + public: + module_builder(const char* name) + : module_builder_base(name) {} + + template + void def_raw(Fn fn, const char* name) + { + add(detail::new_raw_arguments_function(fn), name); + } + + template + void def(Fn fn, const char* name) + { + add(detail::new_wrapped_function(fn), name); + } +}; + // // inline implementations // -inline PyObject* module_builder::module() const +inline PyObject* module_builder_base::module() const { return m_module; } diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp new file mode 100644 index 00000000..548d4053 --- /dev/null +++ b/include/boost/python/object/class.hpp @@ -0,0 +1,103 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CLASS_DWA20011214_HPP +# define CLASS_DWA20011214_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace object { + +template struct holder; + +// Base class for all holders +struct BOOST_PYTHON_EXPORT holder_base : noncopyable +{ + public: + holder_base(converter::type_id_t id); + virtual ~holder_base(); + virtual bool held_by_value() const = 0; + + holder_base* next() const; + converter::type_id_t type() const; + + void install(PyObject* inst); + + struct iterator_policies : default_iterator_policies + { + template + void increment(Iterator& p) + { + p.base() = p.base()->next(); + } + }; + + typedef iterator_adaptor< + holder_base* + , iterator_policies + , value_type_is + , reference_is + , pointer_is + , iterator_category_is > iterator; + + private: + converter::type_id_t m_type; + holder_base* m_next; +}; + +// Abstract base class which holds a Held, somehow. Provides a uniform +// way to get a pointer to the held object +template +struct holder : holder_base +{ + typedef Held held_type; + holder(); + virtual Held* target() = 0; +}; + +// Each extension instance will be one of these +struct instance +{ + PyObject_HEAD + holder_base* objects; +}; + +BOOST_PYTHON_EXPORT holder_base* find_holder_impl(PyObject*, converter::type_id_t); + +template +holder* find_holder(PyObject* p, T* = 0) +{ + return static_cast*>(find_holder_impl(p, converter::type_id())); +} + +BOOST_PYTHON_EXPORT PyTypeObject* class_metatype(); +BOOST_PYTHON_EXPORT PyTypeObject* class_type(); + +// +// implementation +// +inline holder_base* holder_base::next() const +{ + return m_next; +} + +inline converter::type_id_t holder_base::type() const +{ + return m_type; +} + +template +holder::holder() + : holder_base(converter::type_id()) +{ +} + +}}} // namespace boost::python::object + +#endif // CLASS_DWA20011214_HPP diff --git a/include/boost/python/object/class_unwrapper.hpp b/include/boost/python/object/class_unwrapper.hpp new file mode 100644 index 00000000..4fa441e1 --- /dev/null +++ b/include/boost/python/object/class_unwrapper.hpp @@ -0,0 +1,40 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CLASS_UNWRAPPER_DWA20011221_HPP +# define CLASS_UNWRAPPER_DWA20011221_HPP + +# include +# include + +namespace boost { namespace python { namespace object { + +template +struct class_unwrapper +{ + private: + template + struct reference_unwrapper : converter::unwrapper + { + bool convertible(PyObject* p) const + { + return find_holder(p) != 0; + } + + Target convert(PyObject* p, void*&) const + { + return *find_holder(p)->target(); + } + }; + + reference_unwrapper m_reference; +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + reference_unwrapper m_const_reference; +# endif +}; + +}}} // namespace boost::python::object + +#endif // CLASS_UNWRAPPER_DWA20011221_HPP diff --git a/include/boost/python/object/construct.hpp b/include/boost/python/object/construct.hpp new file mode 100644 index 00000000..3ff701d2 --- /dev/null +++ b/include/boost/python/object/construct.hpp @@ -0,0 +1,24 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CONSTRUCT_DWA20011215_HPP +# define CONSTRUCT_DWA20011215_HPP + +namespace boost { namespace python { namespace object { + +template +struct construct +{ + static + template +# include +# include +# include + +namespace boost { namespace python { namespace object { + +// A little metaprogram which selects the type to pass through an +// intermediate forwarding function when the destination argument type +// is T. +template +struct forward +{ + typedef typename mpl::select_type< + is_scalar::value | is_reference::value + , T + , reference_wrapper< + typename add_const::type + > + >::type type; +}; + +}}} // namespace boost::python::object + +#endif // FORWARD_DWA20011215_HPP diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp new file mode 100644 index 00000000..f550e8dc --- /dev/null +++ b/include/boost/python/object/function.hpp @@ -0,0 +1,36 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FUNCTION_DWA20011214_HPP +# define FUNCTION_DWA20011214_HPP + +# include +# include +# include + +namespace boost { namespace python { namespace object { + +// We use boost::function to avoid generating lots of virtual tables +typedef boost::function2 py_function; + +struct BOOST_PYTHON_EXPORT function : PyObject +{ + function(py_function); + ~function(); + + PyObject* call(PyObject*, PyObject*) const; + private: + py_function m_fn; +}; + +extern BOOST_PYTHON_EXPORT PyTypeObject function_type; + +// +// implementations +// + +}}} // namespace boost::python::object + +#endif // FUNCTION_DWA20011214_HPP diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp new file mode 100644 index 00000000..fb5ec382 --- /dev/null +++ b/include/boost/python/object/make_holder.hpp @@ -0,0 +1,124 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MAKE_HOLDER_DWA20011215_HPP +# define MAKE_HOLDER_DWA20011215_HPP + +# include +# include +# include +# include + +namespace boost { namespace python { namespace object { + + +template struct undefined; +template +struct eval +{ +# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 + // based on the (non-conforming) MSVC trick from MPL + template + struct unarymetafunction_vc : UnaryMetaFunction {}; + + // illegal C++ which causes VC to admit that unarymetafunction_vc + // can have a nested template: + template<> + struct unarymetafunction_vc + { + template struct apply; + }; + + typedef typename unarymetafunction_vc< + ::boost::mpl::detail::msvc_never_true::value + >::template apply::type type; +# else + typedef typename UnaryMetaFunction::template apply::type type; +# endif +}; + + +template struct make_holder; + +template <> +struct make_holder<0> +{ + template + struct apply + { + typedef typename eval::type holder; + static void execute( + PyObject* p) + { + (new holder(p))->install(p); + } + }; +}; + + +template <> +struct make_holder<1> +{ + template + struct apply + { + typedef typename eval::type holder; + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + + static void execute( + PyObject* p + , t0 a0) + { + (new holder(p, f0(a0)))->install(p); + } + }; +}; + +template <> +struct make_holder<2> +{ + template + struct apply + { + typedef typename eval::type holder; + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + + static void execute( + PyObject* p, t0 a0, t1 a1) + { + (new holder(p, f0(a0), f1(a1)))->install(p); + } + }; +}; + +template <> +struct make_holder<3> +{ + template + struct apply + { + typedef typename eval::type holder; + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + + static void execute( + PyObject* p, t0 a0, t1 a1, t2 a2) + { + (new holder(p, f0(a0), f1(a1), f2(a2)))->install(p); + } + }; +}; + +}}} // namespace boost::python::object + +#endif // MAKE_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp new file mode 100644 index 00000000..128d170b --- /dev/null +++ b/include/boost/python/object/value_holder.hpp @@ -0,0 +1,80 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef VALUE_HOLDER_DWA20011215_HPP +# define VALUE_HOLDER_DWA20011215_HPP + +# include + +namespace boost { namespace python { namespace object { + +template +struct value_holder : holder +{ + // Forward construction to the held object + value_holder(PyObject*) + : m_held() {} + + template + value_holder(PyObject*, A1 a1) + : m_held(a1) {} + + template + value_holder(PyObject*, A1 a1, A2 a2) + : m_held(a1, a2) {} + + template + value_holder(PyObject*, A1 a1, A2 a2, A3 a3) + : m_held(a1, a2, a3) {} + + template + value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) + : m_held(a1, a2, a3, a4) {} + + template + value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) + : m_held(a1, a2, a3, a4, a5) {} + + template + value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) + : m_held(a1, a2, a3, a4, a5, a6) {} + + template + value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) + : m_held(a1, a2, a3, a4, a5, a6, a7) {} + + template + value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) + : m_held(a1, a2, a3, a4, a5, a6, a7, a8) {} + + template + value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) + : m_held(a1, a2, a3, a4, a5, a6, a7, a8, a9) {} + + template + value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) + : m_held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} + + private: // required holder implementation + Held* target() { return &m_held; } + bool held_by_value() const { return true; } + + private: // data members + Held m_held; +}; + +// A generator metafunction which can be passed to make_holder +struct value_holder_generator +{ + template + struct apply + { + typedef value_holder type; + }; +}; + +}}} // namespace boost::python::object + +#endif // VALUE_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/objects.hpp b/include/boost/python/objects.hpp index 3b1a9094..93173462 100644 --- a/include/boost/python/objects.hpp +++ b/include/boost/python/objects.hpp @@ -17,7 +17,7 @@ namespace boost { namespace python { -class object +class BOOST_PYTHON_DECL object { public: explicit object(ref p); @@ -32,15 +32,36 @@ class object ref m_p; }; -class tuple : public object +class tuple; + +class BOOST_PYTHON_DECL tuple_base : public object { public: - explicit tuple(std::size_t n = 0); - explicit tuple(ref p); + explicit tuple_base(std::size_t n = 0); + explicit tuple_base(ref p); + + static PyTypeObject* type_obj(); + static bool accepts(ref p); + std::size_t size() const; + ref operator[](std::size_t pos) const; + + void set_item(std::size_t pos, const ref& rhs); + + tuple slice(int low, int high) const; + + friend BOOST_PYTHON_DECL tuple operator+(const tuple&, const tuple&); + friend BOOST_PYTHON_DECL tuple& operator+=(tuple&, const tuple&); +}; + +class tuple : public tuple_base +{ + public: + explicit tuple(std::size_t n = 0) : tuple_base(n) {} + explicit tuple(ref p) : tuple_base(p) {} template tuple(const std::pair& x) - : object(ref(PyTuple_New(2))) + : tuple_base(ref(PyTuple_New(2))) { set_item(0, x.first); set_item(1, x.second); @@ -48,7 +69,7 @@ class tuple : public object template tuple(const First& first, const Second& second) - : object(ref(PyTuple_New(2))) + : tuple_base(ref(PyTuple_New(2))) { set_item(0, first); set_item(1, second); @@ -56,7 +77,7 @@ class tuple : public object template tuple(const First& first, const Second& second, const Third& third) - : object(ref(PyTuple_New(3))) + : tuple_base(ref(PyTuple_New(3))) { set_item(0, first); set_item(1, second); @@ -65,7 +86,7 @@ class tuple : public object template tuple(const First& first, const Second& second, const Third& third, const Fourth& fourth) - : object(ref(PyTuple_New(4))) + : tuple_base(ref(PyTuple_New(4))) { set_item(0, first); set_item(1, second); @@ -73,32 +94,31 @@ class tuple : public object set_item(3, fourth); } - static PyTypeObject* type_obj(); - static bool accepts(ref p); - std::size_t size() const; - ref operator[](std::size_t pos) const; - template void set_item(std::size_t pos, const T& rhs) { this->set_item(pos, make_ref(rhs)); } - - void set_item(std::size_t pos, const ref& rhs); - - tuple slice(int low, int high) const; - friend tuple operator+(const tuple&, const tuple&); - tuple& operator+=(const tuple& rhs); + void set_item(std::size_t pos, const ref& rhs) + { + tuple_base::set_item(pos, rhs); + } }; -class list : public object +class list; + +struct BOOST_PYTHON_DECL list_proxy; +struct BOOST_PYTHON_DECL list_slice_proxy; + +class BOOST_PYTHON_DECL list_base : public object { - struct proxy; - struct slice_proxy; + protected: + typedef list_proxy proxy; + typedef list_slice_proxy slice_proxy; public: - explicit list(ref p); - explicit list(std::size_t sz = 0); + explicit list_base(ref p); + explicit list_base(std::size_t sz = 0); static PyTypeObject* type_obj(); static bool accepts(ref p); std::size_t size() const; @@ -106,26 +126,14 @@ class list : public object proxy operator[](std::size_t pos); ref get_item(std::size_t pos) const; - template - void set_item(std::size_t pos, const T& x) - { this->set_item(pos, make_ref(x)); } void set_item(std::size_t pos, const ref& ); // void set_item(std::size_t pos, const object& ); - template - void insert(std::size_t index, const T& x) - { this->insert(index, make_ref(x)); } void insert(std::size_t index, const ref& item); - template - void push_back(const T& item) - { this->push_back(make_ref(item)); } void push_back(const ref& item); - template - void append(const T& item) - { this->append(make_ref(item)); } void append(const ref& item); list slice(int low, int high) const; @@ -135,7 +143,31 @@ class list : public object tuple as_tuple() const; }; -class string +class list : public list_base +{ + public: + explicit list(ref p) : list_base(p) {} + explicit list(std::size_t sz = 0) : list_base(sz) {} + template + void set_item(std::size_t pos, const T& x) + { this->set_item(pos, make_ref(x)); } + template + void insert(std::size_t index, const T& x) + { this->insert(index, make_ref(x)); } + template + void push_back(const T& item) + { this->push_back(make_ref(item)); } + template + void append(const T& item) + { this->append(make_ref(item)); } + + void set_item(std::size_t pos, const ref& x) { list_base::set_item(pos, x); } + void insert(std::size_t index, const ref& item) { list_base::insert(index, item); } + void push_back(const ref& item) { list_base::push_back(item); } + void append(const ref& item) { list_base::append(item); } +}; + +class BOOST_PYTHON_DECL string : public object, public boost::multipliable2 { public: @@ -175,48 +207,31 @@ class string friend string operator%(const string& format, const tuple& args); }; -class dictionary : public object +class dictionary; + +struct BOOST_PYTHON_DECL dictionary_proxy; + +class BOOST_PYTHON_DECL dictionary_base : public object { - private: - struct proxy; + protected: + typedef dictionary_proxy proxy; public: - explicit dictionary(ref p); - dictionary(); + explicit dictionary_base(ref p); + dictionary_base(); void clear(); static PyTypeObject* type_obj(); static bool accepts(ref p); public: - template - proxy operator[](const Key& key) - { return this->operator[](make_ref(key)); } proxy operator[](ref key); - - template - ref operator[](const Key& key) const - { return this->operator[](make_ref(key)); } ref operator[](ref key) const; - - template - ref get_item(const Key& key) const - { return this->get_item(make_ref(key)); } ref get_item(const ref& key) const; - - template - ref get_item(const Key& key, const Default& default_) const - { return this->get_item(make_ref(key), make_ref(default_)); } ref get_item(const ref& key, const ref& default_) const; - template - void set_item(const Key& key, const Value& value) - { this->set_item(make_ref(key), make_ref(value)); } void set_item(const ref& key, const ref& value); - template - void erase(const Key& key) - { this->erase(make_ref(key)); } void erase(ref key); // proxy operator[](const object& key); @@ -235,7 +250,7 @@ class dictionary : public object // TODO: iterator support }; -struct dictionary::proxy +struct BOOST_PYTHON_DECL dictionary_proxy { template const ref& operator=(const T& rhs) @@ -244,19 +259,63 @@ struct dictionary::proxy operator ref() const; private: - friend class dictionary; - proxy(const ref& dict, const ref& key); + friend class dictionary_base; + dictionary_proxy(const ref& dict, const ref& key); // This is needed to work around the very strange MSVC error report that the // return type of the built-in operator= differs from that of the ones // defined above. Couldn't hurt to make these un-assignable anyway, though. - const ref& operator=(const proxy&); // Not actually implemented + const ref& operator=(const dictionary_proxy&); // Not actually implemented private: ref m_dict; ref m_key; }; -struct list::proxy +class dictionary : public dictionary_base +{ + typedef dictionary_proxy proxy; + public: + explicit dictionary(ref p) : dictionary_base(p) {} + dictionary() : dictionary_base() {} + + template + proxy operator[](const Key& key) + { return this->operator[](make_ref(key)); } + proxy operator[](ref key) + { return dictionary_base::operator[](key); } + + template + ref operator[](const Key& key) const + { return this->operator[](make_ref(key)); } + ref operator[](ref key) const + { return dictionary_base::operator[](key); } + + template + ref get_item(const Key& key) const + { return this->get_item(make_ref(key)); } + ref get_item(const ref& key) const + { return dictionary_base::get_item(key); } + + template + ref get_item(const Key& key, const Default& default_) const + { return this->get_item(make_ref(key), make_ref(default_)); } + ref get_item(const ref& key, const ref& default_) const + { return dictionary_base::get_item(key, default_); } + + template + void set_item(const Key& key, const Value& value) + { this->set_item(make_ref(key), make_ref(value)); } + void set_item(const ref& key, const ref& value) + { dictionary_base::set_item(key, value); } + + template + void erase(const Key& key) + { this->erase(make_ref(key)); } + void erase(ref key) + { dictionary_base::erase(key); } +}; + +struct BOOST_PYTHON_DECL list_proxy { template const ref& operator=(const T& rhs) @@ -266,19 +325,19 @@ struct list::proxy operator ref() const; private: - friend class list; - proxy(const ref& list, std::size_t index); + friend class list_base; + list_proxy(const ref& list, std::size_t index); // This is needed to work around the very strange MSVC error report that the // return type of the built-in operator= differs from that of the ones // defined above. Couldn't hurt to make these un-assignable anyway, though. - const ref& operator=(const proxy&); // Not actually implemented + const ref& operator=(const list_proxy&); // Not actually implemented private: list m_list; std::size_t m_index; }; -struct list::slice_proxy +struct BOOST_PYTHON_DECL list_slice_proxy { const list& operator=(const list& rhs); operator ref() const; @@ -286,8 +345,8 @@ struct list::slice_proxy std::size_t size() const; ref operator[](std::size_t pos) const; private: - friend class list; - slice_proxy(const ref& list, int low, int high); + friend class list_base; + list_slice_proxy(const ref& list, int low, int high); private: ref m_list; int m_low, m_high; @@ -297,32 +356,32 @@ struct list::slice_proxy BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -PyObject* to_python(const boost::python::tuple&); -boost::python::tuple from_python(PyObject* p, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(const boost::python::tuple&); +BOOST_PYTHON_DECL boost::python::tuple from_python(PyObject* p, boost::python::type); inline boost::python::tuple from_python(PyObject* p, boost::python::type) { return from_python(p, boost::python::type()); } -PyObject* to_python(const boost::python::list&); -boost::python::list from_python(PyObject* p, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(const boost::python::list&); +BOOST_PYTHON_DECL boost::python::list from_python(PyObject* p, boost::python::type); inline boost::python::list from_python(PyObject* p, boost::python::type) { return from_python(p, boost::python::type()); } -PyObject* to_python(const boost::python::string&); -boost::python::string from_python(PyObject* p, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(const boost::python::string&); +BOOST_PYTHON_DECL boost::python::string from_python(PyObject* p, boost::python::type); inline boost::python::string from_python(PyObject* p, boost::python::type) { return from_python(p, boost::python::type()); } -PyObject* to_python(const boost::python::dictionary&); -boost::python::dictionary from_python(PyObject* p, boost::python::type); +BOOST_PYTHON_DECL PyObject* to_python(const boost::python::dictionary&); +BOOST_PYTHON_DECL boost::python::dictionary from_python(PyObject* p, boost::python::type); inline boost::python::dictionary from_python(PyObject* p, boost::python::type) { diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp index 52e52eee..c766c8b6 100644 --- a/include/boost/python/operators.hpp +++ b/include/boost/python/operators.hpp @@ -31,7 +31,7 @@ namespace boost { namespace python { -tuple standard_coerce(ref l, ref r); +BOOST_PYTHON_DECL tuple standard_coerce(ref l, ref r); namespace detail { diff --git a/src/classes.cpp b/src/classes.cpp index f51d1a2f..b018c0ce 100644 --- a/src/classes.cpp +++ b/src/classes.cpp @@ -11,6 +11,8 @@ // 03 Mar 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve) // 03 Mar 01 bug fix: use bound_function::create() (instead of new bound_function) +#define BOOST_PYTHON_SOURCE + #include #include #include @@ -997,7 +999,7 @@ namespace { } } -void adjust_slice_indices(PyObject* obj, int& start, int& finish) +BOOST_PYTHON_DECL void adjust_slice_indices(PyObject* obj, int& start, int& finish) { int length = callback::call_method(obj, "__len__"); diff --git a/src/conversions.cpp b/src/conversions.cpp index f1534dd9..e6b6161a 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -16,65 +16,16 @@ #define BOOST_PYTHON_SOURCE #include -#include +#include #include #include #ifndef BOOST_NO_LIMITS # include #endif -namespace boost { namespace python { - -// IMPORTANT: this function may only be called from within a catch block! -PyObject* handle_exception_impl(object_functor_base const& f) -{ - try - { - return f(); - } - catch(const boost::python::error_already_set&) - { - // The python error reporting has already been handled. - } - catch(const std::bad_alloc&) - { - PyErr_NoMemory(); - } - catch(const std::exception& x) - { - PyErr_SetString(PyExc_RuntimeError, x.what()); - } - catch(...) - { - PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception"); - } - return 0; -} - -void handle_exception(void (*f)()) -{ - handle_exception( - boost::python::detail::make_void_adaptor(f)); -} - -namespace detail { - - void expect_complex(PyObject* p) - { - if (!PyComplex_Check(p)) - { - PyErr_SetString(PyExc_TypeError, "expected a complex number"); - throw boost::python::argument_error(); - } - } - -} // namespace boost::python::detail - -}} // namespace boost::python - BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -long from_python(PyObject* p, boost::python::type) +BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type) { // Why am I clearing the error here before trying to convert? I know there's a reason... long result; @@ -86,7 +37,7 @@ long from_python(PyObject* p, boost::python::type) return result; } -double from_python(PyObject* p, boost::python::type) +BOOST_PYTHON_DECL double from_python(PyObject* p, boost::python::type) { double result; { @@ -151,48 +102,48 @@ PyObject* integer_to_python(T value) return to_python(value_as_long); } -int from_python(PyObject* p, boost::python::type type) +BOOST_PYTHON_DECL int from_python(PyObject* p, boost::python::type type) { return integer_from_python(p, type); } -PyObject* to_python(unsigned int i) +BOOST_PYTHON_DECL PyObject* to_python(unsigned int i) { return integer_to_python(i); } -unsigned int from_python(PyObject* p, boost::python::type type) +BOOST_PYTHON_DECL unsigned int from_python(PyObject* p, boost::python::type type) { return integer_from_python(p, type); } -short from_python(PyObject* p, boost::python::type type) +BOOST_PYTHON_DECL short from_python(PyObject* p, boost::python::type type) { return integer_from_python(p, type); } -float from_python(PyObject* p, boost::python::type) +BOOST_PYTHON_DECL float from_python(PyObject* p, boost::python::type) { return static_cast(from_python(p, boost::python::type())); } -PyObject* to_python(unsigned short i) +BOOST_PYTHON_DECL PyObject* to_python(unsigned short i) { return integer_to_python(i); } -unsigned short from_python(PyObject* p, boost::python::type type) +BOOST_PYTHON_DECL unsigned short from_python(PyObject* p, boost::python::type type) { return integer_from_python(p, type); } -PyObject* to_python(char c) +BOOST_PYTHON_DECL PyObject* to_python(char c) { if (c == '\0') return PyString_FromString(""); return PyString_FromStringAndSize(&c, 1); } -char from_python(PyObject* p, boost::python::type) +BOOST_PYTHON_DECL char from_python(PyObject* p, boost::python::type) { int l = -1; if (PyString_Check(p)) l = PyString_Size(p); @@ -204,37 +155,37 @@ char from_python(PyObject* p, boost::python::type) return PyString_AsString(p)[0]; } -PyObject* to_python(unsigned char i) +BOOST_PYTHON_DECL PyObject* to_python(unsigned char i) { return integer_to_python(i); } -unsigned char from_python(PyObject* p, boost::python::type type) +BOOST_PYTHON_DECL unsigned char from_python(PyObject* p, boost::python::type type) { return integer_from_python(p, type); } -PyObject* to_python(signed char i) +BOOST_PYTHON_DECL PyObject* to_python(signed char i) { return integer_to_python(i); } -signed char from_python(PyObject* p, boost::python::type type) +BOOST_PYTHON_DECL signed char from_python(PyObject* p, boost::python::type type) { return integer_from_python(p, type); } -PyObject* to_python(unsigned long x) +BOOST_PYTHON_DECL PyObject* to_python(unsigned long x) { return integer_to_python(x); } -unsigned long from_python(PyObject* p, boost::python::type type) +BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type type) { return integer_from_python(p, type); } -void from_python(PyObject* p, boost::python::type) +BOOST_PYTHON_DECL void from_python(PyObject* p, boost::python::type) { if (p != Py_None) { PyErr_SetString(PyExc_TypeError, "expected argument of type None"); @@ -242,7 +193,7 @@ void from_python(PyObject* p, boost::python::type) } } -const char* from_python(PyObject* p, boost::python::type) +BOOST_PYTHON_DECL const char* from_python(PyObject* p, boost::python::type) { const char* s = PyString_AsString(p); if (!s) @@ -250,12 +201,12 @@ const char* from_python(PyObject* p, boost::python::type) return s; } -PyObject* to_python(const std::string& s) +BOOST_PYTHON_DECL PyObject* to_python(const std::string& s) { return PyString_FromStringAndSize(s.data(), s.size()); } -std::string from_python(PyObject* p, boost::python::type) +BOOST_PYTHON_DECL std::string from_python(PyObject* p, boost::python::type) { if (! PyString_Check(p)) { PyErr_SetString(PyExc_TypeError, "expected a string"); @@ -264,7 +215,7 @@ std::string from_python(PyObject* p, boost::python::type) return std::string(PyString_AsString(p), PyString_Size(p)); } -bool from_python(PyObject* p, boost::python::type) +BOOST_PYTHON_DECL bool from_python(PyObject* p, boost::python::type) { int value = from_python(p, boost::python::type()); if (value == 0) @@ -274,12 +225,12 @@ bool from_python(PyObject* p, boost::python::type) #ifdef BOOST_MSVC6_OR_EARLIER // An optimizer bug prevents these from being inlined. -PyObject* to_python(double d) +BOOST_PYTHON_DECL PyObject* to_python(double d) { return PyFloat_FromDouble(d); } -PyObject* to_python(float f) +BOOST_PYTHON_DECL PyObject* to_python(float f) { return PyFloat_FromDouble(f); } diff --git a/src/converter/body.cpp b/src/converter/body.cpp new file mode 100644 index 00000000..637f8c3e --- /dev/null +++ b/src/converter/body.cpp @@ -0,0 +1,18 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include + +namespace boost { namespace python { namespace converter { + +// default implementation is a no-op. Most handles will not hold any +// data that needs to be managed. Unwrap objects which convert +// by-value are an exception. Fortunately, the concrete body subclass +// has that knowledge. +void body::destroy_handle(handle*) const +{ +} + +}}} // namespace boost::python::converter diff --git a/src/converter/handle.cpp b/src/converter/handle.cpp new file mode 100644 index 00000000..1a2b8c31 --- /dev/null +++ b/src/converter/handle.cpp @@ -0,0 +1,35 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include + +namespace boost { namespace python { namespace converter { + +bool handle::convertible() const +{ + for (handle const* p = this; p != 0; p = p->m_next) + { + if (p->m_body == 0) + return false; + } + return true; +} + +void handle::destroy() +{ + // Recurse down the chain releasing from tail to head + if (m_next != 0) + m_next->destroy(); + + // Our body knows how to destroy us. If we never got a body, + // there's nothing to do. + if (m_body) + m_body->destroy_handle(this); +} + +// void handle::dummy::nonnull() {} + +}}} // namespace boost::python::converter diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp new file mode 100644 index 00000000..88d96637 --- /dev/null +++ b/src/converter/registry.cpp @@ -0,0 +1,177 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +# include +# include +# include +# include +# include +# include +# ifdef BOOST_PYTHON_TRACE +# include +# endif + +namespace boost { namespace python { namespace converter { + +namespace // +{ + typedef std::map registry_t; + + registry_t& entries() + { + static registry_t registry; + return registry; + } +} // namespace + +namespace registry +{ + entry* find(type_id_t type) + { + return &entries()[type]; + } + + entry::entry() + : m_wrapper(0) + { + } + + namespace // + { + // A UnaryFunction type which deletes its argument + struct delete_item + { + template + void operator()(T* x) const + { + delete x; + } + }; + + // A UnaryFunction type which returns true iff its argument is a + // unwrapper which can convert the given Python object. + struct convertible + { + convertible(PyObject* p) + : m_p(p) + {} + + bool operator()(unwrapper_base* converter) const + { + return converter->convertible(m_p); + } + + PyObject* m_p; + }; + } + + entry::~entry() + { + if (m_wrapper != 0) + m_wrapper->m_can_unregister = false; + + for (unwrappers::iterator p = m_unwrappers.begin(); p != m_unwrappers.end(); ++p) + { + (*p)->m_can_unregister = false; + } + } + + unwrapper_base* entry::unwrapper(PyObject* p) const + { + unwrappers::const_iterator q = + std::find_if(m_unwrappers.begin(), m_unwrappers.end(), convertible(p)); + + return q == m_unwrappers.end() ? 0 : *q; + } + + wrapper_base* entry::wrapper() const + { + return m_wrapper; + } + + entry::unwrappers::iterator entry::find(unwrapper_base const& x) + { + return std::find(m_unwrappers.begin(), m_unwrappers.end(), &x); + } + + void entry::insert(unwrapper_base& x) + { + unwrappers::iterator p = this->find(x); + + assert(p == m_unwrappers.end()); + if (p != m_unwrappers.end()) + { + throw std::runtime_error( + "trying to register unrapper which is already registered"); + } + m_unwrappers.push_back(&x); + } + + void entry::remove(unwrapper_base& x) + { + unwrappers::iterator p = find(x); + + // Be sure we're not removing a converter which hasn't been + // registered. + assert(p != m_unwrappers.end()); + if (p == m_unwrappers.end()) + { + throw std::runtime_error( + "trying to unregister unwrapper which is not registered"); + } + m_unwrappers.erase(p); + } + + void entry::insert(wrapper_base& x) + { + assert(m_wrapper == 0); // we have a problem otherwise + if (m_wrapper != 0) + { + throw std::runtime_error( + "trying to register wrapper for a type which already has a registered wrapper"); + } + m_wrapper = &x; + } + + void entry::remove(wrapper_base& x) + { + assert(m_wrapper == &x); + if (m_wrapper != &x) + { + throw std::runtime_error( + "trying to unregister a wrapper which is not registered"); + } + m_wrapper = 0; + } + + void insert(wrapper_base& w) + { +# ifdef BOOST_PYTHON_TRACE + std::cout << "inserting wrapper for " << w.key() << std::endl; +# endif + find(w.key())->insert(w); + } + + void insert(unwrapper_base& u) + { +# ifdef BOOST_PYTHON_TRACE + std::cout << "inserting unwrapper for " << u.key() << std::endl; +# endif + find(u.key())->insert(u); + } + + void remove(wrapper_base& w) + { + find(w.key())->remove(w); + } + + void remove(unwrapper_base& u) + { + find(u.key())->remove(u); + } +} // namespace registry + +}}} // namespace boost::python::converter diff --git a/src/converter/type_id.cpp b/src/converter/type_id.cpp new file mode 100644 index 00000000..86974638 --- /dev/null +++ b/src/converter/type_id.cpp @@ -0,0 +1,67 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT +# include +#else +# include +#endif + +namespace boost { namespace python { namespace converter { + +#if 1 +bool type_id_before::operator()(type_id_t const& x, type_id_t const& y) const +{ + return x < y; +} + +BOOST_PYTHON_EXPORT std::ostream& operator<<(std::ostream& os, type_id_t const& x) +{ +# ifdef BOOST_PYTHON_TYPE_ID_NAME + os << x.m_base_type; +# else + os << x.m_base_type->name(); +# endif + // VC6 mistakenly distinguishes typeid(X) from typeid(X const) + // from typeid(X&)... so the name is already correct. I have it + // from Jason Shirk that VC7.0 has the same bug but it will be + // fixed in 7.1 +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + if (x.m_decoration & type_id_t::const_) + os << " const"; + if (x.m_decoration & type_id_t::volatile_) + os << " volatile"; + if (x.m_decoration & type_id_t::reference) + os << "&"; +# endif + return os; +} + +#else +bool type_id_before::operator()(type_id_t const& x, type_id_t const& y) const +{ + for (;;) + { + if (*y == 0) + { + return 0; + } + else if (*x == 0) + { + return 1; + } + else if (*x != *y) + { + return *x < *y; + } + ++x; + ++y; + } +} +#endif + +}}} // namespace boost::python::converter diff --git a/src/converter/unwrap.cpp b/src/converter/unwrap.cpp new file mode 100644 index 00000000..e0c09db6 --- /dev/null +++ b/src/converter/unwrap.cpp @@ -0,0 +1,35 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include + +namespace boost { namespace python { namespace converter { + +namespace +{ + struct pyobject_unwrapper : unwrapper_base + { + pyobject_unwrapper(); + bool convertible(PyObject*) const; + }; + + pyobject_unwrapper static_unwrapper; + + pyobject_unwrapper::pyobject_unwrapper() + : unwrapper_base(type_id()) + { + } + + bool pyobject_unwrapper::convertible(PyObject*) const + { + return true; + } +} + +BOOST_PYTHON_EXPORT unwrapper_base* +unwrap_more_::m_unwrapper = &static_unwrapper; + +}}} // namespace boost::python::converter diff --git a/src/converter/unwrapper.cpp b/src/converter/unwrapper.cpp new file mode 100644 index 00000000..2b0adbd0 --- /dev/null +++ b/src/converter/unwrapper.cpp @@ -0,0 +1,24 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include + +namespace boost { namespace python { namespace converter { + +unwrapper_base::unwrapper_base(type_id_t key) + : body(key) +{ + registry::insert(*this); +} + +unwrapper_base::~unwrapper_base() +{ + if (can_unregister()) + registry::remove(*this); +} + +}}} // namespace boost::python::converter diff --git a/src/converter/wrapper.cpp b/src/converter/wrapper.cpp new file mode 100644 index 00000000..0d817217 --- /dev/null +++ b/src/converter/wrapper.cpp @@ -0,0 +1,30 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include + +namespace boost { namespace python { namespace converter { + +wrapper_base::wrapper_base(type_id_t type) + : body(type) +{ + // static assertions for target. These would go in a header, + // but Metrowerks only respects BOOST_STATIC_ASSERT if it is in an + // instantiated function +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#else +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + registry::insert(*this); +} + +wrapper_base::~wrapper_base() +{ + if (can_unregister()) + registry::remove(*this); +} + +}}} // namespace boost::python::converter diff --git a/src/cross_module.cpp b/src/cross_module.cpp index 5949be4d..2bce5a61 100644 --- a/src/cross_module.cpp +++ b/src/cross_module.cpp @@ -15,7 +15,8 @@ namespace python = boost::python; # include // MSVC6.0SP4 does not know std::fprintf # include // MSVC6.0SP4 does not know std::strcmp -namespace { +namespace +{ PyObject* get_module_dict(const char* module_name) { @@ -26,64 +27,68 @@ namespace { } } -namespace boost { namespace python { namespace detail { +namespace boost { namespace python { -const char* converters_attribute_name = "__converters__"; - -void* import_converter_object(const std::string& module_name, - const std::string& py_class_name, - const std::string& attribute_name) +namespace detail { - static std::string err; - PyObject* module_dict = get_module_dict(const_cast(module_name.c_str())); - PyObject* py_class = PyDict_GetItemString(module_dict, const_cast(py_class_name.c_str())); - if (py_class == 0) { - err = std::string("module ") + module_name + " has no attribute " + py_class_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - python::ref c_obj(PyObject_GetAttrString(py_class, const_cast(attribute_name.c_str())), ref::null_ok); - if (c_obj.get() == 0) { - err = std::string("object ") + module_name + "." + py_class_name + BOOST_PYTHON_DECL const char* converters_attribute_name = "__converters__"; + + BOOST_PYTHON_DECL void* import_converter_object(const std::string& module_name, + const std::string& py_class_name, + const std::string& attribute_name) + { + static std::string err; + PyObject* module_dict = get_module_dict(const_cast(module_name.c_str())); + PyObject* py_class = PyDict_GetItemString(module_dict, const_cast(py_class_name.c_str())); + if (py_class == 0) { + err = std::string("module ") + module_name + " has no attribute " + py_class_name; + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + python::ref c_obj(PyObject_GetAttrString(py_class, const_cast(attribute_name.c_str())), ref::null_ok); + if (c_obj.get() == 0) { + err = std::string("object ") + module_name + "." + py_class_name + " has no attribute " + attribute_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - if (! PyCObject_Check(c_obj.get())) { - err = std::string("object ") + module_name + "." + py_class_name + "." + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + if (! PyCObject_Check(c_obj.get())) { + err = std::string("object ") + module_name + "." + py_class_name + "." + attribute_name + " is not a PyCObject"; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - throw python::import_error(); - } - return PyCObject_AsVoidPtr(c_obj.get()); + PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); + throw python::import_error(); + } + return PyCObject_AsVoidPtr(c_obj.get()); + } + + BOOST_PYTHON_DECL void check_export_converters_api(const int importing_major, + const int importing_minor, + const int imported_major, + const int imported_minor) + { + if (importing_major != imported_major) { + // Python uses fprintf(stderr, ...) for API warnings. + fprintf(stderr, + "Fatal: export_converters_api mismatch:" + " Importing module = %d.%d" + " Imported module = %d.%d\n", + importing_major, importing_minor, + imported_major, imported_minor); + PyErr_SetString(PyExc_RuntimeError, + "Fatal: export_converters_api mismatch"); + throw import_error(); + } + if (importing_minor != imported_minor) { + // Python uses fprintf(stderr, ...) for API warnings. + fprintf(stderr, + "Warning: export_converters_api mismatch:" + " Importing module = %d.%d" + " Imported module = %d.%d\n", + importing_major, importing_minor, + imported_major, imported_minor); + } + } + } -void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor) -{ - if (importing_major != imported_major) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Fatal: export_converters_api mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - PyErr_SetString(PyExc_RuntimeError, - "Fatal: export_converters_api mismatch"); - throw import_error(); - } - if (importing_minor != imported_minor) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Warning: export_converters_api mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - } -} - -}}} // namespace boost::python::detail +}} // namespace boost::python::detail diff --git a/src/errors.cpp b/src/errors.cpp new file mode 100644 index 00000000..1290df50 --- /dev/null +++ b/src/errors.cpp @@ -0,0 +1,68 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#ifndef BOOST_PYTHON_SOURCE +# define BOOST_PYTHON_SOURCE +#endif + +#include + +namespace boost { namespace python { + +// IMPORTANT: this function may only be called from within a catch block! +BOOST_PYTHON_DECL bool handle_exception_impl(function0 f) +{ + try + { + f(); + return false; + } + catch(const boost::python::error_already_set&) + { + // The python error reporting has already been handled. + } + catch(const std::bad_alloc&) + { + PyErr_NoMemory(); + } + catch(const std::exception& x) + { + PyErr_SetString(PyExc_RuntimeError, x.what()); + } + catch(...) + { + PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception"); + } + return true; +} + +BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x) +{ + if (x == 0) + throw error_already_set(); + return x; +} + +namespace detail { + + BOOST_PYTHON_DECL void expect_complex(PyObject* p) + { + if (!PyComplex_Check(p)) + { + PyErr_SetString(PyExc_TypeError, "expected a complex number"); + throw boost::python::argument_error(); + } + } + +// needed by void_adaptor (see void_adaptor.hpp) +BOOST_PYTHON_DECL PyObject arbitrary_object = { 0 }; + + +} // namespace boost::python::detail + +}} // namespace boost::python + + diff --git a/src/extension_class.cpp b/src/extension_class.cpp index e9183c82..f8bcf9ad 100644 --- a/src/extension_class.cpp +++ b/src/extension_class.cpp @@ -12,6 +12,7 @@ #define BOOST_PYTHON_SOURCE #include +#include #include #include #include @@ -52,7 +53,7 @@ BOOST_PYTHON_END_CONVERSION_NAMESPACE namespace boost { namespace python { -tuple standard_coerce(ref l, ref r) +BOOST_PYTHON_DECL tuple standard_coerce(ref l, ref r) { // Introduced sequence points for exception-safety. ref first(detail::operator_dispatcher::create(l, l)); @@ -487,21 +488,15 @@ void operator_dispatcher_dealloc(PyObject* self) int operator_dispatcher_coerce(PyObject** l, PyObject** r) { Py_INCREF(*l); - PyObject* new_r = handle_exception( - bind(operator_dispatcher::create, - ref(*r, ref::increment_count), - ref())); - if (new_r) - { - *r = new_r; - return 0; - } - else - { - return -1; - } -} + return handle_exception( + bind_return( + *r + , bind(operator_dispatcher::create, + ref(*r, ref::increment_count), + ref()))) + ? -1 : 0; +} #define PY_DEFINE_OPERATOR(id, symbol) \ PyObject* operator_dispatcher_call_##id(PyObject* left, PyObject* right) \ diff --git a/src/gen_call.py b/src/gen_call.py new file mode 100644 index 00000000..dd178648 --- /dev/null +++ b/src/gen_call.py @@ -0,0 +1,82 @@ +# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +# distribute this software is granted provided this copyright notice appears +# in all copies. This software is provided "as is" without express or implied +# warranty, and with no claim as to its suitability for any purpose. +# +# This work was funded in part by Lawrence Berkeley National Labs + +from gen_function import * +import string + +header = '''// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// +// This work was funded in part by Lawrence Berkeley National Labs +// +// This file generated for %d-argument member functions and %d-argument free +// functions by gen_call.py + +#ifndef CALL_DWA20011214_HPP +# define CALL_DWA20011214_HPP + +# include + +namespace boost { namespace python { + +''' +_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') + +def gen_call(member_function_args, free_function_args = None): + if free_function_args is None: + free_function_args = member_function_args + 1 + + return (header % (member_function_args, free_function_args) + + gen_functions( +'''template +PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +''', free_function_args) + + +'''// Member functions +''' + + reduce(lambda x,y: x+y + , map(lambda cv: + gen_functions( +'''template +PyObject* call(R (A0::*f)(%(A%+%:, %))%1, PyObject* args, PyObject* keywords) +{ + return detail::returning::call(f, args, keywords); +} + +''' + , member_function_args, cv) + , _cv_qualifiers)) + + +''' +}} // namespace boost::python + +#endif // CALL_DWA20011214_HPP +''') + +if __name__ == '__main__': + import sys + + if len(sys.argv) == 1: + member_function_args = 5 + free_function_args = 6 + else: + member_function_args = int(sys.argv[1]) + if len(sys.argv) > 2: + free_function_args = int(sys.argv[2]) + else: + free_function_args = member_function_args + + print gen_call(member_function_args, free_function_args) + + diff --git a/src/gen_returning.py b/src/gen_returning.py new file mode 100644 index 00000000..2b112cc0 --- /dev/null +++ b/src/gen_returning.py @@ -0,0 +1,191 @@ +# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +# distribute this software is granted provided this copyright notice appears +# in all copies. This software is provided "as is" without express or implied +# warranty, and with no claim as to its suitability for any purpose. +# +# This work was funded in part by Lawrence Berkeley National Labs + +from gen_function import * +import string + +header = '''// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// This work was funded in part by Lawrence Berkeley National Labs +// +// This file generated for %d-argument member functions and %d-argument free +// functions by gen_returning.py +''' + +body_sections = ( +''' +#ifndef RETURNING_DWA20011201_HPP +# define RETURNING_DWA20011201_HPP + +//# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +// Calling C++ from Python +template +struct returning +{ +''', +''' +''', +''' // Free functions +''', +'''}; + +template <> +struct returning +{ + typedef void R; +''', +''' +''', +''' + // Free functions +''', +'''}; + +}}} // namespace boost::python::detail + +#endif // RETURNING_DWA20011201_HPP +''') + +#' + +member_function = ''' template + static PyObject* call(R (A0::*pmf)(%(A%+%:, %))%1, PyObject* args, PyObject* /* keywords */ ) + { + // check that each of the arguments is convertible + unwrap c0(PyTuple_GET_ITEM(args, 0)); +%( unwrap_more c%+(PyTuple_GET_ITEM(args, %+), c%n); +%) +%[r%: // find the result converter + wrap_more r(c%n); +%] if (!c0) return 0; + %[r%:return r( %]((*c0).*pmf)(%(*c%+%:, %))%[r%: )%];%[v%: + return detail::none();%] + }; +''' + +free_function = '''%{ template <%(class A%n%:, %)> +%} static PyObject* call(R (*pf)(%(A%n%:, %)), PyObject*%{ args%}, PyObject* /* keywords */ ) + {%{ + // check that each of the arguments is convertible +%}%( unwrap%{_more%} c%n(PyTuple_GET_ITEM(args, %n)%{, c%-%}); +%)%[r%: + // find the result converter + wrap%{_more%} r%{(c%-)%};%]%{ + if (!c0) return 0;%} + %[r%:return r( %](*pf)(%(*c%n%:, %))%[r%: )%];%[v%: + return detail::none();%] + }; +''' + +def _returns_value(key, n, args, value): + if key == 'r': + return value + # pass the value through gen_function again for recursive expansion +# return apply(gen_function, (value, n) + args +# , {'fill': _returns_value}) + else: + assert key == 'v' + return '' + +def _returns_void(key, n, args, value): + if key == 'v': + return value + else: + assert key == 'r' + # return the empty string, ignoring the value + return '' + +_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') + +_prefix = { +# ' const': ''' + +# // missing cv-qualified -> cv-unqualified member pointer conversions +# # if defined(__MWERKS__) && __MWERKS__ <=0x2406 || defined(BOOST_MSVC) && BOOST_MSVC <= 1200 || defined(__BORLANDC__) +# ''', + ' const volatile': ''' +// missing const volatile type traits +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +'''}; + +def gen_returning(member_function_args, free_function_args = None): + if free_function_args is None: + free_function_args = member_function_args + 1 + + return_none = '''; + return detail::none();''' + + return (header % (member_function_args, free_function_args) + + body_sections[0] + # + # functions returning results + # + + + reduce(lambda x,y: x+y + , map(lambda cv: + _prefix.get(cv,'') + + gen_functions(member_function, + member_function_args, cv, + fill = _returns_value) + '\n' + , _cv_qualifiers)) + + '''# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +''' +## endif // missing cv-qualified -> cv-unqualified member pointer conversions +#''' + # free functions + + gen_functions(free_function, free_function_args, fill = _returns_value) + + body_sections[3] + + # + # functions returning void + # + + + reduce(lambda x,y: x+y + , map(lambda cv: + _prefix.get(cv,'') + + gen_functions(member_function, + member_function_args, cv, fill = + _returns_void) + '\n' + , _cv_qualifiers)) + + + '''# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +''' +## endif // missing cv-qualified -> cv-unqualified member pointer conversions +#''' + # free functions + + gen_functions(free_function, free_function_args, fill = _returns_void) + + body_sections[6] + ) + +if __name__ == '__main__': + import sys + + if len(sys.argv) == 1: + member_function_args = 5 + free_function_args = 6 + else: + member_function_args = int(sys.argv[1]) + if len(sys.argv) > 2: + free_function_args = int(sys.argv[2]) + else: + free_function_args = member_function_args + + print gen_returning(member_function_args, free_function_args) + + diff --git a/src/module_builder.cpp b/src/module_builder.cpp index bd04a89c..0a195621 100644 --- a/src/module_builder.cpp +++ b/src/module_builder.cpp @@ -16,19 +16,19 @@ namespace { ref name_holder; } -bool module_builder::initializing() +bool module_builder_base::initializing() { return name_holder.get() != 0; } -string module_builder::name() +string module_builder_base::name() { // If this fails, you haven't created a module_builder object assert(initializing()); return string(name_holder); } -module_builder::module_builder(const char* name) +module_builder_base::module_builder_base(const char* name) : m_module(Py_InitModule(const_cast(name), initial_methods)) { // If this fails, you've created more than 1 module_builder object in your module @@ -36,29 +36,29 @@ module_builder::module_builder(const char* name) name_holder = ref(PyObject_GetAttrString(m_module, const_cast("__name__"))); } -module_builder::~module_builder() +module_builder_base::~module_builder_base() { name_holder.reset(); } void -module_builder::add(detail::function* x, const char* name) +module_builder_base::add(detail::function* x, const char* name) { reference f(x); // First take possession of the object. detail::function::add_to_namespace(f, name, PyModule_GetDict(m_module)); } -void module_builder::add(ref x, const char* name) +void module_builder_base::add(ref x, const char* name) { PyObject* dictionary = PyModule_GetDict(m_module); PyDict_SetItemString(dictionary, const_cast(name), x.get()); } -void module_builder::add(PyTypeObject* x, const char* name /*= 0*/) +void module_builder_base::add(PyTypeObject* x, const char* name /*= 0*/) { this->add(ref(as_object(x)), name ? name : x->tp_name); } -PyMethodDef module_builder::initial_methods[] = { { 0, 0, 0, 0 } }; +PyMethodDef module_builder_base::initial_methods[] = { { 0, 0, 0, 0 } }; }} // namespace boost::python diff --git a/src/object/class.cpp b/src/object/class.cpp new file mode 100644 index 00000000..cc3903e3 --- /dev/null +++ b/src/object/class.cpp @@ -0,0 +1,165 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace python { namespace object { + +holder_base::holder_base(converter::type_id_t id) + : m_type(id) + , m_next(0) +{ +} + +holder_base::~holder_base() +{ +} + +//BOOST_PYTHON_EXPORT +PyTypeObject class_metatype_object = { + PyObject_HEAD_INIT(0)//&PyType_Type) + 0, + "Boost.Python.class", + PyType_Type.tp_basicsize, + 0, + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | // Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, //&PyType_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, + // PyType_GenericNew /* tp_new */ +}; + +//BOOST_PYTHON_EXPORT +PyTypeObject class_type_object = { + PyObject_HEAD_INIT(0) //&class_metatype_object) + 0, + "Boost.Python.instance", + sizeof(instance), + 0, + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, //&PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew +}; + +BOOST_PYTHON_EXPORT PyTypeObject* class_metatype() +{ + if (class_metatype_object.tp_dict == 0) + { + class_metatype_object.ob_type = &PyType_Type; + class_metatype_object.tp_base = &PyType_Type; + if (PyType_Ready(&class_metatype_object)) + return 0; + } + Py_INCREF(&class_metatype_object); + return &class_metatype_object; +} + +BOOST_PYTHON_EXPORT PyTypeObject* class_type() +{ + if (class_type_object.tp_dict == 0) + { + class_type_object.ob_type = class_metatype(); + class_type_object.tp_base = &PyBaseObject_Type; + if (PyType_Ready(&class_type_object)) + return 0; + } + Py_INCREF(&class_type_object); + return &class_type_object; +} + +void holder_base::install(PyObject* self) +{ + assert(self->ob_type->ob_type == &class_metatype_object); + m_next = ((instance*)self)->objects; + ((instance*)self)->objects = this; +} + +BOOST_PYTHON_EXPORT holder_base* +find_holder_impl(PyObject* inst, converter::type_id_t type) +{ + if (inst->ob_type->ob_type != &class_metatype_object) + return 0; + instance* self = reinterpret_cast(inst); + + holder_base::iterator match = std::find_if( + holder_base::iterator(self->objects), holder_base::iterator(0) + , bind(std::equal_to() + , bind(mem_fn(&holder_base::type), _1) + , type)); + + return match != holder_base::iterator(0) + ? match.base() : 0; +} + +}}} // namespace boost::python::object diff --git a/src/object/function.cpp b/src/object/function.cpp new file mode 100644 index 00000000..4c2de3c7 --- /dev/null +++ b/src/object/function.cpp @@ -0,0 +1,95 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include + +namespace boost { namespace python { namespace object { + + +function::function(py_function implementation) + : m_fn(implementation) +{ + PyObject* p = this; + PyObject_INIT(p, &function_type); +} + +function::~function() +{ +} + +PyObject* function::call(PyObject* args, PyObject* keywords) const +{ + return m_fn(args, keywords); +} + +extern "C" +{ + // Stolen from Python's funcobject.c + static PyObject * + function_descr_get(PyObject *func, PyObject *obj, PyObject *type) + { + if (obj == Py_None) + obj = NULL; + return PyMethod_New(func, obj, type); + } + + static void + function_dealloc(PyObject* p) + { + delete static_cast(p); + } + + static PyObject * + function_call(PyObject *func, PyObject *arg, PyObject *kw) + { + return static_cast(func)->call(arg, kw); + } +} + +PyTypeObject function_type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "Boost.Python.function", + sizeof(function), + 0, + (destructor)function_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, //(reprfunc)func_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + function_call, /* tp_call */ + 0, /* tp_str */ + 0, // PyObject_GenericGetAttr, /* tp_getattro */ + 0, // PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT /* | Py_TPFLAGS_HAVE_GC */,/* tp_flags */ + 0, /* tp_doc */ + 0, // (traverseproc)func_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, //offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, // func_memberlist, /* tp_members */ + 0, //func_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + function_descr_get, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, //offsetof(PyFunctionObject, func_dict), /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, + 0 /* tp_new */ +}; + +}}} // namespace boost::python::object diff --git a/src/objects.cpp b/src/objects.cpp index 70257388..90417dac 100644 --- a/src/objects.cpp +++ b/src/objects.cpp @@ -51,42 +51,42 @@ PyObject* object::get() const BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -PyObject* to_python(const boost::python::tuple& x) +BOOST_PYTHON_DECL PyObject* to_python(const boost::python::tuple& x) { return object_to_python(x); } -boost::python::tuple from_python(PyObject* p, boost::python::type type) +BOOST_PYTHON_DECL boost::python::tuple from_python(PyObject* p, boost::python::type type) { return boost::python::object_from_python(p, type); } -PyObject* to_python(const boost::python::list& x) +BOOST_PYTHON_DECL PyObject* to_python(const boost::python::list& x) { return object_to_python(x); } -boost::python::list from_python(PyObject* p, boost::python::type type) +BOOST_PYTHON_DECL boost::python::list from_python(PyObject* p, boost::python::type type) { return boost::python::object_from_python(p, type); } -PyObject* to_python(const boost::python::dictionary& x) +BOOST_PYTHON_DECL PyObject* to_python(const boost::python::dictionary& x) { return object_to_python(x); } -boost::python::dictionary from_python(PyObject* p, boost::python::type type) +BOOST_PYTHON_DECL boost::python::dictionary from_python(PyObject* p, boost::python::type type) { return boost::python::object_from_python(p, type); } -PyObject* to_python(const boost::python::string& x) +BOOST_PYTHON_DECL PyObject* to_python(const boost::python::string& x) { return object_to_python(x); } -boost::python::string from_python(PyObject* p, boost::python::type type) +BOOST_PYTHON_DECL boost::python::string from_python(PyObject* p, boost::python::type type) { return boost::python::object_from_python(p, type); } @@ -95,14 +95,14 @@ BOOST_PYTHON_END_CONVERSION_NAMESPACE namespace boost { namespace python { -tuple::tuple(std::size_t n) +tuple_base::tuple_base(std::size_t n) : object(ref(PyTuple_New(n))) { for (std::size_t i = 0; i < n; ++i) PyTuple_SET_ITEM(get(), i, detail::none()); } -tuple::tuple(ref p) +tuple_base::tuple_base(ref p) : object(p) { assert(accepts(p)); @@ -113,28 +113,28 @@ tuple::tuple(ref p) } } -PyTypeObject* tuple::type_obj() +PyTypeObject* tuple_base::type_obj() { return &PyTuple_Type; } -bool tuple::accepts(ref p) +bool tuple_base::accepts(ref p) { return PyTuple_Check(p.get()); } -std::size_t tuple::size() const +std::size_t tuple_base::size() const { return PyTuple_Size(get()); } -ref tuple::operator[](std::size_t pos) const +ref tuple_base::operator[](std::size_t pos) const { return ref(PyTuple_GetItem(get(), static_cast(pos)), ref::increment_count); } -void tuple::set_item(std::size_t pos, const ref& rhs) +void tuple_base::set_item(std::size_t pos, const ref& rhs) { int failed = PyTuple_SetItem( get(), static_cast(pos), ref(rhs).release()); // A reference is stolen here. @@ -142,14 +142,14 @@ void tuple::set_item(std::size_t pos, const ref& rhs) assert(failed == 0); } -tuple tuple::slice(int low, int high) const +tuple tuple_base::slice(int low, int high) const { return tuple(ref(PyTuple_GetSlice(get(), low, high))); } -tuple& tuple::operator+=(const tuple& rhs) +BOOST_PYTHON_DECL tuple& operator+=(tuple& self, const tuple& rhs) { - return *this = *this + rhs; + return self = self + rhs; } @@ -216,7 +216,7 @@ string& string::operator*=(unsigned int repeat_count) return *this; } -dictionary::dictionary(ref p) +dictionary_base::dictionary_base(ref p) : object(p) { assert(accepts(p)); @@ -227,49 +227,49 @@ dictionary::dictionary(ref p) } } -dictionary::dictionary() +dictionary_base::dictionary_base() : object(ref(PyDict_New())) {} -PyTypeObject* dictionary::type_obj() +PyTypeObject* dictionary_base::type_obj() { return &PyDict_Type; } -bool dictionary::accepts(ref p) +bool dictionary_base::accepts(ref p) { return PyDict_Check(p.get()); } -void dictionary::clear() +void dictionary_base::clear() { PyDict_Clear(get()); } -const ref& dictionary::proxy::operator=(const ref& rhs) +const ref& dictionary_proxy::operator=(const ref& rhs) { if (PyDict_SetItem(m_dict.get(), m_key.get(), rhs.get()) == -1) throw error_already_set(); return rhs; } -dictionary::proxy::operator ref() const +dictionary_proxy::operator ref() const { return ref(m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get()), ref::increment_count); } -dictionary::proxy::proxy(const ref& dict, const ref& key) +dictionary_proxy::dictionary_proxy(const ref& dict, const ref& key) : m_dict(dict), m_key(key) {} -dictionary::proxy dictionary::operator[](ref key) +dictionary_proxy dictionary_base::operator[](ref key) { return proxy(reference(), key); } -ref dictionary::operator[](ref key) const { +ref dictionary_base::operator[](ref key) const { // An odd MSVC bug causes the ".operator Ptr()" to be needed return proxy(reference(), key).operator ref(); } -ref dictionary::get_item(const ref& key) const +ref dictionary_base::get_item(const ref& key) const { return get_item(key, ref()); } -ref dictionary::get_item(const ref& key, const ref& default_) const +ref dictionary_base::get_item(const ref& key, const ref& default_) const { PyObject* value_or_null = PyDict_GetItem(get(), key.get()); if (value_or_null == 0 && !PyErr_Occurred()) @@ -278,22 +278,22 @@ ref dictionary::get_item(const ref& key, const ref& default_) const return ref(value_or_null, ref::increment_count); // Will throw if there was another error } -void dictionary::set_item(const ref& key, const ref& value) +void dictionary_base::set_item(const ref& key, const ref& value) { if (PyDict_SetItem(get(), key.get(), value.get()) == -1) throw error_already_set(); } -void dictionary::erase(ref key) { +void dictionary_base::erase(ref key) { if (PyDict_DelItem(get(), key.get()) == -1) throw error_already_set(); } -list dictionary::items() const { return list(ref(PyDict_Items(get()))); } -list dictionary::keys() const { return list(ref(PyDict_Keys(get()))); } -list dictionary::values() const { return list(ref(PyDict_Values(get()))); } +list dictionary_base::items() const { return list(ref(PyDict_Items(get()))); } +list dictionary_base::keys() const { return list(ref(PyDict_Keys(get()))); } +list dictionary_base::values() const { return list(ref(PyDict_Values(get()))); } -std::size_t dictionary::size() const { return static_cast(PyDict_Size(get())); } +std::size_t dictionary_base::size() const { return static_cast(PyDict_Size(get())); } string operator+(string x, string y) { @@ -338,7 +338,7 @@ tuple operator+(const tuple& x, const tuple& y) } -list::list(ref p) +list_base::list_base(ref p) : object(p) { assert(accepts(p)); @@ -349,97 +349,97 @@ list::list(ref p) } } -list::list(std::size_t sz) +list_base::list_base(std::size_t sz) : object(ref(PyList_New(sz))) { } -PyTypeObject* list::type_obj() +PyTypeObject* list_base::type_obj() { return &PyList_Type; } -bool list::accepts(ref p) +bool list_base::accepts(ref p) { return PyList_Check(p.get()); } -std::size_t list::size() const +std::size_t list_base::size() const { return PyList_Size(get()); } -ref list::operator[](std::size_t pos) const +ref list_base::operator[](std::size_t pos) const { return ref(PyList_GetItem(get(), pos), ref::increment_count); } -list::proxy list::operator[](std::size_t pos) +list_proxy list_base::operator[](std::size_t pos) { return proxy(reference(), pos); } -void list::insert(std::size_t index, const ref& item) +void list_base::insert(std::size_t index, const ref& item) { if (PyList_Insert(get(), index, item.get()) == -1) throw error_already_set(); } -void list::push_back(const ref& item) +void list_base::push_back(const ref& item) { if (PyList_Append(get(), item.get()) == -1) throw error_already_set(); } -void list::append(const ref& item) +void list_base::append(const ref& item) { this->push_back(item); } -list list::slice(int low, int high) const +list list_base::slice(int low, int high) const { return list(ref(PyList_GetSlice(get(), low, high))); } -list::slice_proxy list::slice(int low, int high) +list_slice_proxy list_base::slice(int low, int high) { - return slice_proxy(reference(), low, high); + return list_slice_proxy(reference(), low, high); } -void list::sort() +void list_base::sort() { if (PyList_Sort(get()) == -1) throw error_already_set(); } -void list::reverse() +void list_base::reverse() { if (PyList_Reverse(get()) == -1) throw error_already_set(); } -tuple list::as_tuple() const +tuple list_base::as_tuple() const { return tuple(ref(PyList_AsTuple(get()))); } -const ref& list::proxy::operator=(const ref& rhs) +const ref& list_proxy::operator=(const ref& rhs) { m_list.set_item(m_index, rhs); return rhs; } -list::proxy::operator ref() const +list_proxy::operator ref() const { return ref(PyList_GetItem(m_list.get(), m_index), ref::increment_count); } -ref list::get_item(std::size_t pos) const +ref list_base::get_item(std::size_t pos) const { return ref(PyList_GetItem(this->get(), pos), ref::increment_count); } -void list::set_item(std::size_t pos, const ref& rhs) +void list_base::set_item(std::size_t pos, const ref& rhs) { int result = PyList_SetItem(this->get(), pos, rhs.get()); if (result == -1) @@ -447,39 +447,39 @@ void list::set_item(std::size_t pos, const ref& rhs) Py_INCREF(rhs.get()); } -list::proxy::proxy(const ref& list, std::size_t index) +list_proxy::list_proxy(const ref& list, std::size_t index) : m_list(list), m_index(index) { } -const list& list::slice_proxy::operator=(const list& rhs) +const list& list_slice_proxy::operator=(const list& rhs) { if (PyList_SetSlice(m_list.get(), m_low, m_high, rhs.get()) == -1) throw error_already_set(); return rhs; } -list::slice_proxy::operator ref() const +list_slice_proxy::operator ref() const { return ref(PyList_GetSlice(m_list.get(), m_low, m_high)); } -list::slice_proxy::operator list() const +list_slice_proxy::operator list() const { return list(this->operator ref()); } -std::size_t list::slice_proxy::size() const +std::size_t list_slice_proxy::size() const { return this->operator list().size(); } -ref list::slice_proxy::operator[](std::size_t pos) const +ref list_slice_proxy::operator[](std::size_t pos) const { return this->operator list()[pos].operator ref(); } -list::slice_proxy::slice_proxy(const ref& list, int low, int high) +list_slice_proxy::list_slice_proxy(const ref& list, int low, int high) : m_list(list), m_low(low), m_high(high) { } diff --git a/src/types.cpp b/src/types.cpp index f411aa42..e76503d2 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -8,6 +8,7 @@ #define BOOST_PYTHON_SOURCE +#include #include #include // for handle_exception() #include @@ -25,9 +26,11 @@ namespace boost { namespace python { -namespace { - +namespace +{ using detail::type_object_base; + using detail::call_object; + // Define a family of forwarding functions that can be called from a // PyTypeObject's slots. These functions dispatch through a (virtual) member @@ -35,7 +38,6 @@ namespace { // uniform way, preventing us from having to rewrite the dispatching code over // and over. - // Given a function object f with signature // // PyObject* f(PyTypeObject*,PyObject*) @@ -43,88 +45,24 @@ namespace { // calls f inside of handle_exception, and returns the result. If an exception // is thrown by f, returns 0. template - PyObject* obj_call(PyObject* obj, F const& f) + PyObject* obj_call(PyObject* obj, F f) { - return handle_exception( - boost::bind(f, static_cast(obj->ob_type), obj)); + PyObject* result; + return call_object(result, obj, f) ? 0 : result; } - - // int_converter/value_holder - // - // A simple function object which converts its argument to a PyObject*. We - // need this because handle_exception needs to return a PyObject*, even if the - // function being called is supposed to return int. It has two parts... - - // holds the value actually returned by the underlying function - template - struct value_holder : PyObject - { - value_holder() : is_set(false), value(-1) {} - - // Tricky constructor allows us to grab the result even if rhs == 0. - explicit value_holder(value_holder const* rhs) - : is_set(rhs ? rhs->is_set : false), value(rhs ? rhs->value : -1) {} - - // true if the function object was ever called (false if an exception occurred) - bool is_set; - - // The returned value - T value; - }; - - // The function object - template - struct int_converter - { - typedef PyObject* result_type; - - PyObject* operator()(R const& x) - { - m_holder.is_set = true; - m_holder.value = x; - return &m_holder; // returns - } - - value_holder m_holder; - }; - - // Call the given int-returning function object inside of handle_exception, - // returning a value_holder. F is a function object with "signature" + // Call the given integer-returning function object inside of + // handle_exception, returning a value_holder. F is a function + // object with "signature" // // R F(PyTypeObject*, PyObject*) // // where R is an integer type. template - value_holder int_call_holder(PyObject* obj, F f) + R int_call(PyObject* obj, F f, R* = 0) { - return value_holder( - - // The int_converter object containing the value_holder is valid - // through the life of the full-expression, so we can construct from - // the pointer - static_cast*>( - handle_exception( - - boost::bind( - // Add an int_converter back-end to f - int_converter() - // Bind the object's type and the object itself into f - , boost::bind(f, static_cast(obj->ob_type), obj) - ) - - ) - ) - ); - } - - // Just like int_call_holder (above), but returns the integer directly. If F - // throws an exception, returns -1 - template - R int_call(PyObject* obj, F f) - { - value_holder const v(int_call_holder(obj, f)); - return v.value; + R result; + return call_object(result, obj, f) ? -1 : result; } // Implemented in terms of obj_call, above @@ -171,27 +109,18 @@ namespace { int call_length_function(PyObject* obj, int (type_object_base::*f)(PyObject*) const) { - value_holder const r(int_call_holder(obj, bind(f, _1, _2))); - - if (!r.is_set) - { + int result; + if (call_object(result, obj, bind(f, _1, _2))) return -1; - } - const int outcome = r.value; - if (outcome >= 0) - return outcome; + if (result >= 0) + return result; PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0"); return -1; } } // anonymous namespace -namespace detail { - // needed by void_adaptor (see void_adaptor.hpp) - PyObject arbitrary_object; -} - extern "C" { // @@ -247,14 +176,11 @@ static PyObject* do_instance_call(PyObject* obj, PyObject* args, PyObject* keywo static void do_instance_dealloc(PyObject* obj) { - PyObject* success = handle_exception( - // translate the void return value of instance_dealloc into a PyObject* - // that can indicate no error. - detail::make_void_adaptor( + if (handle_exception( bind(&type_object_base::instance_dealloc - , static_cast(obj->ob_type) - , obj))); - if (!success) + , static_cast(obj->ob_type) + , obj)) + ) { assert(!"exception during destruction!"); } @@ -300,11 +226,9 @@ static PyObject* do_instance_sq_item(PyObject* obj, int index) return 0; } - return handle_exception( - bind(&type_object_base::instance_sequence_item - , static_cast(obj->ob_type) - , obj - , index)); + return obj_call( + obj + , bind(&type_object_base::instance_sequence_item, _1, _2, index)); } static int do_instance_mp_ass_subscript(PyObject* obj, PyObject* index, PyObject* value) diff --git a/test/complicated.hpp b/test/complicated.hpp new file mode 100644 index 00000000..123c53fe --- /dev/null +++ b/test/complicated.hpp @@ -0,0 +1,39 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef COMPLICATED_DWA20011215_HPP +# define COMPLICATED_DWA20011215_HPP +# include + +# include "simple_type.hpp" + +struct complicated +{ + complicated(simple const&, int = 0); + ~complicated(); + + int get_n() const; + + char* s; + int n; +}; + +inline complicated::complicated(simple const&s, int n) + : s(s.s), n(n) +{ + std::cout << "constructing complicated: " << this->s << ", " << n << std::endl; +} + +inline complicated::~complicated() +{ + std::cout << "destroying complicated: " << this->s << ", " << n << std::endl; +} + +inline int complicated::get_n() const +{ + return n; +} + +#endif // COMPLICATED_DWA20011215_HPP diff --git a/test/m1.cpp b/test/m1.cpp new file mode 100644 index 00000000..f4ad6390 --- /dev/null +++ b/test/m1.cpp @@ -0,0 +1,281 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +// Seems to be neccessary to suppress an ICE with MSVC +#include "boost/mpl/comparison/less.hpp" + +#include "simple_type.hpp" +#include "complicated.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" void +dealloc(PyObject* self) +{ + PyObject_Del(self); +} + +struct NoddyObject : PyObject +{ + int x; +}; + +PyTypeObject NoddyType = { + PyObject_HEAD_INIT(NULL) + 0, + "Noddy", + sizeof(NoddyObject), + 0, + dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ +}; + +struct SimpleObject : PyObject +{ + simple x; +}; + +PyTypeObject SimpleType = { + PyObject_HEAD_INIT(NULL) + 0, + "Simple", + sizeof(SimpleObject), + 0, + dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ +}; + +extern "C" PyObject* +new_noddy(PyObject* self, PyObject* args) +{ + NoddyObject* noddy; + + if (!PyArg_ParseTuple(args,":new_noddy")) + return NULL; + + noddy = PyObject_New(NoddyObject, &NoddyType); + noddy->x = 42; + + return (PyObject*)noddy; +} + +extern "C" PyObject* +new_simple(PyObject* self, PyObject* args) +{ + SimpleObject* simple; + + if (!PyArg_ParseTuple(args,":new_simple")) + return NULL; + + simple = PyObject_New(SimpleObject, &SimpleType); + simple->x.s = "hello, world"; + + return (PyObject*)simple; +} + +static PyMethodDef methods[] = { + { "new_noddy", new_noddy, METH_VARARGS }, + { "new_simple", new_simple, METH_VARARGS }, + {0, 0, 0, 0} +}; + +struct int_wrapper + : boost::python::converter::wrapper +{ + PyObject* convert(int const& x) const + { + return PyInt_FromLong(x); + } +}; + +struct simple_wrapper + : boost::python::converter::wrapper +{ + PyObject* convert(simple const& x) const + { + SimpleObject* p = PyObject_New(SimpleObject, &SimpleType); + p->x = x; + return p; + } +}; + +struct simple_ref_wrapper + : boost::python::converter::wrapper +{ + PyObject* convert(simple& x) const + { + SimpleObject* p = PyObject_New(SimpleObject, &SimpleType); + p->x = x; + return p; + } +}; + +struct native_int_unwrapper + : boost::python::converter::unwrapper +{ + bool convertible(PyObject* p) const + { + return PyInt_Check(p); + } + + int convert(PyObject* p, void*&) const + { + return PyInt_AsLong(p); + } +}; + +struct noddy_int_unwrapper + : boost::python::converter::unwrapper +{ + bool convertible(PyObject* p) const + { + return p->ob_type == &NoddyType; + } + + int convert(PyObject* p, void*&) const + { + return static_cast(p)->x; + } +}; + +struct noddy_int_ref_unwrapper + : boost::python::converter::unwrapper +{ + bool convertible(PyObject* p) const + { + return p->ob_type == &NoddyType; + } + + int& convert(PyObject* p, void*&) const + { + return static_cast(p)->x; + } +}; + +struct simple_ref_unwrapper + : boost::python::converter::unwrapper +{ + bool convertible(PyObject* p) const + { + return p->ob_type == &SimpleType; + } + + simple& convert(PyObject* p, void*&) const + { + return static_cast(p)->x; + } +}; + +struct simple_const_ref_unwrapper + : boost::python::converter::unwrapper +{ + bool convertible(PyObject* p) const + { + return p->ob_type == &SimpleType; + } + + simple const& convert(PyObject* p, void*&) const + { + return static_cast(p)->x; + } +}; + +int f(simple const& s) +{ + return strlen(s.s); +} + +simple const& g(simple const& x) +{ + return x; +} + +BOOST_PYTHON_MODULE_INIT(m1) +{ + PyObject* m1 = Py_InitModule(const_cast("m1"), methods); + + static int_wrapper wrap_int; + static simple_wrapper wrap_simple; + static native_int_unwrapper unwrap_int1; + static noddy_int_unwrapper unwrap_int2; + static noddy_int_ref_unwrapper unwrap_int3; + static simple_ref_unwrapper unwrap_simple; +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // These compilers will need additional converters + static simple_const_ref_unwrapper unwrap_simple_const_ref; + static simple_ref_wrapper wrap_simple_ref; +#endif + static boost::python::object::class_unwrapper unwrap_complicated; + + PyObject* d = PyModule_GetDict(m1); + if (d == NULL) + return; + + if (PyDict_SetItemString( + d, "xclass", (PyObject *)boost::python::object::class_metatype()) < 0) + return; + + if (PyDict_SetItemString( + d, "xinst", (PyObject *)boost::python::object::class_type()) < 0) + return; + + if (PyDict_SetItemString( + d, "f", boost::python::make_function(f)) < 0) + return; + + if (PyDict_SetItemString( + d, "g", boost::python::make_function(g)) < 0) + return; + + if (PyDict_SetItemString( + d, "get_n", boost::python::make_function(&complicated::get_n)) < 0) + return; + + if (PyDict_SetItemString( + d, "init1" + , boost::python::make_constructor< + complicated + , boost::mpl::type_list + , boost::python::object::value_holder_generator>() + ) < 0) + return; + + if (PyDict_SetItemString( + d, "init2" + , boost::python::make_constructor< + complicated + , boost::mpl::type_list + , boost::python::object::value_holder_generator>() + ) < 0) + return; +} + +#include "module_tail.cpp" diff --git a/test/m2.cpp b/test/m2.cpp new file mode 100644 index 00000000..d2093a20 --- /dev/null +++ b/test/m2.cpp @@ -0,0 +1,197 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include "simple_type.hpp" + +using boost::python::wrap; +using boost::python::unwrap; + +extern "C" { + PyObject* + unwrap_simple(PyObject* self, PyObject* args) + { + PyObject* p; + if (!PyArg_ParseTuple(args, "O", &p)) + return 0; + + boost::python::unwrap in(p); + if (!in) + return 0; + + simple x = *in; + + return PyString_FromString(x.s); + }; + + PyObject* + unwrap_simple_ref(PyObject* self, PyObject* args) + { + PyObject* p; + if (!PyArg_ParseTuple(args, "O", &p)) + return 0; + + unwrap in(p); + if (!in) + return 0; + + simple& x = *in; + + return PyString_FromString(x.s); + }; + + PyObject* + unwrap_simple_const_ref(PyObject* self, PyObject* args) + { + PyObject* p; + if (!PyArg_ParseTuple(args, "O", &p)) + return 0; + + unwrap in(p); + if (!in) + return 0; + + simple const& x = *in; + + return PyString_FromString(x.s); + }; + + PyObject* + unwrap_int(PyObject* self, PyObject* args) + { + PyObject* p; + if (!PyArg_ParseTuple(args, "O", &p)) + return 0; + + unwrap in(p); + if (!in) + return 0; + + int x = *in; + + return PyInt_FromLong(x); + }; + + PyObject* + unwrap_int_ref(PyObject* self, PyObject* args) + { + PyObject* p; + if (!PyArg_ParseTuple(args, "O", &p)) + return 0; + + unwrap in(p); + if (!in) + return 0; + + int& x = *in; + + return PyInt_FromLong(x); + }; + + PyObject* + unwrap_int_const_ref(PyObject* self, PyObject* args) + { + PyObject* p; + if (!PyArg_ParseTuple(args, "O", &p)) + return 0; + + unwrap in(p); + if (!in) + return 0; + + int const& x = *in; + + return PyInt_FromLong(x); + }; + + // ------------------- +} +template struct xxxx; + +template +PyObject* +rewrap(PyObject* self, PyObject* args, xxxx* = 0) +{ + PyObject* p; + if (!PyArg_ParseTuple(args, "O", &p)) + return 0; + + boost::python::unwrap in(p); + if (!in) + return 0; + + boost::python::wrap out; + if (!out) + return 0; + + T x = *in; + return out(x); +} + +extern "C" +{ + PyObject* + wrap_simple(PyObject* self, PyObject* args) + { + return rewrap(self, args); + }; + + PyObject* + wrap_simple_ref(PyObject* self, PyObject* args) + { + return rewrap(self, args); + }; + + PyObject* + wrap_simple_const_ref(PyObject* self, PyObject* args) + { + return rewrap(self, args); + }; + + PyObject* + wrap_int(PyObject* self, PyObject* args) + { + return rewrap(self, args); + }; + + PyObject* + wrap_int_ref(PyObject* self, PyObject* args) + { + return rewrap(self, args); + }; + + PyObject* + wrap_int_const_ref(PyObject* self, PyObject* args) + { + return rewrap(self, args); + }; +} + +PyMethodDef initial_methods[] = +{ + { "unwrap_int", unwrap_int, METH_VARARGS, 0 }, + { "unwrap_int_ref", unwrap_int_ref, METH_VARARGS, 0 }, + { "unwrap_int_const_ref", unwrap_int_const_ref, METH_VARARGS, 0 }, + { "unwrap_simple", unwrap_simple, METH_VARARGS, 0 }, + { "unwrap_simple_ref", unwrap_simple_ref, METH_VARARGS, 0 }, + { "unwrap_simple_const_ref", unwrap_simple_const_ref, METH_VARARGS, 0 }, + + { "wrap_int", wrap_int, METH_VARARGS, 0 }, + { "wrap_int_ref", wrap_int_ref, METH_VARARGS, 0 }, + { "wrap_int_const_ref", wrap_int_const_ref, METH_VARARGS, 0 }, + { "wrap_simple", wrap_simple, METH_VARARGS, 0 }, + { "wrap_simple_ref", wrap_simple_ref, METH_VARARGS, 0 }, + { "wrap_simple_const_ref", wrap_simple_const_ref, METH_VARARGS, 0 }, + { 0, 0, 0, 0 } +}; + +BOOST_PYTHON_MODULE_INIT(m2) +{ + Py_InitModule(const_cast("m2"), initial_methods); +} + +#include "module_tail.cpp" diff --git a/test/module_tail.cpp b/test/module_tail.cpp new file mode 100644 index 00000000..6849bf83 --- /dev/null +++ b/test/module_tail.cpp @@ -0,0 +1,39 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#if defined(_WIN32) +# ifdef __MWERKS__ +# pragma ANSI_strict off +# endif +# include +# ifdef __MWERKS__ +# pragma ANSI_strict reset +# endif + +extern "C" BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved ); + +# ifdef BOOST_MSVC +extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) +{ + throw; +} +# endif + +BOOL WINAPI DllMain( + HINSTANCE, //hDllInst + DWORD fdwReason, + LPVOID // lpvReserved + ) +{ +# ifdef BOOST_MSVC + _set_se_translator(structured_exception_translator); +# endif + (void)fdwReason; // warning suppression. + + return 1; +} +#endif // _WIN32 + diff --git a/test/newtest.py b/test/newtest.py new file mode 100644 index 00000000..783e2240 --- /dev/null +++ b/test/newtest.py @@ -0,0 +1,95 @@ +""" +>>> from m1 import * + +>>> from m2 import * + +>>> n = new_noddy() +>>> s = new_simple() +>>> unwrap_int(n) +42 +>>> unwrap_int_ref(n) +42 +>>> unwrap_int_const_ref(n) +42 +>>> unwrap_simple(s) +'hello, world' +>>> unwrap_simple_ref(s) +'hello, world' +>>> unwrap_simple_const_ref(s) +'hello, world' +>>> unwrap_int(5) +5 + +Can't get a reference to a built-in integer object +>>> try: +... unwrap_int_ref(7) +... except: pass +... else: print 'no exception' + +>>> try: +... unwrap_int_const_ref(9) +... except: pass +... else: print 'no exception' + +>>> wrap_int(n) +42 + +try: wrap_int_ref(n) +... except: pass +... else: print 'no exception' + +>>> wrap_int_const_ref(n) +42 + +>>> unwrap_simple_ref(wrap_simple(s)) +'hello, world' + +>>> unwrap_simple_ref(wrap_simple_ref(s)) +'hello, world' + +>>> unwrap_simple_ref(wrap_simple_const_ref(s)) +'hello, world' + +>>> f(s) +12 + +>>> unwrap_simple(g(s)) +'hello, world' + +>>> f(g(s)) +12 + +>>> C = xclass('C', (xinst,), {'__init__': init1, 'get_n': get_n}) +>>> c = C(s, 99) +>>> c.get_n() +99 + +>>> D = xclass('D', (xinst,), {'__init__': init2, 'get_n': get_n}) +>>> d = D(s) +>>> d.get_n() +0 + +""" + +def run(args = None): + + ### Strange bug somewhere: with Metrowerks: it will crash in + ### garbage-collection code unless traceback and sre have been + ### loaded before m1. + +# import traceback +# import sre +# import m2 +# import m1 + import sys + import doctest + + if args is not None: + sys.argv = args + # import sys + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) diff --git a/test/simple_type.hpp b/test/simple_type.hpp new file mode 100644 index 00000000..2df97cfd --- /dev/null +++ b/test/simple_type.hpp @@ -0,0 +1,14 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef SIMPLE_TYPE_DWA2001128_HPP +# define SIMPLE_TYPE_DWA2001128_HPP + +struct simple +{ + char* s; +}; + +#endif // SIMPLE_TYPE_DWA2001128_HPP From 14f6f8852646f649823774e4ed69877bb0edf17d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 28 Dec 2001 13:26:36 +0000 Subject: [PATCH 0146/1042] irix_CC workaround; updated makefiles [SVN r12163] --- build/como.mak | 1 + build/filemgr.py | 1 + build/gcc.mak | 1 + build/irix_CC.mak | 10 +++++----- build/linux_gcc.mak | 10 +++++----- build/mingw32.mak | 2 +- build/tru64_cxx.mak | 10 +++++----- build/vc60.mak | 16 ++++++++-------- build/win32_mwcc.mak | 6 +++--- include/boost/python/detail/config.hpp | 9 +++++++++ 10 files changed, 39 insertions(+), 27 deletions(-) diff --git a/build/como.mak b/build/como.mak index 8f05e309..edf05f83 100644 --- a/build/como.mak +++ b/build/como.mak @@ -7,6 +7,7 @@ LIBSRC = \ classes.cpp \ conversions.cpp \ cross_module.cpp \ + errors.cpp \ extension_class.cpp \ functions.cpp \ init_function.cpp \ diff --git a/build/filemgr.py b/build/filemgr.py index 99f4ca30..93cef1cb 100644 --- a/build/filemgr.py +++ b/build/filemgr.py @@ -8,6 +8,7 @@ bpl_exa = "/libs/python/example" files = ( bpl_src + "/classes.cpp", bpl_src + "/conversions.cpp", +bpl_src + "/errors.cpp", bpl_src + "/extension_class.cpp", bpl_src + "/functions.cpp", bpl_src + "/init_function.cpp", diff --git a/build/gcc.mak b/build/gcc.mak index ce718f2b..b818030e 100644 --- a/build/gcc.mak +++ b/build/gcc.mak @@ -11,6 +11,7 @@ LIBSRC = \ classes.cpp \ conversions.cpp \ cross_module.cpp \ + errors.cpp \ extension_class.cpp \ functions.cpp \ init_function.cpp \ diff --git a/build/irix_CC.mak b/build/irix_CC.mak index ec387746..f7d6004e 100644 --- a/build/irix_CC.mak +++ b/build/irix_CC.mak @@ -17,10 +17,10 @@ ROOT=$(HOME) BOOST=$(ROOT)/boost -PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python -PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python -#PYINC=-I/usr/local/Python-2.1/include/python2.1 +#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python +#PYINC=-I/usr/local/Python-1.5.2/include/python1.5 +PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python +PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1 STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers STDOPTS= @@ -35,7 +35,7 @@ MAKEDEP=-M LD=CC -LANG:std -n32 -mips4 LDOPTS=-shared -OBJ=classes.o conversions.o extension_class.o functions.o \ +OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ init_function.o module_builder.o \ objects.o types.o cross_module.o DEPOBJ=$(OBJ) \ diff --git a/build/linux_gcc.mak b/build/linux_gcc.mak index ef643991..3b466e7d 100644 --- a/build/linux_gcc.mak +++ b/build/linux_gcc.mak @@ -17,12 +17,12 @@ ROOT=$(HOME) BOOST=$(ROOT)/boost -PYEXE=PYTHONPATH=. /usr/bin/python -PYINC=-I/usr/include/python1.5 +#PYEXE=PYTHONPATH=. /usr/bin/python +#PYINC=-I/usr/include/python1.5 #PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python #PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python -#PYINC=-I/usr/local/Python-2.1/include/python2.1 +PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python +PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1 STDOPTS=-fPIC -ftemplate-depth-21 WARNOPTS= @@ -36,7 +36,7 @@ MAKEDEP=-M LD=$(CPP) LDOPTS=-shared -OBJ=classes.o conversions.o extension_class.o functions.o \ +OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ init_function.o module_builder.o \ objects.o types.o cross_module.o DEPOBJ=$(OBJ) \ diff --git a/build/mingw32.mak b/build/mingw32.mak index bf590409..d8c31b68 100644 --- a/build/mingw32.mak +++ b/build/mingw32.mak @@ -52,7 +52,7 @@ CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \ LD=g++ LDOPTS=-shared -OBJ=classes.o conversions.o extension_class.o functions.o \ +OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ init_function.o module_builder.o \ objects.o types.o cross_module.o diff --git a/build/tru64_cxx.mak b/build/tru64_cxx.mak index f996a0c1..a64927b1 100644 --- a/build/tru64_cxx.mak +++ b/build/tru64_cxx.mak @@ -17,10 +17,10 @@ ROOT=$(HOME) BOOST=$(ROOT)/boost -PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python -PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -#PYEXE=PYTHONPATH=. /usr/local/Python-2.1/bin/python -#PYINC=-I/usr/local/Python-2.1/include/python2.1 +#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python +#PYINC=-I/usr/local/Python-1.5.2/include/python1.5 +PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python +PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1 #STLPORTINC=-I/usr/local/STLport-4.1b3/stlport #STLPORTINC=-I/usr/local/STLport-4.1b4/stlport #STLPORTOPTS= \ @@ -46,7 +46,7 @@ LDOPTS=-shared -expect_unresolved 'Py*' -expect_unresolved '_Py*' #HIDDEN=-hidden -OBJ=classes.o conversions.o extension_class.o functions.o \ +OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ init_function.o module_builder.o \ objects.o types.o cross_module.o DEPOBJ=$(OBJ) \ diff --git a/build/vc60.mak b/build/vc60.mak index a348de54..6f303791 100644 --- a/build/vc60.mak +++ b/build/vc60.mak @@ -14,14 +14,14 @@ ROOT=R: BOOST_WIN="$(ROOT)\boost" BOOST_UNIX=$(HOME)/boost -PYEXE="C:\Program files\Python\python.exe" -PYINC=/I"C:\Program files\Python\include" -PYLIB="C:\Program files\Python\libs\python15.lib" -#PYEXE="C:\Python21\python.exe" -#PYINC=/I"C:\Python21\include" -#PYLIB="C:\Python21\libs\python21.lib" +#PYEXE="C:\Program files\Python\python.exe" +#PYINC=/I"C:\Program files\Python\include" +#PYLIB="C:\Program files\Python\libs\python15.lib" +PYEXE="C:\Python21\python.exe" +PYINC=/I"C:\Python21\include" +PYLIB="C:\Python21\libs\python21.lib" -STDOPTS=/nologo /MD /GR /GX /Zm200 +STDOPTS=/nologo /MD /GR /GX /Zm200 /DBOOST_PYTHON_STATIC_LIB WARNOPTS= OPTOPTS= @@ -32,7 +32,7 @@ CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) /I$(BOOST_WIN) $(PYINC) \ LD=link.exe LDOPTS=/nologo /dll /incremental:no -OBJ=classes.obj conversions.obj extension_class.obj functions.obj \ +OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \ init_function.obj module_builder.obj \ objects.obj types.obj cross_module.obj diff --git a/build/win32_mwcc.mak b/build/win32_mwcc.mak index ac054c07..c49af71c 100755 --- a/build/win32_mwcc.mak +++ b/build/win32_mwcc.mak @@ -10,7 +10,7 @@ # 14 Dec 01 derived from vc60.mak (R.W. Grosse-Kunstleve) ROOT=R: -BOOST_WIN="$(ROOT)\boostdev" +BOOST_WIN="$(ROOT)\boost" BOOST_UNIX=$(HOME)/boost #PYEXE="C:\Program files\Python\python.exe" @@ -20,7 +20,7 @@ PYEXE="C:\Python21\python.exe" PYINC=-I"C:\Python21\include" PYLIB="C:\Python21\libs\python21.lib" -STDOPTS=-gccinc -prefix UseDLLPrefix.h +STDOPTS=-gccinc -prefix UseDLLPrefix.h -DBOOST_PYTHON_STATIC_LIB WARNOPTS=-warn on,nounusedexpr,nounused OPTOPTS=-O @@ -31,7 +31,7 @@ CPPOPTS=$(STDOPTS) $(WARNOPTS) $(OPTOPTS) \ LD=mwld LDOPTS=-export dllexport -shared -OBJ=classes.obj conversions.obj extension_class.obj functions.obj \ +OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \ init_function.obj module_builder.obj \ objects.obj types.obj cross_module.obj diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 498fa07a..c79eb2ca 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -129,4 +129,13 @@ # endif #endif +#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 +// Work around a compiler bug. +// boost::python::detail::function has to be seen by the compiler before the +// boost::function class template. +namespace boost { namespace python { namespace detail { +class function; +}}} +#endif + #endif // CONFIG_DWA052200_H_ From 2eb2e52a79dbd4d24be54cda2b1cd864e8ca8e31 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 28 Dec 2001 23:52:01 +0000 Subject: [PATCH 0147/1042] workaround some compiler limitations [SVN r12165] --- .../boost/python/detail/extension_class.hpp | 54 +++++++++++-------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 00f9b6b4..05ebe229 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -38,20 +38,45 @@ template struct right_operand; enum without_downcast_t { without_downcast }; -namespace detail { +namespace detail +{ // forward declarations -class extension_instance; -class extension_class_base; -template class instance_holder; -template class instance_value_holder; -template class instance_ptr_holder; -template struct operand_select; + class extension_instance; + class extension_class_base; + template class instance_holder; + template class instance_value_holder; + template class instance_ptr_holder; + template struct operand_select; template struct choose_op; template struct choose_rop; template struct choose_unary_op; template struct define_operator; + class BOOST_PYTHON_DECL extension_instance : public instance + { + public: + extension_instance(PyTypeObject* class_); + ~extension_instance(); + + void add_implementation(std::auto_ptr holder); + + typedef std::vector held_objects; + const held_objects& wrapped_objects() const + { return m_wrapped_objects; } + private: + held_objects m_wrapped_objects; + }; + +} // namespace detail + +# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT +BOOST_PYTHON_EXPORT_TEMPLATE_CLASS class_t; +BOOST_PYTHON_EXPORT_TEMPLATE_CLASS meta_class; +# endif + +namespace detail { + BOOST_PYTHON_DECL meta_class* extension_meta_class(); BOOST_PYTHON_DECL extension_instance* get_extension_instance(PyObject* p); BOOST_PYTHON_DECL void report_missing_instance_data(extension_instance*, class_t*, const std::type_info&); @@ -813,21 +838,6 @@ class instance_ptr_holder : public instance_holder PtrType m_ptr; }; -class BOOST_PYTHON_DECL extension_instance : public instance -{ - public: - extension_instance(PyTypeObject* class_); - ~extension_instance(); - - void add_implementation(std::auto_ptr holder); - - typedef std::vector held_objects; - const held_objects& wrapped_objects() const - { return m_wrapped_objects; } - private: - held_objects m_wrapped_objects; -}; - // // Template function implementations // From ed9bc835a267ff3fc5116708bb50c71d38868f3b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 28 Dec 2001 23:56:10 +0000 Subject: [PATCH 0148/1042] Stuck the extension_class code in the DLL whenever possible Removed some flotsam [SVN r12166] --- include/boost/python/detail/config.hpp | 44 ++++++++++++++++++++------ 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index c79eb2ca..97d84a79 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -76,19 +76,29 @@ # define BOOST_PYTHON_STATIC_LINK #endif -#if defined(BOOST_MSVC) && defined(_DLL) && !defined(BOOST_PYTHON_HAS_DLL_RUNTIME) -# define BOOST_PYTHON_HAS_DLL_RUNTIME +#if defined(__MWERKS__) +# define BOOST_PYTHON_NO_TEMPLATE_EXPORT #endif -#if defined(__BORLANDC__) && defined(_RTLDLL) && !defined(BOOST_PYTHON_HAS_DLL_RUNTIME) -# define BOOST_PYTHON_HAS_DLL_RUNTIME +#if defined(__GNUC__) +# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern +# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD extern #endif -#if defined(__ICL) && defined(_DLL) && !defined(BOOST_PYTHON_HAS_DLL_RUNTIME) -# define BOOST_PYTHON_HAS_DLL_RUNTIME +// Handle default cases +#ifndef BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD +# ifdef _WIN32 +# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern +# else +# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD +# endif #endif -#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32) // && !defined(BOOST_PYTHON_STATIC_LINK) +#ifndef BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD +# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD +#endif + +#if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32) # if defined(BOOST_PYTHON_SOURCE) # define BOOST_PYTHON_DECL __declspec(dllexport) # define BOOST_PYTHON_BUILD_DLL @@ -101,10 +111,26 @@ # define BOOST_PYTHON_DECL #endif -#if (defined(BOOST_MSVC) || defined(__BORLANDC__)) && !defined(BOOST_PYTHON_NO_LIB) && !defined(BOOST_PYTHON_SOURCE) -// # include +#ifndef BOOST_PYTHON_DECL_TEMPLATE +# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT +# define BOOST_PYTHON_DECL_TEMPLATE BOOST_PYTHON_DECL +# else +# define BOOST_PYTHON_DECL_TEMPLATE +# endif #endif +#if defined(BOOST_PYTHON_SOURCE) +# define BOOST_PYTHON_EXPORT BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD +#else +# define BOOST_PYTHON_EXPORT BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD +#endif + +# ifndef BOOST_PYTHON_EXPORT_TEMPLATE +# define BOOST_PYTHON_EXPORT_TEMPLATE BOOST_PYTHON_EXPORT template +# endif + +# define BOOST_PYTHON_EXPORT_TEMPLATE_CLASS BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL + // Borland C++ Fix/error check: #if defined(__BORLANDC__) # if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551) From 94c0e947f5f6c03bd73ac66627de95f900d583e7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 28 Dec 2001 23:59:02 +0000 Subject: [PATCH 0149/1042] Stuck the extension_class code in the DLL whenever possible Removed copyability restriction in class_base to enable the above [SVN r12167] --- include/boost/python/classes.hpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/include/boost/python/classes.hpp b/include/boost/python/classes.hpp index 548a57db..31af430f 100644 --- a/include/boost/python/classes.hpp +++ b/include/boost/python/classes.hpp @@ -128,6 +128,10 @@ namespace detail { private: // boost::python::type_object_base required interface implementation void instance_dealloc(PyObject*) const; // subclasses should not override this + + private: // noncopyable, without the size bloat + class_base(const class_base&); + void operator=(const class_base&); private: string m_name; @@ -141,11 +145,12 @@ namespace detail { // A type which acts a lot like a built-in Python class. T is the obj type, // so class_t is a very simple "class-alike". template -class class_t +class BOOST_PYTHON_DECL_TEMPLATE class_t : public boost::python::detail::class_base { public: class_t(meta_class* meta_class_obj, string name, tuple bases, const dictionary& name_space); + ~class_t(); // Standard Python functions. PyObject* call(PyObject* args, PyObject* keywords); @@ -218,15 +223,11 @@ class class_t private: // Implementation of boost::python::detail::class_base required interface void delete_instance(PyObject*) const; - - private: // noncopyable, without the size bloat - class_t(const class_t&); - void operator=(const class_t&); }; // The type of a class_t object. template -class meta_class +class BOOST_PYTHON_DECL_TEMPLATE meta_class : public boost::python::detail::reprable< boost::python::detail::callable< boost::python::detail::getattrable< @@ -264,6 +265,11 @@ class_t::class_t(meta_class* meta_class_obj, string name, tuple bases, con { } +template +class_t::~class_t() +{ +} + template void class_t::delete_instance(PyObject* obj) const { From dc831fb3f62897eb052d6e37fc8e64daa061a364 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 29 Dec 2001 00:00:19 +0000 Subject: [PATCH 0150/1042] Stuck the extension_class code in the DLL whenever possible [SVN r12168] --- src/extension_class.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/extension_class.cpp b/src/extension_class.cpp index f8bcf9ad..cc784ca6 100644 --- a/src/extension_class.cpp +++ b/src/extension_class.cpp @@ -11,6 +11,7 @@ #define BOOST_PYTHON_SOURCE +#include #include #include #include @@ -681,4 +682,9 @@ PyNumberMethods operator_dispatcher::number_methods = } // namespace detail +# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT +template class BOOST_PYTHON_DECL meta_class; +template class BOOST_PYTHON_DECL class_t; +# endif + }} // namespace boost::python From 1247ff2543e8816a0c9f9ea2eaf39609a57aaffd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 31 Dec 2001 17:02:43 +0000 Subject: [PATCH 0151/1042] *** empty log message *** [SVN r12177] --- include/boost/python/converter/unwrap.hpp | 31 +++-------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/include/boost/python/converter/unwrap.hpp b/include/boost/python/converter/unwrap.hpp index 6dda61fb..4a2ea04c 100644 --- a/include/boost/python/converter/unwrap.hpp +++ b/include/boost/python/converter/unwrap.hpp @@ -11,6 +11,7 @@ # include # include # include +# include # include namespace boost { namespace python { namespace converter { @@ -55,7 +56,7 @@ struct unwrap_more_ : unwrap_base // unspecified storage which may be allocated by the unwrapper to // do value conversions. mutable void* m_storage; - friend class unwrapper; + typedef typename unwrapper_select::type unwrapper_t; }; // specialization for PyObject* @@ -142,32 +143,6 @@ unwrap_more_::unwrap_more_(PyObject* source) { } -# if 0 -template <> -inline unwrap_more_::unwrap_more_(PyObject* source, handle& prev) - : unwrap_base(source, m_unwrapper, prev) -{ -} - -template <> -inline unwrap_more_::unwrap_more_(PyObject* source) - : unwrap_base(source, m_unwrapper) - -{ -} - -template <> -inline PyObject* unwrap_more_::operator*() -{ - return source(); -} - -template <> -inline bool unwrap_more_::convertible(PyObject*) const -{ - return true; -} -# endif template inline unwrap_::unwrap_(PyObject* source) : unwrap_more_(source) @@ -178,7 +153,7 @@ template T unwrap_more_::operator*() { return static_cast*>( - get_body())->do_conversion(this); + get_body())->convert(this->m_source, this->m_storage); } template From 015b875a9ec0bc82016959bea34e18bc061965ea Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Jan 2002 18:21:06 +0000 Subject: [PATCH 0152/1042] Convertibility checks now collect the auxiliary conversion data [SVN r12186] --- src/converter/registry.cpp | 50 +++++++++++++------------------------ src/converter/unwrap.cpp | 10 ++++---- src/converter/unwrapper.cpp | 7 ++++++ 3 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index 88d96637..d247353c 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -39,35 +39,6 @@ namespace registry { } - namespace // - { - // A UnaryFunction type which deletes its argument - struct delete_item - { - template - void operator()(T* x) const - { - delete x; - } - }; - - // A UnaryFunction type which returns true iff its argument is a - // unwrapper which can convert the given Python object. - struct convertible - { - convertible(PyObject* p) - : m_p(p) - {} - - bool operator()(unwrapper_base* converter) const - { - return converter->convertible(m_p); - } - - PyObject* m_p; - }; - } - entry::~entry() { if (m_wrapper != 0) @@ -79,12 +50,25 @@ namespace registry } } - unwrapper_base* entry::unwrapper(PyObject* p) const + std::pair + entry::unwrapper(PyObject* p) const { - unwrappers::const_iterator q = - std::find_if(m_unwrappers.begin(), m_unwrappers.end(), convertible(p)); + unwrapper_base* body = 0; + void* data = 0; - return q == m_unwrappers.end() ? 0 : *q; + for (unwrappers::const_iterator q = m_unwrappers.begin(), + finish = m_unwrappers.end(); + q != finish; + ++q) + { + data = (*q)->can_convert(p); + if (data != 0) + { + body = *q; + break; + } + } + return std::make_pair(body,data); } wrapper_base* entry::wrapper() const diff --git a/src/converter/unwrap.cpp b/src/converter/unwrap.cpp index e0c09db6..33a7d7ae 100644 --- a/src/converter/unwrap.cpp +++ b/src/converter/unwrap.cpp @@ -13,7 +13,7 @@ namespace struct pyobject_unwrapper : unwrapper_base { pyobject_unwrapper(); - bool convertible(PyObject*) const; + void* can_convert(PyObject*) const; }; pyobject_unwrapper static_unwrapper; @@ -23,13 +23,13 @@ namespace { } - bool pyobject_unwrapper::convertible(PyObject*) const + void* pyobject_unwrapper::can_convert(PyObject*) const { - return true; + return non_null; } } -BOOST_PYTHON_EXPORT unwrapper_base* -unwrap_more_::m_unwrapper = &static_unwrapper; +BOOST_PYTHON_DECL std::pair +unwrap_more_::m_unwrapper(&static_unwrapper,&static_unwrapper); }}} // namespace boost::python::converter diff --git a/src/converter/unwrapper.cpp b/src/converter/unwrapper.cpp index 2b0adbd0..6279febf 100644 --- a/src/converter/unwrapper.cpp +++ b/src/converter/unwrapper.cpp @@ -21,4 +21,11 @@ unwrapper_base::~unwrapper_base() registry::remove(*this); } +namespace +{ + int arbitrary; +} + +void* const unwrapper_base::non_null = &arbitrary; + }}} // namespace boost::python::converter From e934be2d991249f2bf18ce58a520e40ef8abb113 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Jan 2002 18:21:31 +0000 Subject: [PATCH 0153/1042] BOOST_PYTHON_EXPORT -> BOOST_PYTHON_DECL [SVN r12187] --- src/converter/type_id.cpp | 2 +- src/object/class.cpp | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/converter/type_id.cpp b/src/converter/type_id.cpp index 86974638..fc2db66a 100644 --- a/src/converter/type_id.cpp +++ b/src/converter/type_id.cpp @@ -19,7 +19,7 @@ bool type_id_before::operator()(type_id_t const& x, type_id_t const& y) const return x < y; } -BOOST_PYTHON_EXPORT std::ostream& operator<<(std::ostream& os, type_id_t const& x) +BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_id_t const& x) { # ifdef BOOST_PYTHON_TYPE_ID_NAME os << x.m_base_type; diff --git a/src/object/class.cpp b/src/object/class.cpp index cc3903e3..bdd66a77 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -4,7 +4,7 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include #include #include #include @@ -23,7 +23,6 @@ holder_base::~holder_base() { } -//BOOST_PYTHON_EXPORT PyTypeObject class_metatype_object = { PyObject_HEAD_INIT(0)//&PyType_Type) 0, @@ -68,7 +67,6 @@ PyTypeObject class_metatype_object = { // PyType_GenericNew /* tp_new */ }; -//BOOST_PYTHON_EXPORT PyTypeObject class_type_object = { PyObject_HEAD_INIT(0) //&class_metatype_object) 0, @@ -112,7 +110,7 @@ PyTypeObject class_type_object = { PyType_GenericNew }; -BOOST_PYTHON_EXPORT PyTypeObject* class_metatype() +BOOST_PYTHON_DECL PyTypeObject* class_metatype() { if (class_metatype_object.tp_dict == 0) { @@ -125,7 +123,7 @@ BOOST_PYTHON_EXPORT PyTypeObject* class_metatype() return &class_metatype_object; } -BOOST_PYTHON_EXPORT PyTypeObject* class_type() +BOOST_PYTHON_DECL PyTypeObject* class_type() { if (class_type_object.tp_dict == 0) { @@ -145,7 +143,7 @@ void holder_base::install(PyObject* self) ((instance*)self)->objects = this; } -BOOST_PYTHON_EXPORT holder_base* +BOOST_PYTHON_DECL holder_base* find_holder_impl(PyObject* inst, converter::type_id_t type) { if (inst->ob_type->ob_type != &class_metatype_object) From a7b844810789cb6c7daa7c61187d3e1a55ae09e1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Jan 2002 18:45:49 +0000 Subject: [PATCH 0154/1042] obsolete now that Boost.Python is in a shared lib. [SVN r12188] --- include/boost/python/export.hpp | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 include/boost/python/export.hpp diff --git a/include/boost/python/export.hpp b/include/boost/python/export.hpp deleted file mode 100644 index 1229dffe..00000000 --- a/include/boost/python/export.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef EXPORT_DWA20011220_HPP -# define EXPORT_DWA20011220_HPP - -# include -# ifdef _WIN32 -# ifdef BOOST_PYTHON_SOURCE -# define BOOST_PYTHON_EXPORT __declspec(dllexport) -# else -# define BOOST_PYTHON_EXPORT __declspec(dllimport) -# endif -# else -# define BOOST_PYTHON_EXPORT -# endif - -#endif // EXPORT_DWA20011220_HPP From ccd21d52549450c82284a71f2712e602f1feb212 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Jan 2002 18:47:32 +0000 Subject: [PATCH 0155/1042] Accounting for by-value conversions Convertibility checks now collect the auxiliary conversion data [SVN r12189] --- include/boost/python/converter/class.hpp | 78 +++++++++++++----------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/include/boost/python/converter/class.hpp b/include/boost/python/converter/class.hpp index 305ec448..6e09a961 100644 --- a/include/boost/python/converter/class.hpp +++ b/include/boost/python/converter/class.hpp @@ -11,46 +11,54 @@ namespace boost { namespace python { namespace converter { -struct class_unwrapper_base -{ - class_unwrapper_base(type_id_t sought_type); - void* -}; - template struct class_unwrapper + : private unwrapper + , private unwrapper + , private unwrapper + , private unwrapper { - struct ref_unwrapper : unwrapper - { - bool convertible(PyObject* p) const - { - return p->ob_type == &SimpleType; - } - - simple const& convert(PyObject* p, void*&) const - { - return static_cast(p)->x; - } - - }; - -# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - struct const_ref_unwrapper : unwrapper - { - bool convertible(PyObject* p) const - { - return p->ob_type == &SimpleType; - } - - simple const& convert(PyObject* p, void*&) const - { - return static_cast(p)->x; - } - - }; -# endif + private: + void* can_convert(PyObject*) const; + T& convert(PyObject*, void*, boost::type) const; + T const& convert(PyObject*, void*, boost::type) const; + T* convert(PyObject*, void*, boost::type) const; + T const* convert(PyObject*, void*, boost::type) const; }; +// +// implementations +// +template +void* class_unwrapper::can_convert(PyObject* p) const +{ + return object::find_holder(p); +} + +template +T& class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +{ + return *static_cast*>(holder_)->target(); +} + +template +T const& class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +{ + return *static_cast*>(holder_)->target(); +} + +template +T* class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +{ + return static_cast*>(holder_)->target(); +} + +template +T const* class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +{ + return static_cast*>(holder_)->target(); +} + }}} // namespace boost::python::converter #endif // CLASS_DWA20011215_HPP From bfcb36927c98ca69095b482ebb159e06d2a7a654 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Jan 2002 18:49:20 +0000 Subject: [PATCH 0156/1042] Accounting for by-value conversions [SVN r12190] --- include/boost/python/converter/target.hpp | 44 ++++++++++++++++------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/include/boost/python/converter/target.hpp b/include/boost/python/converter/target.hpp index 6effb996..f8f33171 100644 --- a/include/boost/python/converter/target.hpp +++ b/include/boost/python/converter/target.hpp @@ -33,8 +33,6 @@ namespace boost { namespace python { namespace converter { // importantly, avoids having to dynamically allocate room for // an lvalue of types which can be cheaply copied. // -// In the tables below, "cv" stands for the set of all possible -// cv-qualifications. // Target Source // int int @@ -46,10 +44,16 @@ namespace boost { namespace python { namespace converter { // On compilers supporting partial specialization: // // Target Source -// T T& -// T cv& T& -// T cv* T* -// T cv*const& T* +// T T const& +// T& T& +// T const& T const& +// T volatile T& +// T const volatile& T const& +// T* T* +// T const* T const* +// T volatile T* +// T const volatile* T const* +// T cv*const& same as T cv* // T cv*& T*& <- should this be legal? // T cv*volatile& T*& <- should this be legal? // T cv*const volatile& T*& <- should this be legal? @@ -75,7 +79,11 @@ struct target typedef typename mpl::select_type< use_identity , T - , typename add_reference::type>::type + , typename add_reference< + typename add_const< + typename remove_volatile::type + >::type + >::type >::type type; }; @@ -86,13 +94,23 @@ struct target template struct target { - typedef typename remove_cv::type& type; + typedef typename remove_volatile::type& type; +}; + +template +struct target +{ + typedef typename boost::mpl::select_type< + is_scalar::value + , typename remove_cv::type + , typename remove_volatile::type const& + >::type type; }; template struct target { - typedef typename remove_cv::type* type; + typedef typename remove_volatile::type* type; }; // Handle T*-cv for completeness. Function arguments in a signature @@ -102,19 +120,19 @@ struct target template struct target { - typedef typename remove_cv::type* type; + typedef typename remove_volatile::type* type; }; template struct target { - typedef typename remove_cv::type* type; + typedef typename remove_volatile::type* type; }; template struct target { - typedef typename remove_cv::type* type; + typedef typename remove_volatile::type* type; }; // non-const references to pointers should be handled by the @@ -122,7 +140,7 @@ struct target template struct target { - typedef typename remove_cv::type* type; + typedef typename remove_volatile::type* type; }; # endif From b2944a12debbac87919f7841d1547af5e1a97b45 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Jan 2002 18:52:04 +0000 Subject: [PATCH 0157/1042] Convertibility checks now collect the auxiliary conversion data BOOST_PYTHON_EXPORT -> BOOST_PYTHON_DECL [SVN r12191] --- .../boost/python/converter/registration.hpp | 13 ++-- include/boost/python/converter/registry.hpp | 21 +++--- include/boost/python/converter/unwrap.hpp | 65 ++++++++++--------- include/boost/python/converter/unwrapper.hpp | 18 +---- .../boost/python/converter/unwrapper_base.hpp | 17 ++++- 5 files changed, 68 insertions(+), 66 deletions(-) diff --git a/include/boost/python/converter/registration.hpp b/include/boost/python/converter/registration.hpp index 0d85d1d7..b8a6326b 100644 --- a/include/boost/python/converter/registration.hpp +++ b/include/boost/python/converter/registration.hpp @@ -5,18 +5,19 @@ // to its suitability for any purpose. #ifndef REGISTRATION_DWA20011130_HPP # define REGISTRATION_DWA20011130_HPP -# include +# include # include # include -# include +# include +# include # ifdef BOOST_PYTHON_TRACE # include # endif namespace boost { namespace python { namespace converter { -struct BOOST_PYTHON_EXPORT wrapper_base; -struct BOOST_PYTHON_EXPORT unwrapper_base; +struct BOOST_PYTHON_DECL wrapper_base; +struct BOOST_PYTHON_DECL unwrapper_base; // This class is really sort of a "templated namespace". It manages a // static data member which refers to the registry entry for T. This @@ -28,7 +29,7 @@ struct registration public: // member functions // Return a converter which can convert the given Python object to // T, or 0 if no such converter exists - static unwrapper_base* unwrapper(PyObject*); + static std::pair unwrapper(PyObject*); // Return a converter which can convert T to a Python object, or 0 // if no such converter exists @@ -61,7 +62,7 @@ inline registry::entry* registration::entry() } template -unwrapper_base* registration::unwrapper(PyObject* p) +std::pair registration::unwrapper(PyObject* p) { # ifdef BOOST_PYTHON_TRACE std::cout << "retrieving unwrapper for " << type_id() << std::endl; diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index 30eeba8d..2023a732 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -7,20 +7,21 @@ # define REGISTRY_DWA20011127_HPP # include # include -# include +# include # include # include +# include namespace boost { namespace python { namespace converter { -struct BOOST_PYTHON_EXPORT wrapper_base; -struct BOOST_PYTHON_EXPORT unwrapper_base; +struct BOOST_PYTHON_DECL wrapper_base; +struct BOOST_PYTHON_DECL unwrapper_base; // This namespace acts as a sort of singleton namespace registry { // These are the elements stored in the registry - class BOOST_PYTHON_EXPORT entry + class BOOST_PYTHON_DECL entry { public: // member functions entry(); @@ -30,7 +31,7 @@ namespace registry // Python object from_python to the C++ type with which this // converter is associated in the registry, or 0 if no such // converter exists. - unwrapper_base* unwrapper(PyObject*) const; + std::pair unwrapper(PyObject*) const; // Return a converter appropriate for converting a C++ object // whose type this entry is associated with in the registry to a @@ -61,12 +62,12 @@ namespace registry converter::wrapper_base* m_wrapper; }; - BOOST_PYTHON_EXPORT entry* find(type_id_t); + BOOST_PYTHON_DECL entry* find(type_id_t); - BOOST_PYTHON_EXPORT void insert(wrapper_base& x); - BOOST_PYTHON_EXPORT void insert(unwrapper_base& x); - BOOST_PYTHON_EXPORT void remove(wrapper_base& x); - BOOST_PYTHON_EXPORT void remove(unwrapper_base& x); + BOOST_PYTHON_DECL void insert(wrapper_base& x); + BOOST_PYTHON_DECL void insert(unwrapper_base& x); + BOOST_PYTHON_DECL void remove(wrapper_base& x); + BOOST_PYTHON_DECL void remove(unwrapper_base& x); } }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/unwrap.hpp b/include/boost/python/converter/unwrap.hpp index 4a2ea04c..ffd0f081 100644 --- a/include/boost/python/converter/unwrap.hpp +++ b/include/boost/python/converter/unwrap.hpp @@ -12,22 +12,28 @@ # include # include # include -# include +# include +# include namespace boost { namespace python { namespace converter { template struct unwrapper; -struct BOOST_PYTHON_EXPORT body; +struct BOOST_PYTHON_DECL body; -struct BOOST_PYTHON_EXPORT unwrap_base : handle +struct BOOST_PYTHON_DECL unwrap_base : handle { public: // member functions - inline unwrap_base(PyObject* source, body*, handle& prev); - inline unwrap_base(PyObject* source, body*); + inline unwrap_base(PyObject* source, std::pair, handle& prev); + inline unwrap_base(PyObject* source, std::pair); inline PyObject* source() const; - + + protected: + inline PyObject*& source(); + inline void* data() const; + private: // data members PyObject* m_source; + void* m_data; }; // These converters will be used by the function wrappers. They don't @@ -47,15 +53,7 @@ struct unwrap_more_ : unwrap_base // this constructor is only for the use of unwrap_ unwrap_more_(PyObject* source); - private: // helper functions - // Return the unwrapper which will convert the given Python object - // to T, or 0 if no such converter exists - static unwrapper_base* lookup(PyObject*); - private: - // unspecified storage which may be allocated by the unwrapper to - // do value conversions. - mutable void* m_storage; typedef typename unwrapper_select::type unwrapper_t; }; @@ -78,9 +76,9 @@ struct unwrap_more_ return source(); } - bool convertible(PyObject*) const + void* can_convert(PyObject*) const { - return true; + return &m_unwrapper; } protected: // constructor @@ -91,7 +89,7 @@ struct unwrap_more_ { } private: - static BOOST_PYTHON_EXPORT unwrapper_base* m_unwrapper; + static BOOST_PYTHON_DECL std::pair m_unwrapper; }; template @@ -104,42 +102,47 @@ struct unwrap_ : unwrap_more_ // // implementations // -inline unwrap_base::unwrap_base(PyObject* source, body* body, handle& prev) - : handle(body, prev) +inline unwrap_base::unwrap_base( + PyObject* source, std::pair unwrapper, handle& prev) + : handle(unwrapper.first, prev) , m_source(source) + , m_data(unwrapper.second) { } -inline unwrap_base::unwrap_base(PyObject* source, body* body) - : handle(body) +inline unwrap_base::unwrap_base(PyObject* source, std::pair unwrapper) + : handle(unwrapper.first) , m_source(source) + , m_data(unwrapper.second) { } +inline void* unwrap_base::data() const +{ + return m_data; +} + inline PyObject* unwrap_base::source() const { return m_source; } -template -inline unwrapper_base* unwrap_more_::lookup(PyObject* source) +inline PyObject*& unwrap_base::source() { - // Find the converters registered for T and get a unwrapper - // appropriate for the source object - return registration::unwrapper(source); + return m_source; } template unwrap_more_::unwrap_more_(PyObject* source, handle& prev) - : unwrap_base(source, lookup(source), prev) - , m_storage(0) + : unwrap_base(source, + registration::unwrapper(source), + prev) { } template unwrap_more_::unwrap_more_(PyObject* source) - : unwrap_base(source, lookup(source)) - , m_storage(0) + : unwrap_base(source, registration::unwrapper(source)) { } @@ -153,7 +156,7 @@ template T unwrap_more_::operator*() { return static_cast*>( - get_body())->convert(this->m_source, this->m_storage); + get_body())->convert(this->source(), this->data(), boost::type()); } template diff --git a/include/boost/python/converter/unwrapper.hpp b/include/boost/python/converter/unwrapper.hpp index a30ff522..7f0609cf 100644 --- a/include/boost/python/converter/unwrapper.hpp +++ b/include/boost/python/converter/unwrapper.hpp @@ -9,6 +9,7 @@ # include # include # include +# include namespace boost { namespace python { namespace converter { @@ -21,13 +22,7 @@ struct unwrapper : unwrapper_base public: unwrapper(); - T do_conversion(unwrap_more_ const* handle) const; - - private: - virtual T convert(PyObject*, void*&) const = 0; - - private: // body required interface implementation - void destroy_handle(handle*) const {} + virtual T convert(PyObject*, void* data, boost::type) const = 0; }; // @@ -39,15 +34,6 @@ unwrapper::unwrapper() { } -// We could think about making this virtual in an effort to get its -// code generated in the module where the unwrapper is defined, but -// it's not clear that it's a good tradeoff. -template -T unwrapper::do_conversion(unwrap_more_ const* handle) const -{ - return convert(handle->source(), handle->m_storage); -} - }}} // namespace boost::python::converter #endif // UNWRAPPER_DWA2001127_HPP diff --git a/include/boost/python/converter/unwrapper_base.hpp b/include/boost/python/converter/unwrapper_base.hpp index 54e2e54c..ea437eb2 100644 --- a/include/boost/python/converter/unwrapper_base.hpp +++ b/include/boost/python/converter/unwrapper_base.hpp @@ -8,16 +8,27 @@ # include # include # include -# include +# include namespace boost { namespace python { namespace converter { -struct BOOST_PYTHON_EXPORT unwrapper_base : body +struct BOOST_PYTHON_DECL unwrapper_base : body { public: unwrapper_base(type_id_t); // registers ~unwrapper_base(); // unregisters - virtual bool convertible(PyObject*) const = 0; + + // Must return non-null iff the conversion will be successful. Any + // non-null pointer is acceptable, and will be passed on to the + // convert() function, so useful data can be stored there. + virtual void* can_convert(PyObject*) const = 0; + + protected: + // this is an arbitrary non-null pointer you can use to indicate success + static void* const non_null; + + private: // body required interface implementation + void destroy_handle(handle*) const {} }; }}} // namespace boost::python::converter From a179f87d54b4a7fc2e50aff59b109a1df6237889 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Jan 2002 18:53:12 +0000 Subject: [PATCH 0158/1042] BOOST_PYTHON_EXPORT -> BOOST_PYTHON_DECL [SVN r12192] --- include/boost/python/converter/body.hpp | 7 +++---- include/boost/python/converter/handle.hpp | 7 +++---- include/boost/python/converter/type_id.hpp | 11 +++++------ include/boost/python/converter/wrap.hpp | 4 ++-- include/boost/python/converter/wrapper.hpp | 5 ++--- include/boost/python/object/class.hpp | 10 +++++----- include/boost/python/object/function.hpp | 6 +++--- 7 files changed, 23 insertions(+), 27 deletions(-) diff --git a/include/boost/python/converter/body.hpp b/include/boost/python/converter/body.hpp index c8d932a0..72653ee0 100644 --- a/include/boost/python/converter/body.hpp +++ b/include/boost/python/converter/body.hpp @@ -5,20 +5,19 @@ // to its suitability for any purpose. #ifndef BODY_DWA2001127_HPP # define BODY_DWA2001127_HPP -# include +# include # include -# include namespace boost { namespace python { namespace converter { -struct BOOST_PYTHON_EXPORT handle; +struct BOOST_PYTHON_DECL handle; namespace registry { class entry; } -struct BOOST_PYTHON_EXPORT body +struct BOOST_PYTHON_DECL body { public: body(type_id_t key); diff --git a/include/boost/python/converter/handle.hpp b/include/boost/python/converter/handle.hpp index 16a50b38..03671634 100644 --- a/include/boost/python/converter/handle.hpp +++ b/include/boost/python/converter/handle.hpp @@ -5,19 +5,18 @@ // to its suitability for any purpose. #ifndef HANDLE_DWA20011130_HPP # define HANDLE_DWA20011130_HPP -# include +# include # include # include -# include namespace boost { namespace python { namespace converter { -struct BOOST_PYTHON_EXPORT body; +struct BOOST_PYTHON_DECL body; // The common base class for unwrap_ and wrap_ handle objects. They // share a common base so that handles can be linked into a chain // within a function wrapper which is managed by a single object. -struct BOOST_PYTHON_EXPORT handle : boost::noncopyable +struct BOOST_PYTHON_DECL handle : boost::noncopyable { public: // member functions diff --git a/include/boost/python/converter/type_id.hpp b/include/boost/python/converter/type_id.hpp index ddc04266..c383c352 100644 --- a/include/boost/python/converter/type_id.hpp +++ b/include/boost/python/converter/type_id.hpp @@ -5,12 +5,11 @@ // to its suitability for any purpose. #ifndef TYPE_ID_DWA20011127_HPP # define TYPE_ID_DWA20011127_HPP -# include -# include +# include +# include # include # include # include -# include # include # include # include @@ -48,7 +47,7 @@ typedef std::type_info const* base_id_t; bool operator<(type_id_t const& rhs) const; bool operator==(type_id_t const& rhs) const; - friend BOOST_PYTHON_EXPORT std::ostream& operator<<(std::ostream&, type_id_t const&); + friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&); private: decoration m_decoration; @@ -188,12 +187,12 @@ type_id_t type_id(detail::dummy* = 0) } # endif -struct BOOST_PYTHON_EXPORT type_id_before +struct BOOST_PYTHON_DECL type_id_before { bool operator()(type_id_t const& x, type_id_t const& y) const; }; -BOOST_PYTHON_EXPORT std::ostream& operator<<(std::ostream&, type_id_t const&); +BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&); }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/wrap.hpp b/include/boost/python/converter/wrap.hpp index 91c9de86..e26cf0f6 100644 --- a/include/boost/python/converter/wrap.hpp +++ b/include/boost/python/converter/wrap.hpp @@ -9,13 +9,13 @@ # include # include # include -# include +# include # include # include namespace boost { namespace python { namespace converter { -struct BOOST_PYTHON_EXPORT wrapper_base; +struct BOOST_PYTHON_DECL wrapper_base; template struct wrapper; diff --git a/include/boost/python/converter/wrapper.hpp b/include/boost/python/converter/wrapper.hpp index ada5e8cb..49c32186 100644 --- a/include/boost/python/converter/wrapper.hpp +++ b/include/boost/python/converter/wrapper.hpp @@ -5,13 +5,12 @@ // to its suitability for any purpose. #ifndef WRAPPER_DWA2001127_HPP # define WRAPPER_DWA2001127_HPP -# include +# include # include # include # include # include # include -# include namespace boost { namespace python { namespace converter { @@ -19,7 +18,7 @@ struct source_holder_base; struct wrap_base; template struct wrap_more_; -struct BOOST_PYTHON_EXPORT wrapper_base : body +struct BOOST_PYTHON_DECL wrapper_base : body { public: wrapper_base(type_id_t); // registers diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 548d4053..35085e5f 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -7,7 +7,7 @@ # define CLASS_DWA20011214_HPP # include -# include +# include # include # include # include @@ -17,7 +17,7 @@ namespace boost { namespace python { namespace object { template struct holder; // Base class for all holders -struct BOOST_PYTHON_EXPORT holder_base : noncopyable +struct BOOST_PYTHON_DECL holder_base : noncopyable { public: holder_base(converter::type_id_t id); @@ -68,7 +68,7 @@ struct instance holder_base* objects; }; -BOOST_PYTHON_EXPORT holder_base* find_holder_impl(PyObject*, converter::type_id_t); +BOOST_PYTHON_DECL holder_base* find_holder_impl(PyObject*, converter::type_id_t); template holder* find_holder(PyObject* p, T* = 0) @@ -76,8 +76,8 @@ holder* find_holder(PyObject* p, T* = 0) return static_cast*>(find_holder_impl(p, converter::type_id())); } -BOOST_PYTHON_EXPORT PyTypeObject* class_metatype(); -BOOST_PYTHON_EXPORT PyTypeObject* class_type(); +BOOST_PYTHON_DECL PyTypeObject* class_metatype(); +BOOST_PYTHON_DECL PyTypeObject* class_type(); // // implementation diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index f550e8dc..a0257676 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -7,7 +7,7 @@ # define FUNCTION_DWA20011214_HPP # include -# include +# include # include namespace boost { namespace python { namespace object { @@ -15,7 +15,7 @@ namespace boost { namespace python { namespace object { // We use boost::function to avoid generating lots of virtual tables typedef boost::function2 py_function; -struct BOOST_PYTHON_EXPORT function : PyObject +struct BOOST_PYTHON_DECL function : PyObject { function(py_function); ~function(); @@ -25,7 +25,7 @@ struct BOOST_PYTHON_EXPORT function : PyObject py_function m_fn; }; -extern BOOST_PYTHON_EXPORT PyTypeObject function_type; +extern BOOST_PYTHON_DECL PyTypeObject function_type; // // implementations From bdf68f092e6b7b94fa87b04d3da6c53c5f8fd16b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Jan 2002 18:55:23 +0000 Subject: [PATCH 0159/1042] Accounting for by-value conversions Convertibility checks now collect the auxiliary conversion data [SVN r12193] --- test/m1.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/test/m1.cpp b/test/m1.cpp index f4ad6390..809a0d63 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -14,8 +14,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -141,12 +141,12 @@ struct simple_ref_wrapper struct native_int_unwrapper : boost::python::converter::unwrapper { - bool convertible(PyObject* p) const + void* can_convert(PyObject* p) const { - return PyInt_Check(p); + return PyInt_Check(p) ? non_null : 0; } - int convert(PyObject* p, void*&) const + int convert(PyObject* p, void*, boost::type) const { return PyInt_AsLong(p); } @@ -155,12 +155,12 @@ struct native_int_unwrapper struct noddy_int_unwrapper : boost::python::converter::unwrapper { - bool convertible(PyObject* p) const + void* can_convert(PyObject* p) const { - return p->ob_type == &NoddyType; + return p->ob_type == &NoddyType ? non_null : 0; } - int convert(PyObject* p, void*&) const + int convert(PyObject* p, void*, boost::type) const { return static_cast(p)->x; } @@ -169,12 +169,12 @@ struct noddy_int_unwrapper struct noddy_int_ref_unwrapper : boost::python::converter::unwrapper { - bool convertible(PyObject* p) const + void* can_convert(PyObject* p) const { - return p->ob_type == &NoddyType; + return p->ob_type == &NoddyType ? non_null : 0; } - int& convert(PyObject* p, void*&) const + int& convert(PyObject* p, void*, boost::type) const { return static_cast(p)->x; } @@ -183,12 +183,12 @@ struct noddy_int_ref_unwrapper struct simple_ref_unwrapper : boost::python::converter::unwrapper { - bool convertible(PyObject* p) const + void* can_convert(PyObject* p) const { - return p->ob_type == &SimpleType; + return p->ob_type == &SimpleType ? non_null : 0; } - simple& convert(PyObject* p, void*&) const + simple& convert(PyObject* p, void*, boost::type) const { return static_cast(p)->x; } @@ -197,12 +197,12 @@ struct simple_ref_unwrapper struct simple_const_ref_unwrapper : boost::python::converter::unwrapper { - bool convertible(PyObject* p) const + void* can_convert(PyObject* p) const { - return p->ob_type == &SimpleType; + return p->ob_type == &SimpleType ? non_null : 0; } - simple const& convert(PyObject* p, void*&) const + simple const& convert(PyObject* p, void*, boost::type) const { return static_cast(p)->x; } @@ -228,12 +228,12 @@ BOOST_PYTHON_MODULE_INIT(m1) static noddy_int_unwrapper unwrap_int2; static noddy_int_ref_unwrapper unwrap_int3; static simple_ref_unwrapper unwrap_simple; + static simple_const_ref_unwrapper unwrap_simple_const_ref; #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // These compilers will need additional converters - static simple_const_ref_unwrapper unwrap_simple_const_ref; static simple_ref_wrapper wrap_simple_ref; #endif - static boost::python::object::class_unwrapper unwrap_complicated; + static boost::python::converter::class_unwrapper unwrap_complicated; PyObject* d = PyModule_GetDict(m1); if (d == NULL) From 1201761ff399b73378d5a70a88cbd86bfb99938e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 2 Jan 2002 17:53:34 +0000 Subject: [PATCH 0160/1042] initial checkin [SVN r12198] --- .../python/converter/unwrapper_select.hpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 include/boost/python/converter/unwrapper_select.hpp diff --git a/include/boost/python/converter/unwrapper_select.hpp b/include/boost/python/converter/unwrapper_select.hpp new file mode 100644 index 00000000..d60923af --- /dev/null +++ b/include/boost/python/converter/unwrapper_select.hpp @@ -0,0 +1,33 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef UNWRAPPER_SELECT_DWA20011229_HPP +# define UNWRAPPER_SELECT_DWA20011229_HPP + +namespace boost { namespace python { namespace converter { + +template struct unwrapper; + +// Select the type returned by unwrapper objects when unwrapping a +// given type. When unwrapping T const&, the unwrapper returns T&, so +// that the same unwrapper object can be used for both conversions (on +// a conforming compiler). +template +struct unwrapper_select +{ + typedef unwrapper type; +}; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct unwrapper_select +{ + typedef unwrapper type; +}; +# endif + +}}} // namespace boost::python::converter + +#endif // UNWRAPPER_SELECT_DWA20011229_HPP From 586e6178b49f3f7602852d7c1d31f7c94f3cd893 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 4 Jan 2002 02:06:21 +0000 Subject: [PATCH 0161/1042] commented [SVN r12209] --- test/m1.cpp | 73 +++++++++++++++++++++++++++++++++++++++---------- test/m2.cpp | 27 +++++++++++++++++- test/newtest.py | 6 ++++ 3 files changed, 90 insertions(+), 16 deletions(-) diff --git a/test/m1.cpp b/test/m1.cpp index 809a0d63..db450f77 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -5,7 +5,7 @@ // to its suitability for any purpose. // Seems to be neccessary to suppress an ICE with MSVC -#include "boost/mpl/comparison/less.hpp" +#include #include "simple_type.hpp" #include "complicated.hpp" @@ -21,12 +21,14 @@ #include #include +// Declare some straightforward extension types extern "C" void dealloc(PyObject* self) { PyObject_Del(self); } +// Noddy is a type we got from one of the Python sample files struct NoddyObject : PyObject { int x; @@ -50,6 +52,22 @@ PyTypeObject NoddyType = { 0, /*tp_hash */ }; +// Create a Noddy containing 42 +extern "C" PyObject* +new_noddy(PyObject* self, PyObject* args) +{ + NoddyObject* noddy; + + if (!PyArg_ParseTuple(args,":new_noddy")) + return NULL; + + noddy = PyObject_New(NoddyObject, &NoddyType); + noddy->x = 42; + + return (PyObject*)noddy; +} + +// Simple is a wrapper around a struct simple, which just contains a char* struct SimpleObject : PyObject { simple x; @@ -73,20 +91,7 @@ PyTypeObject SimpleType = { 0, /*tp_hash */ }; -extern "C" PyObject* -new_noddy(PyObject* self, PyObject* args) -{ - NoddyObject* noddy; - - if (!PyArg_ParseTuple(args,":new_noddy")) - return NULL; - - noddy = PyObject_New(NoddyObject, &NoddyType); - noddy->x = 42; - - return (PyObject*)noddy; -} - +// Create a Simple containing "hello, world" extern "C" PyObject* new_simple(PyObject* self, PyObject* args) { @@ -101,12 +106,21 @@ new_simple(PyObject* self, PyObject* args) return (PyObject*)simple; } +// Initial method table for the module static PyMethodDef methods[] = { { "new_noddy", new_noddy, METH_VARARGS }, { "new_simple", new_simple, METH_VARARGS }, {0, 0, 0, 0} }; +// +// Declare some wrappers/unwrappers to test the low-level conversion +// mechanism. See boost/python/converter/source.hpp,target.hpp for a +// description of how the type parameters to wrapper<> and unwrapper<> +// are selected. +// + +// Wrap an int by converting it to a Python Int struct int_wrapper : boost::python::converter::wrapper { @@ -116,6 +130,7 @@ struct int_wrapper } }; +// Wrap a simple by converting it to a Simple struct simple_wrapper : boost::python::converter::wrapper { @@ -127,6 +142,10 @@ struct simple_wrapper } }; +// wrap a mutable reference to a simple by converting it to a +// Simple. Normally we wouldn't do it this way, since modifications to +// the result clearly don't change the original object, but here we're +// just proving that the mechanism works. struct simple_ref_wrapper : boost::python::converter::wrapper { @@ -138,6 +157,9 @@ struct simple_ref_wrapper } }; +// extract an int from a Python Int by converting it to an int. Since +// int is a scalar type, we convert by-value. Since Python Ints are +// immutable, there's no non-const reference converter. struct native_int_unwrapper : boost::python::converter::unwrapper { @@ -152,6 +174,7 @@ struct native_int_unwrapper } }; +// Extract an int from a Noddy struct noddy_int_unwrapper : boost::python::converter::unwrapper { @@ -166,6 +189,7 @@ struct noddy_int_unwrapper } }; +// Extract a mutable reference to an int from a Noddy. struct noddy_int_ref_unwrapper : boost::python::converter::unwrapper { @@ -180,6 +204,7 @@ struct noddy_int_ref_unwrapper } }; +// Extract a mutable reference to a simple from a Simple struct simple_ref_unwrapper : boost::python::converter::unwrapper { @@ -194,6 +219,7 @@ struct simple_ref_unwrapper } }; +// Extract a const reference to a simple from a Simple struct simple_const_ref_unwrapper : boost::python::converter::unwrapper { @@ -208,11 +234,17 @@ struct simple_const_ref_unwrapper } }; +// +// Some C++ functions to expose to Python +// + +// Returns the length of s's held string int f(simple const& s) { return strlen(s.s); } +// A trivial passthru function for simple objects simple const& g(simple const& x) { return x; @@ -222,6 +254,7 @@ BOOST_PYTHON_MODULE_INIT(m1) { PyObject* m1 = Py_InitModule(const_cast("m1"), methods); + // Create the converters; they are self-registering/unregistering. static int_wrapper wrap_int; static simple_wrapper wrap_simple; static native_int_unwrapper unwrap_int1; @@ -233,32 +266,41 @@ BOOST_PYTHON_MODULE_INIT(m1) // These compilers will need additional converters static simple_ref_wrapper wrap_simple_ref; #endif + + // This unwrapper extracts pointers and references to the "complicated" class. static boost::python::converter::class_unwrapper unwrap_complicated; PyObject* d = PyModule_GetDict(m1); if (d == NULL) return; + // Insert the extension metaclass object if (PyDict_SetItemString( d, "xclass", (PyObject *)boost::python::object::class_metatype()) < 0) return; + // Insert the base class for all extension classes if (PyDict_SetItemString( d, "xinst", (PyObject *)boost::python::object::class_type()) < 0) return; + // Expose f() if (PyDict_SetItemString( d, "f", boost::python::make_function(f)) < 0) return; + // Expose g() if (PyDict_SetItemString( d, "g", boost::python::make_function(g)) < 0) return; + // Expose complicated's get_n() member function. See newtest.py + // for how it's used to build an extension class. if (PyDict_SetItemString( d, "get_n", boost::python::make_function(&complicated::get_n)) < 0) return; + // Expose complicated::complicated(simple const&, int) as init1 if (PyDict_SetItemString( d, "init1" , boost::python::make_constructor< @@ -268,6 +310,7 @@ BOOST_PYTHON_MODULE_INIT(m1) ) < 0) return; + // Expose complicated::complicated(simple const&) as init2 if (PyDict_SetItemString( d, "init2" , boost::python::make_constructor< diff --git a/test/m2.cpp b/test/m2.cpp index d2093a20..04750dd7 100644 --- a/test/m2.cpp +++ b/test/m2.cpp @@ -4,6 +4,13 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. +// This module exercises the converters exposed in m1 at a low level +// by exposing raw Python extension functions that use wrap<> and +// unwrap<> objects. + +// Seems to be neccessary to suppress an ICE with MSVC +#include + #include #include #include "simple_type.hpp" @@ -11,7 +18,10 @@ using boost::python::wrap; using boost::python::unwrap; -extern "C" { +extern "C" +{ + // Get a simple (by value) from the argument, and return the + // string it holds. PyObject* unwrap_simple(PyObject* self, PyObject* args) { @@ -28,6 +38,8 @@ extern "C" { return PyString_FromString(x.s); }; + // Likewise, but demands that its possible to get a non-const + // reference to the simple. PyObject* unwrap_simple_ref(PyObject* self, PyObject* args) { @@ -44,6 +56,7 @@ extern "C" { return PyString_FromString(x.s); }; + // Likewise, with a const reference to the simple object. PyObject* unwrap_simple_const_ref(PyObject* self, PyObject* args) { @@ -60,6 +73,8 @@ extern "C" { return PyString_FromString(x.s); }; + // Get an int (by value) from the argument, and convert it to a + // Python Int. PyObject* unwrap_int(PyObject* self, PyObject* args) { @@ -76,6 +91,7 @@ extern "C" { return PyInt_FromLong(x); }; + // Get a non-const reference to an int from the argument PyObject* unwrap_int_ref(PyObject* self, PyObject* args) { @@ -92,6 +108,7 @@ extern "C" { return PyInt_FromLong(x); }; + // Get a const reference to an int from the argument. PyObject* unwrap_int_const_ref(PyObject* self, PyObject* args) { @@ -110,8 +127,12 @@ extern "C" { // ------------------- } + +// MSVC6 bug workaround template struct xxxx; +// rewrap extracts a T from the argument, then converts the T back +// to a PyObject* and returns it. template PyObject* rewrap(PyObject* self, PyObject* args, xxxx* = 0) @@ -134,6 +155,10 @@ rewrap(PyObject* self, PyObject* args, xxxx* = 0) extern "C" { + // + // Use rewrap to test simple, simple&, simple const&, int, + // int&, int const& + // PyObject* wrap_simple(PyObject* self, PyObject* args) { diff --git a/test/newtest.py b/test/newtest.py index 783e2240..b866258c 100644 --- a/test/newtest.py +++ b/test/newtest.py @@ -59,11 +59,17 @@ try: wrap_int_ref(n) >>> f(g(s)) 12 +Create an extension class which wraps "complicated" (init1 and get_n) +are a complicated constructor and member function, respectively. + >>> C = xclass('C', (xinst,), {'__init__': init1, 'get_n': get_n}) >>> c = C(s, 99) >>> c.get_n() 99 +Create another extension class which wraps "complicated" (init2 is a +different constructor -- no overloading yet). + >>> D = xclass('D', (xinst,), {'__init__': init2, 'get_n': get_n}) >>> d = D(s) >>> d.get_n() From 451aac806e9dc8938ad542bd8ecb8387415d8500 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 4 Jan 2002 20:15:49 +0000 Subject: [PATCH 0162/1042] remove extra semicolons [SVN r12214] --- include/boost/python/detail/returning.hpp | 124 +++++++++++----------- src/gen_returning.py | 4 +- test/m2.cpp | 24 ++--- 3 files changed, 76 insertions(+), 76 deletions(-) diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 28f1846e..ed107d37 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -33,7 +33,7 @@ struct returning wrap_more r(c0); if (!c0) return 0; return r( ((*c0).*pmf)() ); - }; + } template static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) { @@ -45,7 +45,7 @@ struct returning wrap_more r(c1); if (!c0) return 0; return r( ((*c0).*pmf)(*c1) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { @@ -58,7 +58,7 @@ struct returning wrap_more r(c2); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { @@ -72,7 +72,7 @@ struct returning wrap_more r(c3); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { @@ -87,7 +87,7 @@ struct returning wrap_more r(c4); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { @@ -103,7 +103,7 @@ struct returning wrap_more r(c5); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); - }; + } template static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) @@ -115,7 +115,7 @@ struct returning wrap_more r(c0); if (!c0) return 0; return r( ((*c0).*pmf)() ); - }; + } template static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) { @@ -127,7 +127,7 @@ struct returning wrap_more r(c1); if (!c0) return 0; return r( ((*c0).*pmf)(*c1) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) { @@ -140,7 +140,7 @@ struct returning wrap_more r(c2); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) { @@ -154,7 +154,7 @@ struct returning wrap_more r(c3); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) { @@ -169,7 +169,7 @@ struct returning wrap_more r(c4); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) { @@ -185,7 +185,7 @@ struct returning wrap_more r(c5); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); - }; + } template static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject* /* keywords */ ) @@ -197,7 +197,7 @@ struct returning wrap_more r(c0); if (!c0) return 0; return r( ((*c0).*pmf)() ); - }; + } template static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -209,7 +209,7 @@ struct returning wrap_more r(c1); if (!c0) return 0; return r( ((*c0).*pmf)(*c1) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -222,7 +222,7 @@ struct returning wrap_more r(c2); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -236,7 +236,7 @@ struct returning wrap_more r(c3); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -251,7 +251,7 @@ struct returning wrap_more r(c4); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -267,7 +267,7 @@ struct returning wrap_more r(c5); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); - }; + } // missing const volatile type traits @@ -282,7 +282,7 @@ struct returning wrap_more r(c0); if (!c0) return 0; return r( ((*c0).*pmf)() ); - }; + } template static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -294,7 +294,7 @@ struct returning wrap_more r(c1); if (!c0) return 0; return r( ((*c0).*pmf)(*c1) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -307,7 +307,7 @@ struct returning wrap_more r(c2); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -321,7 +321,7 @@ struct returning wrap_more r(c3); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -336,7 +336,7 @@ struct returning wrap_more r(c4); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -352,7 +352,7 @@ struct returning wrap_more r(c5); if (!c0) return 0; return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); - }; + } # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -361,7 +361,7 @@ struct returning // find the result converter wrap r; return r( (*pf)() ); - }; + } template static PyObject* call(R (*pf)(A0), PyObject* args, PyObject* /* keywords */ ) { @@ -372,7 +372,7 @@ struct returning wrap_more r(c0); if (!c0) return 0; return r( (*pf)(*c0) ); - }; + } template static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject* /* keywords */ ) { @@ -384,7 +384,7 @@ struct returning wrap_more r(c1); if (!c0) return 0; return r( (*pf)(*c0, *c1) ); - }; + } template static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject* /* keywords */ ) { @@ -397,7 +397,7 @@ struct returning wrap_more r(c2); if (!c0) return 0; return r( (*pf)(*c0, *c1, *c2) ); - }; + } template static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { @@ -411,7 +411,7 @@ struct returning wrap_more r(c3); if (!c0) return 0; return r( (*pf)(*c0, *c1, *c2, *c3) ); - }; + } template static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { @@ -426,7 +426,7 @@ struct returning wrap_more r(c4); if (!c0) return 0; return r( (*pf)(*c0, *c1, *c2, *c3, *c4) ); - }; + } template static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { @@ -442,7 +442,7 @@ struct returning wrap_more r(c5); if (!c0) return 0; return r( (*pf)(*c0, *c1, *c2, *c3, *c4, *c5) ); - }; + } }; template <> @@ -458,7 +458,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) { @@ -469,7 +469,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { @@ -481,7 +481,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { @@ -494,7 +494,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { @@ -508,7 +508,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3, *c4); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { @@ -523,7 +523,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) @@ -534,7 +534,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) { @@ -545,7 +545,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) { @@ -557,7 +557,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) { @@ -570,7 +570,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) { @@ -584,7 +584,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3, *c4); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) { @@ -599,7 +599,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject* /* keywords */ ) @@ -610,7 +610,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -621,7 +621,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -633,7 +633,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -646,7 +646,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -660,7 +660,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3, *c4); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -675,7 +675,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); return detail::none(); - }; + } // missing const volatile type traits @@ -689,7 +689,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -700,7 +700,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -712,7 +712,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -725,7 +725,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -739,7 +739,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3, *c4); return detail::none(); - }; + } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* /* keywords */ ) { @@ -754,7 +754,7 @@ struct returning if (!c0) return 0; ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); return detail::none(); - }; + } # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -762,7 +762,7 @@ struct returning { (*pf)(); return detail::none(); - }; + } template static PyObject* call(R (*pf)(A0), PyObject* args, PyObject* /* keywords */ ) { @@ -772,7 +772,7 @@ struct returning if (!c0) return 0; (*pf)(*c0); return detail::none(); - }; + } template static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject* /* keywords */ ) { @@ -783,7 +783,7 @@ struct returning if (!c0) return 0; (*pf)(*c0, *c1); return detail::none(); - }; + } template static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject* /* keywords */ ) { @@ -795,7 +795,7 @@ struct returning if (!c0) return 0; (*pf)(*c0, *c1, *c2); return detail::none(); - }; + } template static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { @@ -808,7 +808,7 @@ struct returning if (!c0) return 0; (*pf)(*c0, *c1, *c2, *c3); return detail::none(); - }; + } template static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { @@ -822,7 +822,7 @@ struct returning if (!c0) return 0; (*pf)(*c0, *c1, *c2, *c3, *c4); return detail::none(); - }; + } template static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { @@ -837,7 +837,7 @@ struct returning if (!c0) return 0; (*pf)(*c0, *c1, *c2, *c3, *c4, *c5); return detail::none(); - }; + } }; }}} // namespace boost::python::detail diff --git a/src/gen_returning.py b/src/gen_returning.py index 2b112cc0..2c33cfe5 100644 --- a/src/gen_returning.py +++ b/src/gen_returning.py @@ -74,7 +74,7 @@ member_function = ''' template %] if (!c0) return 0; %[r%:return r( %]((*c0).*pmf)(%(*c%+%:, %))%[r%: )%];%[v%: return detail::none();%] - }; + } ''' free_function = '''%{ template <%(class A%n%:, %)> @@ -88,7 +88,7 @@ free_function = '''%{ template <%(class A%n%:, %)> if (!c0) return 0;%} %[r%:return r( %](*pf)(%(*c%n%:, %))%[r%: )%];%[v%: return detail::none();%] - }; + } ''' def _returns_value(key, n, args, value): diff --git a/test/m2.cpp b/test/m2.cpp index 04750dd7..377ce02e 100644 --- a/test/m2.cpp +++ b/test/m2.cpp @@ -36,7 +36,7 @@ extern "C" simple x = *in; return PyString_FromString(x.s); - }; + } // Likewise, but demands that its possible to get a non-const // reference to the simple. @@ -54,7 +54,7 @@ extern "C" simple& x = *in; return PyString_FromString(x.s); - }; + } // Likewise, with a const reference to the simple object. PyObject* @@ -71,7 +71,7 @@ extern "C" simple const& x = *in; return PyString_FromString(x.s); - }; + } // Get an int (by value) from the argument, and convert it to a // Python Int. @@ -89,7 +89,7 @@ extern "C" int x = *in; return PyInt_FromLong(x); - }; + } // Get a non-const reference to an int from the argument PyObject* @@ -106,7 +106,7 @@ extern "C" int& x = *in; return PyInt_FromLong(x); - }; + } // Get a const reference to an int from the argument. PyObject* @@ -123,7 +123,7 @@ extern "C" int const& x = *in; return PyInt_FromLong(x); - }; + } // ------------------- } @@ -163,37 +163,37 @@ extern "C" wrap_simple(PyObject* self, PyObject* args) { return rewrap(self, args); - }; + } PyObject* wrap_simple_ref(PyObject* self, PyObject* args) { return rewrap(self, args); - }; + } PyObject* wrap_simple_const_ref(PyObject* self, PyObject* args) { return rewrap(self, args); - }; + } PyObject* wrap_int(PyObject* self, PyObject* args) { return rewrap(self, args); - }; + } PyObject* wrap_int_ref(PyObject* self, PyObject* args) { return rewrap(self, args); - }; + } PyObject* wrap_int_const_ref(PyObject* self, PyObject* args) { return rewrap(self, args); - }; + } } PyMethodDef initial_methods[] = From acdae42fc538593b730f3d9ce58c6e771d1661f3 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 4 Jan 2002 20:49:20 +0000 Subject: [PATCH 0163/1042] work-around for cxx [SVN r12215] --- include/boost/python/detail/config.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 97d84a79..886e2fa8 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -76,7 +76,7 @@ # define BOOST_PYTHON_STATIC_LINK #endif -#if defined(__MWERKS__) +#if defined(__MWERKS__) || (defined(__DECCXX_VER) && __DECCXX_VER <= 60290024) # define BOOST_PYTHON_NO_TEMPLATE_EXPORT #endif From e2623c5e82ed2c8af75a17b09c6b80e0182cf4fb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 4 Jan 2002 23:32:23 +0000 Subject: [PATCH 0164/1042] fixes for gcc-3.0.3 [SVN r12221] --- include/boost/python/detail/wrap_python.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index d0ad5dd2..3807eae1 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -47,7 +47,9 @@ typedef int pid_t; # define HAVE_STRERROR # endif # define NT_THREADS -# define WITH_THREAD +# if __GNUC__ < 3 || __GNUC__ == 3 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ < 3 +# define WITH_THREAD +# endif # ifndef NETSCAPE_PI # define USE_SOCKET # endif From 8d27b4822507b72b63b3ffa834c5e874ddd71c16 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 5 Jan 2002 02:18:00 +0000 Subject: [PATCH 0165/1042] update for cxx 6.5 and irix_CC [SVN r12222] --- include/boost/python/detail/config.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 886e2fa8..c488cb64 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -76,7 +76,9 @@ # define BOOST_PYTHON_STATIC_LINK #endif -#if defined(__MWERKS__) || (defined(__DECCXX_VER) && __DECCXX_VER <= 60290024) +#if defined(__MWERKS__) \ + || (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \ + || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) # define BOOST_PYTHON_NO_TEMPLATE_EXPORT #endif From b65f4ff963a6ea6a7962b5b221a2befd76d404df Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:29:54 +0000 Subject: [PATCH 0166/1042] added inlines [SVN r12224] --- include/boost/python/call.hpp | 62 +++++++++++++++++------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp index bdda879d..b95a31d5 100644 --- a/include/boost/python/call.hpp +++ b/include/boost/python/call.hpp @@ -17,188 +17,188 @@ namespace boost { namespace python { template -PyObject* call(R (*f)(), PyObject* args, PyObject* keywords) +inline PyObject* call(R (*f)(), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (*f)(A0), PyObject* args, PyObject* keywords) +inline PyObject* call(R (*f)(A0), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (*f)(A0, A1), PyObject* args, PyObject* keywords) +inline PyObject* call(R (*f)(A0, A1), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords) +inline PyObject* call(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords) +inline PyObject* call(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords) +inline PyObject* call(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords) +inline PyObject* call(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } // Member functions template -PyObject* call(R (A0::*f)(), PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1), PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)() const, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)() const, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)() volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)() volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } template -PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } From 462b91fb0830dc5b23d21ee84bc249b3f666ac51 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:30:46 +0000 Subject: [PATCH 0167/1042] Added min/max argument count checking [SVN r12225] --- include/boost/python/make_function.hpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index d824c0a4..fddc640b 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -12,27 +12,30 @@ # include # include # include +# include namespace boost { namespace python { template -PyObject* make_function(F f) +objects::function* make_function(F f) { - return new object::function( - object::py_function( - bind(detail::caller(), f, _1, _2))); + return new objects::function( + objects::py_function( + bind(detail::caller(), f, _1, _2)) + , detail::arg_tuple_size::value); } template -PyObject* make_constructor(T* = 0, ArgList* = 0, Generator* = 0) +objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0) { enum { nargs = mpl::size::value }; - return new object::function( - object::py_function( + return new objects::function( + objects::py_function( bind(detail::caller(), - object::make_holder + objects::make_holder ::template apply::execute - , _1, _2))); + , _1, _2)) + , nargs + 1); } }} // namespace boost::python From 4b88b9eed19077136414ff961ff648fcf7c9d791 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:31:27 +0000 Subject: [PATCH 0168/1042] Added most of the module_builder interface [SVN r12226] --- include/boost/python/module.hpp | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index c20279c3..b257b9ff 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -8,5 +8,68 @@ # include # include +# include +# include +# include + +namespace boost { namespace python { + +class BOOST_PYTHON_DECL module_base +{ + public: + // Create a module. REQUIRES: only one module is created per module. + module_base(const char* name); + ~module_base(); + + // Add elements to the module + void add(PyObject* x, const char* name); + void add(PyTypeObject* x, const char* name = 0); + void add(ref x, const char*name); + void add_overload(objects::function* x, const char* name); + + // Return true iff a module is currently being built. + static bool initializing(); + + // Return the name of the module currently being built. + // REQUIRES: initializing() == true + static string name(); + + // Return a pointer to the Python module object being built + PyObject* module() const; + + private: + PyObject* m_module; + static PyMethodDef initial_methods[1]; +}; + +class module : public module_base +{ + public: + module(const char* name) + : module_base(name) {} + +# if 0 + template + void def_raw(Fn fn, const char* name) + { + add(detail::new_raw_arguments_function(fn), name); + } +# endif + template + void def(Fn fn, const char* name) + { + add_overload(make_function(fn), name); + } +}; + +// +// inline implementations +// +inline PyObject* module_base::module() const +{ + return m_module; +} + +}} // namespace boost::python #endif // MODULE_DWA20011221_HPP From 8d56c529916bb3e12c0241ab3af50691d5b329b6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:32:51 +0000 Subject: [PATCH 0169/1042] simplification: I didn't really understand what I was dealing with, so I pared things down. [SVN r12227] --- include/boost/python/converter/source.hpp | 58 +++-------------------- 1 file changed, 7 insertions(+), 51 deletions(-) diff --git a/include/boost/python/converter/source.hpp b/include/boost/python/converter/source.hpp index 9af1cf49..94fdc5b8 100644 --- a/include/boost/python/converter/source.hpp +++ b/include/boost/python/converter/source.hpp @@ -17,63 +17,19 @@ namespace boost { namespace python { namespace converter { // ../../../more/generic_programming.html#type_generator) is used // to select the argument type to use when converting T to a PyObject* -template struct source; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -// Since for some strange reason temporaries can't be bound to const -// volatile references (8.5.3/5 in the C++ standard), we cannot use a -// const volatile reference as the standard for values and references. template struct source { - typedef T const& type; -}; + BOOST_STATIC_CONSTANT(bool, use_identity = (::boost::is_pointer::value)); -// This will handle the following: -// T const volatile& -> T const volatile& -// T volatile& -> T const volatile& -// T const& -> T const& -// T& -> T const& -template -struct source -{ - typedef T const& type; -}; - -template -struct source -{ - typedef T const* type; -}; - -template -struct source -{ - typedef T const* type; -}; - -// Deal with references to pointers -template -struct source -{ - typedef T const* type; -}; - -template -struct source -{ - typedef T const* type; -}; -# else -template -struct source -{ - typedef typename add_reference< - typename add_const::type + typedef typename mpl::select_type< + use_identity + , T + , typename add_reference< + typename add_const::type + >::type >::type type; }; -# endif }}} // namespace boost::python::converter From 1cc65a47eb708d0569319481bda49ff8fe8ad247 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:33:33 +0000 Subject: [PATCH 0170/1042] Added wrapper for PyObject* [SVN r12228] --- include/boost/python/converter/wrap.hpp | 29 +++++++++++++++++++--- include/boost/python/converter/wrapper.hpp | 2 ++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/include/boost/python/converter/wrap.hpp b/include/boost/python/converter/wrap.hpp index e26cf0f6..ec87f73d 100644 --- a/include/boost/python/converter/wrap.hpp +++ b/include/boost/python/converter/wrap.hpp @@ -16,6 +16,7 @@ namespace boost { namespace python { namespace converter { struct BOOST_PYTHON_DECL wrapper_base; +extern BOOST_PYTHON_DECL body& identity_wrapper; template struct wrapper; @@ -66,13 +67,33 @@ struct wrap_ : wrap_more_ ~wrap_(); }; + +// Specialization for PyObject* +template <> +struct wrap_more_ : wrap_base +{ + protected: + typedef PyObject* source_t; + + public: // member functions + wrap_more_(handle& prev) + : wrap_base(&identity_wrapper, prev) {} + + PyObject* operator()(source_t x) const { return x; } + + protected: // constructor for wrap_, below + wrap_more_() + : wrap_base(&identity_wrapper) {} + private: + friend class wrapper; +}; + // // implementations // - inline wrap_base::wrap_base(body* body, handle& prev) - : handle(body, prev), - m_target(0) + : handle(body, prev) + , m_target(0) { } @@ -119,7 +140,7 @@ template PyObject* wrap_more_::operator()(source_t x) const { return static_cast*>( - get_body())->do_conversion(*this, source_holder(x)); + this->get_body())->do_conversion(*this, source_holder(x)); } template diff --git a/include/boost/python/converter/wrapper.hpp b/include/boost/python/converter/wrapper.hpp index 49c32186..80afae46 100644 --- a/include/boost/python/converter/wrapper.hpp +++ b/include/boost/python/converter/wrapper.hpp @@ -27,6 +27,8 @@ struct BOOST_PYTHON_DECL wrapper_base : body virtual PyObject* do_conversion(wrap_base const&, source_holder_base const&) const = 0; }; +extern BOOST_PYTHON_DECL body& identity_wrapper; + template struct wrapper : wrapper_base { From fb333f36419cb3c32211d1c811c1d718d213419a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:34:14 +0000 Subject: [PATCH 0171/1042] Bug fix: convertability checks were missed in one case [SVN r12229] --- include/boost/python/detail/returning.hpp | 29 ++++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index ed107d37..87aecac5 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -359,8 +359,9 @@ struct returning static PyObject* call(R (*pf)(), PyObject*, PyObject* /* keywords */ ) { // find the result converter - wrap r; - return r( (*pf)() ); + wrap c0; + if (!c0) return 0; + return c0( (*pf)() ); } template static PyObject* call(R (*pf)(A0), PyObject* args, PyObject* /* keywords */ ) @@ -369,9 +370,9 @@ struct returning unwrap c0(PyTuple_GET_ITEM(args, 0)); // find the result converter - wrap_more r(c0); + wrap_more c1(c0); if (!c0) return 0; - return r( (*pf)(*c0) ); + return c1( (*pf)(*c0) ); } template static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject* /* keywords */ ) @@ -381,9 +382,9 @@ struct returning unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); // find the result converter - wrap_more r(c1); + wrap_more c2(c1); if (!c0) return 0; - return r( (*pf)(*c0, *c1) ); + return c2( (*pf)(*c0, *c1) ); } template static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject* /* keywords */ ) @@ -394,9 +395,9 @@ struct returning unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); // find the result converter - wrap_more r(c2); + wrap_more c3(c2); if (!c0) return 0; - return r( (*pf)(*c0, *c1, *c2) ); + return c3( (*pf)(*c0, *c1, *c2) ); } template static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) @@ -408,9 +409,9 @@ struct returning unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); // find the result converter - wrap_more r(c3); + wrap_more c4(c3); if (!c0) return 0; - return r( (*pf)(*c0, *c1, *c2, *c3) ); + return c4( (*pf)(*c0, *c1, *c2, *c3) ); } template static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) @@ -423,9 +424,9 @@ struct returning unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); // find the result converter - wrap_more r(c4); + wrap_more c5(c4); if (!c0) return 0; - return r( (*pf)(*c0, *c1, *c2, *c3, *c4) ); + return c5( (*pf)(*c0, *c1, *c2, *c3, *c4) ); } template static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) @@ -439,9 +440,9 @@ struct returning unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); // find the result converter - wrap_more r(c5); + wrap_more c6(c5); if (!c0) return 0; - return r( (*pf)(*c0, *c1, *c2, *c3, *c4, *c5) ); + return c6( (*pf)(*c0, *c1, *c2, *c3, *c4, *c5) ); } }; From 26d520af3cd25249987f0864cac66f1fc1683818 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:35:27 +0000 Subject: [PATCH 0172/1042] avoiding naming conflict, object:: -> objects:: [SVN r12230] --- include/boost/python/converter/class.hpp | 10 +++++----- include/boost/python/object/class.hpp | 4 ++-- include/boost/python/object/class_unwrapper.hpp | 4 ++-- include/boost/python/object/construct.hpp | 4 ++-- include/boost/python/object/make_holder.hpp | 4 ++-- include/boost/python/object/value_holder.hpp | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/boost/python/converter/class.hpp b/include/boost/python/converter/class.hpp index 6e09a961..c6fef86a 100644 --- a/include/boost/python/converter/class.hpp +++ b/include/boost/python/converter/class.hpp @@ -32,31 +32,31 @@ struct class_unwrapper template void* class_unwrapper::can_convert(PyObject* p) const { - return object::find_holder(p); + return objects::find_holder(p); } template T& class_unwrapper::convert(PyObject*, void* holder_, boost::type) const { - return *static_cast*>(holder_)->target(); + return *static_cast*>(holder_)->target(); } template T const& class_unwrapper::convert(PyObject*, void* holder_, boost::type) const { - return *static_cast*>(holder_)->target(); + return *static_cast*>(holder_)->target(); } template T* class_unwrapper::convert(PyObject*, void* holder_, boost::type) const { - return static_cast*>(holder_)->target(); + return static_cast*>(holder_)->target(); } template T const* class_unwrapper::convert(PyObject*, void* holder_, boost::type) const { - return static_cast*>(holder_)->target(); + return static_cast*>(holder_)->target(); } }}} // namespace boost::python::converter diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 35085e5f..b272d5fe 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -12,7 +12,7 @@ # include # include -namespace boost { namespace python { namespace object { +namespace boost { namespace python { namespace objects { template struct holder; @@ -98,6 +98,6 @@ holder::holder() { } -}}} // namespace boost::python::object +}}} // namespace boost::python::objects #endif // CLASS_DWA20011214_HPP diff --git a/include/boost/python/object/class_unwrapper.hpp b/include/boost/python/object/class_unwrapper.hpp index 4fa441e1..666c6e93 100644 --- a/include/boost/python/object/class_unwrapper.hpp +++ b/include/boost/python/object/class_unwrapper.hpp @@ -9,7 +9,7 @@ # include # include -namespace boost { namespace python { namespace object { +namespace boost { namespace python { namespace objects { template struct class_unwrapper @@ -35,6 +35,6 @@ struct class_unwrapper # endif }; -}}} // namespace boost::python::object +}}} // namespace boost::python::objects #endif // CLASS_UNWRAPPER_DWA20011221_HPP diff --git a/include/boost/python/object/construct.hpp b/include/boost/python/object/construct.hpp index 3ff701d2..1eb73e4a 100644 --- a/include/boost/python/object/construct.hpp +++ b/include/boost/python/object/construct.hpp @@ -6,7 +6,7 @@ #ifndef CONSTRUCT_DWA20011215_HPP # define CONSTRUCT_DWA20011215_HPP -namespace boost { namespace python { namespace object { +namespace boost { namespace python { namespace objects { template struct construct @@ -19,6 +19,6 @@ struct construct } }; -}}} // namespace boost::python::object +}}} // namespace boost::python::objects #endif // CONSTRUCT_DWA20011215_HPP diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index fb5ec382..76b3a5f4 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -11,7 +11,7 @@ # include # include -namespace boost { namespace python { namespace object { +namespace boost { namespace python { namespace objects { template struct undefined; @@ -119,6 +119,6 @@ struct make_holder<3> }; }; -}}} // namespace boost::python::object +}}} // namespace boost::python::objects #endif // MAKE_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 128d170b..a06afe84 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -8,7 +8,7 @@ # include -namespace boost { namespace python { namespace object { +namespace boost { namespace python { namespace objects { template struct value_holder : holder @@ -75,6 +75,6 @@ struct value_holder_generator }; }; -}}} // namespace boost::python::object +}}} // namespace boost::python::objects #endif // VALUE_HOLDER_DWA20011215_HPP From ab22e1b3a9b592837f73fb29de5feb275e440626 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:36:28 +0000 Subject: [PATCH 0173/1042] Added most of the module_builder interface [SVN r12231] --- Jamfile | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Jamfile b/Jamfile index 18372684..13cb04d7 100644 --- a/Jamfile +++ b/Jamfile @@ -13,17 +13,19 @@ PYTHON_PROPERTIES dll bpl : - src/converter/body.cpp - src/converter/handle.cpp - src/converter/registry.cpp - src/converter/wrapper.cpp - src/converter/unwrap.cpp - src/converter/unwrapper.cpp - src/converter/type_id.cpp - src/object/class.cpp - src/object/function.cpp - src/errors.cpp - : + src/converter/body.cpp + src/converter/handle.cpp + src/converter/registry.cpp + src/converter/wrapper.cpp + src/converter/unwrap.cpp + src/converter/unwrapper.cpp + src/converter/type_id.cpp + src/object/class.cpp + src/object/function.cpp + src/errors.cpp + src/module.cpp + src/objects.cpp + : $(PYTHON_PROPERTIES) BOOST_PYTHON_SOURCE ; From d598d0a4dbc3fad4426d6dc90b8d6d76c047fcd6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:39:34 +0000 Subject: [PATCH 0174/1042] added inlines [SVN r12232] --- src/gen_call.py | 4 +- test/m1.cpp | 99 ++++++++------------------- test/m2.cpp | 177 +++++++----------------------------------------- test/newtest.py | 21 ++---- 4 files changed, 61 insertions(+), 240 deletions(-) diff --git a/src/gen_call.py b/src/gen_call.py index dd178648..f609c0ae 100644 --- a/src/gen_call.py +++ b/src/gen_call.py @@ -36,7 +36,7 @@ def gen_call(member_function_args, free_function_args = None): return (header % (member_function_args, free_function_args) + gen_functions( '''template -PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords) +inline PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } @@ -49,7 +49,7 @@ PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords) , map(lambda cv: gen_functions( '''template -PyObject* call(R (A0::*f)(%(A%+%:, %))%1, PyObject* args, PyObject* keywords) +inline PyObject* call(R (A0::*f)(%(A%+%:, %))%1, PyObject* args, PyObject* keywords) { return detail::returning::call(f, args, keywords); } diff --git a/test/m1.cpp b/test/m1.cpp index db450f77..78471bfc 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -4,15 +4,13 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -// Seems to be neccessary to suppress an ICE with MSVC -#include - #include "simple_type.hpp" #include "complicated.hpp" #include #include #include #include +#include #include #include #include @@ -53,17 +51,10 @@ PyTypeObject NoddyType = { }; // Create a Noddy containing 42 -extern "C" PyObject* -new_noddy(PyObject* self, PyObject* args) +PyObject* new_noddy() { - NoddyObject* noddy; - - if (!PyArg_ParseTuple(args,":new_noddy")) - return NULL; - - noddy = PyObject_New(NoddyObject, &NoddyType); + NoddyObject* noddy = PyObject_New(NoddyObject, &NoddyType); noddy->x = 42; - return (PyObject*)noddy; } @@ -92,27 +83,13 @@ PyTypeObject SimpleType = { }; // Create a Simple containing "hello, world" -extern "C" PyObject* -new_simple(PyObject* self, PyObject* args) +PyObject* new_simple() { - SimpleObject* simple; - - if (!PyArg_ParseTuple(args,":new_simple")) - return NULL; - - simple = PyObject_New(SimpleObject, &SimpleType); + SimpleObject* simple = PyObject_New(SimpleObject, &SimpleType); simple->x.s = "hello, world"; - return (PyObject*)simple; } -// Initial method table for the module -static PyMethodDef methods[] = { - { "new_noddy", new_noddy, METH_VARARGS }, - { "new_simple", new_simple, METH_VARARGS }, - {0, 0, 0, 0} -}; - // // Declare some wrappers/unwrappers to test the low-level conversion // mechanism. See boost/python/converter/source.hpp,target.hpp for a @@ -252,7 +229,7 @@ simple const& g(simple const& x) BOOST_PYTHON_MODULE_INIT(m1) { - PyObject* m1 = Py_InitModule(const_cast("m1"), methods); + boost::python::module m1("m1"); // Create the converters; they are self-registering/unregistering. static int_wrapper wrap_int; @@ -262,63 +239,45 @@ BOOST_PYTHON_MODULE_INIT(m1) static noddy_int_ref_unwrapper unwrap_int3; static simple_ref_unwrapper unwrap_simple; static simple_const_ref_unwrapper unwrap_simple_const_ref; -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - // These compilers will need additional converters static simple_ref_wrapper wrap_simple_ref; -#endif // This unwrapper extracts pointers and references to the "complicated" class. static boost::python::converter::class_unwrapper unwrap_complicated; - PyObject* d = PyModule_GetDict(m1); - if (d == NULL) - return; - // Insert the extension metaclass object - if (PyDict_SetItemString( - d, "xclass", (PyObject *)boost::python::object::class_metatype()) < 0) - return; - + m1.add(boost::python::objects::class_metatype(), "xclass"); + // Insert the base class for all extension classes - if (PyDict_SetItemString( - d, "xinst", (PyObject *)boost::python::object::class_type()) < 0) - return; + m1.add(boost::python::objects::class_type(), "xinst"); + m1.def(new_noddy, "new_noddy"); + m1.def(new_simple, "new_simple"); + // Expose f() - if (PyDict_SetItemString( - d, "f", boost::python::make_function(f)) < 0) - return; + m1.def(f, "f"); // Expose g() - if (PyDict_SetItemString( - d, "g", boost::python::make_function(g)) < 0) - return; + m1.def(g, "g"); // Expose complicated's get_n() member function. See newtest.py // for how it's used to build an extension class. - if (PyDict_SetItemString( - d, "get_n", boost::python::make_function(&complicated::get_n)) < 0) - return; + m1.def(&complicated::get_n, "get_n"); // Expose complicated::complicated(simple const&, int) as init1 - if (PyDict_SetItemString( - d, "init1" - , boost::python::make_constructor< - complicated - , boost::mpl::type_list - , boost::python::object::value_holder_generator>() - ) < 0) - return; - - // Expose complicated::complicated(simple const&) as init2 - if (PyDict_SetItemString( - d, "init2" - , boost::python::make_constructor< - complicated - , boost::mpl::type_list - , boost::python::object::value_holder_generator>() - ) < 0) - return; + boost::python::objects::function* init = boost::python::make_constructor< + complicated + , boost::mpl::type_list + , boost::python::objects::value_holder_generator>(); + + boost::python::ref manager(init); + + init->add_overload( + boost::python::make_constructor< + complicated + , boost::mpl::type_list + , boost::python::objects::value_holder_generator>()); + + m1.add(manager, "init1"); } #include "module_tail.cpp" diff --git a/test/m2.cpp b/test/m2.cpp index 377ce02e..3c5267d0 100644 --- a/test/m2.cpp +++ b/test/m2.cpp @@ -7,10 +7,6 @@ // This module exercises the converters exposed in m1 at a low level // by exposing raw Python extension functions that use wrap<> and // unwrap<> objects. - -// Seems to be neccessary to suppress an ICE with MSVC -#include - #include #include #include "simple_type.hpp" @@ -22,106 +18,40 @@ extern "C" { // Get a simple (by value) from the argument, and return the // string it holds. - PyObject* - unwrap_simple(PyObject* self, PyObject* args) + PyObject* unwrap_simple(simple x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - boost::python::unwrap in(p); - if (!in) - return 0; - - simple x = *in; - return PyString_FromString(x.s); } // Likewise, but demands that its possible to get a non-const // reference to the simple. - PyObject* - unwrap_simple_ref(PyObject* self, PyObject* args) + PyObject* unwrap_simple_ref(simple& x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - unwrap in(p); - if (!in) - return 0; - - simple& x = *in; - return PyString_FromString(x.s); } // Likewise, with a const reference to the simple object. - PyObject* - unwrap_simple_const_ref(PyObject* self, PyObject* args) + PyObject* unwrap_simple_const_ref(simple const& x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - unwrap in(p); - if (!in) - return 0; - - simple const& x = *in; - return PyString_FromString(x.s); } // Get an int (by value) from the argument, and convert it to a // Python Int. - PyObject* - unwrap_int(PyObject* self, PyObject* args) + PyObject* unwrap_int(int x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - unwrap in(p); - if (!in) - return 0; - - int x = *in; - return PyInt_FromLong(x); } // Get a non-const reference to an int from the argument - PyObject* - unwrap_int_ref(PyObject* self, PyObject* args) + PyObject* unwrap_int_ref(int& x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - unwrap in(p); - if (!in) - return 0; - - int& x = *in; - return PyInt_FromLong(x); } // Get a const reference to an int from the argument. - PyObject* - unwrap_int_const_ref(PyObject* self, PyObject* args) + PyObject* unwrap_int_const_ref(int const& x) { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - unwrap in(p); - if (!in) - return 0; - - int const& x = *in; - return PyInt_FromLong(x); } @@ -134,89 +64,28 @@ template struct xxxx; // rewrap extracts a T from the argument, then converts the T back // to a PyObject* and returns it. template -PyObject* -rewrap(PyObject* self, PyObject* args, xxxx* = 0) +struct rewrap { - PyObject* p; - if (!PyArg_ParseTuple(args, "O", &p)) - return 0; - - boost::python::unwrap in(p); - if (!in) - return 0; - - boost::python::wrap out; - if (!out) - return 0; - - T x = *in; - return out(x); -} - -extern "C" -{ - // - // Use rewrap to test simple, simple&, simple const&, int, - // int&, int const& - // - PyObject* - wrap_simple(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } - - PyObject* - wrap_simple_ref(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } - - PyObject* - wrap_simple_const_ref(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } - - PyObject* - wrap_int(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } - - PyObject* - wrap_int_ref(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } - - PyObject* - wrap_int_const_ref(PyObject* self, PyObject* args) - { - return rewrap(self, args); - } -} - -PyMethodDef initial_methods[] = -{ - { "unwrap_int", unwrap_int, METH_VARARGS, 0 }, - { "unwrap_int_ref", unwrap_int_ref, METH_VARARGS, 0 }, - { "unwrap_int_const_ref", unwrap_int_const_ref, METH_VARARGS, 0 }, - { "unwrap_simple", unwrap_simple, METH_VARARGS, 0 }, - { "unwrap_simple_ref", unwrap_simple_ref, METH_VARARGS, 0 }, - { "unwrap_simple_const_ref", unwrap_simple_const_ref, METH_VARARGS, 0 }, - - { "wrap_int", wrap_int, METH_VARARGS, 0 }, - { "wrap_int_ref", wrap_int_ref, METH_VARARGS, 0 }, - { "wrap_int_const_ref", wrap_int_const_ref, METH_VARARGS, 0 }, - { "wrap_simple", wrap_simple, METH_VARARGS, 0 }, - { "wrap_simple_ref", wrap_simple_ref, METH_VARARGS, 0 }, - { "wrap_simple_const_ref", wrap_simple_const_ref, METH_VARARGS, 0 }, - { 0, 0, 0, 0 } + static T f(T x) { return x; } }; BOOST_PYTHON_MODULE_INIT(m2) { - Py_InitModule(const_cast("m2"), initial_methods); + boost::python::module m2("m2"); + + m2.def(unwrap_int, "unwrap_int"); + m2.def(unwrap_int_ref, "unwrap_int_ref"); + m2.def(unwrap_int_const_ref, "unwrap_int_const_ref"); + m2.def(unwrap_simple, "unwrap_simple"); + m2.def(unwrap_simple_ref, "unwrap_simple_ref"); + m2.def(unwrap_simple_const_ref, "unwrap_simple_const_ref"); + + m2.def(&rewrap::f, "wrap_int"); + m2.def(&rewrap::f, "wrap_int_ref"); + m2.def(&rewrap::f, "wrap_int_const_ref"); + m2.def(&rewrap::f, "wrap_simple"); + m2.def(&rewrap::f, "wrap_simple_ref"); + m2.def(&rewrap::f, "wrap_simple_const_ref"); } #include "module_tail.cpp" diff --git a/test/newtest.py b/test/newtest.py index b866258c..d29ac129 100644 --- a/test/newtest.py +++ b/test/newtest.py @@ -20,16 +20,14 @@ >>> unwrap_int(5) 5 -Can't get a reference to a built-in integer object +Can't get a non-const reference to a built-in integer object >>> try: ... unwrap_int_ref(7) ... except: pass ... else: print 'no exception' ->>> try: -... unwrap_int_const_ref(9) -... except: pass -... else: print 'no exception' +>>> unwrap_int_const_ref(9) +9 >>> wrap_int(n) 42 @@ -63,16 +61,11 @@ Create an extension class which wraps "complicated" (init1 and get_n) are a complicated constructor and member function, respectively. >>> C = xclass('C', (xinst,), {'__init__': init1, 'get_n': get_n}) ->>> c = C(s, 99) ->>> c.get_n() +>>> c1 = C(s, 99) +>>> c1.get_n() 99 - -Create another extension class which wraps "complicated" (init2 is a -different constructor -- no overloading yet). - ->>> D = xclass('D', (xinst,), {'__init__': init2, 'get_n': get_n}) ->>> d = D(s) ->>> d.get_n() +>>> c2 = C(s) +>>> c2.get_n() 0 """ From 03fef3106d17d2b3e46dfc2175d047276f720cfd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:39:52 +0000 Subject: [PATCH 0175/1042] Bug fix: convertability checks were missed in one case [SVN r12233] --- src/gen_returning.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/gen_returning.py b/src/gen_returning.py index 2c33cfe5..80e3342b 100644 --- a/src/gen_returning.py +++ b/src/gen_returning.py @@ -84,29 +84,23 @@ free_function = '''%{ template <%(class A%n%:, %)> %}%( unwrap%{_more%} c%n(PyTuple_GET_ITEM(args, %n)%{, c%-%}); %)%[r%: // find the result converter - wrap%{_more%} r%{(c%-)%};%]%{ - if (!c0) return 0;%} - %[r%:return r( %](*pf)(%(*c%n%:, %))%[r%: )%];%[v%: + wrap%{_more%} c%n%{(c%-)%};%]%[not-void-and-0-arg%: + if (!c0) return 0;%] + %[r%:return c%n( %](*pf)(%(*c%n%:, %))%[r%: )%];%[v%: return detail::none();%] } ''' def _returns_value(key, n, args, value): - if key == 'r': + if key != 'v': return value - # pass the value through gen_function again for recursive expansion -# return apply(gen_function, (value, n) + args -# , {'fill': _returns_value}) else: - assert key == 'v' return '' def _returns_void(key, n, args, value): - if key == 'v': + if key == 'v' or key == 'not-void-and-0-arg' and n != 0: return value else: - assert key == 'r' - # return the empty string, ignoring the value return '' _cv_qualifiers = ('', ' const', ' volatile', ' const volatile') From cdac34efeaa77d6ea82606e731f3c46c795e62b4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:40:33 +0000 Subject: [PATCH 0176/1042] Added wrapper for PyObject* [SVN r12234] --- src/converter/wrapper.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/converter/wrapper.cpp b/src/converter/wrapper.cpp index 0d817217..567ff99d 100644 --- a/src/converter/wrapper.cpp +++ b/src/converter/wrapper.cpp @@ -12,12 +12,6 @@ namespace boost { namespace python { namespace converter { wrapper_base::wrapper_base(type_id_t type) : body(type) { - // static assertions for target. These would go in a header, - // but Metrowerks only respects BOOST_STATIC_ASSERT if it is in an - // instantiated function -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -#else -#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION registry::insert(*this); } @@ -27,4 +21,21 @@ wrapper_base::~wrapper_base() registry::remove(*this); } +namespace +{ + // This doesn't actually get called, but we need something to fill + // in the slot in the wrap class. + struct identity_wrapper_t : wrapper + { + PyObject* convert(PyObject* source) const + { + return source; + } + }; + + identity_wrapper_t identity_wrapper_object; +} + +BOOST_PYTHON_DECL body& identity_wrapper = identity_wrapper_object; + }}} // namespace boost::python::converter From 65c74e39761c0237581d0459d1db6775ec055478 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:40:53 +0000 Subject: [PATCH 0177/1042] avoiding naming conflict, object:: -> objects:: [SVN r12235] --- src/object/class.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index bdd66a77..1b855120 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -3,15 +3,13 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. - #include -#include #include #include #include #include -namespace boost { namespace python { namespace object { +namespace boost { namespace python { namespace objects { holder_base::holder_base(converter::type_id_t id) : m_type(id) @@ -160,4 +158,4 @@ find_holder_impl(PyObject* inst, converter::type_id_t type) ? match.base() : 0; } -}}} // namespace boost::python::object +}}} // namespace boost::python::objects From 72aa7682352c5cfeb327810521168472ffd5adff Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 6 Jan 2002 14:41:51 +0000 Subject: [PATCH 0178/1042] Added overload capability [SVN r12236] --- src/object/function.cpp | 59 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/src/object/function.cpp b/src/object/function.cpp index 4c2de3c7..52a0456c 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -5,12 +5,16 @@ // to its suitability for any purpose. #include +#include -namespace boost { namespace python { namespace object { +namespace boost { namespace python { namespace objects { -function::function(py_function implementation) +function::function(py_function implementation, unsigned min_args, unsigned max_args) : m_fn(implementation) + , m_min_args(min_args) + , m_max_args(std::max(max_args,min_args)) + , m_overloads(0) { PyObject* p = this; PyObject_INIT(p, &function_type); @@ -18,22 +22,65 @@ function::function(py_function implementation) function::~function() { + PyObject* overloads = m_overloads; + Py_XDECREF(overloads); } PyObject* function::call(PyObject* args, PyObject* keywords) const { - return m_fn(args, keywords); + int nargs = PyTuple_GET_SIZE(args); + function const* f = this; + do + { + // Check for a plausible number of arguments + if (nargs >= f->m_min_args && nargs <= f->m_max_args) + { + // Call the function + PyObject* result = f->m_fn(args, keywords); + + // If the result is NULL but no error was set, m_fn failed + // the argument-matching test. + + // This assumes that all other error-reporters are + // well-behaved and never return NULL to python without + // setting an error. + if (result != 0 || PyErr_Occurred()) + return result; + } + f = f->m_overloads; + } + while (f); + // None of the overloads matched; time to generate the error message + argument_error(args, keywords); + return 0; +} + +void function::argument_error(PyObject* args, PyObject* keywords) const +{ + // This function needs to be improved to do better error reporting. + PyErr_BadArgument(); +} + +void function::add_overload(function* overload) +{ + function* parent = this; + + while (parent->m_overloads != 0) + { + parent = parent->m_overloads; + } + parent->m_overloads = overload; } extern "C" { // Stolen from Python's funcobject.c static PyObject * - function_descr_get(PyObject *func, PyObject *obj, PyObject *type) + function_descr_get(PyObject *func, PyObject *obj, PyObject *type_) { if (obj == Py_None) obj = NULL; - return PyMethod_New(func, obj, type); + return PyMethod_New(func, obj, type_); } static void @@ -92,4 +139,4 @@ PyTypeObject function_type = { 0 /* tp_new */ }; -}}} // namespace boost::python::object +}}} // namespace boost::python::objects From e83e8a8f1caf73c4068646b7c9b852b36910e690 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 7 Jan 2002 06:45:53 +0000 Subject: [PATCH 0179/1042] object::->objects:: [SVN r12237] --- include/boost/python/object/forward.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/object/forward.hpp b/include/boost/python/object/forward.hpp index cc9d65bb..88eefe6b 100644 --- a/include/boost/python/object/forward.hpp +++ b/include/boost/python/object/forward.hpp @@ -11,7 +11,7 @@ # include # include -namespace boost { namespace python { namespace object { +namespace boost { namespace python { namespace objects { // A little metaprogram which selects the type to pass through an // intermediate forwarding function when the destination argument type @@ -28,6 +28,6 @@ struct forward >::type type; }; -}}} // namespace boost::python::object +}}} // namespace boost::python::objects #endif // FORWARD_DWA20011215_HPP From 0dafa9e2299d0b0f629482ce03998d30f4dff0a7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 7 Jan 2002 06:46:32 +0000 Subject: [PATCH 0180/1042] check number of arguments [SVN r12238] --- include/boost/python/object/function.hpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index a0257676..ed7dd319 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -8,21 +8,30 @@ # include # include +# include # include -namespace boost { namespace python { namespace object { +namespace boost { namespace python { namespace objects { // We use boost::function to avoid generating lots of virtual tables typedef boost::function2 py_function; struct BOOST_PYTHON_DECL function : PyObject { - function(py_function); + function(py_function, unsigned min_args, unsigned max_args = 0); ~function(); PyObject* call(PyObject*, PyObject*) const; - private: + void add_overload(function* overload); + + private: // helper functions + void argument_error(PyObject* args, PyObject* keywords) const; + + private: // data members py_function m_fn; + unsigned m_min_args; + unsigned m_max_args; + function* m_overloads; }; extern BOOST_PYTHON_DECL PyTypeObject function_type; @@ -31,6 +40,6 @@ extern BOOST_PYTHON_DECL PyTypeObject function_type; // implementations // -}}} // namespace boost::python::object +}}} // namespace boost::python::objects #endif // FUNCTION_DWA20011214_HPP From 9923a4c4ff81a150fa5367cccd1b392908afe54e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 7 Jan 2002 06:47:22 +0000 Subject: [PATCH 0181/1042] More "realism" [SVN r12239] --- include/boost/python/converter/class.hpp | 18 +++---- include/boost/python/object/class.hpp | 53 ++++++-------------- include/boost/python/object/value_holder.hpp | 12 +++-- src/object/class.cpp | 29 ++++++----- 4 files changed, 48 insertions(+), 64 deletions(-) diff --git a/include/boost/python/converter/class.hpp b/include/boost/python/converter/class.hpp index c6fef86a..458ecee4 100644 --- a/include/boost/python/converter/class.hpp +++ b/include/boost/python/converter/class.hpp @@ -32,31 +32,31 @@ struct class_unwrapper template void* class_unwrapper::can_convert(PyObject* p) const { - return objects::find_holder(p); + return objects::find_instance(p); } template -T& class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +T& class_unwrapper::convert(PyObject*, void* found, boost::type) const { - return *static_cast*>(holder_)->target(); + return *static_cast(found); } template -T const& class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +T const& class_unwrapper::convert(PyObject*, void* found, boost::type) const { - return *static_cast*>(holder_)->target(); + return *static_cast(found); } template -T* class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +T* class_unwrapper::convert(PyObject*, void* found, boost::type) const { - return static_cast*>(holder_)->target(); + return static_cast(found); } template -T const* class_unwrapper::convert(PyObject*, void* holder_, boost::type) const +T const* class_unwrapper::convert(PyObject*, void* found, boost::type) const { - return static_cast*>(holder_)->target(); + return static_cast(found); } }}} // namespace boost::python::converter diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index b272d5fe..bc8f40d1 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -17,15 +17,16 @@ namespace boost { namespace python { namespace objects { template struct holder; // Base class for all holders -struct BOOST_PYTHON_DECL holder_base : noncopyable +struct BOOST_PYTHON_DECL instance_holder : noncopyable { public: - holder_base(converter::type_id_t id); - virtual ~holder_base(); - virtual bool held_by_value() const = 0; + instance_holder(); + virtual ~instance_holder(); - holder_base* next() const; - converter::type_id_t type() const; + // return the next holder in a chain + instance_holder* next() const; + + virtual void* holds(converter::type_id_t) = 0; void install(PyObject* inst); @@ -39,41 +40,30 @@ struct BOOST_PYTHON_DECL holder_base : noncopyable }; typedef iterator_adaptor< - holder_base* + instance_holder* , iterator_policies , value_type_is - , reference_is - , pointer_is + , reference_is + , pointer_is , iterator_category_is > iterator; private: - converter::type_id_t m_type; - holder_base* m_next; -}; - -// Abstract base class which holds a Held, somehow. Provides a uniform -// way to get a pointer to the held object -template -struct holder : holder_base -{ - typedef Held held_type; - holder(); - virtual Held* target() = 0; + instance_holder* m_next; }; // Each extension instance will be one of these struct instance { PyObject_HEAD - holder_base* objects; + instance_holder* objects; }; -BOOST_PYTHON_DECL holder_base* find_holder_impl(PyObject*, converter::type_id_t); +BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::type_id_t); template -holder* find_holder(PyObject* p, T* = 0) +T* find_instance(PyObject* p, T* = 0) { - return static_cast*>(find_holder_impl(p, converter::type_id())); + return static_cast(find_instance_impl(p, converter::type_id())); } BOOST_PYTHON_DECL PyTypeObject* class_metatype(); @@ -82,22 +72,11 @@ BOOST_PYTHON_DECL PyTypeObject* class_type(); // // implementation // -inline holder_base* holder_base::next() const +inline instance_holder* instance_holder::next() const { return m_next; } -inline converter::type_id_t holder_base::type() const -{ - return m_type; -} - -template -holder::holder() - : holder_base(converter::type_id()) -{ -} - }}} // namespace boost::python::objects #endif // CLASS_DWA20011214_HPP diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index a06afe84..be7247da 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -7,11 +7,12 @@ # define VALUE_HOLDER_DWA20011215_HPP # include +# include namespace boost { namespace python { namespace objects { template -struct value_holder : holder +struct value_holder : instance_holder { // Forward construction to the held object value_holder(PyObject*) @@ -58,8 +59,7 @@ struct value_holder : holder : m_held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} private: // required holder implementation - Held* target() { return &m_held; } - bool held_by_value() const { return true; } + void* holds(converter::type_id_t); private: // data members Held m_held; @@ -75,6 +75,12 @@ struct value_holder_generator }; }; +template +void* value_holder::holds(converter::type_id_t x) +{ + return x == converter::type_id() ? &m_held : 0; +} + }}} // namespace boost::python::objects #endif // VALUE_HOLDER_DWA20011215_HPP diff --git a/src/object/class.cpp b/src/object/class.cpp index 1b855120..8e85f38b 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -11,13 +11,12 @@ namespace boost { namespace python { namespace objects { -holder_base::holder_base(converter::type_id_t id) - : m_type(id) - , m_next(0) +instance_holder::instance_holder() + : m_next(0) { } -holder_base::~holder_base() +instance_holder::~instance_holder() { } @@ -134,28 +133,28 @@ BOOST_PYTHON_DECL PyTypeObject* class_type() return &class_type_object; } -void holder_base::install(PyObject* self) +void instance_holder::install(PyObject* self) { assert(self->ob_type->ob_type == &class_metatype_object); m_next = ((instance*)self)->objects; ((instance*)self)->objects = this; } -BOOST_PYTHON_DECL holder_base* -find_holder_impl(PyObject* inst, converter::type_id_t type) +BOOST_PYTHON_DECL void* +find_instance_impl(PyObject* inst, converter::type_id_t type) { if (inst->ob_type->ob_type != &class_metatype_object) return 0; + instance* self = reinterpret_cast(inst); - holder_base::iterator match = std::find_if( - holder_base::iterator(self->objects), holder_base::iterator(0) - , bind(std::equal_to() - , bind(mem_fn(&holder_base::type), _1) - , type)); - - return match != holder_base::iterator(0) - ? match.base() : 0; + for (instance_holder::iterator match(self->objects), end(0); match != end; ++match) + { + void* const found = (*match).holds(type); + if (found) + return found; + } + return 0; } }}} // namespace boost::python::objects From 10a04acf418f39cca5f046d5456699c7200f8045 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 9 Jan 2002 21:20:51 +0000 Subject: [PATCH 0182/1042] Missing this-> inserted (due to EDG 245 diagnostics) [SVN r12261] --- include/boost/python/converter/unwrap.hpp | 2 +- include/boost/python/converter/wrap.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/converter/unwrap.hpp b/include/boost/python/converter/unwrap.hpp index ffd0f081..525f1bb0 100644 --- a/include/boost/python/converter/unwrap.hpp +++ b/include/boost/python/converter/unwrap.hpp @@ -162,7 +162,7 @@ T unwrap_more_::operator*() template unwrap_::~unwrap_() { - destroy(); + this->destroy(); } }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/wrap.hpp b/include/boost/python/converter/wrap.hpp index ec87f73d..97d7b8de 100644 --- a/include/boost/python/converter/wrap.hpp +++ b/include/boost/python/converter/wrap.hpp @@ -158,7 +158,7 @@ wrap_::wrap_() template wrap_::~wrap_() { - destroy(); + this->destroy(); } }}} // namespace boost::python::converter From 8cff66e8c62dd88f5fcdc3cceb4bcccca23cf6e0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 9 Jan 2002 23:23:44 +0000 Subject: [PATCH 0183/1042] initial checkin [SVN r12264] --- src/module.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/module.cpp diff --git a/src/module.cpp b/src/module.cpp new file mode 100644 index 00000000..9faaca06 --- /dev/null +++ b/src/module.cpp @@ -0,0 +1,78 @@ +// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// The author gratefully acknowleges the support of Dragon Systems, Inc., in +// producing this work. + +#include +#include + +namespace boost { namespace python { + +namespace { + ref name_holder; +} + +bool module_base::initializing() +{ + return name_holder.get() != 0; +} + +string module_base::name() +{ + // If this fails, you haven't created a module object + assert(initializing()); + return string(name_holder); +} + +module_base::module_base(const char* name) + : m_module(Py_InitModule(const_cast(name), initial_methods)) +{ + // If this fails, you've created more than 1 module object in your module + assert(name_holder.get() == 0); + name_holder = ref(PyObject_GetAttrString(m_module, const_cast("__name__"))); +} + +module_base::~module_base() +{ + name_holder.reset(); +} + +void module_base::add(PyObject* x, const char* name) +{ + add(ref(x), name); +} + +void module_base::add(ref x, const char* name) +{ + ref f(x); // First take possession of the object. + if (PyObject_SetAttrString(m_module, const_cast(name), x.get()) < 0) + throw error_already_set(); +} + +void module_base::add(PyTypeObject* x, const char* name /*= 0*/) +{ + this->add((PyObject*)x, name ? name : x->tp_name); +} + +void module_base::add_overload(objects::function* x, const char* name) +{ + PyObject* existing = PyObject_HasAttrString(m_module, const_cast(name)) + ? PyObject_GetAttrString(m_module, const_cast(name)) + : 0; + + if (existing != 0 && existing->ob_type == &objects::function_type) + { + static_cast(existing)->add_overload(x); + } + else + { + add(x, name); + } +} + +PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; + +}} // namespace boost::python From aeef66ce3504ddeaaa60b677739132f9287a6fcf Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 10 Jan 2002 02:32:47 +0000 Subject: [PATCH 0184/1042] Handle cv-qualified member functions [SVN r12265] --- .../boost/python/detail/arg_tuple_size.hpp | 116 ++++++++++++++++++ src/gen_arg_tuple_size.py | 19 ++- 2 files changed, 133 insertions(+), 2 deletions(-) diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index e6b6ccc1..a330a939 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -99,6 +99,122 @@ struct arg_tuple_size BOOST_STATIC_CONSTANT(std::size_t, value = 6); }; + +// Metrowerks thinks this creates ambiguities +# if !defined(__MWERKS__) || __MWERKS__ > 0x2406 + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 1); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 2); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 3); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 4); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 5); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 6); +}; + + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 1); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 2); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 3); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 4); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 5); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 6); +}; + + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 1); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 2); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 3); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 4); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 5); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = 6); +}; + + +# endif // __MWERKS__ # else // We will use the "sizeof() trick" to work around the lack of diff --git a/src/gen_arg_tuple_size.py b/src/gen_arg_tuple_size.py index 68e379cb..5edd3286 100644 --- a/src/gen_arg_tuple_size.py +++ b/src/gen_arg_tuple_size.py @@ -21,6 +21,15 @@ header = '''// (C) Copyright David Abrahams 2001. Permission to copy, use, modi _cv_qualifiers = ('', ' const', ' volatile', ' const volatile') +_suffix = { + '': ''' +// Metrowerks thinks this creates ambiguities +# if !defined(__MWERKS__) || __MWERKS__ > 0x2406 +''', ' const volatile': ''' +# endif // __MWERKS__ +''' + }; + def gen_arg_tuple_size(member_function_args, free_function_args = None): if free_function_args is None: free_function_args = member_function_args + 1 @@ -53,14 +62,20 @@ struct arg_tuple_size ''', free_function_args) + '\n' - + gen_functions( + + + reduce(lambda x,y: x+'\n'+y + , map( + lambda cv: gen_functions( '''template struct arg_tuple_size { BOOST_STATIC_CONSTANT(std::size_t, value = %+); }; -''', member_function_args, '') +''' + , member_function_args, cv) + _suffix.get(cv, '') + , _cv_qualifiers)) + + '''# else From 98c9e67625052c9c3ee3dea2c3a338da96230e70 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 10 Jan 2002 13:59:14 +0000 Subject: [PATCH 0185/1042] Fixed mistaken "C" linkage [SVN r12268] --- test/m2.cpp | 67 +++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/test/m2.cpp b/test/m2.cpp index 3c5267d0..7ea1f9ac 100644 --- a/test/m2.cpp +++ b/test/m2.cpp @@ -14,48 +14,43 @@ using boost::python::wrap; using boost::python::unwrap; -extern "C" +// Get a simple (by value) from the argument, and return the +// string it holds. +PyObject* unwrap_simple(simple x) { - // Get a simple (by value) from the argument, and return the - // string it holds. - PyObject* unwrap_simple(simple x) - { - return PyString_FromString(x.s); - } + return PyString_FromString(x.s); +} - // Likewise, but demands that its possible to get a non-const - // reference to the simple. - PyObject* unwrap_simple_ref(simple& x) - { - return PyString_FromString(x.s); - } +// Likewise, but demands that its possible to get a non-const +// reference to the simple. +PyObject* unwrap_simple_ref(simple& x) +{ + return PyString_FromString(x.s); +} - // Likewise, with a const reference to the simple object. - PyObject* unwrap_simple_const_ref(simple const& x) - { - return PyString_FromString(x.s); - } +// Likewise, with a const reference to the simple object. +PyObject* unwrap_simple_const_ref(simple const& x) +{ + return PyString_FromString(x.s); +} - // Get an int (by value) from the argument, and convert it to a - // Python Int. - PyObject* unwrap_int(int x) - { - return PyInt_FromLong(x); - } +// Get an int (by value) from the argument, and convert it to a +// Python Int. +PyObject* unwrap_int(int x) +{ + return PyInt_FromLong(x); +} - // Get a non-const reference to an int from the argument - PyObject* unwrap_int_ref(int& x) - { - return PyInt_FromLong(x); - } +// Get a non-const reference to an int from the argument +PyObject* unwrap_int_ref(int& x) +{ + return PyInt_FromLong(x); +} - // Get a const reference to an int from the argument. - PyObject* unwrap_int_const_ref(int const& x) - { - return PyInt_FromLong(x); - } - - // ------------------- +// Get a const reference to an int from the argument. +PyObject* unwrap_int_const_ref(int const& x) +{ + return PyInt_FromLong(x); } // MSVC6 bug workaround From 7d1cbcb0c12955e990576384c94f3199c42ef848 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 10 Jan 2002 19:07:18 +0000 Subject: [PATCH 0186/1042] Possible workaround for cxx 6.2 [SVN r12270] --- include/boost/python/object/forward.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/boost/python/object/forward.hpp b/include/boost/python/object/forward.hpp index 88eefe6b..149b7330 100644 --- a/include/boost/python/object/forward.hpp +++ b/include/boost/python/object/forward.hpp @@ -19,8 +19,12 @@ namespace boost { namespace python { namespace objects { template struct forward { + BOOST_STATIC_CONSTANT( + bool, by_value = (is_scalar::value | is_reference::value) + ); + typedef typename mpl::select_type< - is_scalar::value | is_reference::value + by_value , T , reference_wrapper< typename add_const::type From dd1ac7952b961d9c9c77d1c9d0c251984115c260 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 10 Jan 2002 19:28:16 +0000 Subject: [PATCH 0187/1042] Modified Files: boost/graph/breadth_first_search.hpp MSVC workaround boost/python/reference.hpp boost/python/converter/type_id.hpp boost/python/converter/unwrap.hpp boost/python/converter/wrap.hpp boost/python/converter/wrapper.hpp boost/python/detail/config.hpp libs/python/Jamfile libs/python/src/converter/registry.cpp libs/python/src/converter/type_id.cpp libs/python/src/converter/unwrap.cpp libs/python/test/m1.cpp Added Files: boost/python/converter/wrapper_base.hpp CXX 6.x fixes [SVN r12271] --- Jamfile | 2 + include/boost/python/converter/type_id.hpp | 102 +++++++++++------- include/boost/python/converter/unwrap.hpp | 2 +- include/boost/python/converter/wrap.hpp | 2 +- include/boost/python/converter/wrapper.hpp | 16 +-- .../boost/python/converter/wrapper_base.hpp | 28 +++++ include/boost/python/reference.hpp | 11 +- src/converter/registry.cpp | 2 +- src/converter/type_id.cpp | 36 ++----- src/converter/unwrap.cpp | 5 +- 10 files changed, 116 insertions(+), 90 deletions(-) create mode 100644 include/boost/python/converter/wrapper_base.hpp diff --git a/Jamfile b/Jamfile index 13cb04d7..deb8c690 100644 --- a/Jamfile +++ b/Jamfile @@ -8,6 +8,7 @@ PYTHON_PROPERTIES += <*>"-inline deferred" <*>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers BOOST_PYTHON_DYNAMIC_LIB + BOOST_PYTHON_V2 ; @@ -22,6 +23,7 @@ dll bpl src/converter/type_id.cpp src/object/class.cpp src/object/function.cpp + # src/object/inheritance.cpp src/errors.cpp src/module.cpp src/objects.cpp diff --git a/include/boost/python/converter/type_id.hpp b/include/boost/python/converter/type_id.hpp index c383c352..cf3e4a0d 100644 --- a/include/boost/python/converter/type_id.hpp +++ b/include/boost/python/converter/type_id.hpp @@ -32,24 +32,43 @@ namespace detail # define BOOST_PYTHON_TYPE_ID_NAME # endif -# if 1 +// type ids which represent the same information as std::type_info +// (i.e. the top-level reference and cv-qualifiers are stripped), but +// which works across shared libraries. +struct undecorated_type_id_t : totally_ordered +{ +# ifdef BOOST_PYTHON_TYPE_ID_NAME + typedef char const* base_id_t; +# else + typedef std::type_info const* base_id_t; +# endif + + undecorated_type_id_t(base_id_t); + + bool operator<(undecorated_type_id_t const& rhs) const; + bool operator==(undecorated_type_id_t const& rhs) const; + + friend BOOST_PYTHON_DECL std::ostream& operator<<( + std::ostream&, undecorated_type_id_t const&); + + private: // data members + base_id_t m_base_type; +}; + struct type_id_t : totally_ordered { enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 }; -# ifdef BOOST_PYTHON_TYPE_ID_NAME -typedef char const* base_id_t; -# else -typedef std::type_info const* base_id_t; -# endif - - type_id_t(base_id_t, decoration decoration); + type_id_t(undecorated_type_id_t, decoration decoration); bool operator<(type_id_t const& rhs) const; bool operator==(type_id_t const& rhs) const; friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&); - private: + private: // type + typedef undecorated_type_id_t base_id_t; + + private: // data members decoration m_decoration; base_id_t m_base_type; }; @@ -129,14 +148,22 @@ struct is_reference_to_volatile # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template -inline type_id_t type_id(detail::dummy* = 0) +inline undecorated_type_id_t undecorated_type_id(detail::dummy* = 0) { - return type_id_t( + return undecorated_type_id_t( # ifdef BOOST_PYTHON_TYPE_ID_NAME typeid(T).name() # else &typeid(T) -# endif +# endif + ); +} + +template +inline type_id_t type_id(detail::dummy* = 0) +{ + return type_id_t( + undecorated_type_id() , type_id_t::decoration( (is_const::value || is_reference_to_const::value ? type_id_t::const_ : 0) @@ -147,51 +174,48 @@ inline type_id_t type_id(detail::dummy* = 0) ); } -inline type_id_t::type_id_t(base_id_t base_t, decoration decoration) +inline undecorated_type_id_t::undecorated_type_id_t(base_id_t base_t) + : m_base_type(base_t) +{ +} + +inline type_id_t::type_id_t(undecorated_type_id_t base_t, decoration decoration) : m_decoration(decoration) , m_base_type(base_t) { } +inline bool undecorated_type_id_t::operator<(undecorated_type_id_t const& rhs) const +{ +# ifdef BOOST_PYTHON_TYPE_ID_NAME + return std::strcmp(m_base_type, rhs.m_base_type) < 0; +# else + return m_base_type->before(*rhs.m_base_type); +# endif +} + inline bool type_id_t::operator<(type_id_t const& rhs) const { return m_decoration < rhs.m_decoration || m_decoration == rhs.m_decoration + && m_base_type < rhs.m_base_type; +} + +inline bool undecorated_type_id_t::operator==(undecorated_type_id_t const& rhs) const +{ # ifdef BOOST_PYTHON_TYPE_ID_NAME - && std::strcmp(m_base_type, rhs.m_base_type) < 0; + return !std::strcmp(m_base_type, rhs.m_base_type); # else - && m_base_type->before(*rhs.m_base_type); + return *m_base_type == *rhs.m_base_type; # endif } inline bool type_id_t::operator==(type_id_t const& rhs) const { - return m_decoration == rhs.m_decoration -# ifdef BOOST_PYTHON_TYPE_ID_NAME - && !std::strcmp(m_base_type, rhs.m_base_type); -# else - && *m_base_type == *rhs.m_base_type; -# endif + return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type; } -# else -// This is the type which is used to identify a type -typedef char const* type_id_t; - -// This is a workaround for a silly MSVC bug -// Converts a compile-time type to its corresponding runtime identifier. -template -type_id_t type_id(detail::dummy* = 0) -{ - return typeid(T).name(); -} -# endif - -struct BOOST_PYTHON_DECL type_id_before -{ - bool operator()(type_id_t const& x, type_id_t const& y) const; -}; - +BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, undecorated_type_id_t const&); BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&); }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/unwrap.hpp b/include/boost/python/converter/unwrap.hpp index 525f1bb0..3380d49d 100644 --- a/include/boost/python/converter/unwrap.hpp +++ b/include/boost/python/converter/unwrap.hpp @@ -89,7 +89,7 @@ struct unwrap_more_ { } private: - static BOOST_PYTHON_DECL std::pair m_unwrapper; + static BOOST_PYTHON_DECL std::pair& m_unwrapper; }; template diff --git a/include/boost/python/converter/wrap.hpp b/include/boost/python/converter/wrap.hpp index 97d7b8de..eb23c6d3 100644 --- a/include/boost/python/converter/wrap.hpp +++ b/include/boost/python/converter/wrap.hpp @@ -11,11 +11,11 @@ # include # include # include +# include # include namespace boost { namespace python { namespace converter { -struct BOOST_PYTHON_DECL wrapper_base; extern BOOST_PYTHON_DECL body& identity_wrapper; template struct wrapper; diff --git a/include/boost/python/converter/wrapper.hpp b/include/boost/python/converter/wrapper.hpp index 80afae46..5d4874d2 100644 --- a/include/boost/python/converter/wrapper.hpp +++ b/include/boost/python/converter/wrapper.hpp @@ -5,28 +5,14 @@ // to its suitability for any purpose. #ifndef WRAPPER_DWA2001127_HPP # define WRAPPER_DWA2001127_HPP -# include +# include # include -# include # include # include # include namespace boost { namespace python { namespace converter { -struct source_holder_base; -struct wrap_base; -template struct wrap_more_; - -struct BOOST_PYTHON_DECL wrapper_base : body -{ - public: - wrapper_base(type_id_t); // registers - ~wrapper_base(); // unregisters - - virtual PyObject* do_conversion(wrap_base const&, source_holder_base const&) const = 0; -}; - extern BOOST_PYTHON_DECL body& identity_wrapper; template diff --git a/include/boost/python/converter/wrapper_base.hpp b/include/boost/python/converter/wrapper_base.hpp new file mode 100644 index 00000000..585959ae --- /dev/null +++ b/include/boost/python/converter/wrapper_base.hpp @@ -0,0 +1,28 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef WRAPPER_BASE_DWA2002110_HPP +# define WRAPPER_BASE_DWA2002110_HPP +# include +# include + +namespace boost { namespace python { namespace converter { + +struct source_holder_base; +struct wrap_base; +template struct wrap_more_; + +struct BOOST_PYTHON_DECL wrapper_base : body +{ + public: + wrapper_base(type_id_t); // registers + ~wrapper_base(); // unregisters + + virtual PyObject* do_conversion(wrap_base const&, source_holder_base const&) const = 0; +}; + +}}} // namespace boost::python::converter + +#endif // WRAPPER_BASE_DWA2002110_HPP diff --git a/include/boost/python/reference.hpp b/include/boost/python/reference.hpp index 4eb9ad51..b950f01b 100644 --- a/include/boost/python/reference.hpp +++ b/include/boost/python/reference.hpp @@ -16,7 +16,9 @@ # include # include # include -# include + +# ifndef BOOST_PYTHON_V2 +# include BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE @@ -35,14 +37,19 @@ struct py_ptr_conversions : Base }; BOOST_PYTHON_END_CONVERSION_NAMESPACE +# endif namespace boost { namespace python { +# ifndef BOOST_PYTHON_V2 BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions); +# endif template class reference +# ifndef BOOST_PYTHON_V2 : public py_ptr_conversions, T> +# endif { public: typedef T value_type; @@ -165,11 +172,13 @@ private: typedef reference ref; +#ifndef BOOST_PYTHON_V2 template ref make_ref(const T& x) { return ref(to_python(x)); } +#endif }} // namespace boost::python diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index d247353c..4ce9e709 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -18,7 +18,7 @@ namespace boost { namespace python { namespace converter { namespace // { - typedef std::map registry_t; + typedef std::map registry_t; registry_t& entries() { diff --git a/src/converter/type_id.cpp b/src/converter/type_id.cpp index fc2db66a..421cc5cf 100644 --- a/src/converter/type_id.cpp +++ b/src/converter/type_id.cpp @@ -13,19 +13,18 @@ namespace boost { namespace python { namespace converter { -#if 1 -bool type_id_before::operator()(type_id_t const& x, type_id_t const& y) const +BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, undecorated_type_id_t const& x) { - return x < y; +# ifdef BOOST_PYTHON_TYPE_ID_NAME + return os << x.m_base_type; +# else + return os << x.m_base_type->name(); +# endif } BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_id_t const& x) { -# ifdef BOOST_PYTHON_TYPE_ID_NAME os << x.m_base_type; -# else - os << x.m_base_type->name(); -# endif // VC6 mistakenly distinguishes typeid(X) from typeid(X const) // from typeid(X&)... so the name is already correct. I have it // from Jason Shirk that VC7.0 has the same bug but it will be @@ -41,27 +40,4 @@ BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_id_t const& x) return os; } -#else -bool type_id_before::operator()(type_id_t const& x, type_id_t const& y) const -{ - for (;;) - { - if (*y == 0) - { - return 0; - } - else if (*x == 0) - { - return 1; - } - else if (*x != *y) - { - return *x < *y; - } - ++x; - ++y; - } -} -#endif - }}} // namespace boost::python::converter diff --git a/src/converter/unwrap.cpp b/src/converter/unwrap.cpp index 33a7d7ae..6a72ab77 100644 --- a/src/converter/unwrap.cpp +++ b/src/converter/unwrap.cpp @@ -17,6 +17,7 @@ namespace }; pyobject_unwrapper static_unwrapper; + std::pair unwrapper_pair(&static_unwrapper,&static_unwrapper); pyobject_unwrapper::pyobject_unwrapper() : unwrapper_base(type_id()) @@ -29,7 +30,7 @@ namespace } } -BOOST_PYTHON_DECL std::pair -unwrap_more_::m_unwrapper(&static_unwrapper,&static_unwrapper); +BOOST_PYTHON_DECL std::pair& +unwrap_more_::m_unwrapper = unwrapper_pair; }}} // namespace boost::python::converter From 0964ecac8c88b9fd9464b08ad651909ff7b8c52c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 10 Jan 2002 20:10:32 +0000 Subject: [PATCH 0188/1042] cxx fixes [SVN r12272] --- include/boost/python/detail/cast.hpp | 7 +++++-- include/boost/python/reference.hpp | 11 ++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/boost/python/detail/cast.hpp b/include/boost/python/detail/cast.hpp index 67fe7b34..367f1f14 100644 --- a/include/boost/python/detail/cast.hpp +++ b/include/boost/python/detail/cast.hpp @@ -9,8 +9,9 @@ #ifndef CAST_DWA052500_H_ # define CAST_DWA052500_H_ -# include -# include +# ifndef BOOST_PYTHON_V2 +# include +# include namespace boost { namespace python { @@ -75,4 +76,6 @@ struct downcast }} // namespace boost::python +# endif // BOOST_PYTHON_V2 + #endif // CAST_DWA052500_H_ diff --git a/include/boost/python/reference.hpp b/include/boost/python/reference.hpp index b950f01b..e081e07c 100644 --- a/include/boost/python/reference.hpp +++ b/include/boost/python/reference.hpp @@ -14,8 +14,10 @@ # include # include # include +# include # include # include +# include # ifndef BOOST_PYTHON_V2 # include @@ -165,7 +167,14 @@ private: #endif inline PyObject* object() const - { return as_object(m_p); } + { +#ifdef BOOST_PYTHON_V2 + return (PyObject*)( + (char*)&m_p->ob_type - offsetof(PyObject,ob_type)); +#else + return as_object(m_p); +#endif + } T* m_p; }; From b796db648ae317ea008ffe4ee5b4421ccf156035 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 14 Jan 2002 21:28:49 +0000 Subject: [PATCH 0189/1042] added default constructor for use with BGL [SVN r12318] --- include/boost/python/converter/type_id.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/boost/python/converter/type_id.hpp b/include/boost/python/converter/type_id.hpp index cf3e4a0d..2c0c1a26 100644 --- a/include/boost/python/converter/type_id.hpp +++ b/include/boost/python/converter/type_id.hpp @@ -44,6 +44,9 @@ struct undecorated_type_id_t : totally_ordered # endif undecorated_type_id_t(base_id_t); + + // default constructor for use in BGL graph internal properties + undecorated_type_id_t() {} bool operator<(undecorated_type_id_t const& rhs) const; bool operator==(undecorated_type_id_t const& rhs) const; From 7926e1bc3cfd28fe4a121926835c4343e09b207d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 20 Jan 2002 03:08:08 +0000 Subject: [PATCH 0190/1042] Fixes for reference parameters to constructors [SVN r12364] --- .../boost/python/detail/extension_class.hpp | 77 +++++++++-- include/boost/python/detail/init_function.hpp | 52 +++++++- include/boost/python/reference.hpp | 117 ++++++++++++----- src/gen_extclass.py | 122 ++++++++++++------ src/gen_init_function.py | 52 +++++++- 5 files changed, 328 insertions(+), 92 deletions(-) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 05ebe229..638217d1 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -1,4 +1,4 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and +// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and // distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. @@ -727,25 +727,80 @@ class held_instance : public Held public: held_instance(PyObject*) : Held() {} template - held_instance(PyObject*, A1 a1) : Held(a1) {} + held_instance(PyObject*, A1 a1) : Held( + typename unwrap_parameter::type(a1)) {} template - held_instance(PyObject*, A1 a1, A2 a2) : Held(a1, a2) {} + held_instance(PyObject*, A1 a1, A2 a2) : Held( + typename unwrap_parameter::type(a1) + , typename unwrap_parameter::type(a2)) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held(a1, a2, a3) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held( + typename unwrap_parameter::type(a1) + , typename unwrap_parameter::type(a2) + , typename unwrap_parameter::type(a3)) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held(a1, a2, a3, a4) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held( + typename unwrap_parameter::type(a1) + , typename unwrap_parameter::type(a2) + , typename unwrap_parameter::type(a3) + , typename unwrap_parameter::type(a4)) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held(a1, a2, a3, a4, a5) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held( + typename unwrap_parameter::type(a1) + , typename unwrap_parameter::type(a2) + , typename unwrap_parameter::type(a3) + , typename unwrap_parameter::type(a4) + , typename unwrap_parameter::type(a5)) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held(a1, a2, a3, a4, a5, a6) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held( + typename unwrap_parameter::type(a1) + , typename unwrap_parameter::type(a2) + , typename unwrap_parameter::type(a3) + , typename unwrap_parameter::type(a4) + , typename unwrap_parameter::type(a5) + , typename unwrap_parameter::type(a6)) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held(a1, a2, a3, a4, a5, a6, a7) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held( + typename unwrap_parameter::type(a1) + , typename unwrap_parameter::type(a2) + , typename unwrap_parameter::type(a3) + , typename unwrap_parameter::type(a4) + , typename unwrap_parameter::type(a5) + , typename unwrap_parameter::type(a6) + , typename unwrap_parameter::type(a7)) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held(a1, a2, a3, a4, a5, a6, a7, a8) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held( + typename unwrap_parameter::type(a1) + , typename unwrap_parameter::type(a2) + , typename unwrap_parameter::type(a3) + , typename unwrap_parameter::type(a4) + , typename unwrap_parameter::type(a5) + , typename unwrap_parameter::type(a6) + , typename unwrap_parameter::type(a7) + , typename unwrap_parameter::type(a8)) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held( + typename unwrap_parameter::type(a1) + , typename unwrap_parameter::type(a2) + , typename unwrap_parameter::type(a3) + , typename unwrap_parameter::type(a4) + , typename unwrap_parameter::type(a5) + , typename unwrap_parameter::type(a6) + , typename unwrap_parameter::type(a7) + , typename unwrap_parameter::type(a8) + , typename unwrap_parameter::type(a9)) {} template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} + held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held( + typename unwrap_parameter::type(a1) + , typename unwrap_parameter::type(a2) + , typename unwrap_parameter::type(a3) + , typename unwrap_parameter::type(a4) + , typename unwrap_parameter::type(a5) + , typename unwrap_parameter::type(a6) + , typename unwrap_parameter::type(a7) + , typename unwrap_parameter::type(a8) + , typename unwrap_parameter::type(a9) + , typename unwrap_parameter::type(a10)) {} }; // Abstract base class for all obj holders. Base for template class diff --git a/include/boost/python/detail/init_function.hpp b/include/boost/python/detail/init_function.hpp index 69df703d..ed34f9be 100644 --- a/include/boost/python/detail/init_function.hpp +++ b/include/boost/python/detail/init_function.hpp @@ -1,4 +1,4 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and +// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and // distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. @@ -89,11 +89,14 @@ namespace detail { typedef void const_reference; }; + struct reference_parameter_base {}; + template class reference_parameter + : public reference_parameter_base { - typedef typename parameter_traits::const_reference const_reference; public: + typedef typename parameter_traits::const_reference const_reference; reference_parameter(const_reference value) : value(value) {} operator const_reference() { return value; } @@ -101,6 +104,51 @@ namespace detail { const_reference value; }; +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct unwrap_parameter + { + typedef typename boost::add_reference::type type; + }; + + template + struct unwrap_parameter > + { + typedef typename reference_parameter::const_reference type; + }; +# else + template + struct unwrap_parameter_helper + { + template + struct apply + { + typedef typename T::const_reference type; + }; + }; + + template <> + struct unwrap_parameter_helper + { + template + struct apply + { + typedef typename add_reference::type type; + }; + }; + + template + struct unwrap_parameter + { + BOOST_STATIC_CONSTANT( + bool, is_wrapped = (is_base_and_derived::value)); + + typedef typename unwrap_parameter_helper< + is_wrapped + >::template apply::type type; + }; +# endif + class extension_instance; class instance_holder_base; diff --git a/include/boost/python/reference.hpp b/include/boost/python/reference.hpp index e081e07c..f0cdab55 100644 --- a/include/boost/python/reference.hpp +++ b/include/boost/python/reference.hpp @@ -59,18 +59,10 @@ public: reference(const reference& rhs) : m_p(rhs.m_p) { - Py_XINCREF(object()); + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XINCREF(m_p); } -#if !defined(BOOST_MSVC6_OR_EARLIER) - template - reference(const reference& rhs) - : m_p(rhs.object()) - { - Py_XINCREF(object()); - } -#endif - reference() : m_p(0) {} // These are two ways of spelling the same thing, that we need to increment @@ -81,85 +73,140 @@ public: template explicit reference(T2* x) - : m_p(expect_non_null(x)) {} + : m_p(expect_non_null(x)) + { + assert(m_p->ob_refcnt > 0); + } template reference(T2* x, increment_count_t) - : m_p(expect_non_null(x)) { Py_INCREF(object()); } + : m_p(expect_non_null(x)) + { + assert(m_p->ob_refcnt > 0); + Py_INCREF(m_p); + } template reference(T2* x, allow_null) - : m_p(x) {} + : m_p(x) + { + assert(m_p == 0 || m_p->ob_refcnt > 0); + } template reference(T2* x, allow_null, increment_count_t) - : m_p(x) { Py_XINCREF(object()); } + : m_p(x) + { + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XINCREF(m_p); + } template reference(T2* x, increment_count_t, allow_null) - : m_p(x) { Py_XINCREF(object()); } - -#if !defined(BOOST_MSVC6_OR_EARLIER) - template - reference& operator=(const reference& rhs) + : m_p(x) { - Py_XDECREF(object()); - m_p = rhs.m_p; - Py_XINCREF(object()); - return *this; + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XINCREF(m_p); } -#endif - + reference& operator=(const reference& rhs) { + assert(rhs.m_p == 0 || rhs.m_p->ob_refcnt > 0); Py_XINCREF(static_cast(rhs.m_p)); - Py_XDECREF(object()); + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XDECREF(m_p); m_p = rhs.m_p; return *this; } ~reference() { + assert(m_p == 0 || m_p->ob_refcnt > 0); Py_XDECREF(m_p); } - T& operator*() const { return *m_p; } + T& operator*() const + { + assert(m_p == 0 || m_p->ob_refcnt > 0); + return *m_p; + } // MSVC doesn't like boost::dereferencable unless T has a default // constructor, so operator-> must be defined by hand :( - T* operator->() const { return &**this; } + T* operator->() const + { + assert(m_p == 0 || m_p->ob_refcnt > 0); + return &**this; + } - T* get() const { return m_p; } + T* get() const + { + assert(m_p == 0 || m_p->ob_refcnt > 0); + return m_p; + } T* release() { + assert(m_p == 0 || m_p->ob_refcnt > 0); T* p = m_p; m_p = 0; return p; } void reset() - { Py_XDECREF(m_p); m_p = 0; } + { + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XDECREF(m_p); + m_p = 0; + } template void reset(T2* x) - { Py_XDECREF(m_p); m_p = expect_non_null(x);} + { + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XDECREF(m_p); + m_p = expect_non_null(x); + assert(m_p == 0 || m_p->ob_refcnt > 0); + } template void reset(T2* x, increment_count_t) - { Py_XDECREF(m_p); m_p = expect_non_null(x); Py_INCREF(object()); } + { + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XDECREF(m_p); + m_p = expect_non_null(x); + assert(m_p->ob_refcnt > 0); + Py_INCREF(m_p); + } template void reset(T2* x, allow_null) - { Py_XDECREF(m_p); m_p = x;} + { + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XDECREF(m_p); + m_p = x; + assert(m_p == 0 || m_p->ob_refcnt > 0); + } template void reset(T2* x, allow_null, increment_count_t) - { Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); } + { + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XDECREF(m_p); + m_p = x; + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XINCREF(m_p); + } template void reset(T2* x, increment_count_t, allow_null) - { Py_XDECREF(m_p); m_p = x; Py_XINCREF(object()); } + { + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XDECREF(m_p); + m_p = x; + assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XINCREF(m_p); + } #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) private: diff --git a/src/gen_extclass.py b/src/gen_extclass.py index b794dc2c..6316bab9 100644 --- a/src/gen_extclass.py +++ b/src/gen_extclass.py @@ -3,7 +3,7 @@ import string def gen_extclass(args): return ( -"""// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and +"""// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and // distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. @@ -43,26 +43,51 @@ template struct right_operand; enum without_downcast_t { without_downcast }; -namespace detail { +namespace detail +{ // forward declarations -class extension_instance; -class extension_class_base; -template class instance_holder; -template class instance_value_holder; -template class instance_ptr_holder; -template struct operand_select; + class extension_instance; + class extension_class_base; + template class instance_holder; + template class instance_value_holder; + template class instance_ptr_holder; + template struct operand_select; template struct choose_op; template struct choose_rop; template struct choose_unary_op; template struct define_operator; -meta_class* extension_meta_class(); -extension_instance* get_extension_instance(PyObject* p); -void report_missing_instance_data(extension_instance*, class_t*, const std::type_info&); -void report_missing_ptr_data(extension_instance*, class_t*, const std::type_info&); -void report_missing_class_object(const std::type_info&); -void report_released_smart_pointer(const std::type_info&); + class BOOST_PYTHON_DECL extension_instance : public instance + { + public: + extension_instance(PyTypeObject* class_); + ~extension_instance(); + + void add_implementation(std::auto_ptr holder); + + typedef std::vector held_objects; + const held_objects& wrapped_objects() const + { return m_wrapped_objects; } + private: + held_objects m_wrapped_objects; + }; + +} // namespace detail + +# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT +BOOST_PYTHON_EXPORT_TEMPLATE_CLASS class_t; +BOOST_PYTHON_EXPORT_TEMPLATE_CLASS meta_class; +# endif + +namespace detail { + +BOOST_PYTHON_DECL meta_class* extension_meta_class(); +BOOST_PYTHON_DECL extension_instance* get_extension_instance(PyObject* p); +BOOST_PYTHON_DECL void report_missing_instance_data(extension_instance*, class_t*, const std::type_info&); +BOOST_PYTHON_DECL void report_missing_ptr_data(extension_instance*, class_t*, const std::type_info&); +BOOST_PYTHON_DECL void report_missing_class_object(const std::type_info&); +BOOST_PYTHON_DECL void report_released_smart_pointer(const std::type_info&); template T* check_non_null(T* p) @@ -76,7 +101,7 @@ template class held_instance; typedef void* (*conversion_function_ptr)(void*); -struct base_class_info +struct BOOST_PYTHON_DECL base_class_info { base_class_info(extension_class_base* t, conversion_function_ptr f) :class_object(t), convert(f) @@ -90,7 +115,7 @@ typedef base_class_info derived_class_info; struct add_operator_base; -class extension_class_base : public class_t +class BOOST_PYTHON_DECL extension_class_base : public class_t { public: extension_class_base(const char* name); @@ -270,8 +295,7 @@ class python_extension_class_converters boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); throw boost::python::argument_error(); #if defined(__MWERKS__) && __MWERKS__ <= 0x2406 - PtrType x; - return x; + return *(PtrType*)0; #endif } @@ -384,7 +408,7 @@ namespace detail { template class instance_holder; -class read_only_setattr_function : public function +class BOOST_PYTHON_DECL read_only_setattr_function : public function { public: read_only_setattr_function(const char* name); @@ -703,13 +727,15 @@ class held_instance : public Held public:""" + gen_functions("""%{ template <%(class A%n%:, %)>%} - held_instance(PyObject*%(, A%n% a%n%)) : Held(%(a%n%:, %)) {}""", args) + held_instance(PyObject*%(, A%n% a%n%)) : Held( + %(typename unwrap_parameter::type(a%n)%: + , %)) {}""", args) + """ }; // Abstract base class for all obj holders. Base for template class // instance_holder<>, below. -class instance_holder_base +class BOOST_PYTHON_DECL instance_holder_base { public: virtual ~instance_holder_base() {} @@ -738,12 +764,39 @@ class instance_value_holder : public instance_holder public: Held* target() { return &m_held; } Wrapper* value_target() { return &m_held; } -""" - + gen_functions("""%{ - template <%(class A%n%:, %)>%} - instance_value_holder(extension_instance* p%(, A%n a%n%)) : - m_held(p%(, a%n%)) {}""", args) - + """ + + instance_value_holder(extension_instance* p) : + m_held(p) {} + template + instance_value_holder(extension_instance* p, A1 a1) : + m_held(p, a1) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2) : + m_held(p, a1, a2) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3) : + m_held(p, a1, a2, a3) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4) : + m_held(p, a1, a2, a3, a4) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : + m_held(p, a1, a2, a3, a4, a5) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : + m_held(p, a1, a2, a3, a4, a5, a6) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : + m_held(p, a1, a2, a3, a4, a5, a6, a7) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : + m_held(p, a1, a2, a3, a4, a5, a6, a7, a8) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : + m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9) {} + template + instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : + m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} public: // implementation of instance_holder_base required interface bool held_by_value() { return true; } @@ -770,21 +823,6 @@ class instance_ptr_holder : public instance_holder PtrType m_ptr; }; -class extension_instance : public instance -{ - public: - extension_instance(PyTypeObject* class_); - ~extension_instance(); - - void add_implementation(std::auto_ptr holder); - - typedef std::vector held_objects; - const held_objects& wrapped_objects() const - { return m_wrapped_objects; } - private: - held_objects m_wrapped_objects; -}; - // // Template function implementations // diff --git a/src/gen_init_function.py b/src/gen_init_function.py index 80a9c199..ff294dbb 100644 --- a/src/gen_init_function.py +++ b/src/gen_init_function.py @@ -4,7 +4,7 @@ import string def gen_init_function(args): return ( -"""// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and +"""// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and // distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. @@ -95,11 +95,14 @@ namespace detail { typedef void const_reference; }; + struct reference_parameter_base {}; + template class reference_parameter + : public reference_parameter_base { - typedef typename parameter_traits::const_reference const_reference; public: + typedef typename parameter_traits::const_reference const_reference; reference_parameter(const_reference value) : value(value) {} operator const_reference() { return value; } @@ -107,6 +110,51 @@ namespace detail { const_reference value; }; +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct unwrap_parameter + { + typedef typename boost::add_reference::type type; + }; + + template + struct unwrap_parameter > + { + typedef typename reference_parameter::const_reference type; + }; +# else + template + struct unwrap_parameter_helper + { + template + struct apply + { + typedef typename T::const_reference type; + }; + }; + + template <> + struct unwrap_parameter_helper + { + template + struct apply + { + typedef typename add_reference::type type; + }; + }; + + template + struct unwrap_parameter + { + BOOST_STATIC_CONSTANT( + bool, is_wrapped = (is_base_and_derived::value)); + + typedef typename unwrap_parameter_helper< + is_wrapped + >::template apply::type type; + }; +# endif + class extension_instance; class instance_holder_base; From c3a311ab85a7f6612885459cf8eadbeebc561372 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 20 Jan 2002 23:07:05 +0000 Subject: [PATCH 0191/1042] Explicit qualifications help MSVC6 [SVN r12380] --- include/boost/python/make_function.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index fddc640b..f9ffd5c3 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -6,13 +6,13 @@ #ifndef MAKE_FUNCTION_DWA20011221_HPP # define MAKE_FUNCTION_DWA20011221_HPP -# include -# include -# include # include # include # include # include +# include +# include +# include namespace boost { namespace python { @@ -21,7 +21,7 @@ objects::function* make_function(F f) { return new objects::function( objects::py_function( - bind(detail::caller(), f, _1, _2)) + ::boost::bind(detail::caller(), f, _1, _2)) , detail::arg_tuple_size::value); } @@ -31,7 +31,7 @@ objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0) enum { nargs = mpl::size::value }; return new objects::function( objects::py_function( - bind(detail::caller(), + ::boost::bind(detail::caller(), objects::make_holder ::template apply::execute , _1, _2)) From a48f252cfaa9d2d15881ee3de7c199616093965e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 20 Jan 2002 23:41:56 +0000 Subject: [PATCH 0192/1042] Moved add_overload functionality to function::add_to_namespace [SVN r12381] --- include/boost/python/module.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index b257b9ff..317cc5e4 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -11,6 +11,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -25,7 +26,6 @@ class BOOST_PYTHON_DECL module_base void add(PyObject* x, const char* name); void add(PyTypeObject* x, const char* name = 0); void add(ref x, const char*name); - void add_overload(objects::function* x, const char* name); // Return true iff a module is currently being built. static bool initializing(); @@ -58,7 +58,7 @@ class module : public module_base template void def(Fn fn, const char* name) { - add_overload(make_function(fn), name); + this->add(boost::python::make_function(fn), name); } }; From 386992c3b8ad845a0790348a987f6c8321560d3d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 20 Jan 2002 23:43:36 +0000 Subject: [PATCH 0193/1042] suppress gcc warning [SVN r12382] --- include/boost/python/converter/class.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/boost/python/converter/class.hpp b/include/boost/python/converter/class.hpp index 458ecee4..f437a73a 100644 --- a/include/boost/python/converter/class.hpp +++ b/include/boost/python/converter/class.hpp @@ -18,6 +18,10 @@ struct class_unwrapper , private unwrapper , private unwrapper { + protected: +# ifdef __GNUC__ // suppress warning that "all member functions are private" (duh) + void uncallable(); +# endif private: void* can_convert(PyObject*) const; T& convert(PyObject*, void*, boost::type) const; From 3d03ca3d10268ddf08b87a49770b712de2bb7e91 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 20 Jan 2002 23:50:52 +0000 Subject: [PATCH 0194/1042] made it possible to initialize from type_info [SVN r12383] --- include/boost/python/converter/type_id.hpp | 67 +++++++++++++++------- src/converter/type_id.cpp | 6 +- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/include/boost/python/converter/type_id.hpp b/include/boost/python/converter/type_id.hpp index 2c0c1a26..fd731f83 100644 --- a/include/boost/python/converter/type_id.hpp +++ b/include/boost/python/converter/type_id.hpp @@ -37,24 +37,25 @@ namespace detail // which works across shared libraries. struct undecorated_type_id_t : totally_ordered { + undecorated_type_id_t(std::type_info const&); + + // default constructor needed to build arrays, etc. + undecorated_type_id_t(); + + bool operator<(undecorated_type_id_t const& rhs) const; + bool operator==(undecorated_type_id_t const& rhs) const; + + char const* name() const; + friend BOOST_PYTHON_DECL std::ostream& operator<<( + std::ostream&, undecorated_type_id_t const&); + + private: // data members # ifdef BOOST_PYTHON_TYPE_ID_NAME typedef char const* base_id_t; # else typedef std::type_info const* base_id_t; # endif - undecorated_type_id_t(base_id_t); - - // default constructor for use in BGL graph internal properties - undecorated_type_id_t() {} - - bool operator<(undecorated_type_id_t const& rhs) const; - bool operator==(undecorated_type_id_t const& rhs) const; - - friend BOOST_PYTHON_DECL std::ostream& operator<<( - std::ostream&, undecorated_type_id_t const&); - - private: // data members base_id_t m_base_type; }; @@ -66,8 +67,10 @@ struct type_id_t : totally_ordered bool operator<(type_id_t const& rhs) const; bool operator==(type_id_t const& rhs) const; + friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&); - + + operator undecorated_type_id_t const&() const; private: // type typedef undecorated_type_id_t base_id_t; @@ -153,13 +156,7 @@ struct is_reference_to_volatile template inline undecorated_type_id_t undecorated_type_id(detail::dummy* = 0) { - return undecorated_type_id_t( -# ifdef BOOST_PYTHON_TYPE_ID_NAME - typeid(T).name() -# else - &typeid(T) -# endif - ); + return undecorated_type_id_t(typeid(T)); } template @@ -177,8 +174,19 @@ inline type_id_t type_id(detail::dummy* = 0) ); } -inline undecorated_type_id_t::undecorated_type_id_t(base_id_t base_t) - : m_base_type(base_t) +inline undecorated_type_id_t::undecorated_type_id_t(std::type_info const& id) + : m_base_type( +# ifdef BOOST_PYTHON_TYPE_ID_NAME + id.name() +# else + &id +# endif + ) +{ +} + +inline undecorated_type_id_t::undecorated_type_id_t() + : m_base_type() { } @@ -218,6 +226,21 @@ inline bool type_id_t::operator==(type_id_t const& rhs) const return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type; } +inline type_id_t::operator undecorated_type_id_t const&() const +{ + return m_base_type; +} + +inline char const* undecorated_type_id_t::name() const +{ +# ifdef BOOST_PYTHON_TYPE_ID_NAME + return m_base_type; +# else + return m_base_type->name(); +# endif +} + + BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, undecorated_type_id_t const&); BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&); diff --git a/src/converter/type_id.cpp b/src/converter/type_id.cpp index 421cc5cf..688dd2bc 100644 --- a/src/converter/type_id.cpp +++ b/src/converter/type_id.cpp @@ -15,11 +15,7 @@ namespace boost { namespace python { namespace converter { BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, undecorated_type_id_t const& x) { -# ifdef BOOST_PYTHON_TYPE_ID_NAME - return os << x.m_base_type; -# else - return os << x.m_base_type->name(); -# endif + return os << x.name(); } BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_id_t const& x) From dabb22bb6aaa636bc245c747447eaccf4249feaf Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 20 Jan 2002 23:52:36 +0000 Subject: [PATCH 0195/1042] added class wrapping [SVN r12384] --- include/boost/python/object/class.hpp | 38 +++++- .../boost/python/object/class_unwrapper.hpp | 8 +- include/boost/python/object/function.hpp | 8 +- include/boost/python/object/value_holder.hpp | 8 +- src/object/class.cpp | 118 +++++++++++++++--- 5 files changed, 150 insertions(+), 30 deletions(-) diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index bc8f40d1..808e3669 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -6,16 +6,44 @@ #ifndef CLASS_DWA20011214_HPP # define CLASS_DWA20011214_HPP +# include # include # include # include # include +# include # include +# include -namespace boost { namespace python { namespace objects { +namespace boost { namespace python { + +class module; + +namespace objects { template struct holder; +// To identify a class, we don't need cv/reference decorations +typedef converter::undecorated_type_id_t class_id; + +struct BOOST_PYTHON_DECL class_base : noncopyable +{ + // constructor + class_base( + module& name_space // Which name space the class will live in + , char const* name // The name of the class + + , std::size_t num_types // A list of class_ids. The first is the type + , class_id const*const types // this is wrapping. The rest are the types of + // any bases. + ); + + // Retrieve a pointer to the underlying object + PyObject* object() const { return m_object.get(); } + private: + ref m_object; +}; + // Base class for all holders struct BOOST_PYTHON_DECL instance_holder : noncopyable { @@ -28,7 +56,7 @@ struct BOOST_PYTHON_DECL instance_holder : noncopyable virtual void* holds(converter::type_id_t) = 0; - void install(PyObject* inst); + void install(PyObject* inst) throw(); struct iterator_policies : default_iterator_policies { @@ -58,6 +86,8 @@ struct instance instance_holder* objects; }; +// Given a type_id, find the instance data which corresponds to it, or +// return 0 in case no such type is held. BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::type_id_t); template @@ -66,8 +96,8 @@ T* find_instance(PyObject* p, T* = 0) return static_cast(find_instance_impl(p, converter::type_id())); } -BOOST_PYTHON_DECL PyTypeObject* class_metatype(); -BOOST_PYTHON_DECL PyTypeObject* class_type(); +BOOST_PYTHON_DECL ref class_metatype(); +BOOST_PYTHON_DECL ref class_type(); // // implementation diff --git a/include/boost/python/object/class_unwrapper.hpp b/include/boost/python/object/class_unwrapper.hpp index 666c6e93..0877ff24 100644 --- a/include/boost/python/object/class_unwrapper.hpp +++ b/include/boost/python/object/class_unwrapper.hpp @@ -18,14 +18,14 @@ struct class_unwrapper template struct reference_unwrapper : converter::unwrapper { - bool convertible(PyObject* p) const + void* can_convert(PyObject* p) const { - return find_holder(p) != 0; + return find_instance(p); } - Target convert(PyObject* p, void*&) const + Target convert(PyObject* p, void* data, ) const { - return *find_holder(p)->target(); + return *find_instance(p)->target(); } }; diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index ed7dd319..cc2695d8 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -22,10 +22,16 @@ struct BOOST_PYTHON_DECL function : PyObject ~function(); PyObject* call(PyObject*, PyObject*) const; - void add_overload(function* overload); + + // Add an attributeto the name_space with the given name. If it is + // a function object (this class), and an existing function is + // already there, add it as an overload. + static void add_to_namespace( + PyObject* name_space, char const* name, PyObject* attribute); private: // helper functions void argument_error(PyObject* args, PyObject* keywords) const; + void add_overload(function* overload); private: // data members py_function m_fn; diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index be7247da..d6e38a79 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -8,6 +8,8 @@ # include # include +# include +# include namespace boost { namespace python { namespace objects { @@ -76,9 +78,11 @@ struct value_holder_generator }; template -void* value_holder::holds(converter::type_id_t x) +void* value_holder::holds(converter::type_id_t dst_t) { - return x == converter::type_id() ? &m_held : 0; + converter::type_id_t src_t = converter::type_id(); + return src_t == dst_t ? &m_held + : find_static_type(&m_held, src_t, dst_t); } }}} // namespace boost::python::objects diff --git a/src/object/class.cpp b/src/object/class.cpp index 8e85f38b..5ebabba1 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -6,8 +6,14 @@ #include #include #include +#include +#include +#include +#include #include +#include #include +#include namespace boost { namespace python { namespace objects { @@ -64,6 +70,20 @@ PyTypeObject class_metatype_object = { // PyType_GenericNew /* tp_new */ }; +// Get the metatype object for all extension classes. +BOOST_PYTHON_DECL ref class_metatype() +{ + if (class_metatype_object.tp_dict == 0) + { + class_metatype_object.ob_type = &PyType_Type; + class_metatype_object.tp_base = &PyType_Type; + if (PyType_Ready(&class_metatype_object)) + return ref(); + } + return ref((PyObject*)&class_metatype_object, ref::increment_count); +} + +// Do we really need this? I'm beginning to think we don't! PyTypeObject class_type_object = { PyObject_HEAD_INIT(0) //&class_metatype_object) 0, @@ -107,33 +127,21 @@ PyTypeObject class_type_object = { PyType_GenericNew }; -BOOST_PYTHON_DECL PyTypeObject* class_metatype() -{ - if (class_metatype_object.tp_dict == 0) - { - class_metatype_object.ob_type = &PyType_Type; - class_metatype_object.tp_base = &PyType_Type; - if (PyType_Ready(&class_metatype_object)) - return 0; - } - Py_INCREF(&class_metatype_object); - return &class_metatype_object; -} - -BOOST_PYTHON_DECL PyTypeObject* class_type() +BOOST_PYTHON_DECL ref class_type() { if (class_type_object.tp_dict == 0) { - class_type_object.ob_type = class_metatype(); + class_type_object.ob_type = (PyTypeObject*)class_metatype().release(); class_type_object.tp_base = &PyBaseObject_Type; if (PyType_Ready(&class_type_object)) - return 0; + return ref(); } - Py_INCREF(&class_type_object); - return &class_type_object; + return ref((PyObject*)&class_type_object, ref::increment_count); } -void instance_holder::install(PyObject* self) +// Install the instance data for a C++ object into a Python instance +// object. +void instance_holder::install(PyObject* self) throw() { assert(self->ob_type->ob_type == &class_metatype_object); m_next = ((instance*)self)->objects; @@ -157,4 +165,76 @@ find_instance_impl(PyObject* inst, converter::type_id_t type) return 0; } +namespace +{ + struct class_registry + { + public: + ref get(class_id id) const; + void set(class_id, ref class_object); + private: + typedef detail::map_entry entry; + std::vector m_impl; + }; + + class_registry& registry() + { + static class_registry x; + return x; + } + + ref class_registry::get(class_id id) const + { + std::vector::const_iterator start = m_impl.begin(); + std::vector::const_iterator finish = m_impl.end(); + + std::vector::const_iterator p + = boost::detail::lower_bound(start, finish, id); + + if (p == finish && p->key != id) + { + string report("extension class wrapper for base class "); + (report += id.name()) += "has not been created yet"; + PyErr_SetObject(PyExc_RuntimeError, report.get()); + throw error_already_set(); + } + return p->value; + } + + void class_registry::set(class_id id, ref object) + { + std::vector::iterator start = m_impl.begin(); + std::vector::iterator finish = m_impl.end(); + m_impl.insert( + boost::detail::lower_bound(start, finish, id) + , entry(id, object)); + } +} + +class_base::class_base( + module& m, char const* name, std::size_t num_types, class_id const* const types) +{ + class_registry& r = registry(); + assert(num_types >= 1); + tuple bases(std::max(num_types - 1, static_cast(1))); + if (num_types > 1) + { + for (std::size_t i = 1; i < num_types; ++i) + bases.set_item(i - 1, r.get(types[i])); + } + else + { + bases.set_item(0, class_type()); + } + + tuple args(3); + args.set_item(0, string(name).reference()); + args.set_item(1, bases.reference()); + args.set_item(2, dictionary().reference()); + + m_object = ref(PyObject_CallObject(class_metatype().get(), args.get())); + r.set(types[0], m_object); + m.add(m_object, name); +} + }}} // namespace boost::python::objects From f7a5e6deb81ce98b71fb99280b4cbf55244c10bb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 20 Jan 2002 23:52:52 +0000 Subject: [PATCH 0196/1042] Moved add_overload functionality to function::add_to_namespace [SVN r12385] --- src/module.cpp | 23 +++------------------- src/object/function.cpp | 42 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/module.cpp b/src/module.cpp index 9faaca06..0851805f 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -7,7 +7,6 @@ // producing this work. #include -#include namespace boost { namespace python { @@ -47,9 +46,9 @@ void module_base::add(PyObject* x, const char* name) void module_base::add(ref x, const char* name) { - ref f(x); // First take possession of the object. - if (PyObject_SetAttrString(m_module, const_cast(name), x.get()) < 0) - throw error_already_set(); + // Use function::add_to_namespace to achieve overloading if + // appropriate. + objects::function::add_to_namespace(m_module, name, x.get()); } void module_base::add(PyTypeObject* x, const char* name /*= 0*/) @@ -57,22 +56,6 @@ void module_base::add(PyTypeObject* x, const char* name /*= 0*/) this->add((PyObject*)x, name ? name : x->tp_name); } -void module_base::add_overload(objects::function* x, const char* name) -{ - PyObject* existing = PyObject_HasAttrString(m_module, const_cast(name)) - ? PyObject_GetAttrString(m_module, const_cast(name)) - : 0; - - if (existing != 0 && existing->ob_type == &objects::function_type) - { - static_cast(existing)->add_overload(x); - } - else - { - add(x, name); - } -} - PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; }} // namespace boost::python diff --git a/src/object/function.cpp b/src/object/function.cpp index 52a0456c..3755dfb1 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include namespace boost { namespace python { namespace objects { @@ -28,7 +30,7 @@ function::~function() PyObject* function::call(PyObject* args, PyObject* keywords) const { - int nargs = PyTuple_GET_SIZE(args); + std::size_t nargs = PyTuple_GET_SIZE(args); function const* f = this; do { @@ -63,6 +65,8 @@ void function::argument_error(PyObject* args, PyObject* keywords) const void function::add_overload(function* overload) { + Py_XINCREF(overload); + function* parent = this; while (parent->m_overloads != 0) @@ -72,6 +76,42 @@ void function::add_overload(function* overload) parent->m_overloads = overload; } +void function::add_to_namespace( + PyObject* name_space, char const* name_, PyObject* attribute_) +{ + ref attribute(attribute_, ref::increment_count); + string name(name_); + + if (attribute_->ob_type == &function_type) + { + PyObject* dict = 0; + + if (PyClass_Check(name_space)) + dict = ((PyClassObject*)name_space)->cl_dict; + else if (PyType_Check(name_space)) + dict = ((PyTypeObject*)name_space)->tp_dict; + else + dict = PyObject_GetAttrString(name_space, "__dict__"); + + if (dict == 0) + throw error_already_set(); + + ref existing(PyObject_GetItem(dict, name.get()), ref::null_ok); + + if (existing.get() && existing->ob_type == &function_type) + { + static_cast(existing.get())->add_overload( + static_cast(attribute_)); + return; + } + } + + // The PyObject_GetAttrString() call above left an active error + PyErr_Clear(); + if (PyObject_SetAttr(name_space, name.get(), attribute_) < 0) + throw error_already_set(); +} + extern "C" { // Stolen from Python's funcobject.c From 4a1d077238fecb53f5010b7c197e9c52fb70e544 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 20 Jan 2002 23:54:26 +0000 Subject: [PATCH 0197/1042] Added implicit conversion tests [SVN r12386] --- test/newtest.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/test/newtest.py b/test/newtest.py index d29ac129..0636641b 100644 --- a/test/newtest.py +++ b/test/newtest.py @@ -60,14 +60,82 @@ try: wrap_int_ref(n) Create an extension class which wraps "complicated" (init1 and get_n) are a complicated constructor and member function, respectively. ->>> C = xclass('C', (xinst,), {'__init__': init1, 'get_n': get_n}) ->>> c1 = C(s, 99) +>>> c1 = complicated(s, 99) >>> c1.get_n() 99 ->>> c2 = C(s) +>>> c2 = complicated(s) >>> c2.get_n() 0 +>>> a = A() +>>> b = B() +>>> c = C() +>>> d = D() + +------ +>>> take_a(a) +0 + +>>> try: +... take_b(a) +... except: pass +... else: print 'no exception' + +>>> try: +... take_c(a) +... except: pass +... else: print 'no exception' + +>>> try: +... take_d(a) +... except: pass +... else: print 'no exception' + +------ +>>> take_a(b) +0 + +>>> take_b(b) +1 + +>>> try: +... take_c(b) +... except: pass +... else: print 'no exception' + +>>> try: +... take_d(b) +... except: pass +... else: print 'no exception' + +------- +>>> take_a(c) +0 + +>>> try: +... take_b(c) +... except: pass +... else: print 'no exception' + +>>> take_c(c) +2 + +>>> try: +... take_d(c) +... except: pass +... else: print 'no exception' + +------- +>>> take_a(d) +0 +>>> take_b(d) +1 +>>> take_c(d) +2 +>>> take_d(d) +3 + + """ def run(args = None): From 03e9e4c1d9fff14e25f62f0aecca289ab9630dd1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 21 Jan 2002 00:47:05 +0000 Subject: [PATCH 0198/1042] Added class wrapping [SVN r12387] --- Jamfile | 2 +- include/boost/python/class.hpp | 166 ++++++ include/boost/python/detail/map_entry.hpp | 44 ++ include/boost/python/detail/wrap_function.hpp | 56 ++ .../boost/python/object/class_converters.hpp | 101 ++++ include/boost/python/object/class_wrapper.hpp | 62 +++ include/boost/python/object/inheritance.hpp | 165 ++++++ src/object/inheritance.cpp | 493 ++++++++++++++++++ test/m1.cpp | 99 +++- 9 files changed, 1164 insertions(+), 24 deletions(-) create mode 100644 include/boost/python/class.hpp create mode 100644 include/boost/python/detail/map_entry.hpp create mode 100644 include/boost/python/detail/wrap_function.hpp create mode 100644 include/boost/python/object/class_converters.hpp create mode 100644 include/boost/python/object/class_wrapper.hpp create mode 100644 include/boost/python/object/inheritance.hpp create mode 100644 src/object/inheritance.cpp diff --git a/Jamfile b/Jamfile index deb8c690..71e0c5b7 100644 --- a/Jamfile +++ b/Jamfile @@ -23,7 +23,7 @@ dll bpl src/converter/type_id.cpp src/object/class.cpp src/object/function.cpp - # src/object/inheritance.cpp + src/object/inheritance.cpp src/errors.cpp src/module.cpp src/objects.cpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp new file mode 100644 index 00000000..d61a8fc0 --- /dev/null +++ b/include/boost/python/class.hpp @@ -0,0 +1,166 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CLASS_DWA200216_HPP +# define CLASS_DWA200216_HPP + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +namespace // put some convenience classes into the unnamed namespace for the user +{ + // A type list for specifying bases + template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename B, ::boost::mpl::null_argument) > + struct bases : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(B) >::type + {}; + + // A type list for specifying arguments + template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename A, ::boost::mpl::null_argument) > + struct args : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(A) >::type + {}; +} + +namespace boost { namespace python { + +// Forward declarations +namespace objects +{ + struct value_holder_generator; +} + +namespace detail +{ + // This is an mpl BinaryMetaFunction object with a runtime behavior, + // which is to write the id of the type which is passed as its 2nd + // compile-time argument into the iterator pointed to by its runtime + // argument + struct write_type_id + { + // The first argument is Ignored because mpl::for_each is still + // currently an accumulate (reduce) implementation. + template struct apply + { + // also an artifact of accumulate-based for_each + typedef void type; + + // Here's the runtime behavior + static void execute(converter::undecorated_type_id_t** p) + { + *(*p)++ = converter::undecorated_type_id(); + } + }; + }; +} + +// +// class_ +// +// This is the primary mechanism through which users will expose +// C++ classes to Python. The three template arguments are: +// +// T - The class being exposed to Python +// +// Bases - An MPL sequence of base classes +// +// HolderGenerator - +// An optional type generator for the "holder" which +// maintains the C++ object inside the Python instance. The +// default just holds the object "by-value", but other +// holders can be substituted which will hold the C++ object +// by smart pointer, for example. +// +template < + class T // class being wrapped + , class Bases = mpl::type_list<>::type + , class HolderGenerator = objects::value_holder_generator + > +class class_ : objects::class_base +{ + typedef class_ self; + public: + + // Construct with the module and class name + class_(module&, char const* name); + + // 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. + template + self& def(F f, char const* name) + { + // Use function::add_to_namespace to achieve overloading if + // appropriate. + objects::function::add_to_namespace(this->object(), name, detail::wrap_function(f)); + return *this; + } + + // Define the constructor with the given Args, which should be an + // MPL sequence of types. + template + self& def_init(Args const& = Args()) + { + def(make_constructor(), "__init__"); + return *this; + } + + // Define the default constructor. + self& def_init() + { + this->def_init(mpl::type_list<>::type()); + return *this; + } + + private: // types + typedef objects::class_id class_id; + + // A helper class which will contain an array of id objects to be + // passed to the base class constructor + struct id_vector + { + id_vector() + { + // Stick the derived class id into the first element of the array + ids[0] = converter::undecorated_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]; + }; + + private: // helper functions + void initialize_converters(); +}; + + +// +// implementations +// +template +inline class_::class_( + module& m, char const* name = typeid(T).name()) + : class_base(m, name, id_vector::size, id_vector().ids) +{ + // Bring the class converters into existence. This static object + // will survive until the shared library this module lives in is + // unloaded (that doesn't happen until Python terminates). + static objects::class_converters converters(object()); +} + +}} // namespace boost::python + +#endif // CLASS_DWA200216_HPP diff --git a/include/boost/python/detail/map_entry.hpp b/include/boost/python/detail/map_entry.hpp new file mode 100644 index 00000000..9249523a --- /dev/null +++ b/include/boost/python/detail/map_entry.hpp @@ -0,0 +1,44 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MAP_ENTRY_DWA2002118_HPP +# define MAP_ENTRY_DWA2002118_HPP + +namespace boost { namespace python { namespace detail { + +// A trivial type that works well as the value_type of associative +// vector maps +template +struct map_entry +{ + map_entry() {} + map_entry(Key k) : key(k), value() {} + map_entry(Key k, Value v) : key(k), value(v) {} + + bool operator<(map_entry const& rhs) const + { + return this->key < rhs.key; + } + + Key key; + Value value; +}; + +template +bool operator<(map_entry const& e, Key const& k) +{ + return e.key < k; +} + +template +bool operator<(Key const& k, map_entry const& e) +{ + return k < e.key; +} + + +}}} // namespace boost::python::detail + +#endif // MAP_ENTRY_DWA2002118_HPP diff --git a/include/boost/python/detail/wrap_function.hpp b/include/boost/python/detail/wrap_function.hpp new file mode 100644 index 00000000..0424183d --- /dev/null +++ b/include/boost/python/detail/wrap_function.hpp @@ -0,0 +1,56 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef WRAP_FUNCTION_DWA2002118_HPP +# define WRAP_FUNCTION_DWA2002118_HPP + +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +// A function which converts its argument into a Python callable +// object. Not very general yet! + +// This should eventually be replaced with a mechanism for specialized +// wrap/unwrap objects. In other words, to_python(f), where f is a +// function pointer or function type, should produce a callable Python +// object. + +template +struct wrap_function_select +{ + template + static objects::function* execute(F f) + { + return make_function(f); + } +}; + +template<> +struct wrap_function_select +{ + template + static F execute(F f) + { + return f; + } +}; + +template +PyObject* wrap_function(F f) +{ + return wrap_function_select< + type_traits::ice_or< + is_function::value + , is_member_function_pointer::value + >::value >::execute(f); +} + +}}} // namespace boost::python::detail + +#endif // WRAP_FUNCTION_DWA2002118_HPP diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp new file mode 100644 index 00000000..c14103b6 --- /dev/null +++ b/include/boost/python/object/class_converters.hpp @@ -0,0 +1,101 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CLASS_CONVERTERS_DWA2002119_HPP +# define CLASS_CONVERTERS_DWA2002119_HPP + +# include +# include +# include + +namespace boost { namespace python { namespace objects { + +// Instantiating this class brings into existence all converters +// associated with a class Bases is expected to be an mpl sequence of +// base types. +template +struct class_converters +{ + public: // member functions + // Constructor takes the python class object associated with T + class_converters(PyObject* python_class); + + private: // data members + converter::class_unwrapper m_unwrapper; + class_wrapper m_wrapper; +}; + +// +// Implementation details +// + +////////////////////////////////////////////////////////////////////// +// +// register_base_of - +// A BinaryMetaFunction object which registers a single base +// class of T, and the corresponding cast(s) +// + + +// register_downcast/do_nothing - +// Helpers for register_base_of<> which take care of registering +// down-casts +template +struct register_downcast +{ + static void execute() + { + register_conversion(true); + } +}; + +struct do_nothing +{ + static void execute() { } +}; + +// Here's where the real work gets done: +template +struct register_base_of +{ + // Ignored is needed because mpl::for_each is still actually + // accumulate. We're not using any state so it just sits there. + template + struct apply + { + typedef void type; // 'type' needs to be defined for the same reasons + + // Here's the runtime part: + static void execute() + { + // Register the Base class + register_dynamic_id(); + // Register the up-cast + register_conversion(false); + + // Register the down-cast, if appropriate. + mpl::select_type< + is_polymorphic::value + , register_downcast + , do_nothing + >::type::execute(); + } + }; +}; + +template +class_converters::class_converters(PyObject* type_object) + : m_wrapper(type_object) +{ + // register all up/downcasts here + register_dynamic_id(); + + // register each base in the sequence + mpl::for_each >::execute(); +} + +}}} // namespace boost::python::object + +#endif // CLASS_CONVERTERS_DWA2002119_HPP diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp new file mode 100644 index 00000000..0e49ce84 --- /dev/null +++ b/include/boost/python/object/class_wrapper.hpp @@ -0,0 +1,62 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CLASS_WRAPPER_DWA20011221_HPP +# define CLASS_WRAPPER_DWA20011221_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace objects { + +template +struct class_wrapper + : converter::wrapper +{ + class_wrapper(PyObject* type_) + : m_class_object(type_) + { +# ifndef NDEBUG + assert(type_->ob_type == (PyTypeObject*)class_metatype().get()); +# endif NDEBUG + } + + PyObject* convert(T const& x) const + { + // Don't call the type to do the construction, since that + // would require the registration of an __init__ copy + // constructor. Instead, just construct the object in place. + PyObject* raw_result = (PyObject*)PyObject_New( + instance, (PyTypeObject*)m_class_object.get()); + + if (raw_result == 0) + return 0; + + // Everything's OK; Bypass NULL checks but guard against + // exceptions. + ref result(raw_result, ref::allow_null()); + + // Build a value_holder to contain the object using the copy + // constructor + value_holder* p = new value_holder(raw_result, cref(x)); + + // Install it in the instance + p->install(raw_result); + + // Return the new result + return result.release(); + } + + private: + ref m_class_object; +}; + + +}}} // namespace boost::python::objects + +#endif // CLASS_WRAPPER_DWA20011221_HPP diff --git a/include/boost/python/object/inheritance.hpp b/include/boost/python/object/inheritance.hpp new file mode 100644 index 00000000..60aeda58 --- /dev/null +++ b/include/boost/python/object/inheritance.hpp @@ -0,0 +1,165 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef INHERITANCE_DWA200216_HPP +# define INHERITANCE_DWA200216_HPP + +# include +# include + +namespace boost { namespace python { namespace objects { + +typedef converter::undecorated_type_id_t class_id; +using converter::undecorated_type_id; + +// Types used to get address and id of most derived type +typedef std::pair dynamic_id_t; +typedef dynamic_id_t (*dynamic_id_function)(void*); + +BOOST_PYTHON_DECL void register_dynamic_id_aux( + class_id static_id, dynamic_id_function get_dynamic_id); + +BOOST_PYTHON_DECL void add_cast( + class_id src_t, class_id dst_t, void* (*cast)(void*), bool polymorphic); + +BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src, class_id dst); + +BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src, class_id dst); + +// is_polymorphic test from John Maddock +template +struct is_polymorphic +{ + struct d1 : public T + { + d1(); + char padding[256]; + }; + struct d2 : public T + { + d2(); + virtual ~d2(); + virtual void foo(); + char padding[256]; + }; + BOOST_STATIC_CONSTANT(bool, value = (sizeof(d2) == sizeof(d1))); +}; + +// +// a generator with an execute() function which, given a source type +// and a pointer to an object of that type, returns its most-derived +// /reachable/ type identifier and object pointer. +// + +// first, the case where T has virtual functions +template +struct polymorphic_id_generator +{ + static dynamic_id_t execute(void* p_) + { + T* p = static_cast(p_); + return std::make_pair(dynamic_cast(p), class_id(typeid(*p))); + } +}; + +// now, the non-polymorphic case. +template +struct non_polymorphic_id_generator +{ + static dynamic_id_t execute(void* p_) + { + return std::make_pair(p_, converter::undecorated_type_id()); + } +}; + +// Now the generalized selector +template +struct dynamic_id_generator +{ + typedef typename mpl::select_type< + is_polymorphic::value + , polymorphic_id_generator + , non_polymorphic_id_generator >::type type; +}; + +// Register the dynamic id function for T with the type-conversion +// system. +template +void register_dynamic_id(T* = 0) +{ + typedef typename dynamic_id_generator::type generator; + register_dynamic_id_aux( + converter::undecorated_type_id(), &generator::execute); +} + +// +// a generator with an execute() function which, given a void* +// pointing to an object of type Source will attempt to convert it to +// an object of type Target. +// + +template +struct dynamic_cast_generator +{ + static void* execute(void* source) + { + return dynamic_cast( + static_cast(source)); + } + +}; + +template +struct implicit_cast_generator +{ + static void* execute(void* source) + { + Target* result = static_cast(source); + return result; + } +}; + +template +struct cast_generator +{ + // CWPro7 will return false sometimes, but that's OK since we can + // always cast up with dynamic_cast<> + BOOST_STATIC_CONSTANT( + bool, is_upcast = ( + is_base_and_derived::value + )); + + typedef typename mpl::select_type< + is_upcast +# if defined(__MWERKS__) && __MWERKS__ <= 0x2406 + // grab a few more implicit_cast cases for CodeWarrior + || !is_polymorphic::value + || !is_polymorphic::value +# endif + , implicit_cast_generator + , dynamic_cast_generator + >::type type; +}; + +template +inline void register_conversion( + // We need this parameter because CWPro7 can't determine + // which is the base reliably. + bool is_downcast = !cast_generator::is_upcast + + // These parameters shouldn't be used, they're an MSVC bug workaround + , Source* = 0, Target* = 0) +{ + typedef typename cast_generator::type generator; + + add_cast(converter::undecorated_type_id() + , converter::undecorated_type_id() + , &generator::execute + , is_downcast); +} + +}}} // namespace boost::python::object + +#endif // INHERITANCE_DWA200216_HPP diff --git a/src/object/inheritance.cpp b/src/object/inheritance.cpp new file mode 100644 index 00000000..5b95e478 --- /dev/null +++ b/src/object/inheritance.cpp @@ -0,0 +1,493 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Procedure: +// +// The search is a BFS over the space of (type,address) pairs +// guided by the edges of the casting graph whose nodes +// correspond to classes, and whose edges are traversed by +// applying associated cast functions to an address. We use +// vertex distance to the goal node in the cast_graph to rate the +// paths. The vertex distance to any goal node is calculated on +// demand and outdated by the addition of edges to the graph. + +namespace boost { +namespace +{ + enum edge_cast_t { edge_cast = 8010 }; +} + +// Install properties +BOOST_INSTALL_PROPERTY(edge, cast); + +namespace +{ + typedef void*(*cast_function)(void*); + + // + // Here we put together the low-level data structures of the + // casting graph representation. + // + typedef python::converter::undecorated_type_id_t class_id; + + // represents a graph of available casts + +#if 0 + struct cast_graph + : +#else + typedef +#endif + adjacency_list > > +#if 0 + {}; +#else + cast_graph; +#endif + + typedef cast_graph::vertex_descriptor vertex_t; + typedef cast_graph::edge_descriptor edge_t; + + struct smart_graph + { + typedef std::vector::const_iterator node_distance_map; + + typedef std::pair out_edges_t; + + // Return a map of the distances from any node to the given + // target node + node_distance_map distances_to(vertex_t target) const + { + std::size_t n = num_vertices(m_topology); + if (m_distances.size() != n * n) + { + m_distances.clear(); + m_distances.resize(n * n, std::numeric_limits::max()); + m_known_vertices = n; + } + + std::vector::iterator to_target = m_distances.begin() + n * target; + + // this node hasn't been used as a target yet + if (to_target[target] != 0) + { + typedef reverse_graph reverse_cast_graph; + reverse_cast_graph reverse_topology(m_topology); + + to_target[target] = 0; + + breadth_first_search( + reverse_topology, target + , visitor( + make_bfs_visitor( + record_distances( + make_iterator_property_map( + to_target + , get(vertex_index, reverse_topology) +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + , *to_target +# endif + ) + , on_tree_edge() + )))); + } + + return to_target; + } + + cast_graph& topology() { return m_topology; } + cast_graph const& topology() const { return m_topology; } + + std::size_t known_vertices() const { return m_known_vertices; } + + smart_graph() + : m_known_vertices(0) + {} + + private: + cast_graph m_topology; + mutable std::vector m_distances; + mutable std::size_t m_known_vertices; + }; + + smart_graph& full_graph() + { + static smart_graph x; + return x; + } + + smart_graph& up_graph() + { + static smart_graph x; + return x; + } + + // + // Our index of class types + // + using boost::python::objects::dynamic_id_function; + typedef tuples::tuple< + class_id // static type + , vertex_t // corresponding vertex + , dynamic_id_function // dynamic_id if polymorphic, or 0 + > + index_entry_interface; + typedef index_entry_interface::inherited index_entry; + enum { ksrc_static_t, kvertex, kdynamic_id }; + + typedef std::vector type_index_t; + + + type_index_t& type_index() + { + static type_index_t x; + return x; + } + + template + struct select1st + { + typedef typename tuples::element<0, Tuple>::type result_type; + + result_type const& operator()(Tuple const& x) const + { + return tuples::get<0>(x); + } + }; + + // map a type to a position in the index + inline type_index_t::iterator type_position(class_id type) + { + typedef index_entry entry; + + return std::lower_bound( + type_index().begin(), type_index().end() + , make_tuple(type, vertex_t(), dynamic_id_function(0)) + , boost::bind(std::less() + , boost::bind(select1st(), _1) + , boost::bind(select1st(), _2))); + } + + inline index_entry* seek_type(class_id type) + { + type_index_t::iterator p = type_position(type); + if (p == type_index().end() || tuples::get(*p) != type) + return 0; + else + return &*p; + } + + // Get the entry for a type, inserting if neccessary + inline type_index_t::iterator demand_type(class_id type) + { + type_index_t::iterator p = type_position(type); + + if (p != type_index().end() && tuples::get(*p) == type) + return p; + + vertex_t v = add_vertex(full_graph().topology()); + vertex_t v2 = add_vertex(up_graph().topology()); + assert(v == v2); + return type_index().insert(p, make_tuple(type, v, dynamic_id_function(0))); + } + + // Map a two types to a vertex in the graph, inserting if neccessary + typedef std::pair + type_index_iterator_pair; + + inline type_index_iterator_pair + demand_types(class_id t1, class_id t2) + { + // be sure there will be no reallocation + type_index().reserve(type_index().size() + 2); + type_index_t::iterator first = demand_type(t1); + type_index_t::iterator second = demand_type(t2); + if (first == second) + ++first; + return std::make_pair(first, second); + } + + struct q_elt + { + q_elt(std::size_t distance + , void* src_address + , vertex_t target + , cast_function cast + ) + : distance(distance) + , src_address(src_address) + , target(target) + , cast(cast) + {} + + std::size_t distance; + void* src_address; + vertex_t target; + cast_function cast; + + bool operator<(q_elt const& rhs) const + { + return distance < rhs.distance; + } + }; + + // Optimization: + // + // Given p, src_t, dst_t + // + // Get a pointer pd to the most-derived object + // if it's polymorphic, dynamic_cast to void* + // otherwise pd = p + // + // Get the most-derived typeid src_td + // + // ptrdiff_t offset = p - pd + // + // Now we can keep a cache, for [src_t, offset, src_td, dst_t] of + // the cast transformation function to use on p and the next src_t + // in the chain. src_td, dst_t don't change throughout this + // process. In order to represent unreachability, when a pair is + // found to be unreachable, we stick a 0-returning "dead-cast" + // function in the cache. + + // This is needed in a few places below + inline void* identity_cast(void* p) + { + return p; + } + + void* search(smart_graph const& g, void* p, vertex_t src, vertex_t dst) + { + // I think this test was thoroughly bogus -- dwa + // If we know there's no path; bail now. + // if (src > g.known_vertices() || dst > g.known_vertices()) + // return 0; + + smart_graph::node_distance_map d(g.distances_to(dst)); + + if (d[src] == std::numeric_limits::max()) + return 0; + + typedef property_map::const_type cast_map; + cast_map casts = get(edge_cast, g.topology()); + + typedef std::pair search_state; + typedef std::vector visited_t; + visited_t visited; + std::priority_queue q; + + q.push(q_elt(d[src], p, src, identity_cast)); + while (!q.empty()) + { + q_elt top = q.top(); + q.pop(); + + // Check to see if we have a real state + void* dst_address = top.cast(top.src_address); + if (dst_address == 0) + continue; + + if (top.target == dst) + return dst_address; + + search_state s(top.target,dst_address); + + visited_t::iterator pos = std::lower_bound( + visited.begin(), visited.end(), s); + + // If already visited, continue + if (pos != visited.end() && *pos == s) + continue; + + visited.insert(pos, s); // mark it + + // expand it: + smart_graph::out_edges_t edges = out_edges(s.first, g.topology()); + for (cast_graph::out_edge_iterator p = edges.first + , finish = edges.second + ; p != finish + ; ++p + ) + { + edge_t e = *p; + q.push(q_elt( + d[target(e, g.topology())] + , dst_address + , target(e, g.topology()) + , boost::get(casts, e))); + } + } + return 0; + } + + struct cache_element + { + typedef tuples::tuple< + class_id // source static type + , class_id // target type + , std::ptrdiff_t // offset within source object + , class_id // source dynamic type + >::inherited key_type; + + cache_element(key_type const& k) + : key(k) + , offset(0) + {} + + key_type key; + std::ptrdiff_t offset; + + BOOST_STATIC_CONSTANT( + std::ptrdiff_t, not_found = integer_traits::const_min); + + bool operator<(cache_element const& rhs) const + { + return this->key < rhs.key; + } + + bool unreachable() const + { + return offset == not_found; + } + }; + + enum { kdst_t = ksrc_static_t + 1, koffset, ksrc_dynamic_t }; + typedef std::vector cache_t; + + cache_t& cache() + { + static cache_t x; + return x; + } + + inline void* convert_type(void* const p, class_id src_t, class_id dst_t, bool polymorphic) + { + // Quickly rule out unregistered types + index_entry* src_p = seek_type(src_t); + if (src_p == 0) + return 0; + + index_entry* dst_p = seek_type(dst_t); + if (dst_p == 0) + return 0; + + // Look up the dynamic_id function and call it to get the dynamic + // info + boost::python::objects::dynamic_id_t dynamic_id = polymorphic + ? tuples::get(*src_p)(p) + : std::make_pair(p, src_t); + + // Look in the cache first for a quickie address translation + std::ptrdiff_t offset = (char*)p - (char*)dynamic_id.first; + + cache_element seek(make_tuple(src_t, dst_t, offset, dynamic_id.second)); + cache_t& c = cache(); + cache_t::iterator const cache_pos + = std::lower_bound(c.begin(), c.end(), seek); + + + // if found in the cache, we're done + if (cache_pos != c.end() && cache_pos->key == seek.key) + { + return cache_pos->offset == cache_element::not_found + ? 0 : (char*)p + cache_pos->offset; + } + + // If we are starting at the most-derived type, only look in the up graph + smart_graph const& g = polymorphic && dynamic_id.second != src_t + ? full_graph() : up_graph(); + + void* result = search( + g, p, tuples::get(*src_p) + , tuples::get(*dst_p)); + + // update the cache + c.insert(cache_pos, seek)->offset + = (result == 0) ? cache_element::not_found : (char*)result - (char*)p; + + return result; + } +} + +namespace python { namespace objects { + +BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src_t, class_id dst_t) +{ + return convert_type(p, src_t, dst_t, true); +} + +BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src_t, class_id dst_t) +{ + return convert_type(p, src_t, dst_t, false); +} + +BOOST_PYTHON_DECL void add_cast( + class_id src_t, class_id dst_t, cast_function cast, bool is_downcast) +{ + // adding an edge will invalidate any record of unreachability in + // the cache. + static std::size_t expected_cache_len = 0; + cache_t& c = cache(); + if (c.size() > expected_cache_len) + { + c.erase(std::remove_if( + c.begin(), c.end(), + mem_fn(&cache_element::unreachable)) + , c.end()); + + // If any new cache entries get added, we'll have to do this + // again when the next edge is added + expected_cache_len = c.size(); + } + + type_index_iterator_pair types = demand_types(src_t, dst_t); + vertex_t src = tuples::get(*types.first); + vertex_t dst = tuples::get(*types.second); + + cast_graph* const g[2] = { &up_graph().topology(), &full_graph().topology() }; + + for (cast_graph*const* p = g + (is_downcast ? 1 : 0); p < g + 2; ++p) + { + edge_t e; + bool added; + + tie(e, added) = add_edge(src, dst, **p); + assert(added); + + put(get(edge_cast, **p), e, cast); + put(get(edge_index, **p), e, num_edges(full_graph().topology()) - 1); + } +} + +BOOST_PYTHON_DECL void register_dynamic_id_aux( + class_id static_id, dynamic_id_function get_dynamic_id) +{ + tuples::get(*demand_type(static_id)) = get_dynamic_id; +} + +}}} // namespace boost::python::objects diff --git a/test/m1.cpp b/test/m1.cpp index 78471bfc..da3ca5d5 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -227,10 +229,47 @@ simple const& g(simple const& x) return x; } +struct A +{ + A() : x(0) {} + char const* name() { return "A"; } + int x; +}; + +struct B : A +{ + B() : x(1) {} + char const* name() { return "B"; } + int x; +}; + + +struct C : A +{ + C() : x(2) {} + char const* name() { return "C"; } + virtual ~C() {} + int x; +}; + +struct D : B, C +{ + D() : x(3) {} + char const* name() { return "D"; } + int x; +}; + +int take_a(A const& a) { return a.x; } +int take_b(B const& b) { return b.x; } +int take_c(C const& c) { return c.x; } +int take_d(D const& d) { return d.x; } + BOOST_PYTHON_MODULE_INIT(m1) { - boost::python::module m1("m1"); - + using boost::python::module; + using boost::python::class_; + + module m1("m1"); // Create the converters; they are self-registering/unregistering. static int_wrapper wrap_int; static simple_wrapper wrap_simple; @@ -242,13 +281,16 @@ BOOST_PYTHON_MODULE_INIT(m1) static simple_ref_wrapper wrap_simple_ref; // This unwrapper extracts pointers and references to the "complicated" class. - static boost::python::converter::class_unwrapper unwrap_complicated; + // static boost::python::converter::class_unwrapper unwrap_complicated; // Insert the extension metaclass object - m1.add(boost::python::objects::class_metatype(), "xclass"); + m1.add( + boost::python::objects::class_metatype() + , "xclass"); // Insert the base class for all extension classes - m1.add(boost::python::objects::class_type(), "xinst"); + m1.add(boost::python::objects::class_type() + , "xinst"); m1.def(new_noddy, "new_noddy"); m1.def(new_simple, "new_simple"); @@ -259,25 +301,36 @@ BOOST_PYTHON_MODULE_INIT(m1) // Expose g() m1.def(g, "g"); - // Expose complicated's get_n() member function. See newtest.py - // for how it's used to build an extension class. - m1.def(&complicated::get_n, "get_n"); + m1.def(take_a, "take_a"); + m1.def(take_b, "take_b"); + m1.def(take_c, "take_c"); + m1.def(take_d, "take_d"); - // Expose complicated::complicated(simple const&, int) as init1 - boost::python::objects::function* init = boost::python::make_constructor< - complicated - , boost::mpl::type_list - , boost::python::objects::value_holder_generator>(); - - boost::python::ref manager(init); - - init->add_overload( - boost::python::make_constructor< - complicated - , boost::mpl::type_list - , boost::python::objects::value_holder_generator>()); - - m1.add(manager, "init1"); + class_(m1, "A") + .def_init() + .def(&A::name, "name") + ; + + class_ >(m1, "B") + .def_init() + .def(&B::name, "name") + ; + + class_ >(m1, "C") + .def_init() + .def(&C::name, "name") + ; + + class_ >(m1, "D") + .def_init() + .def(&D::name, "name") + ; + + class_(m1, "complicated") + .def_init(args()) + .def_init(args()) + .def(&complicated::get_n, "get_n") + ; } #include "module_tail.cpp" From 078585db28da772b7cb1d8f31f7198f83463483e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 21 Jan 2002 06:20:15 +0000 Subject: [PATCH 0199/1042] fixed transfer-of-ownership counting to avoid problems [SVN r12392] --- include/boost/python/reference.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/python/reference.hpp b/include/boost/python/reference.hpp index f0cdab55..97edef99 100644 --- a/include/boost/python/reference.hpp +++ b/include/boost/python/reference.hpp @@ -173,10 +173,10 @@ public: void reset(T2* x, increment_count_t) { assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XINCREF(x); Py_XDECREF(m_p); m_p = expect_non_null(x); assert(m_p->ob_refcnt > 0); - Py_INCREF(m_p); } template @@ -192,20 +192,20 @@ public: void reset(T2* x, allow_null, increment_count_t) { assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XINCREF(x); Py_XDECREF(m_p); m_p = x; assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(m_p); } template void reset(T2* x, increment_count_t, allow_null) { assert(m_p == 0 || m_p->ob_refcnt > 0); + Py_XINCREF(x); Py_XDECREF(m_p); m_p = x; assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(m_p); } #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) From 93501af04601590e46feede4a11e03fae700d2d6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 21 Jan 2002 06:23:33 +0000 Subject: [PATCH 0200/1042] always use ref (counting) for safety [SVN r12393] --- include/boost/python/object/class.hpp | 4 ++-- include/boost/python/object/class_converters.hpp | 5 +++-- include/boost/python/object/class_wrapper.hpp | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 808e3669..4817e15d 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -38,8 +38,8 @@ struct BOOST_PYTHON_DECL class_base : noncopyable // any bases. ); - // Retrieve a pointer to the underlying object - PyObject* object() const { return m_object.get(); } + // Retrieve the underlying object + ref object() const { return m_object; } private: ref m_object; }; diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index c14103b6..d4ba4b6d 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -9,6 +9,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -20,7 +21,7 @@ struct class_converters { public: // member functions // Constructor takes the python class object associated with T - class_converters(PyObject* python_class); + class_converters(ref const& python_class); private: // data members converter::class_unwrapper m_unwrapper; @@ -86,7 +87,7 @@ struct register_base_of }; template -class_converters::class_converters(PyObject* type_object) +class_converters::class_converters(ref const& type_object) : m_wrapper(type_object) { // register all up/downcasts here diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index 0e49ce84..cbfb2ae6 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -18,7 +18,7 @@ template struct class_wrapper : converter::wrapper { - class_wrapper(PyObject* type_) + class_wrapper(ref const& type_) : m_class_object(type_) { # ifndef NDEBUG From 41634f9998844058678b169b42e2eedccdb6a9c4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 21 Jan 2002 06:56:27 +0000 Subject: [PATCH 0201/1042] Use ref everywhere for reliability [SVN r12394] --- include/boost/python/class.hpp | 2 +- include/boost/python/module.hpp | 8 ++++---- include/boost/python/object/function.hpp | 2 +- src/module.cpp | 11 +++++++---- src/object/function.cpp | 22 +++++++++++----------- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index d61a8fc0..76a74df2 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -100,7 +100,7 @@ class class_ : objects::class_base { // Use function::add_to_namespace to achieve overloading if // appropriate. - objects::function::add_to_namespace(this->object(), name, detail::wrap_function(f)); + objects::function::add_to_namespace(this->object(), name, ref(detail::wrap_function(f))); return *this; } diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 317cc5e4..318f4a64 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -25,7 +25,7 @@ class BOOST_PYTHON_DECL module_base // Add elements to the module void add(PyObject* x, const char* name); void add(PyTypeObject* x, const char* name = 0); - void add(ref x, const char*name); + void add(ref const& x, const char*name); // Return true iff a module is currently being built. static bool initializing(); @@ -35,10 +35,10 @@ class BOOST_PYTHON_DECL module_base static string name(); // Return a pointer to the Python module object being built - PyObject* module() const; + ref module() const; private: - PyObject* m_module; + ref m_module; static PyMethodDef initial_methods[1]; }; @@ -65,7 +65,7 @@ class module : public module_base // // inline implementations // -inline PyObject* module_base::module() const +inline ref module_base::module() const { return m_module; } diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index cc2695d8..c239b6e6 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -27,7 +27,7 @@ struct BOOST_PYTHON_DECL function : PyObject // a function object (this class), and an existing function is // already there, add it as an overload. static void add_to_namespace( - PyObject* name_space, char const* name, PyObject* attribute); + ref const& name_space, char const* name, ref const& attribute); private: // helper functions void argument_error(PyObject* args, PyObject* keywords) const; diff --git a/src/module.cpp b/src/module.cpp index 0851805f..917f8d3a 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -27,11 +27,14 @@ string module_base::name() } module_base::module_base(const char* name) - : m_module(Py_InitModule(const_cast(name), initial_methods)) + : m_module( + Py_InitModule(const_cast(name), initial_methods) + , ref::increment_count) { // If this fails, you've created more than 1 module object in your module assert(name_holder.get() == 0); - name_holder = ref(PyObject_GetAttrString(m_module, const_cast("__name__"))); + name_holder = ref(PyObject_GetAttrString( + m_module.get() , const_cast("__name__"))); } module_base::~module_base() @@ -44,11 +47,11 @@ void module_base::add(PyObject* x, const char* name) add(ref(x), name); } -void module_base::add(ref x, const char* name) +void module_base::add(ref const& x, const char* name) { // Use function::add_to_namespace to achieve overloading if // appropriate. - objects::function::add_to_namespace(m_module, name, x.get()); + objects::function::add_to_namespace(m_module, name, x); } void module_base::add(PyTypeObject* x, const char* name /*= 0*/) diff --git a/src/object/function.cpp b/src/object/function.cpp index 3755dfb1..7878fa47 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -77,21 +77,21 @@ void function::add_overload(function* overload) } void function::add_to_namespace( - PyObject* name_space, char const* name_, PyObject* attribute_) + ref const& name_space, char const* name_, ref const& attribute) { - ref attribute(attribute_, ref::increment_count); - string name(name_); + string const name(name_); + PyObject* const ns = name_space.get(); - if (attribute_->ob_type == &function_type) + if (attribute->ob_type == &function_type) { PyObject* dict = 0; - if (PyClass_Check(name_space)) - dict = ((PyClassObject*)name_space)->cl_dict; - else if (PyType_Check(name_space)) - dict = ((PyTypeObject*)name_space)->tp_dict; + if (PyClass_Check(ns)) + dict = ((PyClassObject*)ns)->cl_dict; + else if (PyType_Check(ns)) + dict = ((PyTypeObject*)ns)->tp_dict; else - dict = PyObject_GetAttrString(name_space, "__dict__"); + dict = PyObject_GetAttrString(ns, "__dict__"); if (dict == 0) throw error_already_set(); @@ -101,14 +101,14 @@ void function::add_to_namespace( if (existing.get() && existing->ob_type == &function_type) { static_cast(existing.get())->add_overload( - static_cast(attribute_)); + static_cast(attribute.get())); return; } } // The PyObject_GetAttrString() call above left an active error PyErr_Clear(); - if (PyObject_SetAttr(name_space, name.get(), attribute_) < 0) + if (PyObject_SetAttr(ns, name.get(), attribute.get()) < 0) throw error_already_set(); } From ed2ebc7d3d506ab8874cf0ba1f479748d1513534 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 21 Jan 2002 21:18:47 +0000 Subject: [PATCH 0202/1042] added: missing // after #endif [SVN r12405] --- include/boost/python/object/class_wrapper.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index cbfb2ae6..f199a99f 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -23,7 +23,7 @@ struct class_wrapper { # ifndef NDEBUG assert(type_->ob_type == (PyTypeObject*)class_metatype().get()); -# endif NDEBUG +# endif // NDEBUG } PyObject* convert(T const& x) const From 98a1329dd72525920c3edfc19f06b5ea2db418e3 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 22 Jan 2002 01:43:40 +0000 Subject: [PATCH 0203/1042] default argument moved to declaration. [SVN r12414] --- include/boost/python/class.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 76a74df2..abd38d82 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -90,7 +90,7 @@ class class_ : objects::class_base public: // Construct with the module and class name - class_(module&, char const* name); + class_(module&, char const* name = typeid(T).name()); // 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 @@ -152,7 +152,7 @@ class class_ : objects::class_base // template inline class_::class_( - module& m, char const* name = typeid(T).name()) + module& m, char const* name) : class_base(m, name, id_vector::size, id_vector().ids) { // Bring the class converters into existence. This static object From 996d83eae0638804dc51158a3ec315507e7aee61 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 22 Jan 2002 02:32:48 +0000 Subject: [PATCH 0204/1042] fix for EDG [SVN r12415] --- include/boost/python/class.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index abd38d82..25815acc 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -127,6 +127,7 @@ class class_ : objects::class_base // passed to the base class constructor struct id_vector { + typedef objects::class_id class_id; id_vector() { // Stick the derived class id into the first element of the array From 248985e51a080ba328e48b8ce0fa30bba5c27bfe Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 22 Jan 2002 13:12:41 +0000 Subject: [PATCH 0205/1042] ICL compatibility [SVN r12435] --- src/object/inheritance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object/inheritance.cpp b/src/object/inheritance.cpp index 5b95e478..7efc980c 100644 --- a/src/object/inheritance.cpp +++ b/src/object/inheritance.cpp @@ -109,7 +109,7 @@ namespace make_iterator_property_map( to_target , get(vertex_index, reverse_topology) -# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# ifdef BOOST_MSVC_STD_ITERATOR , *to_target # endif ) From 51a66a32028d68c04d91470305a666120405013c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 22 Jan 2002 13:52:05 +0000 Subject: [PATCH 0206/1042] Fixes for gcc-2.95.3 [SVN r12442] --- include/boost/python/class.hpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 25815acc..3b20406e 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -89,8 +89,15 @@ class class_ : objects::class_base typedef class_ self; public: - // Construct with the module and class name - class_(module&, char const* name = typeid(T).name()); + // Construct with the module and automatically derive the class + // name + class_(module&); + + // Construct with the module and class name. [ Would have used a + // default argument but gcc-2.95.2 choked on typeid(T).name() as a + // default parameter value] + class_(module&, char const* name); + // 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 @@ -100,7 +107,8 @@ class class_ : objects::class_base { // Use function::add_to_namespace to achieve overloading if // appropriate. - objects::function::add_to_namespace(this->object(), name, ref(detail::wrap_function(f))); + objects::function::add_to_namespace( + this->object(), name, ref(detail::wrap_function(f))); return *this; } @@ -151,6 +159,17 @@ class class_ : objects::class_base // // implementations // +template +inline class_::class_( + module& m) + : class_base(m, typeid(T).name(), id_vector::size, id_vector().ids) +{ + // Bring the class converters into existence. This static object + // will survive until the shared library this module lives in is + // unloaded (that doesn't happen until Python terminates). + static objects::class_converters converters(object()); +} + template inline class_::class_( module& m, char const* name) From 0389aab0a33211c99fac0986930ab0a037fb74e5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 22 Jan 2002 19:51:04 +0000 Subject: [PATCH 0207/1042] Nicer syntactic sugar [SVN r12447] --- include/boost/python/class.hpp | 40 +++++++++------- include/boost/python/module.hpp | 67 +++++++++++++++++++++------ include/boost/python/object/class.hpp | 3 +- src/module.cpp | 37 +++++---------- src/object/class.cpp | 8 ++-- 5 files changed, 90 insertions(+), 65 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 3b20406e..0f8d2a69 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -6,7 +6,6 @@ #ifndef CLASS_DWA200216_HPP # define CLASS_DWA200216_HPP -# include # include # include # include @@ -84,26 +83,26 @@ template < , class Bases = mpl::type_list<>::type , class HolderGenerator = objects::value_holder_generator > -class class_ : objects::class_base +class class_ : private objects::class_base { typedef class_ self; public: - // Construct with the module and automatically derive the class - // name - class_(module&); + // Automatically derive the class name - only works on some + // compilers because type_info::name is sometimes mangled (gcc) + class_(); - // Construct with the module and class name. [ Would have used a - // default argument but gcc-2.95.2 choked on typeid(T).name() as a - // default parameter value] - class_(module&, char const* name); + // Construct with the class name. [ Would have used a default + // argument but gcc-2.95.2 choked on typeid(T).name() as a default + // parameter value] + class_(char const* name); // 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. template - self& def(F f, char const* name) + self& def(char const* name, F f) { // Use function::add_to_namespace to achieve overloading if // appropriate. @@ -117,7 +116,7 @@ class class_ : objects::class_base template self& def_init(Args const& = Args()) { - def(make_constructor(), "__init__"); + def("__init__", make_constructor()); return *this; } @@ -128,6 +127,9 @@ class class_ : objects::class_base return *this; } + // return the underlying object + ref object() const; + private: // types typedef objects::class_id class_id; @@ -160,9 +162,8 @@ class class_ : objects::class_base // implementations // template -inline class_::class_( - module& m) - : class_base(m, typeid(T).name(), id_vector::size, id_vector().ids) +inline class_::class_() + : class_base(typeid(T).name(), id_vector::size, id_vector().ids) { // Bring the class converters into existence. This static object // will survive until the shared library this module lives in is @@ -171,9 +172,8 @@ inline class_::class_( } template -inline class_::class_( - module& m, char const* name) - : class_base(m, name, id_vector::size, id_vector().ids) +inline class_::class_(char const* name) + : class_base(name, id_vector::size, id_vector().ids) { // Bring the class converters into existence. This static object // will survive until the shared library this module lives in is @@ -181,6 +181,12 @@ inline class_::class_( static objects::class_converters converters(object()); } +template +inline ref class_::object() const +{ + return this->class_base::object(); +} + }} // namespace boost::python #endif // CLASS_DWA200216_HPP diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 318f4a64..a6a3a8e7 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -15,6 +15,8 @@ namespace boost { namespace python { +template class class_; + class BOOST_PYTHON_DECL module_base { public: @@ -23,18 +25,12 @@ class BOOST_PYTHON_DECL module_base ~module_base(); // Add elements to the module - void add(PyObject* x, const char* name); - void add(PyTypeObject* x, const char* name = 0); - void add(ref const& x, const char*name); - - // Return true iff a module is currently being built. - static bool initializing(); + void setattr(const char* name, PyObject*); + void setattr(const char* name, ref const&); + void add(PyTypeObject* x); // just use the type's name + void add_type(ref); - // Return the name of the module currently being built. - // REQUIRES: initializing() == true - static string name(); - - // Return a pointer to the Python module object being built + // Return a reference to the Python module object being built ref module() const; private: @@ -48,17 +44,34 @@ class module : public module_base module(const char* name) : module_base(name) {} + // Add elements to the module + module& setattr(const char* name, PyObject*); + module& setattr(const char* name, PyTypeObject*); + module& setattr(const char* name, ref const&); + module& add(PyTypeObject* x); // just use the type's name + + template + module& add(class_ const& c) + { + std::cout << "adding " << typeid(T).name() << " to module" << std::endl << std::flush; + Py_INCREF(c.object()); + this->add_type(c.object()); + return *this; + } + # if 0 template - void def_raw(Fn fn, const char* name) + void def_raw(char const* name, Fn fn) { add(detail::new_raw_arguments_function(fn), name); } -# endif +# endif + template - void def(Fn fn, const char* name) + module& def(char const* name, Fn fn) { - this->add(boost::python::make_function(fn), name); + this->setattr(name, boost::python::make_function(fn)); + return *this; } }; @@ -70,6 +83,30 @@ inline ref module_base::module() const return m_module; } +inline module& module::setattr(const char* name, PyObject* x) +{ + this->module_base::setattr(name, x); + return *this; +} + +inline module& module::setattr(const char* name, PyTypeObject* x) +{ + this->module_base::setattr(name, (PyObject*)x); + return *this; +} + +inline module& module::setattr(const char* name, ref const& x) +{ + this->module_base::setattr(name, x); + return *this; +} + +inline module& module::add(PyTypeObject* x) +{ + this->module_base::add(x); + return *this; +} + }} // namespace boost::python #endif // MODULE_DWA20011221_HPP diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 4817e15d..53d886fa 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -30,8 +30,7 @@ struct BOOST_PYTHON_DECL class_base : noncopyable { // constructor class_base( - module& name_space // Which name space the class will live in - , char const* name // The name of the class + char const* name // The name of the class , std::size_t num_types // A list of class_ids. The first is the type , class_id const*const types // this is wrapping. The rest are the types of diff --git a/src/module.cpp b/src/module.cpp index 917f8d3a..dbc81729 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -10,53 +10,38 @@ namespace boost { namespace python { -namespace { - ref name_holder; -} - -bool module_base::initializing() -{ - return name_holder.get() != 0; -} - -string module_base::name() -{ - // If this fails, you haven't created a module object - assert(initializing()); - return string(name_holder); -} - module_base::module_base(const char* name) : m_module( Py_InitModule(const_cast(name), initial_methods) , ref::increment_count) { - // If this fails, you've created more than 1 module object in your module - assert(name_holder.get() == 0); - name_holder = ref(PyObject_GetAttrString( - m_module.get() , const_cast("__name__"))); } module_base::~module_base() { - name_holder.reset(); } -void module_base::add(PyObject* x, const char* name) +void module_base::setattr(const char* name, PyObject* x) { - add(ref(x), name); + setattr(name, ref(x)); } -void module_base::add(ref const& x, const char* name) +void module_base::setattr(char const* name, ref const& x) { // Use function::add_to_namespace to achieve overloading if // appropriate. objects::function::add_to_namespace(m_module, name, x); } -void module_base::add(PyTypeObject* x, const char* name /*= 0*/) +void module_base::add(PyTypeObject* x) { - this->add((PyObject*)x, name ? name : x->tp_name); + this->setattr(x->tp_name, (PyObject*)x); +} + +void module_base::add_type(ref x) +{ + assert(PyObject_TypeCheck(x.get(), &PyType_Type)); + add((PyTypeObject*)x.release()); } PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; diff --git a/src/object/class.cpp b/src/object/class.cpp index 5ebabba1..b928ba66 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -190,11 +189,11 @@ namespace std::vector::const_iterator p = boost::detail::lower_bound(start, finish, id); - + if (p == finish && p->key != id) { string report("extension class wrapper for base class "); - (report += id.name()) += "has not been created yet"; + (report += id.name()) += " has not been created yet"; PyErr_SetObject(PyExc_RuntimeError, report.get()); throw error_already_set(); } @@ -212,7 +211,7 @@ namespace } class_base::class_base( - module& m, char const* name, std::size_t num_types, class_id const* const types) + char const* name, std::size_t num_types, class_id const* const types) { class_registry& r = registry(); assert(num_types >= 1); @@ -234,7 +233,6 @@ class_base::class_base( m_object = ref(PyObject_CallObject(class_metatype().get(), args.get())); r.set(types[0], m_object); - m.add(m_object, name); } }}} // namespace boost::python::objects From f2785302392eaf4e1b26c5fed8e3d52f9d48e052 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 22 Jan 2002 19:56:36 +0000 Subject: [PATCH 0208/1042] Nicer syntactic sugar [SVN r12448] --- test/m1.cpp | 93 +++++++++++++++++++++++++++++------------------------ test/m2.cpp | 28 ++++++++-------- 2 files changed, 65 insertions(+), 56 deletions(-) diff --git a/test/m1.cpp b/test/m1.cpp index da3ca5d5..7f88af2b 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -269,7 +269,6 @@ BOOST_PYTHON_MODULE_INIT(m1) using boost::python::module; using boost::python::class_; - module m1("m1"); // Create the converters; they are self-registering/unregistering. static int_wrapper wrap_int; static simple_wrapper wrap_simple; @@ -280,56 +279,66 @@ BOOST_PYTHON_MODULE_INIT(m1) static simple_const_ref_unwrapper unwrap_simple_const_ref; static simple_ref_wrapper wrap_simple_ref; - // This unwrapper extracts pointers and references to the "complicated" class. - // static boost::python::converter::class_unwrapper unwrap_complicated; + module m1("m1"); + + m1 + // Insert the metaclass for all extension classes + .setattr("xclass", boost::python::objects::class_metatype()) - // Insert the extension metaclass object - m1.add( - boost::python::objects::class_metatype() - , "xclass"); - - // Insert the base class for all extension classes - m1.add(boost::python::objects::class_type() - , "xinst"); + // Insert the base class for all extension classes + .setattr("xinst", boost::python::objects::class_type()) - m1.def(new_noddy, "new_noddy"); - m1.def(new_simple, "new_simple"); - - // Expose f() - m1.def(f, "f"); + .def("new_noddy", new_noddy) + .def("new_simple", new_simple) - // Expose g() - m1.def(g, "g"); + // Expose f() + .def("f", f) - m1.def(take_a, "take_a"); - m1.def(take_b, "take_b"); - m1.def(take_c, "take_c"); - m1.def(take_d, "take_d"); + // Expose g() + .def("g", g) - class_(m1, "A") - .def_init() - .def(&A::name, "name") - ; - - class_ >(m1, "B") - .def_init() - .def(&B::name, "name") - ; - - class_ >(m1, "C") - .def_init() - .def(&C::name, "name") + .def("take_a", take_a) + .def("take_b", take_b) + .def("take_c", take_c) + .def("take_d", take_d) + + .add( + class_("A") + .def_init() + .def("name", &A::name) + ) + ; - class_ >(m1, "D") - .def_init() - .def(&D::name, "name") + // sequence points don't ensure that "A" is constructed before "B" + // or "C" below if we make them part of the same chain + m1 + .add( + class_ >("B") + .def_init() + .def("name", &B::name) + ) + + .add( + class_ >("C") + .def_init() + .def("name", &C::name) + ) ; - class_(m1, "complicated") - .def_init(args()) - .def_init(args()) - .def(&complicated::get_n, "get_n") + m1 + .add( + class_ >("D") + .def_init() + .def("name", &D::name) + ) + + .add( + class_("complicated") + .def_init(args()) + .def_init(args()) + .def("get_n", &complicated::get_n) + ) ; } diff --git a/test/m2.cpp b/test/m2.cpp index 7ea1f9ac..d70b0c13 100644 --- a/test/m2.cpp +++ b/test/m2.cpp @@ -66,21 +66,21 @@ struct rewrap BOOST_PYTHON_MODULE_INIT(m2) { - boost::python::module m2("m2"); - - m2.def(unwrap_int, "unwrap_int"); - m2.def(unwrap_int_ref, "unwrap_int_ref"); - m2.def(unwrap_int_const_ref, "unwrap_int_const_ref"); - m2.def(unwrap_simple, "unwrap_simple"); - m2.def(unwrap_simple_ref, "unwrap_simple_ref"); - m2.def(unwrap_simple_const_ref, "unwrap_simple_const_ref"); + boost::python::module("m2") + .def("unwrap_int", unwrap_int) + .def("unwrap_int_ref", unwrap_int_ref) + .def("unwrap_int_const_ref", unwrap_int_const_ref) + .def("unwrap_simple", unwrap_simple) + .def("unwrap_simple_ref", unwrap_simple_ref) + .def("unwrap_simple_const_ref", unwrap_simple_const_ref) - m2.def(&rewrap::f, "wrap_int"); - m2.def(&rewrap::f, "wrap_int_ref"); - m2.def(&rewrap::f, "wrap_int_const_ref"); - m2.def(&rewrap::f, "wrap_simple"); - m2.def(&rewrap::f, "wrap_simple_ref"); - m2.def(&rewrap::f, "wrap_simple_const_ref"); + .def("wrap_int", &rewrap::f) + .def("wrap_int_ref", &rewrap::f) + .def("wrap_int_const_ref", &rewrap::f) + .def("wrap_simple", &rewrap::f) + .def("wrap_simple_ref", &rewrap::f) + .def("wrap_simple_const_ref", &rewrap::f) + ; } #include "module_tail.cpp" From f40a534bfb1b6aabc21b4f5075c49d31a2529c48 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 22 Jan 2002 21:55:08 +0000 Subject: [PATCH 0209/1042] cleanup [SVN r12449] --- include/boost/python/module.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index a6a3a8e7..5661e106 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -53,7 +53,6 @@ class module : public module_base template module& add(class_ const& c) { - std::cout << "adding " << typeid(T).name() << " to module" << std::endl << std::flush; Py_INCREF(c.object()); this->add_type(c.object()); return *this; From 088b1cab833fea1852fc72ed688d14708ef84df5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 23 Jan 2002 06:08:46 +0000 Subject: [PATCH 0210/1042] workarounds for KCC's reservation of 'overload' as a keyword [SVN r12451] --- include/boost/python/object/function.hpp | 2 +- src/object/function.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index c239b6e6..2a05a946 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -31,7 +31,7 @@ struct BOOST_PYTHON_DECL function : PyObject private: // helper functions void argument_error(PyObject* args, PyObject* keywords) const; - void add_overload(function* overload); + void add_overload(function*); private: // data members py_function m_fn; diff --git a/src/object/function.cpp b/src/object/function.cpp index 7878fa47..a30e9f15 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -63,9 +63,9 @@ void function::argument_error(PyObject* args, PyObject* keywords) const PyErr_BadArgument(); } -void function::add_overload(function* overload) +void function::add_overload(function* overload_) { - Py_XINCREF(overload); + Py_XINCREF(overload_); function* parent = this; @@ -73,7 +73,7 @@ void function::add_overload(function* overload) { parent = parent->m_overloads; } - parent->m_overloads = overload; + parent->m_overloads = overload_; } void function::add_to_namespace( From 71032f6c4c0887834d4657b3405729b149810911 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 30 Jan 2002 20:18:39 +0000 Subject: [PATCH 0211/1042] New conversion mechanism, builtin converters [SVN r12590] --- Jamfile | 65 +- include/boost/python/converter/class.hpp | 89 +- .../boost/python/converter/registration.hpp | 94 +- include/boost/python/converter/registry.hpp | 43 +- include/boost/python/converter/source.hpp | 10 +- include/boost/python/converter/unwrap.hpp | 6 +- include/boost/python/converter/unwrapper.hpp | 3 +- include/boost/python/converter/wrap.hpp | 1 + include/boost/python/converter/wrapper.hpp | 1 + .../boost/python/detail/arg_tuple_size.hpp | 12 +- include/boost/python/detail/char_array.hpp | 23 + include/boost/python/detail/eval.hpp | 38 + include/boost/python/detail/returning.hpp | 876 ++++++++++-------- include/boost/python/detail/signature.hpp | 217 +++++ include/boost/python/make_function.hpp | 7 + .../boost/python/object/class_converters.hpp | 2 +- include/boost/python/object/class_wrapper.hpp | 19 +- include/boost/python/object/make_holder.hpp | 36 +- include/boost/python/object/value_holder.hpp | 93 +- include/boost/python/objects.hpp | 4 +- src/converter/registry.cpp | 111 ++- src/gen_arg_tuple_size.py | 12 +- src/gen_signature.py | 90 ++ src/gen_value_holder.py | 35 + src/object/class.cpp | 2 +- test/m1.cpp | 180 ++-- test/m2.cpp | 4 - 27 files changed, 1352 insertions(+), 721 deletions(-) create mode 100644 include/boost/python/detail/char_array.hpp create mode 100644 include/boost/python/detail/eval.hpp create mode 100644 include/boost/python/detail/signature.hpp create mode 100644 src/gen_signature.py create mode 100644 src/gen_value_holder.py diff --git a/Jamfile b/Jamfile index 71e0c5b7..684c21d5 100644 --- a/Jamfile +++ b/Jamfile @@ -8,36 +8,47 @@ PYTHON_PROPERTIES += <*>"-inline deferred" <*>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers BOOST_PYTHON_DYNAMIC_LIB - BOOST_PYTHON_V2 - ; + BOOST_PYTHON_V2 + ; +{ + dll bpl + : + src/converter/from_python.cpp + src/converter/to_python.cpp + src/converter/registry.cpp + src/converter/type_id.cpp + src/object/class.cpp + src/object/function.cpp + src/object/inheritance.cpp + src/errors.cpp + src/module.cpp + src/objects.cpp + src/converter/builtin_converters.cpp + : + $(PYTHON_PROPERTIES) + BOOST_PYTHON_SOURCE + ; -dll bpl - : - src/converter/body.cpp - src/converter/handle.cpp - src/converter/registry.cpp - src/converter/wrapper.cpp - src/converter/unwrap.cpp - src/converter/unwrapper.cpp - src/converter/type_id.cpp - src/object/class.cpp - src/object/function.cpp - src/object/inheritance.cpp - src/errors.cpp - src/module.cpp - src/objects.cpp - : - $(PYTHON_PROPERTIES) - BOOST_PYTHON_SOURCE - ; + extension m1 : test/m1.cpp bpl # BOOST_PYTHON_TRACE + : + : debug-python + ; -extension m1 : test/m1.cpp bpl # BOOST_PYTHON_TRACE - : - : debug-python ; - -extension m2 : test/m2.cpp bpl # BOOST_PYTHON_TRACE + extension m2 : test/m2.cpp bpl # BOOST_PYTHON_TRACE : : debug-python ; -boost-python-runtest try : test/newtest.py m1 m2 : : debug-python ; \ No newline at end of file + boost-python-runtest try : test/newtest.py m1 m2 : : debug-python ; + + extension builtin_converters_ext : test/test_builtin_converters.cpp bpl + : + : debug-python + ; + + boost-python-runtest test_builtin_converters : test/test_builtin_converters.py + builtin_converters_ext + : + : debug-python + ; +} diff --git a/include/boost/python/converter/class.hpp b/include/boost/python/converter/class.hpp index f437a73a..67de6fad 100644 --- a/include/boost/python/converter/class.hpp +++ b/include/boost/python/converter/class.hpp @@ -7,62 +7,69 @@ # define CLASS_DWA20011215_HPP # include -# include +# include namespace boost { namespace python { namespace converter { template -struct class_unwrapper - : private unwrapper - , private unwrapper - , private unwrapper - , private unwrapper +struct class_from_python_converter { - protected: -# ifdef __GNUC__ // suppress warning that "all member functions are private" (duh) - void uncallable(); -# endif - private: - void* can_convert(PyObject*) const; - T& convert(PyObject*, void*, boost::type) const; - T const& convert(PyObject*, void*, boost::type) const; - T* convert(PyObject*, void*, boost::type) const; - T const* convert(PyObject*, void*, boost::type) const; + class_from_python_converter(); + + static void* convertible(PyObject*); + static T& convert_ref(PyObject*, from_python_data&); + static T const& convert_cref(PyObject*, from_python_data&); + static T* convert_ptr(PyObject*, from_python_data&); + static T const* convert_cptr(PyObject*, from_python_data&); + + from_python_converter to_ref; + from_python_converter to_cref; + from_python_converter to_ptr; + from_python_converter to_cptr; }; // // implementations // template -void* class_unwrapper::can_convert(PyObject* p) const +class_from_python_converter::class_from_python_converter() + : to_ref(convertible, convert_ref) + , to_cref(convertible, convert_cref) + , to_ptr(convertible, convert_ptr) + , to_cptr(convertible, convert_cptr) +{} + +template +T& class_from_python_converter::convert_ref(PyObject*, from_python_data& x) +{ + return *static_cast(x.stage1); +} + +template +T const& class_from_python_converter::convert_cref(PyObject*, from_python_data& x) +{ + return *static_cast(x.stage1); +} + + +template +T* class_from_python_converter::convert_ptr(PyObject*, from_python_data& x) +{ + return static_cast(x.stage1); +} + +template +T const* class_from_python_converter::convert_cptr(PyObject*, from_python_data& x) +{ + return static_cast(x.stage1); +} + +template +void* class_from_python_converter::convertible(PyObject* p) { return objects::find_instance(p); } -template -T& class_unwrapper::convert(PyObject*, void* found, boost::type) const -{ - return *static_cast(found); -} - -template -T const& class_unwrapper::convert(PyObject*, void* found, boost::type) const -{ - return *static_cast(found); -} - -template -T* class_unwrapper::convert(PyObject*, void* found, boost::type) const -{ - return static_cast(found); -} - -template -T const* class_unwrapper::convert(PyObject*, void* found, boost::type) const -{ - return static_cast(found); -} - }}} // namespace boost::python::converter #endif // CLASS_DWA20011215_HPP diff --git a/include/boost/python/converter/registration.hpp b/include/boost/python/converter/registration.hpp index b8a6326b..39223d8a 100644 --- a/include/boost/python/converter/registration.hpp +++ b/include/boost/python/converter/registration.hpp @@ -9,6 +9,9 @@ # include # include # include +# include +# include +# include # include # ifdef BOOST_PYTHON_TRACE # include @@ -16,8 +19,9 @@ namespace boost { namespace python { namespace converter { -struct BOOST_PYTHON_DECL wrapper_base; -struct BOOST_PYTHON_DECL unwrapper_base; +template struct from_python_converter; +template struct target; +template struct source; // This class is really sort of a "templated namespace". It manages a // static data member which refers to the registry entry for T. This @@ -28,21 +32,74 @@ struct registration { public: // member functions // Return a converter which can convert the given Python object to - // T, or 0 if no such converter exists - static std::pair unwrapper(PyObject*); + // T, or 0 if no such converter exists. Fill in data with + // the result of the converter's check function + static from_python_converter const* get_from_python(PyObject*, void*& data); // Return a converter which can convert T to a Python object, or 0 // if no such converter exists - static wrapper_base* wrapper(); + static to_python_function::type get_to_python(); + static registry::entry* find_entry(); private: // helper functions static registry::entry* entry(); - static registry::entry* find_entry(); + static registry::entry* known_entry(); private: // data members static registry::entry* m_registry_entry; }; +namespace detail +{ + // An MPL BinaryMetaFunction class which initializes the + // registration entry for the target type of its 2nd argument. + struct setup_target_registration + { + template struct apply + { + typedef T type; + static void execute() + { + typedef typename target::type target_t; + registration::find_entry(); + } + }; + }; + + template + struct find_return_value_entry + { + static void execute() { registration::find_entry(); } + }; + + template <> + struct find_return_value_entry + { + static void execute() {} + }; + +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 + template <> + struct find_return_value_entry + { + static void execute() {} + }; +# endif +} + +template +void acquire_registrations(Sequence signature) +{ + typedef typename mpl::pop_front::sequence args; + typedef typename mpl::front::type return_type; + + mpl::for_each::execute(); + + typedef typename source::type return_source_type; + detail::find_return_value_entry::execute(); +} + + // because this is static POD data it will be initialized to zero template registry::entry* registration::m_registry_entry; @@ -50,33 +107,40 @@ registry::entry* registration::m_registry_entry; template registry::entry* registration::find_entry() { - return registry::find(type_id()); + return m_registry_entry = registry::find(type_id()); } template inline registry::entry* registration::entry() { if (!m_registry_entry) - m_registry_entry = find_entry(); + find_entry(); return m_registry_entry; } template -std::pair registration::unwrapper(PyObject* p) +inline registry::entry* registration::known_entry() { -# ifdef BOOST_PYTHON_TRACE - std::cout << "retrieving unwrapper for " << type_id() << std::endl; -# endif - return entry()->unwrapper(p); + assert(m_registry_entry != 0); + return m_registry_entry; } template -wrapper_base* registration::wrapper() +from_python_converter const* registration::get_from_python(PyObject* p, void*& data) +{ + return static_cast const*>( + known_entry()->get_from_python(p, data) + ); +} + +template +typename to_python_function::type registration::get_to_python() { # ifdef BOOST_PYTHON_TRACE std::cout << "retrieving wrapper for " << type_id() << std::endl; # endif - return entry()->wrapper(); + return reinterpret_cast::type>( + known_entry()->get_to_python()); } }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index 2023a732..21f31692 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -8,14 +8,15 @@ # include # include # include -# include +# include +# include # include # include namespace boost { namespace python { namespace converter { -struct BOOST_PYTHON_DECL wrapper_base; -struct BOOST_PYTHON_DECL unwrapper_base; +struct BOOST_PYTHON_DECL from_python_converter_base; +struct BOOST_PYTHON_DECL to_python_converter_base; // This namespace acts as a sort of singleton namespace registry @@ -31,43 +32,45 @@ namespace registry // Python object from_python to the C++ type with which this // converter is associated in the registry, or 0 if no such // converter exists. - std::pair unwrapper(PyObject*) const; + from_python_converter_base const* get_from_python(PyObject*, void*& data) const; - // Return a converter appropriate for converting a C++ object - // whose type this entry is associated with in the registry to a - // Python object, or 0 if no such converter exists. - wrapper_base* wrapper() const; + // Return a conversion function appropriate for converting a C++ + // object whose type this entry is associated with in the + // registry to a Python object, or 0 if no such converter + // exists. This function must be reinterpret_cast to the + // appropriate to_python_function type. + to_python_function_base get_to_python() const; // Conversion classes use these functions to register // themselves. - void insert(wrapper_base&); - void remove(wrapper_base&); + void insert(from_python_converter_base&); + void remove(from_python_converter_base&); - void insert(unwrapper_base&); - void remove(unwrapper_base&); + void insert(to_python_converter_base&); + void remove(to_python_converter_base&); private: // types - typedef std::list unwrappers; + typedef std::vector from_python_converters; private: // helper functions - unwrappers::iterator find(unwrapper_base const&); + from_python_converters::iterator find(from_python_converter_base const&); private: // data members // The collection of from_python converters for the associated // C++ type. - unwrappers m_unwrappers; + from_python_converters m_from_python_converters; // The unique to_python converter for the associated C++ type. - converter::wrapper_base* m_wrapper; + to_python_converter_base* m_to_python_converter; }; BOOST_PYTHON_DECL entry* find(type_id_t); - BOOST_PYTHON_DECL void insert(wrapper_base& x); - BOOST_PYTHON_DECL void insert(unwrapper_base& x); - BOOST_PYTHON_DECL void remove(wrapper_base& x); - BOOST_PYTHON_DECL void remove(unwrapper_base& x); + BOOST_PYTHON_DECL void insert(to_python_converter_base& x); + BOOST_PYTHON_DECL void insert(from_python_converter_base& x); + BOOST_PYTHON_DECL void remove(to_python_converter_base& x); + BOOST_PYTHON_DECL void remove(from_python_converter_base& x); } }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/source.hpp b/include/boost/python/converter/source.hpp index 94fdc5b8..9abf245f 100644 --- a/include/boost/python/converter/source.hpp +++ b/include/boost/python/converter/source.hpp @@ -20,15 +20,11 @@ namespace boost { namespace python { namespace converter { template struct source { - BOOST_STATIC_CONSTANT(bool, use_identity = (::boost::is_pointer::value)); - - typedef typename mpl::select_type< - use_identity - , T - , typename add_reference< + typedef + typename add_reference< typename add_const::type >::type - >::type type; + type; }; }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/unwrap.hpp b/include/boost/python/converter/unwrap.hpp index 3380d49d..eccb0992 100644 --- a/include/boost/python/converter/unwrap.hpp +++ b/include/boost/python/converter/unwrap.hpp @@ -1,3 +1,4 @@ +#error obsolete // Copyright David Abrahams 2001. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided @@ -27,9 +28,10 @@ struct BOOST_PYTHON_DECL unwrap_base : handle inline unwrap_base(PyObject* source, std::pair); inline PyObject* source() const; + inline void*& data(); + protected: inline PyObject*& source(); - inline void* data() const; private: // data members PyObject* m_source; @@ -117,7 +119,7 @@ inline unwrap_base::unwrap_base(PyObject* source, std::pair) const = 0; + virtual T convert(PyObject*, void*& data, boost::type) const = 0; }; // diff --git a/include/boost/python/converter/wrap.hpp b/include/boost/python/converter/wrap.hpp index eb23c6d3..b61fff19 100644 --- a/include/boost/python/converter/wrap.hpp +++ b/include/boost/python/converter/wrap.hpp @@ -1,3 +1,4 @@ +#error obsolete // Copyright David Abrahams 2001. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided diff --git a/include/boost/python/converter/wrapper.hpp b/include/boost/python/converter/wrapper.hpp index 5d4874d2..e20ed404 100644 --- a/include/boost/python/converter/wrapper.hpp +++ b/include/boost/python/converter/wrapper.hpp @@ -1,3 +1,4 @@ +#error obsolete // Copyright David Abrahams 2001. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index a330a939..04bca0af 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -11,6 +11,8 @@ #ifndef ARG_TUPLE_SIZE_DWA20011201_HPP # define ARG_TUPLE_SIZE_DWA20011201_HPP +# include + namespace boost { namespace python { namespace detail { // Computes (at compile-time) the number of elements that a Python @@ -223,16 +225,6 @@ struct arg_tuple_size // http://groups.yahoo.com/group/boost/message/5441 for // more examples -// This little package is used to transmit the number of arguments -// from the helper functions below to the sizeof() expression below. -// Because we can never have an array of fewer than 1 element, we -// add 1 to n and then subtract 1 from the result of sizeof() below. -template -struct char_array -{ - char elements[n+1]; -}; - // The following helper functions are never actually called, since // they are only used within a sizeof() expression, but the type of // their return value is used to discriminate between various free diff --git a/include/boost/python/detail/char_array.hpp b/include/boost/python/detail/char_array.hpp new file mode 100644 index 00000000..d68aea47 --- /dev/null +++ b/include/boost/python/detail/char_array.hpp @@ -0,0 +1,23 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CHAR_ARRAY_DWA2002129_HPP +# define CHAR_ARRAY_DWA2002129_HPP + +namespace boost { namespace python { namespace detail { + +// This little package is used to transmit the number of arguments +// from the helper functions below to the sizeof() expression below. +// Because we can never have an array of fewer than 1 element, we +// add 1 to n and then subtract 1 from the result of sizeof() below. +template +struct char_array +{ + char elements[n+1]; +}; + +}}} // namespace boost::python::detail + +#endif // CHAR_ARRAY_DWA2002129_HPP diff --git a/include/boost/python/detail/eval.hpp b/include/boost/python/detail/eval.hpp new file mode 100644 index 00000000..3e799507 --- /dev/null +++ b/include/boost/python/detail/eval.hpp @@ -0,0 +1,38 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef EVAL_DWA2002124_HPP +# define EVAL_DWA2002124_HPP + +namespace boost { namespace python { namespace detail { + +template struct undefined; +template +struct eval +{ +# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 + // based on the (non-conforming) MSVC trick from MPL + template + struct unarymetafunction_vc : UnaryMetaFunction {}; + + // illegal C++ which causes VC to admit that unarymetafunction_vc + // can have a nested template: + template<> + struct unarymetafunction_vc + { + template struct apply; + }; + + typedef typename unarymetafunction_vc< + ::boost::mpl::detail::msvc_never_true::value + >::template apply::type type; +# else + typedef typename UnaryMetaFunction::template apply::type type; +# endif +}; + +}}} // namespace boost::python::detail + +#endif // EVAL_DWA2002124_HPP diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 87aecac5..4aa228b5 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -14,8 +14,9 @@ //# include # include # include -# include # include +# include +# include namespace boost { namespace python { namespace detail { @@ -27,246 +28,291 @@ struct returning static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; // find the result converter - wrap_more r(c0); - if (!c0) return 0; - return r( ((*c0).*pmf)() ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); } template static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; // find the result converter - wrap_more r(c1); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; // find the result converter - wrap_more r(c2); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; // find the result converter - wrap_more r(c3); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; // find the result converter - wrap_more r(c4); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); - unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; + from_python c5(PyTuple_GET_ITEM(args, 5)); + if (!c5.convertible()) return 0; // find the result converter - wrap_more r(c5); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); } template static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; // find the result converter - wrap_more r(c0); - if (!c0) return 0; - return r( ((*c0).*pmf)() ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); } template static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; // find the result converter - wrap_more r(c1); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; // find the result converter - wrap_more r(c2); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; // find the result converter - wrap_more r(c3); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; // find the result converter - wrap_more r(c4); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); - unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; + from_python c5(PyTuple_GET_ITEM(args, 5)); + if (!c5.convertible()) return 0; // find the result converter - wrap_more r(c5); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); } template static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; // find the result converter - wrap_more r(c0); - if (!c0) return 0; - return r( ((*c0).*pmf)() ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); } template static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; // find the result converter - wrap_more r(c1); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; // find the result converter - wrap_more r(c2); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; // find the result converter - wrap_more r(c3); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; // find the result converter - wrap_more r(c4); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); - unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; + from_python c5(PyTuple_GET_ITEM(args, 5)); + if (!c5.convertible()) return 0; // find the result converter - wrap_more r(c5); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); } @@ -276,82 +322,97 @@ struct returning static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; // find the result converter - wrap_more r(c0); - if (!c0) return 0; - return r( ((*c0).*pmf)() ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); } template static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; // find the result converter - wrap_more r(c1); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; // find the result converter - wrap_more r(c2); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; // find the result converter - wrap_more r(c3); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; // find the result converter - wrap_more r(c4); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); - unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; + from_python c5(PyTuple_GET_ITEM(args, 5)); + if (!c5.convertible()) return 0; // find the result converter - wrap_more r(c5); - if (!c0) return 0; - return r( ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5) ); + to_python r; + return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); } # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -359,90 +420,104 @@ struct returning static PyObject* call(R (*pf)(), PyObject*, PyObject* /* keywords */ ) { // find the result converter - wrap c0; - if (!c0) return 0; + to_python c0; return c0( (*pf)() ); } template static PyObject* call(R (*pf)(A0), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; // find the result converter - wrap_more c1(c0); - if (!c0) return 0; - return c1( (*pf)(*c0) ); + to_python c1; + return c1( (*pf)(c0(PyTuple_GET_ITEM(args, 0))) ); } template static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; // find the result converter - wrap_more c2(c1); - if (!c0) return 0; - return c2( (*pf)(*c0, *c1) ); + to_python c2; + return c2( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1))) ); } template static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; // find the result converter - wrap_more c3(c2); - if (!c0) return 0; - return c3( (*pf)(*c0, *c1, *c2) ); + to_python c3; + return c3( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); } template static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; // find the result converter - wrap_more c4(c3); - if (!c0) return 0; - return c4( (*pf)(*c0, *c1, *c2, *c3) ); + to_python c4; + return c4( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); } template static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; // find the result converter - wrap_more c5(c4); - if (!c0) return 0; - return c5( (*pf)(*c0, *c1, *c2, *c3, *c4) ); + to_python c5; + return c5( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); } template static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); - unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; + from_python c5(PyTuple_GET_ITEM(args, 5)); + if (!c5.convertible()) return 0; // find the result converter - wrap_more c6(c5); - if (!c0) return 0; - return c6( (*pf)(*c0, *c1, *c2, *c3, *c4, *c5) ); + to_python c6; + return c6( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); } }; @@ -454,75 +529,90 @@ struct returning static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3, *c4); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); - unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; + from_python c5(PyTuple_GET_ITEM(args, 5)); + if (!c5.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); return detail::none(); } @@ -530,75 +620,90 @@ struct returning static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3, *c4); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); - unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; + from_python c5(PyTuple_GET_ITEM(args, 5)); + if (!c5.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); return detail::none(); } @@ -606,75 +711,90 @@ struct returning static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3, *c4); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); - unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; + from_python c5(PyTuple_GET_ITEM(args, 5)); + if (!c5.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); return detail::none(); } @@ -685,75 +805,90 @@ struct returning static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3, *c4); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); return detail::none(); } template static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); - unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; + from_python c5(PyTuple_GET_ITEM(args, 5)); + if (!c5.convertible()) return 0; - if (!c0) return 0; - ((*c0).*pmf)(*c1, *c2, *c3, *c4, *c5); + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); return detail::none(); } @@ -768,75 +903,90 @@ struct returning static PyObject* call(R (*pf)(A0), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; - if (!c0) return 0; - (*pf)(*c0); + (*pf)(c0(PyTuple_GET_ITEM(args, 0))); return detail::none(); } template static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; - if (!c0) return 0; - (*pf)(*c0, *c1); + (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1))); return detail::none(); } template static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; - if (!c0) return 0; - (*pf)(*c0, *c1, *c2); + (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); return detail::none(); } template static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; - if (!c0) return 0; - (*pf)(*c0, *c1, *c2, *c3); + (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); return detail::none(); } template static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; - if (!c0) return 0; - (*pf)(*c0, *c1, *c2, *c3, *c4); + (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); return detail::none(); } template static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); - unwrap_more c1(PyTuple_GET_ITEM(args, 1), c0); - unwrap_more c2(PyTuple_GET_ITEM(args, 2), c1); - unwrap_more c3(PyTuple_GET_ITEM(args, 3), c2); - unwrap_more c4(PyTuple_GET_ITEM(args, 4), c3); - unwrap_more c5(PyTuple_GET_ITEM(args, 5), c4); + from_python c0(PyTuple_GET_ITEM(args, 0)); + if (!c0.convertible()) return 0; + from_python c1(PyTuple_GET_ITEM(args, 1)); + if (!c1.convertible()) return 0; + from_python c2(PyTuple_GET_ITEM(args, 2)); + if (!c2.convertible()) return 0; + from_python c3(PyTuple_GET_ITEM(args, 3)); + if (!c3.convertible()) return 0; + from_python c4(PyTuple_GET_ITEM(args, 4)); + if (!c4.convertible()) return 0; + from_python c5(PyTuple_GET_ITEM(args, 5)); + if (!c5.convertible()) return 0; - if (!c0) return 0; - (*pf)(*c0, *c1, *c2, *c3, *c4, *c5); + (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); return detail::none(); } }; diff --git a/include/boost/python/detail/signature.hpp b/include/boost/python/detail/signature.hpp new file mode 100644 index 00000000..db8b39a4 --- /dev/null +++ b/include/boost/python/detail/signature.hpp @@ -0,0 +1,217 @@ +// (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// This work was funded in part by Lawrence Berkeley and Lawrence +// Livermore National Labs +// +// This file generated for 5-argument member functions and 6-argument free +// functions by gen_signature.py + +#ifndef SIGNATURE_DWA2002128_HPP +# define SIGNATURE_DWA2002128_HPP + +# include + +namespace boost { namespace python { namespace detail { + +template +mpl::type_list +signature(R (*)()) +{ + return mpl::type_list(); +} + +template +mpl::type_list +signature(R (*)(A0)) +{ + return mpl::type_list(); +} + +template +mpl::type_list +signature(R (*)(A0, A1)) +{ + return mpl::type_list(); +} + +template +mpl::type_list +signature(R (*)(A0, A1, A2)) +{ + return mpl::type_list(); +} + +template +mpl::type_list +signature(R (*)(A0, A1, A2, A3)) +{ + return mpl::type_list(); +} + +template +mpl::type_list +signature(R (*)(A0, A1, A2, A3, A4)) +{ + return mpl::type_list(); +} + +template +mpl::type_list +signature(R (*)(A0, A1, A2, A3, A4, A5)) +{ + return mpl::type_list(); +} +template +mpl::type_list signature(R (A0::*)()) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1)) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2)) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3)) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3, A4)) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5)) +{ + return mpl::type_list(); +} + + +template +mpl::type_list signature(R (A0::*)() const) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1) const) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2) const) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3) const) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3, A4) const) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5) const) +{ + return mpl::type_list(); +} + + +template +mpl::type_list signature(R (A0::*)() volatile) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1) volatile) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2) volatile) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3) volatile) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3, A4) volatile) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5) volatile) +{ + return mpl::type_list(); +} + + +template +mpl::type_list signature(R (A0::*)() const volatile) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1) const volatile) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2) const volatile) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3) const volatile) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3, A4) const volatile) +{ + return mpl::type_list(); +} + +template +mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5) const volatile) +{ + return mpl::type_list(); +} + +}}} // namespace boost::python::detail + +#endif // SIGNATURE_DWA2002128_HPP + diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index f9ffd5c3..dfd11865 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -8,8 +8,10 @@ # include # include +# include # include # include +# include # include # include # include @@ -19,6 +21,7 @@ namespace boost { namespace python { template objects::function* make_function(F f) { + converter::acquire_registrations(detail::signature(f)); return new objects::function( objects::py_function( ::boost::bind(detail::caller(), f, _1, _2)) @@ -29,6 +32,10 @@ template objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0) { enum { nargs = mpl::size::value }; + + typedef typename mpl::push_front::sequence signature; + converter::acquire_registrations(signature()); + return new objects::function( objects::py_function( ::boost::bind(detail::caller(), diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index d4ba4b6d..d5978af7 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -24,7 +24,7 @@ struct class_converters class_converters(ref const& python_class); private: // data members - converter::class_unwrapper m_unwrapper; + converter::class_from_python_converter m_unwrapper; class_wrapper m_wrapper; }; diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index f199a99f..26334bc7 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -8,31 +8,31 @@ # include # include -# include # include +# include # include namespace boost { namespace python { namespace objects { template struct class_wrapper - : converter::wrapper + : converter::to_python_converter { class_wrapper(ref const& type_) - : m_class_object(type_) + : converter::to_python_converter(convert) + , m_class_object_keeper(type_) { -# ifndef NDEBUG assert(type_->ob_type == (PyTypeObject*)class_metatype().get()); -# endif // NDEBUG + m_class_object = (PyTypeObject*)type_.get(); } - PyObject* convert(T const& x) const + static PyObject* convert(T const& x) { // Don't call the type to do the construction, since that // would require the registration of an __init__ copy // constructor. Instead, just construct the object in place. PyObject* raw_result = (PyObject*)PyObject_New( - instance, (PyTypeObject*)m_class_object.get()); + instance, m_class_object); if (raw_result == 0) return 0; @@ -53,9 +53,12 @@ struct class_wrapper } private: - ref m_class_object; + ref m_class_object_keeper; + static PyTypeObject* m_class_object; }; +template +PyTypeObject* class_wrapper::m_class_object; }}} // namespace boost::python::objects diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 76b3a5f4..8a72a880 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -10,36 +10,10 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { - -template struct undefined; -template -struct eval -{ -# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 - // based on the (non-conforming) MSVC trick from MPL - template - struct unarymetafunction_vc : UnaryMetaFunction {}; - - // illegal C++ which causes VC to admit that unarymetafunction_vc - // can have a nested template: - template<> - struct unarymetafunction_vc - { - template struct apply; - }; - - typedef typename unarymetafunction_vc< - ::boost::mpl::detail::msvc_never_true::value - >::template apply::type type; -# else - typedef typename UnaryMetaFunction::template apply::type type; -# endif -}; - - template struct make_holder; template <> @@ -48,7 +22,7 @@ struct make_holder<0> template struct apply { - typedef typename eval::type holder; + typedef typename detail::eval::type holder; static void execute( PyObject* p) { @@ -64,7 +38,7 @@ struct make_holder<1> template struct apply { - typedef typename eval::type holder; + typedef typename detail::eval::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; @@ -83,7 +57,7 @@ struct make_holder<2> template struct apply { - typedef typename eval::type holder; + typedef typename detail::eval::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -103,7 +77,7 @@ struct make_holder<3> template struct apply { - typedef typename eval::type holder; + typedef typename detail::eval::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index d6e38a79..85e3797f 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -22,43 +22,116 @@ struct value_holder : instance_holder template value_holder(PyObject*, A1 a1) - : m_held(a1) {} + : m_held( + (unwrap_reference::type&)(a1) + ) + {} template value_holder(PyObject*, A1 a1, A2 a2) - : m_held(a1, a2) {} + : m_held( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + ) + {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3) - : m_held(a1, a2, a3) {} + : m_held( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + ) + {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) - : m_held(a1, a2, a3, a4) {} + : m_held( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + ) + {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - : m_held(a1, a2, a3, a4, a5) {} + : m_held( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - : m_held(a1, a2, a3, a4, a5, a6) {} + : m_held( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + , (unwrap_reference::type&)(a6) + ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) - : m_held(a1, a2, a3, a4, a5, a6, a7) {} + : m_held( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + , (unwrap_reference::type&)(a6) + , (unwrap_reference::type&)(a7) + ) + {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) - : m_held(a1, a2, a3, a4, a5, a6, a7, a8) {} + : m_held( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + , (unwrap_reference::type&)(a6) + , (unwrap_reference::type&)(a7) + , (unwrap_reference::type&)(a8) + ) + {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) - : m_held(a1, a2, a3, a4, a5, a6, a7, a8, a9) {} + : m_held( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + , (unwrap_reference::type&)(a6) + , (unwrap_reference::type&)(a7) + , (unwrap_reference::type&)(a8) + , (unwrap_reference::type&)(a9) + ) + {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) - : m_held(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} + : m_held( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + , (unwrap_reference::type&)(a6) + , (unwrap_reference::type&)(a7) + , (unwrap_reference::type&)(a8) + , (unwrap_reference::type&)(a9) + , (unwrap_reference::type&)(a10) + ) + {} private: // required holder implementation void* holds(converter::type_id_t); diff --git a/include/boost/python/objects.hpp b/include/boost/python/objects.hpp index 93173462..8b230478 100644 --- a/include/boost/python/objects.hpp +++ b/include/boost/python/objects.hpp @@ -354,6 +354,8 @@ struct BOOST_PYTHON_DECL list_slice_proxy }} // namespace boost::python +# ifndef BOOST_PYTHON_V2 + BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE BOOST_PYTHON_DECL PyObject* to_python(const boost::python::tuple&); @@ -389,5 +391,5 @@ inline boost::python::dictionary from_python(PyObject* p, boost::python::type -# include +# include +# include +# include +# include # include -# include # include # include # ifdef BOOST_PYTHON_TRACE @@ -23,6 +24,15 @@ namespace // registry_t& entries() { static registry_t registry; + static bool builtin_converters_initialized = false; + if (!builtin_converters_initialized) + { + // Make this true early because registering the builtin + // converters will cause recursion. + builtin_converters_initialized = true; + + initialize_builtin_converters(); + } return registry; } } // namespace @@ -35,124 +45,127 @@ namespace registry } entry::entry() - : m_wrapper(0) + : m_to_python_converter(0) { } entry::~entry() { - if (m_wrapper != 0) - m_wrapper->m_can_unregister = false; + if (m_to_python_converter != 0) + m_to_python_converter->m_can_unregister = false; - for (unwrappers::iterator p = m_unwrappers.begin(); p != m_unwrappers.end(); ++p) + for (from_python_converters::iterator p = m_from_python_converters.begin() + ; p != m_from_python_converters.end() + ; ++p) { (*p)->m_can_unregister = false; } } - std::pair - entry::unwrapper(PyObject* p) const - { - unwrapper_base* body = 0; - void* data = 0; - - for (unwrappers::const_iterator q = m_unwrappers.begin(), - finish = m_unwrappers.end(); + from_python_converter_base const* + entry::get_from_python(PyObject* p, void*& data_out) const + { + for (from_python_converters::const_iterator q = m_from_python_converters.begin(), + finish = m_from_python_converters.end(); q != finish; ++q) { - data = (*q)->can_convert(p); + void* const data = (*q)->convertible(p); if (data != 0) { - body = *q; + data_out = data; + return *q; break; } } - return std::make_pair(body,data); + return 0; } - wrapper_base* entry::wrapper() const + to_python_function_base entry::get_to_python() const { - return m_wrapper; + return m_to_python_converter + ? m_to_python_converter->converter() + : 0; } - entry::unwrappers::iterator entry::find(unwrapper_base const& x) + entry::from_python_converters::iterator entry::find(from_python_converter_base const& x) { - return std::find(m_unwrappers.begin(), m_unwrappers.end(), &x); + return std::find(m_from_python_converters.begin(), m_from_python_converters.end(), &x); } - void entry::insert(unwrapper_base& x) + void entry::insert(from_python_converter_base& x) { - unwrappers::iterator p = this->find(x); + from_python_converters::iterator p = this->find(x); - assert(p == m_unwrappers.end()); - if (p != m_unwrappers.end()) + if (p != m_from_python_converters.end()) { + assert(!"converter already registered"); throw std::runtime_error( "trying to register unrapper which is already registered"); } - m_unwrappers.push_back(&x); + + m_from_python_converters.push_back(&x); } - void entry::remove(unwrapper_base& x) + void entry::remove(from_python_converter_base& x) { - unwrappers::iterator p = find(x); + from_python_converters::iterator p = find(x); // Be sure we're not removing a converter which hasn't been // registered. - assert(p != m_unwrappers.end()); - if (p == m_unwrappers.end()) + if (p == m_from_python_converters.end()) { + assert(!"trying to unregister from_python_converter which is not registered"); throw std::runtime_error( - "trying to unregister unwrapper which is not registered"); + "trying to unregister from_python_converter which is not registered"); } - m_unwrappers.erase(p); + m_from_python_converters.erase(p); } - void entry::insert(wrapper_base& x) + void entry::insert(to_python_converter_base& x) { - assert(m_wrapper == 0); // we have a problem otherwise - if (m_wrapper != 0) + assert(m_to_python_converter == 0); // we have a problem otherwise + if (m_to_python_converter != 0) { throw std::runtime_error( - "trying to register wrapper for a type which already has a registered wrapper"); + "trying to register to_python_converter for a type which already has a registered to_python_converter"); } - m_wrapper = &x; + m_to_python_converter = &x; } - void entry::remove(wrapper_base& x) + void entry::remove(to_python_converter_base& x) { - assert(m_wrapper == &x); - if (m_wrapper != &x) + assert(m_to_python_converter == &x); + if (m_to_python_converter != &x) { throw std::runtime_error( - "trying to unregister a wrapper which is not registered"); + "trying to unregister a to_python_converter which is not registered"); } - m_wrapper = 0; + m_to_python_converter = 0; } - void insert(wrapper_base& w) + void insert(to_python_converter_base& w) { # ifdef BOOST_PYTHON_TRACE - std::cout << "inserting wrapper for " << w.key() << std::endl; + std::cout << "inserting to_python_converter for " << w.key() << std::endl; # endif find(w.key())->insert(w); } - void insert(unwrapper_base& u) + void insert(from_python_converter_base& u) { # ifdef BOOST_PYTHON_TRACE - std::cout << "inserting unwrapper for " << u.key() << std::endl; + std::cout << "inserting from_python_converter for " << u.key() << std::endl; # endif find(u.key())->insert(u); } - void remove(wrapper_base& w) + void remove(to_python_converter_base& w) { find(w.key())->remove(w); } - void remove(unwrapper_base& u) + void remove(from_python_converter_base& u) { find(u.key())->remove(u); } diff --git a/src/gen_arg_tuple_size.py b/src/gen_arg_tuple_size.py index 5edd3286..9de332ab 100644 --- a/src/gen_arg_tuple_size.py +++ b/src/gen_arg_tuple_size.py @@ -42,6 +42,8 @@ def gen_arg_tuple_size(member_function_args, free_function_args = None): #ifndef ARG_TUPLE_SIZE_DWA20011201_HPP # define ARG_TUPLE_SIZE_DWA20011201_HPP +# include + namespace boost { namespace python { namespace detail { // Computes (at compile-time) the number of elements that a Python @@ -85,16 +87,6 @@ struct arg_tuple_size // http://groups.yahoo.com/group/boost/message/5441 for // more examples -// This little package is used to transmit the number of arguments -// from the helper functions below to the sizeof() expression below. -// Because we can never have an array of fewer than 1 element, we -// add 1 to n and then subtract 1 from the result of sizeof() below. -template -struct char_array -{ - char elements[n+1]; -}; - // The following helper functions are never actually called, since // they are only used within a sizeof() expression, but the type of // their return value is used to discriminate between various free diff --git a/src/gen_signature.py b/src/gen_signature.py new file mode 100644 index 00000000..1af3437d --- /dev/null +++ b/src/gen_signature.py @@ -0,0 +1,90 @@ +# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +# distribute this software is granted provided this copyright notice appears +# in all copies. This software is provided "as is" without express or implied +# warranty, and with no claim as to its suitability for any purpose. +# +# This work was funded in part by Lawrence Berkeley National Labs + +from gen_function import * +import string + +header = '''// (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// This work was funded in part by Lawrence Berkeley and Lawrence +// Livermore National Labs +// +// This file generated for %d-argument member functions and %d-argument free +// functions by gen_signature.py +''' + +_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') + +_suffix = { + '': ''' +// Metrowerks thinks this creates ambiguities +# if !defined(__MWERKS__) || __MWERKS__ > 0x2406 +''', ' const volatile': ''' +# endif // __MWERKS__ +''' + }; + +def gen_arg_tuple_size(member_function_args, free_function_args = None): + if free_function_args is None: + free_function_args = member_function_args + 1 + + return_none = '''; + return detail::none();''' + + return (header % (member_function_args, free_function_args) + + ''' +#ifndef SIGNATURE_DWA2002128_HPP +# define SIGNATURE_DWA2002128_HPP + +# include + +namespace boost { namespace python { namespace detail { +''' + + + gen_functions(''' +template +mpl::type_list +signature(R (*)(%(A%n%:, %))) +{ + return mpl::type_list() +} +''', free_function_args) + + + reduce(lambda x,y: x+'\n'+y + , map( + lambda cv: gen_functions( +'''template +mpl::type_list signature(R (A0::*)(%(A%+%:, %))%1) +{ + return mpl::type_list(); +} + +''', member_function_args, cv) + , _cv_qualifiers)) + '''}}} // namespace boost::python::detail + +#endif // SIGNATURE_DWA2002128_HPP +''') + +if __name__ == '__main__': + import sys + + if len(sys.argv) == 1: + member_function_args = 5 + free_function_args = 6 + else: + member_function_args = int(sys.argv[1]) + if len(sys.argv) > 2: + free_function_args = int(sys.argv[2]) + else: + free_function_args = member_function_args + + print gen_arg_tuple_size(member_function_args, free_function_args) + + diff --git a/src/gen_value_holder.py b/src/gen_value_holder.py new file mode 100644 index 00000000..b01e2c0e --- /dev/null +++ b/src/gen_value_holder.py @@ -0,0 +1,35 @@ +# Copyright David Abrahams 2002. Permission to copy, use, modify, +# sell and distribute this software is granted provided this +# copyright notice appears in all copies. This software is provided +# "as is" without express or implied warranty, and with no claim as +# to its suitability for any purpose. +# +# This work was funded in part by Lawrence Livermore National Labs + +from gen_function import * +import string + +def _generate(member_function_args, free_function_args = None): + return ('''// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef VALUE_HOLDER_DWA20011215_HPP +# define VALUE_HOLDER_DWA20011215_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace objects { + +template +struct value_holder : instance_holder +{ + // Forward construction to the held object +''' + + + gen_functions( diff --git a/src/object/class.cpp b/src/object/class.cpp index b928ba66..de3e32f5 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -46,7 +46,7 @@ PyTypeObject class_metatype_object = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | // Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ diff --git a/test/m1.cpp b/test/m1.cpp index 7f88af2b..6b4c55e1 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -4,19 +4,18 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. + #include "simple_type.hpp" #include "complicated.hpp" -#include -#include -#include -#include #include #include #include +#include #include -#include +//#include #include -#include +#include +#include #include #include #include @@ -61,9 +60,12 @@ PyObject* new_noddy() } // Simple is a wrapper around a struct simple, which just contains a char* -struct SimpleObject : PyObject +struct SimpleObject { + PyObject_HEAD simple x; + + static simple& extract(SimpleObject& o) { return o.x; } }; PyTypeObject SimpleType = { @@ -72,7 +74,7 @@ PyTypeObject SimpleType = { "Simple", sizeof(SimpleObject), 0, - dealloc, /*tp_dealloc*/ + dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ @@ -98,120 +100,38 @@ PyObject* new_simple() // description of how the type parameters to wrapper<> and unwrapper<> // are selected. // - -// Wrap an int by converting it to a Python Int -struct int_wrapper - : boost::python::converter::wrapper -{ - PyObject* convert(int const& x) const - { - return PyInt_FromLong(x); - } -}; +using boost::python::converter::from_python_data; // Wrap a simple by converting it to a Simple -struct simple_wrapper - : boost::python::converter::wrapper +PyObject* simple_to_python(simple const& x) { - PyObject* convert(simple const& x) const - { - SimpleObject* p = PyObject_New(SimpleObject, &SimpleType); - p->x = x; - return p; - } -}; + SimpleObject* p = PyObject_New(SimpleObject, &SimpleType); + p->x = x; + return (PyObject*)p; +} + // wrap a mutable reference to a simple by converting it to a // Simple. Normally we wouldn't do it this way, since modifications to // the result clearly don't change the original object, but here we're // just proving that the mechanism works. -struct simple_ref_wrapper - : boost::python::converter::wrapper +PyObject* simple_ref_to_python(simple& x) { - PyObject* convert(simple& x) const - { - SimpleObject* p = PyObject_New(SimpleObject, &SimpleType); - p->x = x; - return p; - } -}; + SimpleObject* p = PyObject_New(SimpleObject, &SimpleType); + p->x = x; + return (PyObject*)p; +} -// extract an int from a Python Int by converting it to an int. Since -// int is a scalar type, we convert by-value. Since Python Ints are -// immutable, there's no non-const reference converter. -struct native_int_unwrapper - : boost::python::converter::unwrapper +int noddy_to_int(PyObject* p, from_python_data&) { - void* can_convert(PyObject* p) const - { - return PyInt_Check(p) ? non_null : 0; - } - - int convert(PyObject* p, void*, boost::type) const - { - return PyInt_AsLong(p); - } -}; - -// Extract an int from a Noddy -struct noddy_int_unwrapper - : boost::python::converter::unwrapper -{ - void* can_convert(PyObject* p) const - { - return p->ob_type == &NoddyType ? non_null : 0; - } - - int convert(PyObject* p, void*, boost::type) const - { - return static_cast(p)->x; - } -}; + return static_cast(p)->x; +} // Extract a mutable reference to an int from a Noddy. -struct noddy_int_ref_unwrapper - : boost::python::converter::unwrapper +int& noddy_to_int_ref(PyObject* p, from_python_data&) { - void* can_convert(PyObject* p) const - { - return p->ob_type == &NoddyType ? non_null : 0; - } - - int& convert(PyObject* p, void*, boost::type) const - { - return static_cast(p)->x; - } -}; - -// Extract a mutable reference to a simple from a Simple -struct simple_ref_unwrapper - : boost::python::converter::unwrapper -{ - void* can_convert(PyObject* p) const - { - return p->ob_type == &SimpleType ? non_null : 0; - } - - simple& convert(PyObject* p, void*, boost::type) const - { - return static_cast(p)->x; - } -}; - -// Extract a const reference to a simple from a Simple -struct simple_const_ref_unwrapper - : boost::python::converter::unwrapper -{ - void* can_convert(PyObject* p) const - { - return p->ob_type == &SimpleType ? non_null : 0; - } - - simple const& convert(PyObject* p, void*, boost::type) const - { - return static_cast(p)->x; - } -}; + return static_cast(p)->x; +} // // Some C++ functions to expose to Python @@ -232,6 +152,7 @@ simple const& g(simple const& x) struct A { A() : x(0) {} + virtual ~A() {} char const* name() { return "A"; } int x; }; @@ -268,19 +189,38 @@ BOOST_PYTHON_MODULE_INIT(m1) { using boost::python::module; using boost::python::class_; + using boost::python::converter::to_python_converter; + using boost::python::converter::from_python_converter; + using boost::python::reference_from_python; + using boost::python::value_from_python; + using boost::python::type_from_python; + using boost::python::get_member; // Create the converters; they are self-registering/unregistering. - static int_wrapper wrap_int; - static simple_wrapper wrap_simple; - static native_int_unwrapper unwrap_int1; - static noddy_int_unwrapper unwrap_int2; - static noddy_int_ref_unwrapper unwrap_int3; - static simple_ref_unwrapper unwrap_simple; - static simple_const_ref_unwrapper unwrap_simple_const_ref; - static simple_ref_wrapper wrap_simple_ref; + static to_python_converter c1(simple_to_python); + + static from_python_converter c2( + &(boost::python::type_from_python<&NoddyType>::convertible), noddy_to_int); + + static from_python_converter c3( + &(boost::python::type_from_python<&NoddyType>::convertible), noddy_to_int_ref); + + static boost::python::reference_from_python< + &SimpleType + , simple + , SimpleObject + , &SimpleObject::extract + > + unwrap_simple; + + static to_python_converter simple_ref_wrapper(simple_ref_to_python); module m1("m1"); + typedef boost::python::objects::pointer_holder_generator< + boost::python::objects::shared_ptr_generator + > use_shared_ptr; + m1 // Insert the metaclass for all extension classes .setattr("xclass", boost::python::objects::class_metatype()) @@ -303,7 +243,7 @@ BOOST_PYTHON_MODULE_INIT(m1) .def("take_d", take_d) .add( - class_("A") + class_, use_shared_ptr>("A") .def_init() .def("name", &A::name) ) @@ -314,13 +254,13 @@ BOOST_PYTHON_MODULE_INIT(m1) // or "C" below if we make them part of the same chain m1 .add( - class_ >("B") + class_, use_shared_ptr>("B") .def_init() .def("name", &B::name) ) .add( - class_ >("C") + class_, use_shared_ptr>("C") .def_init() .def("name", &C::name) ) @@ -328,7 +268,7 @@ BOOST_PYTHON_MODULE_INIT(m1) m1 .add( - class_ >("D") + class_, use_shared_ptr>("D") .def_init() .def("name", &D::name) ) diff --git a/test/m2.cpp b/test/m2.cpp index d70b0c13..be2934e0 100644 --- a/test/m2.cpp +++ b/test/m2.cpp @@ -7,13 +7,9 @@ // This module exercises the converters exposed in m1 at a low level // by exposing raw Python extension functions that use wrap<> and // unwrap<> objects. -#include #include #include "simple_type.hpp" -using boost::python::wrap; -using boost::python::unwrap; - // Get a simple (by value) from the argument, and return the // string it holds. PyObject* unwrap_simple(simple x) From 1f128575514a887278e0b5ceaffbb43e1d327529 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 30 Jan 2002 22:12:07 +0000 Subject: [PATCH 0212/1042] initial checkin [SVN r12591] --- .../boost/python/reference_from_python.hpp | 57 ++++++++++++++++++ include/boost/python/value_from_python.hpp | 60 +++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 include/boost/python/reference_from_python.hpp create mode 100644 include/boost/python/value_from_python.hpp diff --git a/include/boost/python/reference_from_python.hpp b/include/boost/python/reference_from_python.hpp new file mode 100644 index 00000000..8e7b9b6c --- /dev/null +++ b/include/boost/python/reference_from_python.hpp @@ -0,0 +1,57 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef REFERENCE_FROM_PYTHON_DWA2002130_HPP +# define REFERENCE_FROM_PYTHON_DWA2002130_HPP + +# include +# include + +namespace boost { namespace python { + +// Utility which produces a member extractor function on platforms +// other than VC6. +template +struct get_member +{ + static Member& execute(Class* c) + { + return c->*mp; + } +}; + +template < + PyTypeObject const* python_type + , class Value + , class PythonObject + , Value& (*extract)(PythonObject&) + > +struct reference_from_python : type_from_python +{ + reference_from_python() + : m_mutable_converter(convertible, convert_mutable) + , m_const_converter(convertible, convert_const) + {} + + static Value& convert_mutable(PyObject* op, converter::from_python_data&) + { + return extract(*(PythonObject*)op); + } + + static Value const& convert_const(PyObject* op, converter::from_python_data&) + { + return extract(*(PythonObject*)op); + } + + private: + typedef converter::from_python_converter mutable_converter; + typedef converter::from_python_converter const_converter; + mutable_converter m_mutable_converter; + const_converter m_const_converter; +}; + +}} // namespace boost::python + +#endif // REFERENCE_FROM_PYTHON_DWA2002130_HPP diff --git a/include/boost/python/value_from_python.hpp b/include/boost/python/value_from_python.hpp new file mode 100644 index 00000000..bb4ecf87 --- /dev/null +++ b/include/boost/python/value_from_python.hpp @@ -0,0 +1,60 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef VALUE_FROM_PYTHON_DWA2002130_HPP +# define VALUE_FROM_PYTHON_DWA2002130_HPP + +# include +# include +# include + +namespace boost { namespace python { + +template +struct value_from_python +{ + value_from_python() + : m_converter( + &Derived::convertible + , &Derived::convert + + // Change this to a compile-time check later to avoid + // generating destroy function + , has_trivial_destructor::value ? 0 : &Derived::destroy + ) + { + // Scalar types are really converted by-value; the formulation + // is much simpler. + BOOST_STATIC_ASSERT(!(is_scalar::value)); + } + + static void* get_storage(converter::from_python_data& data) + { + return converter::get_storage(data); + } + + // Mark successful construction + static void constructed(converter::from_python_data& data) + { + data.stage1 = get_storage(data); + } + + inline static void destroy(converter::from_python_data& data) + { + // Get the location of the storage for + void* storage = get_storage(data); + + // Check for successful construction + if (data.stage1 == storage) + static_cast(storage)->~T(); + } + + private: + converter::from_python_converter m_converter; +}; + +}} // namespace boost::python + +#endif // VALUE_FROM_PYTHON_DWA2002130_HPP From 88a8721b89ba445bf83cd2f3272c036f34820302 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 30 Jan 2002 22:18:50 +0000 Subject: [PATCH 0213/1042] initial checkin [SVN r12592] --- src/converter/builtin_converters.cpp | 153 +++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/converter/builtin_converters.cpp diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp new file mode 100644 index 00000000..07a00259 --- /dev/null +++ b/src/converter/builtin_converters.cpp @@ -0,0 +1,153 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include +#include +#include +#include +//#include +#include + +namespace boost { namespace python { namespace converter { + +namespace +{ + struct int_value_functions_base + { + static void* convertible(PyObject* obj) + { + PyNumberMethods* number_methods = obj->ob_type->tp_as_number; + + return number_methods && number_methods->nb_int + ? &number_methods->nb_int : 0; + } + }; + + template + struct int_value_functions : int_value_functions_base + { + static T convert(PyObject* obj, from_python_data& data) + { + unaryfunc f = *static_cast(data.stage1); + ref int_object(f(obj)); + return numeric_cast(PyInt_AsLong(int_object.get())); + } + }; + + struct cstring_value_functions + { + static void* convertible(PyObject* obj) + { + return PyString_Check(obj) ? obj : 0; + } + + static char const* convert(PyObject* obj, from_python_data&) + { + return PyString_AsString(obj); + } + }; + + char constructed; + + struct string_cref_functions + { + typedef std::string const& result_type; + + static void* convertible(PyObject* obj) + { + return obj->ob_type->tp_str ? &obj->ob_type->tp_str : 0; + } + + static std::string const& convert( + PyObject* obj, from_python_data& data) + { + ref string_object((**static_cast(data.stage1))(obj)); + void* storage = get_storage(data); + std::string* p = new (storage) std::string(PyString_AsString(string_object.get())); + + // note that construction is successful. + data.stage1 = &constructed; + return *p; + } + + static void destroy(from_python_data& data) + { + if (data.stage1 == &constructed) + { + typedef std::string string_t; + void* storage = get_storage(data); + ((string_t*)storage)->~string_t(); + } + } + }; + + template + struct rvalue_const_ref_functions : Base + { + static T const& convert(PyObject* obj, from_python_data& data) + { + void* storage = get_storage(data); + T* p = new (storage) T(Base::convert(obj,data)); + + // note that construction is successful. + data.stage1 = &constructed; + return *p; + } + }; + + struct register_int_converters + { + template + struct apply + { + typedef void type; + + static void execute() + { + typedef int_value_functions value_functions; + typedef rvalue_const_ref_functions cref_functions; + + static from_python_converter value_from_python( + value_functions::convertible + , value_functions::convert); + static from_python_converter cref_from_python( + cref_functions::convertible + , cref_functions::convert); + }; + }; + }; +} + +#define REGISTER_INT_CONVERTERS(U) register_int_converters::apply::execute() +#define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U) + + +void initialize_builtin_converters() +{ + REGISTER_INT_CONVERTERS2(char); + REGISTER_INT_CONVERTERS2(short); + REGISTER_INT_CONVERTERS2(int); + REGISTER_INT_CONVERTERS2(long); +// mpl::for_each::execute(); + + static from_python_converter cstring_from_python( + &cstring_value_functions::convertible + , &cstring_value_functions::convert); + + static from_python_converter cstring_cref_from_python( + &rvalue_const_ref_functions::convertible + , &rvalue_const_ref_functions::convert); + + static from_python_converter string_cref_from_python( + &string_cref_functions::convertible + , &string_cref_functions::convert + , &string_cref_functions::destroy); +} + +}}} // namespace boost::python::converter From 6a75fa83b5b6fab78dbe915563fffc5bb298cf1d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 31 Jan 2002 05:53:54 +0000 Subject: [PATCH 0214/1042] New conversion methods, builtin converters ---------------------------------------------------------------------- Committing in . Modified Files: boost/python/reference_from_python.hpp boost/python/value_from_python.hpp boost/python/converter/body.hpp boost/python/converter/handle.hpp libs/python/src/converter/builtin_converters.cpp libs/python/test/m1.cpp libs/python/test/m2.cpp Added Files: boost/python/converter/builtin_converters.hpp boost/python/converter/builtin_to_python_converters.hpp boost/python/converter/from_python.hpp boost/python/converter/from_python_data.hpp boost/python/converter/from_python_function.hpp boost/python/converter/to_python.hpp boost/python/converter/to_python_function.hpp boost/python/object/auto_ptr_generator.hpp boost/python/object/pointer_holder.hpp libs/python/src/converter/from_python.cpp libs/python/src/converter/to_python.cpp libs/python/test/test_builtin_converters.cpp libs/python/test/test_builtin_converters.py Removed Files: boost/python/convert.hpp boost/python/converter/unwrap.hpp boost/python/converter/unwrapper.hpp boost/python/converter/wrap.hpp boost/python/converter/wrapper.hpp boost/python/object/class_unwrapper.hpp ---------------------------------------------------------------------- [SVN r12596] --- include/boost/python/convert.hpp | 84 ------- include/boost/python/converter/body.hpp | 5 - .../python/converter/builtin_converters.hpp | 15 ++ .../builtin_to_python_converters.hpp | 75 ++++++ .../boost/python/converter/from_python.hpp | 169 +++++++++++++ .../python/converter/from_python_data.hpp | 206 +++++++++++++++ .../python/converter/from_python_function.hpp | 23 ++ include/boost/python/converter/handle.hpp | 18 ++ include/boost/python/converter/to_python.hpp | 116 +++++++++ .../python/converter/to_python_function.hpp | 23 ++ include/boost/python/converter/unwrap.hpp | 172 ------------- include/boost/python/converter/unwrapper.hpp | 40 --- include/boost/python/converter/wrap.hpp | 167 ------------ include/boost/python/converter/wrapper.hpp | 57 ----- .../python/object/auto_ptr_generator.hpp | 23 ++ .../boost/python/object/class_unwrapper.hpp | 40 --- .../boost/python/object/pointer_holder.hpp | 201 +++++++++++++++ .../boost/python/reference_from_python.hpp | 17 +- include/boost/python/value_from_python.hpp | 18 +- src/converter/builtin_converters.cpp | 238 ++++++++++++------ src/converter/from_python.cpp | 27 ++ src/converter/to_python.cpp | 24 ++ test/m1.cpp | 8 +- test/m2.cpp | 3 - test/test_builtin_converters.cpp | 65 +++++ test/test_builtin_converters.py | 86 +++++++ 26 files changed, 1259 insertions(+), 661 deletions(-) delete mode 100644 include/boost/python/convert.hpp create mode 100644 include/boost/python/converter/builtin_converters.hpp create mode 100644 include/boost/python/converter/builtin_to_python_converters.hpp create mode 100644 include/boost/python/converter/from_python.hpp create mode 100644 include/boost/python/converter/from_python_data.hpp create mode 100644 include/boost/python/converter/from_python_function.hpp create mode 100644 include/boost/python/converter/to_python.hpp create mode 100644 include/boost/python/converter/to_python_function.hpp delete mode 100644 include/boost/python/converter/unwrap.hpp delete mode 100644 include/boost/python/converter/unwrapper.hpp delete mode 100644 include/boost/python/converter/wrap.hpp delete mode 100644 include/boost/python/converter/wrapper.hpp create mode 100644 include/boost/python/object/auto_ptr_generator.hpp delete mode 100644 include/boost/python/object/class_unwrapper.hpp create mode 100644 include/boost/python/object/pointer_holder.hpp create mode 100644 src/converter/from_python.cpp create mode 100644 src/converter/to_python.cpp create mode 100644 test/test_builtin_converters.cpp create mode 100644 test/test_builtin_converters.py diff --git a/include/boost/python/convert.hpp b/include/boost/python/convert.hpp deleted file mode 100644 index 5614bd3b..00000000 --- a/include/boost/python/convert.hpp +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CONVERT_DWA20011129_HPP -# define CONVERT_DWA20011129_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct converter_gen - { - typedef T value_type; - typedef typename converter::source::type source_t; - typedef converter::wrap_ wrap_t; - typedef converter::wrap_more_ wrap_more_t; - - typedef typename converter::target::type target_t; - typedef converter::unwrap_ unwrap_t; - typedef converter::unwrap_more_ unwrap_more_t; - }; -} - -template -struct wrap : detail::converter_gen::wrap_t -{ - typedef typename detail::converter_gen::wrap_t base_t; - typedef typename detail::converter_gen::source_t source_t; -}; - -template -struct wrap_more : detail::converter_gen::wrap_more_t -{ - typedef typename detail::converter_gen::wrap_more_t base_t; - typedef typename detail::converter_gen::source_t source_t; - wrap_more(converter::handle& prev); -}; - -template -struct unwrap : detail::converter_gen::unwrap_t -{ - typedef typename detail::converter_gen::unwrap_t base_t; - unwrap(PyObject*); -}; - -template -struct unwrap_more : detail::converter_gen::unwrap_more_t -{ - typedef typename detail::converter_gen::unwrap_more_t base_t; - unwrap_more(PyObject*, converter::handle& prev); -}; - -// -// implementations -// -template -inline wrap_more::wrap_more(converter::handle& prev) - : base_t(prev) -{ -} - -template -inline unwrap::unwrap(PyObject* source) - : base_t(source) -{ -} - -template -inline unwrap_more::unwrap_more(PyObject* source, converter::handle& prev) - : base_t(source, prev) -{ -} - -}} // namespace boost::python - -#endif // CONVERT_DWA20011129_HPP diff --git a/include/boost/python/converter/body.hpp b/include/boost/python/converter/body.hpp index 72653ee0..d9170839 100644 --- a/include/boost/python/converter/body.hpp +++ b/include/boost/python/converter/body.hpp @@ -10,8 +10,6 @@ namespace boost { namespace python { namespace converter { -struct BOOST_PYTHON_DECL handle; - namespace registry { class entry; @@ -23,9 +21,6 @@ struct BOOST_PYTHON_DECL body body(type_id_t key); virtual ~body() {} - // default implementation is a no-op - virtual void destroy_handle(handle*) const; - type_id_t key() const; protected: diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp new file mode 100644 index 00000000..9c19cbc5 --- /dev/null +++ b/include/boost/python/converter/builtin_converters.hpp @@ -0,0 +1,15 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BUILTIN_CONVERTERS_DWA2002124_HPP +# define BUILTIN_CONVERTERS_DWA2002124_HPP + +namespace boost { namespace python { namespace converter { + +void initialize_builtin_converters(); + +}}} // namespace boost::python::converter + +#endif // BUILTIN_CONVERTERS_DWA2002124_HPP diff --git a/include/boost/python/converter/builtin_to_python_converters.hpp b/include/boost/python/converter/builtin_to_python_converters.hpp new file mode 100644 index 00000000..4e9f89e3 --- /dev/null +++ b/include/boost/python/converter/builtin_to_python_converters.hpp @@ -0,0 +1,75 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP +# define BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP +# include +# include + +namespace boost { namespace python { namespace converter { + +template struct to_python_lookup; + +template +struct to_python_int +{ + bool convertible() const { return true; } + PyObject* operator()(T x) const { return PyInt_FromLong(long(x)); } +}; + +# define BOOST_PYTHON_TO_INT(T) \ + template <> struct to_python_lookup : to_python_int {}; \ + template <> struct to_python_lookup : to_python_int {}; + +BOOST_PYTHON_TO_INT(char) +BOOST_PYTHON_TO_INT(short) +BOOST_PYTHON_TO_INT(int) +BOOST_PYTHON_TO_INT(long) +# undef BOOST_TO_PYTHON_INT + +template <> +struct to_python_lookup +{ + bool convertible() const { return true; } + PyObject* operator()(char const* x) const { return PyString_FromString(x); } +}; + +template <> +struct to_python_lookup +{ + bool convertible() const { return true; } + PyObject* operator()(std::string const& x) const + { + return PyString_FromString(x.c_str()); + } +}; + +template <> +struct to_python_lookup +{ + bool convertible() const { return true; } + PyObject* operator()(float x) const { return PyFloat_FromDouble(x); } +}; + +template <> +struct to_python_lookup +{ + bool convertible() const { return true; } + PyObject* operator()(double x) const { return PyFloat_FromDouble(x); } +}; + +template <> +struct to_python_lookup +{ + bool convertible() const { return true; } + PyObject* operator()(long double x) const + { + return PyFloat_FromDouble(x); + } +}; + +}}} // namespace boost::python::converter + +#endif // BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp new file mode 100644 index 00000000..234f61d1 --- /dev/null +++ b/include/boost/python/converter/from_python.hpp @@ -0,0 +1,169 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FROM_PYTHON_DWA2002127_HPP +# define FROM_PYTHON_DWA2002127_HPP + +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +// The type of convertibility checking functions +typedef void* (*from_python_check)(PyObject*); +typedef void (*from_python_destructor)(from_python_data&); + +// forward declaration +template struct from_python_lookup; + +// from_python -- +// A body class representing a conversion from python to C++. + +struct BOOST_PYTHON_DECL from_python_converter_base : body +{ + from_python_converter_base(type_id_t, from_python_check); // registers + ~from_python_converter_base(); // unregisters + + // Must return non-null iff the conversion will be successful. Any + // non-null pointer is acceptable, and will be passed on to the + // convert() function, so useful data can be stored there. + inline void* convertible(PyObject*) const; +// inline type_id_t key() const; + private: +// type_id_t m_key; + from_python_check m_convertible; +}; + + +template +struct from_python_converter : from_python_converter_base +{ + public: // types + typedef typename from_python_function::type conversion_function; + + public: // member functions + from_python_converter(from_python_check, conversion_function, from_python_destructor = 0); + T convert(PyObject*, from_python_data&) const; + void destroy(from_python_data&) const; + + private: // data members + conversion_function m_convert; + from_python_destructor m_destroy; +}; + +// ------------------------------------------------------------------------- + +//struct from_python_base +//{ +//}; + +// A class which implements from_python with a registry lookup. +template +struct from_python_lookup // : from_python_base +{ + public: // types + + public: // member functions + from_python_lookup(PyObject* source); + ~from_python_lookup(); + + bool convertible() const; + T operator()(PyObject*); + + public: // functions for use by conversion implementations + // Get the converter object + from_python_converter const* converter() const; + + private: // data members + typedef typename from_python_intermediate_data::type intermediate_t; + mutable intermediate_t m_intermediate_data; + from_python_converter const* m_converter; +}; + +// +// implementations +// +inline void* from_python_converter_base::convertible(PyObject* o) const +{ + return m_convertible(o); +} + +# if 0 +inline type_id_t from_python_converter_base::key() const +{ + return m_key; +} +# endif + +template +inline from_python_converter::from_python_converter( + from_python_check checker + , conversion_function converter + , from_python_destructor destructor // = 0 + ) + : from_python_converter_base(type_id(), checker) + , m_convert(converter) + , m_destroy(destructor) +{ + +} + +template +inline T from_python_converter::convert(PyObject* src, from_python_data& data) const +{ + return this->m_convert(src, data); +} + +template +inline void from_python_converter::destroy(from_python_data& data) const +{ + if (this->m_destroy) + { + this->m_destroy(data); + } +} + +template +inline from_python_lookup::from_python_lookup(PyObject* src) + : m_converter( + registration::get_from_python( + src, m_intermediate_data.stage1)) +{ +} + +template +inline from_python_lookup::~from_python_lookup() +{ + if (m_converter != 0) + m_converter->destroy(m_intermediate_data); +} + +template +inline bool from_python_lookup::convertible() const +{ + return this->m_converter != 0; +} + +template +inline T from_python_lookup::operator()(PyObject* obj) +{ + return this->m_converter->convert(obj, m_intermediate_data); +} + +template +inline from_python_converter const* +from_python_lookup::converter() const +{ + return this->m_converter; +} + +}}} // namespace boost::python::converter + +#endif // FROM_PYTHON_DWA2002127_HPP diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp new file mode 100644 index 00000000..3edcbad7 --- /dev/null +++ b/include/boost/python/converter/from_python_data.hpp @@ -0,0 +1,206 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FROM_PYTHON_AUX_DATA_DWA2002128_HPP +# define FROM_PYTHON_AUX_DATA_DWA2002128_HPP + +# include +# include +# include +# include + +// Keep these for the metaprogram which EDG is choking on. +# if !defined(__EDG__) || (__EDG_VERSION__ > 245) +# include +# include +# include +# include +# endif + +namespace boost { namespace python { namespace converter { + +// A POD which is layout-compatible with the real intermediate data +// for all from_python conversions. There may be additional storage if +// we are converting a reference type. +struct from_python_data +{ + void* stage1; +}; + +namespace detail +{ + template struct referent_alignment; + template struct referent_size; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + template + struct referent_alignment + { + BOOST_STATIC_CONSTANT( + std::size_t, value = alignment_of::value); + }; + + template + struct referent_size + { + BOOST_STATIC_CONSTANT( + std::size_t, value = sizeof(T)); + }; + +# else + + template + struct alignment_chars + { + BOOST_STATIC_CONSTANT( + std::size_T, n = alignment_of::value); + char elements[n + 1]; + }; + + template struct referent_alignment + { + template + static alignment_chars helper(U&); + + static T t; + + BOOST_STATIC_CONSTANT( + std::size_t, value = sizeof(helper(t).elements) - 1); + }; + + + template struct referent_size + { + static T t; + BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(t)); + }; + +# endif + + struct unknown_alignment + { + void* p; + }; + +// EDG is too slow to handle this metaprogram :( +#if !defined(__EDG__) || (__EDG_VERSION__ > 245) + struct alignment_dummy; + + template + struct best_alignment_type + { + template + struct apply + { + BOOST_STATIC_CONSTANT( + std::size_t, align1 = alignment_of::value); + + BOOST_STATIC_CONSTANT( + std::size_t, align2 = alignment_of::value); + + BOOST_STATIC_CONSTANT( + bool, aligned2 = ( + (align2 >= target_alignment) + & (align2 % target_alignment == 0)) + ); + + BOOST_STATIC_CONSTANT( + bool, choose_t2 = ( + aligned2 && ( + is_same::value + | (align2 < alignment_of::value) + | (sizeof(T2) < sizeof(T1))) + )); + + typedef mpl::select_type::type type; + }; + }; + + typedef mpl::type_list< + char,short,int,long,float,double,long double + ,void* + ,void(*)() + ,void (alignment_dummy::*)() + , char (alignment_dummy::*) + > + align_types; +#endif // EDG is too slow + + template + struct aligned_storage + { + typedef Align align_t; + union + { + Align align; + char bytes[size + // this is just a STATIC_ASSERT. For some reason + // MSVC was barfing on the boost one. + - (is_same::value ? size : 0)]; + }; + }; + + template + struct referent_storage + { +// EDG is too slow to handle this metaprogram :( +#if !defined(__EDG__) || (__EDG_VERSION__ > 245) + typedef mpl::for_each< + align_types + , unknown_alignment + , best_alignment_type::value> + > loop; + typedef typename loop::state align_t; +#else + // The Python source makes the assumption that double has + // maximal alignment anyway + typedef double align_t; +#endif + + typedef aligned_storage::value> type; + }; + + template + struct intermediate_data : from_python_data + { + typename referent_storage::type stage2; + }; + + template <> + struct intermediate_data : from_python_data + { + }; + +} + +// ------------------------------------------------------------------------- +// Auxiliary POD storage where the convertible and/or convert functions of a +// from_python object may place arbitrary data. +// +// Always starts with a void* +// +// For references, we produce additional aligned storage sufficient to +// store the referent + +template +struct from_python_intermediate_data +{ + typedef typename mpl::select_type< + is_reference::value, T, void>::type just_reference_t; + + typedef detail::intermediate_data type; +}; + +template +void* get_storage(from_python_data& x, boost::type* = 0) +{ + typedef typename from_python_intermediate_data::type layout; + return static_cast(&x)->stage2.bytes; +} + +}}} // namespace boost::python::converter + +#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP diff --git a/include/boost/python/converter/from_python_function.hpp b/include/boost/python/converter/from_python_function.hpp new file mode 100644 index 00000000..0cf90459 --- /dev/null +++ b/include/boost/python/converter/from_python_function.hpp @@ -0,0 +1,23 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FROM_PYTHON_FUNCTION_DWA2002128_HPP +# define FROM_PYTHON_FUNCTION_DWA2002128_HPP + +# include + +namespace boost { namespace python { namespace converter { + +struct from_python_data; + +template +struct from_python_function +{ + typedef T (*type)(PyObject*, from_python_data&); +}; + +}}} // namespace boost::python::converter + +#endif // FROM_PYTHON_FUNCTION_DWA2002128_HPP diff --git a/include/boost/python/converter/handle.hpp b/include/boost/python/converter/handle.hpp index 03671634..bc06be38 100644 --- a/include/boost/python/converter/handle.hpp +++ b/include/boost/python/converter/handle.hpp @@ -24,6 +24,7 @@ struct BOOST_PYTHON_DECL handle : boost::noncopyable // // Constructors taking a handle links this into a chain of // handles, for more efficient management in function wrappers + handle(); handle(body* body); handle(body* body, handle& prev); @@ -43,6 +44,9 @@ struct BOOST_PYTHON_DECL handle : boost::noncopyable protected: // member functions for derived classes // Get the body we hold inline body* get_body() const; + + inline void set_body(body*); + inline void set_prev(handle&); // Release all bodies in the chain, in reverse order of // initialization. Only actually called for the head of the chain. @@ -59,6 +63,10 @@ struct BOOST_PYTHON_DECL handle : boost::noncopyable // // implementations // +inline handle::handle() + : m_next(0) +{} + inline handle::handle(body* body, handle& prev) : m_body(body), m_next(0) { @@ -85,6 +93,16 @@ inline body* handle::get_body() const return m_body; } +inline void handle::set_body(body* body) +{ + m_body = body; +} + +inline void handle::set_prev(handle& prev) +{ + prev.m_next = this; +} + }}} // namespace boost::python::converter #endif // HANDLE_DWA20011130_HPP diff --git a/include/boost/python/converter/to_python.hpp b/include/boost/python/converter/to_python.hpp new file mode 100644 index 00000000..61dc7dad --- /dev/null +++ b/include/boost/python/converter/to_python.hpp @@ -0,0 +1,116 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TO_PYTHON_DWA2002127_HPP +# define TO_PYTHON_DWA2002127_HPP + +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +template struct to_python_lookup; + +struct BOOST_PYTHON_DECL to_python_converter_base : body +{ + to_python_converter_base(type_id_t, to_python_function_base); // registers + ~to_python_converter_base(); // unregisters + +// inline type_id_t key() const; + inline to_python_function_base converter() const; + private: +// type_id_t m_key; + to_python_function_base m_convert; +}; + +template +struct to_python_converter : to_python_converter_base +{ + public: // types + typedef typename to_python_function::type converter_t; + + public: // member functions + to_python_converter(converter_t); + converter_t converter() const; + + private: // data members + converter_t m_convert; +}; + +// ------------------------------------------------------------------------- + +//struct to_python_base {}; + +template +struct to_python_lookup //: to_python_base +{ + public: // member functions + to_python_lookup(); + bool convertible() const; + PyObject* operator()(T) const; + private: + typename to_python_function::type m_convert; +}; + +// +// implementations +// +# if 0 +inline type_id_t +to_python_converter_base::key() const +{ + return m_key; +} +# endif + +inline to_python_function_base +to_python_converter_base::converter() const +{ + return m_convert; +} + +template +to_python_converter::to_python_converter(converter_t convert) + : to_python_converter_base( + type_id(), reinterpret_cast(convert)) +{ +} + +template +inline typename to_python_function::type +to_python_converter::converter() const +{ + return reinterpret_cast( + this->to_python_converter_base::converter()); +} + +template +inline to_python_lookup::to_python_lookup() + : m_convert( + registration::get_to_python()) +{ +} + +template +inline bool +to_python_lookup::convertible() const +{ + return m_converter != 0; +} + +template +inline PyObject* +to_python_lookup::operator()(T x) const +{ + return m_convert ? m_convert(x) : 0; +} + +}}} // namespace boost::python::converter + +#endif // TO_PYTHON_DWA2002127_HPP diff --git a/include/boost/python/converter/to_python_function.hpp b/include/boost/python/converter/to_python_function.hpp new file mode 100644 index 00000000..9d408749 --- /dev/null +++ b/include/boost/python/converter/to_python_function.hpp @@ -0,0 +1,23 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TO_PYTHON_FUNCTION_DWA2002128_HPP +# define TO_PYTHON_FUNCTION_DWA2002128_HPP + +# include + +namespace boost { namespace python { namespace converter { + +typedef PyObject* (*to_python_function_base)(void); + +template +struct to_python_function +{ + typedef PyObject*(*type)(T); +}; + +}}} // namespace boost::python::converter + +#endif // TO_PYTHON_FUNCTION_DWA2002128_HPP diff --git a/include/boost/python/converter/unwrap.hpp b/include/boost/python/converter/unwrap.hpp deleted file mode 100644 index eccb0992..00000000 --- a/include/boost/python/converter/unwrap.hpp +++ /dev/null @@ -1,172 +0,0 @@ -#error obsolete -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef UNWRAP_BASE_DWA20011130_HPP -# define UNWRAP_BASE_DWA20011130_HPP - -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -template struct unwrapper; -struct BOOST_PYTHON_DECL body; - -struct BOOST_PYTHON_DECL unwrap_base : handle -{ - public: // member functions - inline unwrap_base(PyObject* source, std::pair, handle& prev); - inline unwrap_base(PyObject* source, std::pair); - inline PyObject* source() const; - - inline void*& data(); - - protected: - inline PyObject*& source(); - - private: // data members - PyObject* m_source; - void* m_data; -}; - -// These converters will be used by the function wrappers. They don't -// manage any resources, but are instead linked into a chain which is -// managed by an instance of unwrap_ or wrap_. -template -struct unwrap_more_ : unwrap_base -{ - public: // member functions - // Construction - unwrap_more_(PyObject* source, handle& prev); - - // invoke the conversion or throw an exception if unsuccessful - T operator*(); - - protected: // constructor - // this constructor is only for the use of unwrap_ - unwrap_more_(PyObject* source); - - private: - typedef typename unwrapper_select::type unwrapper_t; -}; - -// specialization for PyObject* -template <> -struct unwrap_more_ - : unwrap_base -{ - public: // member functions - // Construction - unwrap_more_(PyObject* source, handle& prev) - : unwrap_base(source, m_unwrapper, prev) - { - } - - - // invoke the conversion or throw an exception if unsuccessful - PyObject* operator*() - { - return source(); - } - - void* can_convert(PyObject*) const - { - return &m_unwrapper; - } - - protected: // constructor - // this constructor is only for the use of unwrap_ - unwrap_more_(PyObject* source) - : unwrap_base(source, m_unwrapper) - - { - } - private: - static BOOST_PYTHON_DECL std::pair& m_unwrapper; -}; - -template -struct unwrap_ : unwrap_more_ -{ - unwrap_(PyObject* source); - ~unwrap_(); -}; - -// -// implementations -// -inline unwrap_base::unwrap_base( - PyObject* source, std::pair unwrapper, handle& prev) - : handle(unwrapper.first, prev) - , m_source(source) - , m_data(unwrapper.second) -{ -} - -inline unwrap_base::unwrap_base(PyObject* source, std::pair unwrapper) - : handle(unwrapper.first) - , m_source(source) - , m_data(unwrapper.second) -{ -} - -inline void*& unwrap_base::data() -{ - return m_data; -} - -inline PyObject* unwrap_base::source() const -{ - return m_source; -} - -inline PyObject*& unwrap_base::source() -{ - return m_source; -} - -template -unwrap_more_::unwrap_more_(PyObject* source, handle& prev) - : unwrap_base(source, - registration::unwrapper(source), - prev) -{ -} - -template -unwrap_more_::unwrap_more_(PyObject* source) - : unwrap_base(source, registration::unwrapper(source)) -{ -} - -template -inline unwrap_::unwrap_(PyObject* source) - : unwrap_more_(source) -{ -} - -template -T unwrap_more_::operator*() -{ - return static_cast*>( - get_body())->convert(this->source(), this->data(), boost::type()); -} - -template -unwrap_::~unwrap_() -{ - this->destroy(); -} - -}}} // namespace boost::python::converter - -#endif // UNWRAP_BASE_DWA20011130_HPP diff --git a/include/boost/python/converter/unwrapper.hpp b/include/boost/python/converter/unwrapper.hpp deleted file mode 100644 index 8a16e957..00000000 --- a/include/boost/python/converter/unwrapper.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#error obsolete -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef UNWRAPPER_DWA2001127_HPP -# define UNWRAPPER_DWA2001127_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -template struct unwrap_more_; - -// Abstract base for all unwrappers of Ts -template -struct unwrapper : unwrapper_base -{ - public: - unwrapper(); - - virtual T convert(PyObject*, void*& data, boost::type) const = 0; -}; - -// -// implementations -// -template -unwrapper::unwrapper() - : unwrapper_base(type_id()) -{ -} - -}}} // namespace boost::python::converter - -#endif // UNWRAPPER_DWA2001127_HPP diff --git a/include/boost/python/converter/wrap.hpp b/include/boost/python/converter/wrap.hpp deleted file mode 100644 index b61fff19..00000000 --- a/include/boost/python/converter/wrap.hpp +++ /dev/null @@ -1,167 +0,0 @@ -#error obsolete -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef WRAP_DWA2001127_HPP -# define WRAP_DWA2001127_HPP -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -extern BOOST_PYTHON_DECL body& identity_wrapper; - -template struct wrapper; - -struct wrap_base : handle -{ - public: // member functions - wrap_base(body*, handle& prev); - wrap_base(body*); - PyObject* release(); - - public: // accessor, really only for wrappers - PyObject*& target() const; - - protected: - void hold_result(PyObject*) const; - - private: - mutable PyObject* m_target; -}; - -template -struct wrap_more_ : wrap_base -{ - protected: - typedef T source_t; - - public: // member functions - wrap_more_(handle& prev); - - PyObject* operator()(source_t) const; - - protected: // constructor for wrap_, below - wrap_more_(); - - private: // helper functions - static wrapper_base* lookup(); - - private: - friend class wrapper; -}; - -template -struct wrap_ : wrap_more_ -{ - typedef typename wrap_more_::source_t source_t; - public: // member functions - wrap_(); - ~wrap_(); -}; - - -// Specialization for PyObject* -template <> -struct wrap_more_ : wrap_base -{ - protected: - typedef PyObject* source_t; - - public: // member functions - wrap_more_(handle& prev) - : wrap_base(&identity_wrapper, prev) {} - - PyObject* operator()(source_t x) const { return x; } - - protected: // constructor for wrap_, below - wrap_more_() - : wrap_base(&identity_wrapper) {} - private: - friend class wrapper; -}; - -// -// implementations -// -inline wrap_base::wrap_base(body* body, handle& prev) - : handle(body, prev) - , m_target(0) -{ -} - -inline wrap_base::wrap_base(body* body) - : handle(body), - m_target(0) -{ -} - -inline PyObject*& wrap_base::target() const -{ - return m_target; -} - -inline void wrap_base::hold_result(PyObject* p) const -{ - assert(m_target == 0); - m_target = p; -} - -inline PyObject* wrap_base::release() -{ - PyObject* result = m_target; - m_target = 0; - return result; -} - -template -inline wrapper_base* wrap_more_::lookup() -{ - // Find the converters registered for T and get a wrapper - // appropriate for the source object - return registration::wrapper(); -} - -template -inline wrap_more_::wrap_more_(handle& prev) - : wrap_base(lookup(), prev) -{ - -} - -template -PyObject* wrap_more_::operator()(source_t x) const -{ - return static_cast*>( - this->get_body())->do_conversion(*this, source_holder(x)); -} - -template -wrap_more_::wrap_more_() - : wrap_base(lookup()) -{ -} - -template -wrap_::wrap_() - : wrap_more_() -{ -} - -template -wrap_::~wrap_() -{ - this->destroy(); -} - -}}} // namespace boost::python::converter - -#endif // WRAP_DWA2001127_HPP diff --git a/include/boost/python/converter/wrapper.hpp b/include/boost/python/converter/wrapper.hpp deleted file mode 100644 index e20ed404..00000000 --- a/include/boost/python/converter/wrapper.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#error obsolete -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef WRAPPER_DWA2001127_HPP -# define WRAPPER_DWA2001127_HPP -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -extern BOOST_PYTHON_DECL body& identity_wrapper; - -template -struct wrapper : wrapper_base -{ - public: - wrapper(); - - PyObject* do_conversion(wrap_base const&, source_holder_base const&) const; - - // This does the actual conversion - virtual PyObject* convert(T source) const = 0; -}; - -// -// implementations -// - -template -wrapper::wrapper() - : wrapper_base(type_id()) -{ -} - - -template -PyObject* wrapper::do_conversion(wrap_base const& handle_, source_holder_base const& data_) const -{ - // Casting pointers instead of references suppresses a CWPro7 bug. - wrap_more_ const& handle = *static_cast const*>(&handle_); - source_holder const& data = *static_cast const*>(&data_); - if (handle.target() == 0) - { - handle.hold_result(convert(data.value)); - } - return handle.target(); -} - -}}} // namespace boost::python::converter - -#endif // WRAPPER_DWA2001127_HPP diff --git a/include/boost/python/object/auto_ptr_generator.hpp b/include/boost/python/object/auto_ptr_generator.hpp new file mode 100644 index 00000000..9c13e436 --- /dev/null +++ b/include/boost/python/object/auto_ptr_generator.hpp @@ -0,0 +1,23 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef AUTO_PTR_GENERATOR_DWA2002123_HPP +# define AUTO_PTR_GENERATOR_DWA2002123_HPP +# include + +namespace boost { namespace python { namespace object { + +struct auto_ptr_generator +{ + template + struct apply + { + typedef std::auto_ptr type; + }; +}; + +}}} // namespace boost::python::object + +#endif // AUTO_PTR_GENERATOR_DWA2002123_HPP diff --git a/include/boost/python/object/class_unwrapper.hpp b/include/boost/python/object/class_unwrapper.hpp deleted file mode 100644 index 0877ff24..00000000 --- a/include/boost/python/object/class_unwrapper.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_UNWRAPPER_DWA20011221_HPP -# define CLASS_UNWRAPPER_DWA20011221_HPP - -# include -# include - -namespace boost { namespace python { namespace objects { - -template -struct class_unwrapper -{ - private: - template - struct reference_unwrapper : converter::unwrapper - { - void* can_convert(PyObject* p) const - { - return find_instance(p); - } - - Target convert(PyObject* p, void* data, ) const - { - return *find_instance(p)->target(); - } - }; - - reference_unwrapper m_reference; -# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - reference_unwrapper m_const_reference; -# endif -}; - -}}} // namespace boost::python::objects - -#endif // CLASS_UNWRAPPER_DWA20011221_HPP diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp new file mode 100644 index 00000000..81fcac0c --- /dev/null +++ b/include/boost/python/object/pointer_holder.hpp @@ -0,0 +1,201 @@ +// Copyright David Abrahams 2001. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef POINTER_HOLDER_DWA20011215_HPP +# define POINTER_HOLDER_DWA20011215_HPP + +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace objects { + +template +struct pointer_holder : instance_holder +{ + pointer_holder(Pointer); + + // Forward construction to the held object + pointer_holder(PyObject*) + : m_p(new Value) {} + + + template + pointer_holder(PyObject*, A1 a1) + : m_p(new Value( + (unwrap_reference::type&)(a1) + )) + {} + + template + pointer_holder(PyObject*, A1 a1, A2 a2) + : m_p(new Value( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + )) + {} + + template + pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3) + : m_p(new Value( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + )) + {} + + template + pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) + : m_p(new Value( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + )) + {} + + template + pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) + : m_p(new Value( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + )) {} + + template + pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) + : m_p(new Value( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + , (unwrap_reference::type&)(a6) + )) {} + + template + pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) + : m_p(new Value( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + , (unwrap_reference::type&)(a6) + , (unwrap_reference::type&)(a7) + )) + {} + + template + pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) + : m_p(new Value( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + , (unwrap_reference::type&)(a6) + , (unwrap_reference::type&)(a7) + , (unwrap_reference::type&)(a8) + )) + {} + + template + pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) + : m_p(new Value( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + , (unwrap_reference::type&)(a6) + , (unwrap_reference::type&)(a7) + , (unwrap_reference::type&)(a8) + , (unwrap_reference::type&)(a9) + )) + {} + + template + pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) + : m_p(new Value( + (unwrap_reference::type&)(a1) + , (unwrap_reference::type&)(a2) + , (unwrap_reference::type&)(a3) + , (unwrap_reference::type&)(a4) + , (unwrap_reference::type&)(a5) + , (unwrap_reference::type&)(a6) + , (unwrap_reference::type&)(a7) + , (unwrap_reference::type&)(a8) + , (unwrap_reference::type&)(a9) + , (unwrap_reference::type&)(a10) + )) + {} + + private: // required holder implementation + void* holds(converter::type_id_t); + + private: // data members + Pointer m_p; +}; + +}}} + +// back to namespace boost for this forward declaration +namespace boost +{ + template class shared_ptr; +} + +namespace boost { namespace python { namespace objects { + +struct shared_ptr_generator +{ + template + struct apply + { + typedef boost::shared_ptr type; + }; +}; + +// A generator metafunction which can be passed to make_holder +// PointerGenerator should be another generator metafunction which +// makes the appropriate (smart) pointer type to hold the argument to +// pointer_holder_generator. +template +struct pointer_holder_generator +{ + template + struct apply + { + typedef typename detail::eval::type pointer; + typedef pointer_holder type; + }; +}; + +template +pointer_holder::pointer_holder(Pointer p) + : m_p(p) +{ +} + +template +void* pointer_holder::holds(converter::type_id_t dst_t) +{ + if (dst_t == converter::type_id()) + return &this->m_p; + + converter::type_id_t src_t = converter::type_id(); + return src_t == dst_t ? &*this->m_p + : find_dynamic_type(&*this->m_p, src_t, dst_t); +} + +}}} // namespace boost::python::objects + +#endif // POINTER_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/reference_from_python.hpp b/include/boost/python/reference_from_python.hpp index 8e7b9b6c..a9631dc5 100644 --- a/include/boost/python/reference_from_python.hpp +++ b/include/boost/python/reference_from_python.hpp @@ -26,23 +26,28 @@ template < PyTypeObject const* python_type , class Value , class PythonObject - , Value& (*extract)(PythonObject&) + , class Extract > -struct reference_from_python : type_from_python +struct reference_from_python { + typedef type_from_python convertible_t; + reference_from_python() - : m_mutable_converter(convertible, convert_mutable) - , m_const_converter(convertible, convert_const) + : m_mutable_converter( + &convertible_t::convertible, convert_mutable) + + , m_const_converter( + &convertible_t::convertible, convert_const) {} static Value& convert_mutable(PyObject* op, converter::from_python_data&) { - return extract(*(PythonObject*)op); + return Extract::execute(*(PythonObject*)op); } static Value const& convert_const(PyObject* op, converter::from_python_data&) { - return extract(*(PythonObject*)op); + return Extract::execute(*(PythonObject*)op); } private: diff --git a/include/boost/python/value_from_python.hpp b/include/boost/python/value_from_python.hpp index bb4ecf87..0ff80323 100644 --- a/include/boost/python/value_from_python.hpp +++ b/include/boost/python/value_from_python.hpp @@ -9,12 +9,27 @@ # include # include # include +# include namespace boost { namespace python { template struct value_from_python { + typedef converter::from_python_check from_python_check; + + value_from_python(from_python_check convertible) + : m_converter( + convertible + , &Derived::convert + + // Change this to a compile-time check later to avoid + // generating destroy function + , has_trivial_destructor::value ? 0 : &Derived::destroy + ) + { + } + value_from_python() : m_converter( &Derived::convertible @@ -25,9 +40,6 @@ struct value_from_python , has_trivial_destructor::value ? 0 : &Derived::destroy ) { - // Scalar types are really converted by-value; the formulation - // is much simpler. - BOOST_STATIC_ASSERT(!(is_scalar::value)); } static void* get_storage(converter::from_python_data& data) diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index 07a00259..c2ce3dae 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -8,7 +8,8 @@ #include #include #include -#include +#include +#include #include #include //#include @@ -18,113 +19,185 @@ namespace boost { namespace python { namespace converter { namespace { - struct int_value_functions_base + // Only an object which we know is holding a char const* can be + // converted to one + struct convertible_to_cstring { - static void* convertible(PyObject* obj) + static unaryfunc* execute(PyObject* obj) { - PyNumberMethods* number_methods = obj->ob_type->tp_as_number; - - return number_methods && number_methods->nb_int - ? &number_methods->nb_int : 0; - } - }; - - template - struct int_value_functions : int_value_functions_base - { - static T convert(PyObject* obj, from_python_data& data) - { - unaryfunc f = *static_cast(data.stage1); - ref int_object(f(obj)); - return numeric_cast(PyInt_AsLong(int_object.get())); + return PyString_Check(obj) ? &obj->ob_type->tp_str : 0; } }; - struct cstring_value_functions + struct extract_cstring { - static void* convertible(PyObject* obj) - { - return PyString_Check(obj) ? obj : 0; - } - - static char const* convert(PyObject* obj, from_python_data&) + static char const* execute(PyObject* obj) { return PyString_AsString(obj); } }; - char constructed; - - struct string_cref_functions + // Any object which can be converted to a Python string can also be + // converted to a C++ string, since the latter owns its bytes. + struct convertible_to_string { - typedef std::string const& result_type; - - static void* convertible(PyObject* obj) + static unaryfunc* execute(PyObject* obj) { return obj->ob_type->tp_str ? &obj->ob_type->tp_str : 0; } + }; + + // Transform a function returning a unaryfunc* into one that returns a void* + template + struct return_void_ptr + { + static void* execute(PyObject* p) { return F::execute(p); } + }; + + template < + class T // The target type + , class Convertible // returns a pointer to a unaryfunc producing an object + , class TExtract // ...from which TExtract extracts T's constructor argument + > + struct tp_scalar_from_python + : from_python_converter + { + private: + typedef return_void_ptr convertible_fn; - static std::string const& convert( - PyObject* obj, from_python_data& data) + public: + tp_scalar_from_python() + : from_python_converter( + &convertible_fn::execute + , convert) + {} + + static T convert(PyObject* obj, from_python_data& data) { - ref string_object((**static_cast(data.stage1))(obj)); - void* storage = get_storage(data); - std::string* p = new (storage) std::string(PyString_AsString(string_object.get())); + unaryfunc converter = *(unaryfunc*)data.stage1; + ref converted(converter(obj)); + return TExtract::execute(converted.get()); + } + }; + + // Extract a reference to T using the functions in the source + // object's type slots + template < + class T // The target type + , class Convertible // returns a pointer to a unaryfunc producing an object + , class TExtract // ...from which TExtract extracts T's constructor argument + > + struct tp_cref_from_python + : value_from_python > + { + private: + typedef value_from_python > base; + + public: + tp_cref_from_python() + : base(&return_void_ptr::execute) + {} + + static T const& convert(PyObject* obj, from_python_data& data) + { + unaryfunc converter = *(unaryfunc*)data.stage1; + + void* storage = get_storage(data); + + ref converted(converter(obj)); + + T* const p = new (storage) T(TExtract::execute(converted.get())); // note that construction is successful. - data.stage1 = &constructed; + data.stage1 = p; + return *p; } + }; - static void destroy(from_python_data& data) + struct convertible_to_int + { + static unaryfunc* execute(PyObject* obj) { - if (data.stage1 == &constructed) + PyNumberMethods* number_methods = obj->ob_type->tp_as_number; + if (number_methods == 0) + return 0; + + // For floating types, return the float conversion slot to avoid + // creating a new object. We'll handle that in + // py_int_or_float_as_long, below + if (PyObject_TypeCheck(obj, &PyFloat_Type) && number_methods->nb_float) + return &number_methods->nb_float; + + return number_methods && number_methods->nb_int + ? &number_methods->nb_int : 0; + } + }; + + struct py_int_or_float_as_long + { + static long execute(PyObject* obj) + { + if (PyObject_TypeCheck(obj, &PyFloat_Type)) { - typedef std::string string_t; - void* storage = get_storage(data); - ((string_t*)storage)->~string_t(); + return numeric_cast(PyFloat_AS_DOUBLE(obj)); + } + else + { + return PyInt_AS_LONG(obj); } } }; - template - struct rvalue_const_ref_functions : Base + struct convertible_to_double { - static T const& convert(PyObject* obj, from_python_data& data) + static unaryfunc* execute(PyObject* obj) { - void* storage = get_storage(data); - T* p = new (storage) T(Base::convert(obj,data)); - - // note that construction is successful. - data.stage1 = &constructed; - return *p; + PyNumberMethods* number_methods = obj->ob_type->tp_as_number; + if (number_methods == 0) + return 0; + + // For integer types, return the tp_int conversion slot to avoid + // creating a new object. We'll handle that in + // py_float_or_int_as_double, below + if (PyObject_TypeCheck(obj, &PyInt_Type) && number_methods->nb_int) + return &number_methods->nb_int; + + return number_methods && number_methods->nb_float + ? &number_methods->nb_float : 0; } }; - struct register_int_converters + struct py_float_or_int_as_double { - template - struct apply + static double execute(PyObject* obj) { - typedef void type; - - static void execute() + if (PyObject_TypeCheck(obj, &PyInt_Type)) { - typedef int_value_functions value_functions; - typedef rvalue_const_ref_functions cref_functions; - - static from_python_converter value_from_python( - value_functions::convertible - , value_functions::convert); - static from_python_converter cref_from_python( - cref_functions::convertible - , cref_functions::convert); - }; - }; + return PyInt_AS_LONG(obj); + } + else + { + return PyFloat_AS_DOUBLE(obj); + } + } }; -} -#define REGISTER_INT_CONVERTERS(U) register_int_converters::apply::execute() + template + struct scalar_from_python + { + tp_cref_from_python cref_converter; + tp_scalar_from_python value_converter; + }; + + template + void register_int_converters(T* = 0) + { + static scalar_from_python x; + }; +} + +#define REGISTER_INT_CONVERTERS(U) register_int_converters() #define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U) @@ -134,20 +207,21 @@ void initialize_builtin_converters() REGISTER_INT_CONVERTERS2(short); REGISTER_INT_CONVERTERS2(int); REGISTER_INT_CONVERTERS2(long); -// mpl::for_each::execute(); - static from_python_converter cstring_from_python( - &cstring_value_functions::convertible - , &cstring_value_functions::convert); + static scalar_from_python< + float,convertible_to_double,py_float_or_int_as_double> float_from_python; + + static scalar_from_python< + double,convertible_to_double,py_float_or_int_as_double> double_from_python; + + static scalar_from_python< + long double,convertible_to_double,py_float_or_int_as_double> long_double_from_python; + + static scalar_from_python< + char const*, convertible_to_cstring, extract_cstring> cstring_from_python; - static from_python_converter cstring_cref_from_python( - &rvalue_const_ref_functions::convertible - , &rvalue_const_ref_functions::convert); - - static from_python_converter string_cref_from_python( - &string_cref_functions::convertible - , &string_cref_functions::convert - , &string_cref_functions::destroy); + static tp_cref_from_python< + std::string, convertible_to_string, extract_cstring> string_from_python; } }}} // namespace boost::python::converter diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp new file mode 100644 index 00000000..979ad935 --- /dev/null +++ b/src/converter/from_python.cpp @@ -0,0 +1,27 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include + +namespace boost { namespace python { namespace converter { + +from_python_converter_base::from_python_converter_base( + type_id_t type + , from_python_check checker + ) + : body(type) + , m_convertible(checker) +{ + registry::insert(*this); +} + +from_python_converter_base::~from_python_converter_base() +{ + if (can_unregister()) + registry::remove(*this); +} + +}}} // namespace boost::python::converter diff --git a/src/converter/to_python.cpp b/src/converter/to_python.cpp new file mode 100644 index 00000000..9cede51d --- /dev/null +++ b/src/converter/to_python.cpp @@ -0,0 +1,24 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include + +namespace boost { namespace python { namespace converter { + +to_python_converter_base::to_python_converter_base(type_id_t key, to_python_function_base convert) + : body(key) + , m_convert(convert) +{ + registry::insert(*this); +} + +to_python_converter_base::~to_python_converter_base() +{ + registry::remove(*this); +} + +}}} // namespace boost::python::converter diff --git a/test/m1.cpp b/test/m1.cpp index 6b4c55e1..d422b426 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -64,8 +64,11 @@ struct SimpleObject { PyObject_HEAD simple x; +}; - static simple& extract(SimpleObject& o) { return o.x; } +struct extract_simple_object +{ + static simple& execute(SimpleObject& o) { return o.x; } }; PyTypeObject SimpleType = { @@ -209,12 +212,13 @@ BOOST_PYTHON_MODULE_INIT(m1) &SimpleType , simple , SimpleObject - , &SimpleObject::extract + , extract_simple_object > unwrap_simple; static to_python_converter simple_ref_wrapper(simple_ref_to_python); + module m1("m1"); typedef boost::python::objects::pointer_holder_generator< diff --git a/test/m2.cpp b/test/m2.cpp index be2934e0..0a5df161 100644 --- a/test/m2.cpp +++ b/test/m2.cpp @@ -49,9 +49,6 @@ PyObject* unwrap_int_const_ref(int const& x) return PyInt_FromLong(x); } -// MSVC6 bug workaround -template struct xxxx; - // rewrap extracts a T from the argument, then converts the T back // to a PyObject* and returns it. template diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp new file mode 100644 index 00000000..6ffccdf9 --- /dev/null +++ b/test/test_builtin_converters.cpp @@ -0,0 +1,65 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include + + +template +struct by_value +{ + static T rewrap(T x) + { + return x; + } +}; + +template +struct by_const_reference +{ + static T rewrap(T const& x) + { + return x; + } +}; + +BOOST_PYTHON_MODULE_INIT(builtin_converters_ext) +{ + boost::python::module("builtin_converters_ext") + + .def("rewrap_value_signed_char", by_value::rewrap) + .def("rewrap_value_unsigned_char", by_value::rewrap) + .def("rewrap_value_int", by_value::rewrap) + .def("rewrap_value_unsigned_int", by_value::rewrap) + .def("rewrap_value_short", by_value::rewrap) + .def("rewrap_value_unsigned_short", by_value::rewrap) + .def("rewrap_value_long", by_value::rewrap) + .def("rewrap_value_unsigned_long", by_value::rewrap) + .def("rewrap_value_float", by_value::rewrap) + .def("rewrap_value_double", by_value::rewrap) + .def("rewrap_value_long_double", by_value::rewrap) + .def("rewrap_value_string", by_value::rewrap) + .def("rewrap_value_cstring", by_value::rewrap) + + + .def("rewrap_const_reference_signed_char", by_const_reference::rewrap) + .def("rewrap_const_reference_unsigned_char", by_const_reference::rewrap) + .def("rewrap_const_reference_int", by_const_reference::rewrap) + .def("rewrap_const_reference_unsigned_int", by_const_reference::rewrap) + .def("rewrap_const_reference_short", by_const_reference::rewrap) + .def("rewrap_const_reference_unsigned_short", by_const_reference::rewrap) + .def("rewrap_const_reference_long", by_const_reference::rewrap) + .def("rewrap_const_reference_unsigned_long", by_const_reference::rewrap) + .def("rewrap_const_reference_float", by_const_reference::rewrap) + .def("rewrap_const_reference_double", by_const_reference::rewrap) + .def("rewrap_const_reference_long_double", by_const_reference::rewrap) + .def("rewrap_const_reference_string", by_const_reference::rewrap) + .def("rewrap_const_reference_cstring", by_const_reference::rewrap) + + ; +} + diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py new file mode 100644 index 00000000..3941a29c --- /dev/null +++ b/test/test_builtin_converters.py @@ -0,0 +1,86 @@ +""" +>>> from builtin_converters_ext import * +>>> rewrap_value_signed_char(42) +42 +>>> rewrap_value_unsigned_char(42) +42 +>>> rewrap_value_int(42) +42 +>>> rewrap_value_unsigned_int(42) +42 +>>> rewrap_value_short(42) +42 +>>> rewrap_value_unsigned_short(42) +42 +>>> rewrap_value_long(42) +42 +>>> rewrap_value_unsigned_long(42) +42 + +>>> abs(rewrap_value_float(4.2) - 4.2) < .000001 +1 +>>> rewrap_value_double(4.2) - 4.2 +0.0 +>>> rewrap_value_long_double(4.2) - 4.2 +0.0 + +>>> rewrap_value_cstring('hello, world') +'hello, world' +>>> rewrap_value_string('yo, wassup?') +'yo, wassup?' + +>>> rewrap_const_reference_signed_char(42) +42 +>>> rewrap_const_reference_unsigned_char(42) +42 +>>> rewrap_const_reference_int(42) +42 +>>> rewrap_const_reference_unsigned_int(42) +42 +>>> rewrap_const_reference_short(42) +42 +>>> rewrap_const_reference_unsigned_short(42) +42 +>>> rewrap_const_reference_long(42) +42 +>>> rewrap_const_reference_unsigned_long(42) +42 +>>> abs(rewrap_const_reference_float(4.2) - 4.2) < .000001 +1 +>>> rewrap_const_reference_double(4.2) - 4.2 +0.0 +>>> rewrap_const_reference_long_double(4.2) - 4.2 +0.0 + +>>> rewrap_const_reference_cstring('hello, world') +'hello, world' +>>> rewrap_const_reference_string('yo, wassup?') +'yo, wassup?' + +Now check implicit conversions between floating/integer types + +>>> rewrap_const_reference_float(42) +42.0 + +>>> rewrap_const_reference_int(42.0) +42 + +>>> rewrap_value_float(42) +42.0 + +>>> rewrap_value_int(42.0) +42 + +""" +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From b3117c2b02b9793325de5cc231e41327cac74903 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 1 Feb 2002 04:36:46 +0000 Subject: [PATCH 0215/1042] Use call policies [SVN r12618] --- include/boost/python/converter/smart_ptr.hpp | 70 ++ include/boost/python/converter/to_python.hpp | 2 +- include/boost/python/converter/type_id.hpp | 82 +- include/boost/python/copy_const_reference.hpp | 42 + .../boost/python/copy_non_const_reference.hpp | 42 + .../boost/python/default_call_policies.hpp | 72 ++ include/boost/python/detail/caller.hpp | 220 ++++- .../boost/python/detail/indirect_traits.hpp | 116 +++ include/boost/python/detail/returning.hpp | 842 +++++++++++++----- include/boost/python/from_python.hpp | 42 + include/boost/python/make_function.hpp | 15 +- include/boost/python/module.hpp | 16 +- .../python/return_internal_reference.hpp | 45 + include/boost/python/return_value_policy.hpp | 20 + include/boost/python/to_python.hpp | 37 + include/boost/python/type_from_python.hpp | 23 + src/objects.cpp | 4 +- test/m1.cpp | 13 +- test/m2.cpp | 28 +- 19 files changed, 1380 insertions(+), 351 deletions(-) create mode 100644 include/boost/python/converter/smart_ptr.hpp create mode 100644 include/boost/python/copy_const_reference.hpp create mode 100644 include/boost/python/copy_non_const_reference.hpp create mode 100644 include/boost/python/default_call_policies.hpp create mode 100644 include/boost/python/detail/indirect_traits.hpp create mode 100644 include/boost/python/from_python.hpp create mode 100644 include/boost/python/return_internal_reference.hpp create mode 100644 include/boost/python/return_value_policy.hpp create mode 100644 include/boost/python/to_python.hpp create mode 100644 include/boost/python/type_from_python.hpp diff --git a/include/boost/python/converter/smart_ptr.hpp b/include/boost/python/converter/smart_ptr.hpp new file mode 100644 index 00000000..bae4c2b8 --- /dev/null +++ b/include/boost/python/converter/smart_ptr.hpp @@ -0,0 +1,70 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef SMART_PTR_DWA2002123_HPP +# define SMART_PTR_DWA2002123_HPP + +# include +# include +namespace boost { namespace python { namespace converter { + +template +class smart_ptr_wrapper + : wrapper +{ + smart_ptr_wrapper(ref const& type_) + : m_class_object(type_) + { + assert(type_->ob_type == (PyTypeObject*)class_metatype().get()); + } + + PyObject* convert(Pointer x) const; + + private: + ref m_class_object; + + smart_ptr_converters(); +} + + +// +// implementations +// + +template +PyObject* smart_ptr_wrapper::convert(Pointer x) const +{ + if (x.operator->() == 0) + return detail::none(); + + // Don't call the type to do the construction, since that + // would require the registration of an __init__ copy + // constructor. Instead, just construct the object in place. + PyObject* raw_result = (PyObject*)PyObject_New( + instance, (PyTypeObject*)m_class_object.get()); + + if (raw_result == 0) + return 0; + + // Everything's OK; Bypass NULL checks but guard against + // exceptions. + ref result(raw_result, ref::allow_null()); + + // Build a value_holder to contain the object using the copy + // constructor + objects::pointer_holder* + p = new objects::pointer_holder(x); + + // Install it in the instance + p->install(raw_result); + + // Return the new result + return result.release(); +} + + +}}} // namespace boost::python::converter + +#endif // SMART_PTR_DWA2002123_HPP diff --git a/include/boost/python/converter/to_python.hpp b/include/boost/python/converter/to_python.hpp index 61dc7dad..a1d6c28b 100644 --- a/include/boost/python/converter/to_python.hpp +++ b/include/boost/python/converter/to_python.hpp @@ -101,7 +101,7 @@ template inline bool to_python_lookup::convertible() const { - return m_converter != 0; + return m_convert != 0; } template diff --git a/include/boost/python/converter/type_id.hpp b/include/boost/python/converter/type_id.hpp index fd731f83..e5068604 100644 --- a/include/boost/python/converter/type_id.hpp +++ b/include/boost/python/converter/type_id.hpp @@ -6,10 +6,8 @@ #ifndef TYPE_ID_DWA20011127_HPP # define TYPE_ID_DWA20011127_HPP # include -# include +# include # include -# include -# include # include # include # include @@ -79,80 +77,6 @@ struct type_id_t : totally_ordered base_id_t m_base_type; }; -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_reference_to_const -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -template -struct is_reference_to_const -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; - -template -struct is_reference_to_volatile -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -template -struct is_reference_to_volatile -{ - BOOST_STATIC_CONSTANT(bool, value = true); -}; -# else -template -struct is_const_help -{ - typedef typename mpl::select_type< - is_const::value - , type_traits::yes_type - , type_traits::no_type - >::type type; -}; - -template -struct is_volatile_help -{ - typedef typename mpl::select_type< - is_volatile::value - , type_traits::yes_type - , type_traits::no_type - >::type type; -}; - -template -typename is_const_help::type reference_to_const_helper(V&); - -type_traits::no_type -reference_to_const_helper(...); - -template -struct is_reference_to_const -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_const_helper(t)) == sizeof(type_traits::yes_type)); -}; - -template -typename is_volatile_help::type reference_to_volatile_helper(V&); -type_traits::no_type reference_to_volatile_helper(...); - -template -struct is_reference_to_volatile -{ - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = sizeof(reference_to_volatile_helper(t)) == sizeof(type_traits::yes_type)); -}; -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template inline undecorated_type_id_t undecorated_type_id(detail::dummy* = 0) { @@ -165,9 +89,9 @@ inline type_id_t type_id(detail::dummy* = 0) return type_id_t( undecorated_type_id() , type_id_t::decoration( - (is_const::value || is_reference_to_const::value + (is_const::value || python::detail::is_reference_to_const::value ? type_id_t::const_ : 0) - | (is_volatile::value || is_reference_to_volatile::value + | (is_volatile::value || python::detail::is_reference_to_volatile::value ? type_id_t::volatile_ : 0) | (is_reference::value ? type_id_t::reference : 0) ) diff --git a/include/boost/python/copy_const_reference.hpp b/include/boost/python/copy_const_reference.hpp new file mode 100644 index 00000000..55e8f87f --- /dev/null +++ b/include/boost/python/copy_const_reference.hpp @@ -0,0 +1,42 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef COPY_CONST_REFERENCE_DWA2002131_HPP +# define COPY_CONST_REFERENCE_DWA2002131_HPP +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + template + struct copy_const_reference_expects_a_const_reference_return_type +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} +# endif + ; +} + +template struct to_python; + +struct copy_const_reference +{ + template + struct apply + { + typedef typename mpl::select_type< + detail::is_reference_to_const::value + , to_python + , detail::copy_const_reference_expects_a_const_reference_return_type + >::type type; + }; +}; + + +}} // namespace boost::python + +#endif // COPY_CONST_REFERENCE_DWA2002131_HPP diff --git a/include/boost/python/copy_non_const_reference.hpp b/include/boost/python/copy_non_const_reference.hpp new file mode 100644 index 00000000..4afdc369 --- /dev/null +++ b/include/boost/python/copy_non_const_reference.hpp @@ -0,0 +1,42 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef COPY_NON_CONST_REFERENCE_DWA2002131_HPP +# define COPY_NON_CONST_REFERENCE_DWA2002131_HPP +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + template + struct copy_non_const_reference_expects_a_non_const_reference_return_type +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} +# endif + ; +} + +template struct to_python; + +struct copy_non_const_reference +{ + template + struct apply + { + typedef typename mpl::select_type< + boost::python::detail::is_reference_to_non_const::value + , to_python + , detail::copy_non_const_reference_expects_a_non_const_reference_return_type + >::type type; + }; +}; + + +}} // namespace boost::python + +#endif // COPY_NON_CONST_REFERENCE_DWA2002131_HPP diff --git a/include/boost/python/default_call_policies.hpp b/include/boost/python/default_call_policies.hpp new file mode 100644 index 00000000..3dc3d4d4 --- /dev/null +++ b/include/boost/python/default_call_policies.hpp @@ -0,0 +1,72 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef DEFAULT_CALL_POLICIES_DWA2002131_HPP +# define DEFAULT_CALL_POLICIES_DWA2002131_HPP +# include +# include + +namespace boost { namespace python { + +template struct to_python; + +namespace detail +{ +// for "readable" error messages + template struct specify_a_result_policy_to_wrap_functions_returning +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} +# endif + ; +} + +struct default_result_converter; + +struct default_call_policies +{ + // Nothing to do + static bool precall(PyObject*) + { + return true; + } + + // Pass the result through + static PyObject* postcall(PyObject*, PyObject* result) + { + return result; + } + + typedef default_result_converter result_converter; +}; + +struct default_result_converter +{ + template + struct apply + { + typedef typename mpl::select_type< + is_reference::value | is_pointer::value + , detail::specify_a_result_policy_to_wrap_functions_returning + , to_python + >::type type; + }; +}; + +// Exceptions for c strings an PyObject*s +template <> +struct default_result_converter::apply +{ + typedef boost::python::to_python type; +}; + +template <> +struct default_result_converter::apply +{ + typedef boost::python::to_python type; +}; + +}} // namespace boost::python + +#endif // DEFAULT_CALL_POLICIES_DWA2002131_HPP diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index 95c6dc7a..fe022961 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -6,19 +6,229 @@ #ifndef CALLER_DWA20011214_HPP # define CALLER_DWA20011214_HPP -# include # include +# include +# include +# include +# include +# include -namespace boost { namespace python { namespace detail { +namespace boost { namespace python +{ + template struct to_python; +}} + +namespace boost { namespace python { namespace detail { + +// for "readable" error messages +template struct must_use_a_result_handler_to_wrap_functions_returning +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) +{} +# endif +; + +struct to_python_generator +{ + template + struct apply + { + typedef typename mpl::select_type< + is_reference::value | is_pointer::value + , must_use_a_result_handler_to_wrap_functions_returning + , to_python + >::type type; + }; +}; struct caller { typedef PyObject* result_type; - template - PyObject* operator()(F f, PyObject* args, PyObject* keywords) + template + PyObject* operator()(R (*f)(), PyObject* args, PyObject* keywords, P const& policies) const { - return call(f, args, keywords); + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (*f)(A0), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (*f)(A0, A1), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + +// Member functions + template + PyObject* operator()(R (A0::*f)(), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)() const, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)() volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); + } + + template + PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords, P const& policies) const + { + return returning::call(f, args, keywords, policies); } }; diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp new file mode 100644 index 00000000..c76ffbc0 --- /dev/null +++ b/include/boost/python/detail/indirect_traits.hpp @@ -0,0 +1,116 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef INDIRECT_TRAITS_DWA2002131_HPP +# define INDIRECT_TRAITS_DWA2002131_HPP +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct is_reference_to_const +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_reference_to_const +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template +struct is_reference_to_non_const +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_reference_to_non_const +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template +struct is_reference_to_volatile +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_reference_to_volatile +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; +# else + +typedef char (&inner_yes_type)[3]; +typedef char (&inner_no_type)[2]; +typedef char (&outer_no_type)[1]; + +template +struct is_const_help +{ + typedef typename mpl::select_type< + is_const::value + , inner_yes_type + , inner_no_type + >::type type; +}; + +template +struct is_volatile_help +{ + typedef typename mpl::select_type< + is_volatile::value + , inner_yes_type + , inner_no_type + >::type type; +}; + +template +typename is_const_help::type reference_to_const_helper(V&); + +outer_no_type +reference_to_const_helper(...); + +template +struct is_reference_to_const +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); +}; + +template +struct is_reference_to_non_const +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)); +}; + +template +typename is_volatile_help::type reference_to_volatile_helper(V&); +outer_no_type reference_to_volatile_helper(...); + +template +struct is_reference_to_volatile +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)); +}; +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +}}} // namespace boost::python::detail + +#endif // INDIRECT_TRAITS_DWA2002131_HPP diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 4aa228b5..c8533f9e 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -18,25 +18,38 @@ # include # include +namespace boost { namespace python +{ + template struct to_python; +}} // namespace boost::python + namespace boost { namespace python { namespace detail { // Calling C++ from Python template struct returning { - template - static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -45,11 +58,19 @@ struct returning if (!c1.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -60,11 +81,19 @@ struct returning if (!c2.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -77,11 +106,19 @@ struct returning if (!c3.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -96,11 +133,19 @@ struct returning if (!c4.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -117,23 +162,39 @@ struct returning if (!c5.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -142,11 +203,19 @@ struct returning if (!c1.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -157,11 +226,19 @@ struct returning if (!c2.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -174,11 +251,19 @@ struct returning if (!c3.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -193,11 +278,19 @@ struct returning if (!c4.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -214,23 +307,39 @@ struct returning if (!c5.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -239,11 +348,19 @@ struct returning if (!c1.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -254,11 +371,19 @@ struct returning if (!c2.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -271,11 +396,19 @@ struct returning if (!c3.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -290,11 +423,19 @@ struct returning if (!c4.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -311,26 +452,42 @@ struct returning if (!c5.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); + + if (!result) return 0; + return policies.postcall(args, result); } // missing const volatile type traits # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -339,11 +496,19 @@ struct returning if (!c1.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -354,11 +519,19 @@ struct returning if (!c2.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -371,11 +544,19 @@ struct returning if (!c3.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -390,11 +571,19 @@ struct returning if (!c4.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -411,31 +600,58 @@ struct returning if (!c5.convertible()) return 0; // find the result converter - to_python r; - return r( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); + + if (!result) return 0; + return policies.postcall(args, result); } # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - static PyObject* call(R (*pf)(), PyObject*, PyObject* /* keywords */ ) + + + template + static PyObject* call(R (*pf)(), PyObject* args, PyObject*, P const& policies) { // find the result converter - to_python c0; - return c0( (*pf)() ); + typedef typename P::result_converter result_converter; + typename eval::type c0; + if (!c0.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = c0( (*pf)() ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (*pf)(A0), PyObject* args, PyObject* /* keywords */ ) + + template + static PyObject* call(R (*pf)(A0), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; // find the result converter - to_python c1; - return c1( (*pf)(c0(PyTuple_GET_ITEM(args, 0))) ); + typedef typename P::result_converter result_converter; + typename eval::type c1; + if (!c1.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = c1( (*pf)(c0(PyTuple_GET_ITEM(args, 0))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -444,11 +660,19 @@ struct returning if (!c1.convertible()) return 0; // find the result converter - to_python c2; - return c2( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1))) ); + typedef typename P::result_converter result_converter; + typename eval::type c2; + if (!c2.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = c2( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -459,11 +683,19 @@ struct returning if (!c2.convertible()) return 0; // find the result converter - to_python c3; - return c3( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); + typedef typename P::result_converter result_converter; + typename eval::type c3; + if (!c3.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = c3( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -476,11 +708,19 @@ struct returning if (!c3.convertible()) return 0; // find the result converter - to_python c4; - return c4( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); + typedef typename P::result_converter result_converter; + typename eval::type c4; + if (!c4.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = c4( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -495,11 +735,19 @@ struct returning if (!c4.convertible()) return 0; // find the result converter - to_python c5; - return c5( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); + typedef typename P::result_converter result_converter; + typename eval::type c5; + if (!c5.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = c5( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); + + if (!result) return 0; + return policies.postcall(args, result); } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -516,8 +764,16 @@ struct returning if (!c5.convertible()) return 0; // find the result converter - to_python c6; - return c6( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); + typedef typename P::result_converter result_converter; + typename eval::type c6; + if (!c6.convertible()) return 0; + + if (!policies.precall(args)) return 0; + + PyObject* result = c6( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); + + if (!result) return 0; + return policies.postcall(args, result); } }; @@ -525,30 +781,36 @@ template <> struct returning { typedef void R; - template - static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; from_python c1(PyTuple_GET_ITEM(args, 1)); if (!c1.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -557,12 +819,15 @@ struct returning if (!c1.convertible()) return 0; from_python c2(PyTuple_GET_ITEM(args, 2)); if (!c2.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -573,12 +838,15 @@ struct returning if (!c2.convertible()) return 0; from_python c3(PyTuple_GET_ITEM(args, 3)); if (!c3.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -591,12 +859,15 @@ struct returning if (!c3.convertible()) return 0; from_python c4(PyTuple_GET_ITEM(args, 4)); if (!c4.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -611,35 +882,44 @@ struct returning if (!c4.convertible()) return 0; from_python c5(PyTuple_GET_ITEM(args, 5)); if (!c5.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; from_python c1(PyTuple_GET_ITEM(args, 1)); if (!c1.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -648,12 +928,15 @@ struct returning if (!c1.convertible()) return 0; from_python c2(PyTuple_GET_ITEM(args, 2)); if (!c2.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -664,12 +947,15 @@ struct returning if (!c2.convertible()) return 0; from_python c3(PyTuple_GET_ITEM(args, 3)); if (!c3.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -682,12 +968,15 @@ struct returning if (!c3.convertible()) return 0; from_python c4(PyTuple_GET_ITEM(args, 4)); if (!c4.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -702,35 +991,44 @@ struct returning if (!c4.convertible()) return 0; from_python c5(PyTuple_GET_ITEM(args, 5)); if (!c5.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; from_python c1(PyTuple_GET_ITEM(args, 1)); if (!c1.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -739,12 +1037,15 @@ struct returning if (!c1.convertible()) return 0; from_python c2(PyTuple_GET_ITEM(args, 2)); if (!c2.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -755,12 +1056,15 @@ struct returning if (!c2.convertible()) return 0; from_python c3(PyTuple_GET_ITEM(args, 3)); if (!c3.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -773,12 +1077,15 @@ struct returning if (!c3.convertible()) return 0; from_python c4(PyTuple_GET_ITEM(args, 4)); if (!c4.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -793,38 +1100,47 @@ struct returning if (!c4.convertible()) return 0; from_python c5(PyTuple_GET_ITEM(args, 5)); if (!c5.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - return detail::none(); + + return policies.postcall(args, detail::none()); } // missing const volatile type traits # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; from_python c1(PyTuple_GET_ITEM(args, 1)); if (!c1.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -833,12 +1149,15 @@ struct returning if (!c1.convertible()) return 0; from_python c2(PyTuple_GET_ITEM(args, 2)); if (!c2.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -849,12 +1168,15 @@ struct returning if (!c2.convertible()) return 0; from_python c3(PyTuple_GET_ITEM(args, 3)); if (!c3.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -867,12 +1189,15 @@ struct returning if (!c3.convertible()) return 0; from_python c4(PyTuple_GET_ITEM(args, 4)); if (!c4.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -887,42 +1212,53 @@ struct returning if (!c4.convertible()) return 0; from_python c5(PyTuple_GET_ITEM(args, 5)); if (!c5.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - return detail::none(); + + return policies.postcall(args, detail::none()); } # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - static PyObject* call(R (*pf)(), PyObject*, PyObject* /* keywords */ ) + + template + static PyObject* call(R (*pf)(), PyObject*, PyObject*, P const& policies) { (*pf)(); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (*pf)(A0), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (*pf)(A0), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + (*pf)(c0(PyTuple_GET_ITEM(args, 0))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); if (!c0.convertible()) return 0; from_python c1(PyTuple_GET_ITEM(args, 1)); if (!c1.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -931,12 +1267,15 @@ struct returning if (!c1.convertible()) return 0; from_python c2(PyTuple_GET_ITEM(args, 2)); if (!c2.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -947,12 +1286,15 @@ struct returning if (!c2.convertible()) return 0; from_python c3(PyTuple_GET_ITEM(args, 3)); if (!c3.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -965,12 +1307,15 @@ struct returning if (!c3.convertible()) return 0; from_python c4(PyTuple_GET_ITEM(args, 4)); if (!c4.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - return detail::none(); + + return policies.postcall(args, detail::none()); } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) + template + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) { // check that each of the arguments is convertible from_python c0(PyTuple_GET_ITEM(args, 0)); @@ -985,9 +1330,12 @@ struct returning if (!c4.convertible()) return 0; from_python c5(PyTuple_GET_ITEM(args, 5)); if (!c5.convertible()) return 0; - + + if (!policies.precall(args)) return 0; + (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - return detail::none(); + + return policies.postcall(args, detail::none()); } }; diff --git a/include/boost/python/from_python.hpp b/include/boost/python/from_python.hpp new file mode 100644 index 00000000..995f7877 --- /dev/null +++ b/include/boost/python/from_python.hpp @@ -0,0 +1,42 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FROM_PYTHON_DWA2002128_HPP +# define FROM_PYTHON_DWA2002128_HPP + +# include +# include + +namespace boost { namespace python { + +template +struct from_python + : converter::from_python_lookup::type> +{ + typedef converter::from_python_lookup::type> base; + from_python(PyObject*); +}; + +// specialization for PyObject* +template <> +struct from_python +{ + from_python(PyObject*) {} + bool convertible() const { return true; } + PyObject* operator()(PyObject* source) const { return source; } +}; + +// +// implementations +// +template +from_python::from_python(PyObject* source) + : base(source) +{ +} + +}} // namespace boost::python + +#endif // FROM_PYTHON_DWA2002128_HPP diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index dfd11865..6f989256 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -15,6 +15,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -24,7 +25,17 @@ objects::function* make_function(F f) converter::acquire_registrations(detail::signature(f)); return new objects::function( objects::py_function( - ::boost::bind(detail::caller(), f, _1, _2)) + ::boost::bind(detail::caller(), f, _1, _2, default_call_policies())) + , detail::arg_tuple_size::value); +} + +template +objects::function* make_function(F f, Policies const& policies) +{ + converter::acquire_registrations(detail::signature(f)); + return new objects::function( + objects::py_function( + ::boost::bind(detail::caller(), f, _1, _2, policies)) , detail::arg_tuple_size::value); } @@ -41,7 +52,7 @@ objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0) ::boost::bind(detail::caller(), objects::make_holder ::template apply::execute - , _1, _2)) + , _1, _2, default_call_policies())) , nargs + 1); } diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 5661e106..3a243b06 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -58,20 +58,20 @@ class module : public module_base return *this; } -# if 0 - template - void def_raw(char const* name, Fn fn) - { - add(detail::new_raw_arguments_function(fn), name); - } -# endif - template module& def(char const* name, Fn fn) { this->setattr(name, boost::python::make_function(fn)); return *this; } + + + template + module& def(char const* name, Fn fn, ResultHandler handler) + { + this->setattr(name, boost::python::make_function(fn, handler)); + return *this; + } }; // diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp new file mode 100644 index 00000000..ac7f3fbf --- /dev/null +++ b/include/boost/python/return_internal_reference.hpp @@ -0,0 +1,45 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef RETURN_INTERNAL_REFERENCE_DWA2002131_HPP +# define RETURN_INTERNAL_REFERENCE_DWA2002131_HPP + +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + template + struct return_internal_reference_requires_a_pointer_or_reference_return_type +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} +# endif + ; +}; + +struct internal_reference_to_python_generator +{ + template + struct apply + { + typedef typename mpl::select_type< + !is_object::value + , internal_reference_to_python + , detail::return_internal_reference_requires_a_pointer_or_reference_return_type + >::type type; + }; +}; + +template +struct return_internal_reference : Base +{ + typedef wrap_internal_reference result_converter; +}; + +}} // namespace boost::python + +#endif // RETURN_INTERNAL_REFERENCE_DWA2002131_HPP diff --git a/include/boost/python/return_value_policy.hpp b/include/boost/python/return_value_policy.hpp new file mode 100644 index 00000000..0beec47b --- /dev/null +++ b/include/boost/python/return_value_policy.hpp @@ -0,0 +1,20 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef RETURN_VALUE_POLICY_DWA2002131_HPP +# define RETURN_VALUE_POLICY_DWA2002131_HPP +# include + +namespace boost { namespace python { + +template +struct return_value_policy : Base +{ + typedef Handler result_converter; +}; + +}} // namespace boost::python + +#endif // RETURN_VALUE_POLICY_DWA2002131_HPP diff --git a/include/boost/python/to_python.hpp b/include/boost/python/to_python.hpp new file mode 100644 index 00000000..e00346bb --- /dev/null +++ b/include/boost/python/to_python.hpp @@ -0,0 +1,37 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TO_PYTHON_DWA2002128_HPP +# define TO_PYTHON_DWA2002128_HPP + +# include +# include + +namespace boost { namespace python { + +template +struct to_python + : converter::to_python_lookup::type> +{ +}; + +// specialization for PyObject* +template <> +struct to_python +{ + bool convertible() const { return true; } + PyObject* operator()(PyObject* source) const { return source; } +}; + +template <> +struct to_python +{ + bool convertible() const { return true; } + PyObject* operator()(PyObject* source) const { return source; } +}; + +}} // namespace boost::python + +#endif // TO_PYTHON_DWA2002128_HPP diff --git a/include/boost/python/type_from_python.hpp b/include/boost/python/type_from_python.hpp new file mode 100644 index 00000000..46d59d13 --- /dev/null +++ b/include/boost/python/type_from_python.hpp @@ -0,0 +1,23 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TYPE_FROM_PYTHON_DWA2002130_HPP +# define TYPE_FROM_PYTHON_DWA2002130_HPP + +namespace boost { namespace python { + +template +struct type_from_python +{ + static void* convertible(PyObject* op) + { + return PyObject_TypeCheck( + op, const_cast(python_type)) ? op : 0; + } +}; + +}} // namespace boost::python + +#endif // TYPE_FROM_PYTHON_DWA2002130_HPP diff --git a/src/objects.cpp b/src/objects.cpp index 90417dac..b447b262 100644 --- a/src/objects.cpp +++ b/src/objects.cpp @@ -8,7 +8,9 @@ // TODO: Move inline implementations from objects.cpp here -#define BOOST_PYTHON_SOURCE +#ifndef BOOST_PYTHON_SOURCE +r# define BOOST_PYTHON_SOURCE +#endif #include #include diff --git a/test/m1.cpp b/test/m1.cpp index d422b426..b807dc43 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -12,7 +12,8 @@ #include #include #include -//#include +#include +#include #include #include #include @@ -198,6 +199,9 @@ BOOST_PYTHON_MODULE_INIT(m1) using boost::python::value_from_python; using boost::python::type_from_python; using boost::python::get_member; + using boost::python::copy_const_reference; + using boost::python::return_value_policy; + using boost::mpl::type_list; // Create the converters; they are self-registering/unregistering. static to_python_converter c1(simple_to_python); @@ -239,7 +243,8 @@ BOOST_PYTHON_MODULE_INIT(m1) .def("f", f) // Expose g() - .def("g", g) + .def("g", g , return_value_policy() + ) .def("take_a", take_a) .def("take_b", take_b) @@ -279,8 +284,8 @@ BOOST_PYTHON_MODULE_INIT(m1) .add( class_("complicated") - .def_init(args()) - .def_init(args()) + .def_init(type_list()) + .def_init(type_list()) .def("get_n", &complicated::get_n) ) ; diff --git a/test/m2.cpp b/test/m2.cpp index 0a5df161..afffb27d 100644 --- a/test/m2.cpp +++ b/test/m2.cpp @@ -8,6 +8,9 @@ // by exposing raw Python extension functions that use wrap<> and // unwrap<> objects. #include +#include +#include +#include #include "simple_type.hpp" // Get a simple (by value) from the argument, and return the @@ -59,6 +62,10 @@ struct rewrap BOOST_PYTHON_MODULE_INIT(m2) { + using boost::python::return_value_policy; + using boost::python::copy_const_reference; + using boost::python::copy_non_const_reference; + boost::python::module("m2") .def("unwrap_int", unwrap_int) .def("unwrap_int_ref", unwrap_int_ref) @@ -68,11 +75,24 @@ BOOST_PYTHON_MODULE_INIT(m2) .def("unwrap_simple_const_ref", unwrap_simple_const_ref) .def("wrap_int", &rewrap::f) - .def("wrap_int_ref", &rewrap::f) - .def("wrap_int_const_ref", &rewrap::f) + + .def("wrap_int_ref", &rewrap::f + , return_value_policy() + ) + + .def("wrap_int_const_ref", &rewrap::f + , return_value_policy() + ) + .def("wrap_simple", &rewrap::f) - .def("wrap_simple_ref", &rewrap::f) - .def("wrap_simple_const_ref", &rewrap::f) + + .def("wrap_simple_ref", &rewrap::f + , return_value_policy() + ) + + .def("wrap_simple_const_ref", &rewrap::f + , return_value_policy() + ) ; } From 7a16cd4c37525ff4ce58cf8f074d80633a019668 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Feb 2002 00:46:38 +0000 Subject: [PATCH 0216/1042] remove local rule usage for the time being. [SVN r12625] --- build/Jamfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Jamfile b/build/Jamfile index 7fd8c285..744c8ec2 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -136,7 +136,7 @@ bpl-test noncopyable_import : ../example/noncopyable_import.cpp ; ############## cross-module tests from ../example ########## # A simple rule to build a test which depends on multiple modules in the PYTHONPATH -local rule boost-python-multi-example-runtest ( test-name : modules + ) +rule boost-python-multi-example-runtest ( test-name : modules + ) { boost-python-runtest $(test-name) : ../example/tst_$(test-name).py $(modules) libboost_python From 684e391a9a38d4fb2687bc634da7e102e45727ed Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Feb 2002 00:49:24 +0000 Subject: [PATCH 0217/1042] remove local rule usage for the time being. [SVN r12626] --- build/Jamfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index 744c8ec2..1ea3665d 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -64,7 +64,7 @@ include python.jam ; local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_DYNAMIC_LIB ; ####################### -local rule bpl-test ( test-name : sources + ) +rule bpl-test ( test-name : sources + ) { boost-python-test $(test-name) : $(sources) libboost_python ; } @@ -108,7 +108,7 @@ boost-python-runtest comprehensive ############# simple tests from ../example ############ -local rule boost-python-example-runtest ( name ) +rule boost-python-example-runtest ( name ) { bpl-test $(name) : ../example/$(name).cpp ; From 12988b879e344446decf84bcf6764383bf7e1c50 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Feb 2002 08:31:11 +0000 Subject: [PATCH 0218/1042] *** empty log message *** [SVN r12627] --- include/boost/python/copy_const_reference.hpp | 4 ++-- include/boost/python/copy_non_const_reference.hpp | 4 ++-- include/boost/python/default_call_policies.hpp | 12 ++++++++---- include/boost/python/make_function.hpp | 6 ------ 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/include/boost/python/copy_const_reference.hpp b/include/boost/python/copy_const_reference.hpp index 55e8f87f..57c45fd4 100644 --- a/include/boost/python/copy_const_reference.hpp +++ b/include/boost/python/copy_const_reference.hpp @@ -21,7 +21,7 @@ namespace detail ; } -template struct to_python; +template struct to_python_value; struct copy_const_reference { @@ -30,7 +30,7 @@ struct copy_const_reference { typedef typename mpl::select_type< detail::is_reference_to_const::value - , to_python + , to_python_value , detail::copy_const_reference_expects_a_const_reference_return_type >::type type; }; diff --git a/include/boost/python/copy_non_const_reference.hpp b/include/boost/python/copy_non_const_reference.hpp index 4afdc369..dead736f 100644 --- a/include/boost/python/copy_non_const_reference.hpp +++ b/include/boost/python/copy_non_const_reference.hpp @@ -21,7 +21,7 @@ namespace detail ; } -template struct to_python; +template struct to_python_value; struct copy_non_const_reference { @@ -30,7 +30,7 @@ struct copy_non_const_reference { typedef typename mpl::select_type< boost::python::detail::is_reference_to_non_const::value - , to_python + , to_python_value , detail::copy_non_const_reference_expects_a_non_const_reference_return_type >::type type; }; diff --git a/include/boost/python/default_call_policies.hpp b/include/boost/python/default_call_policies.hpp index 3dc3d4d4..475278e4 100644 --- a/include/boost/python/default_call_policies.hpp +++ b/include/boost/python/default_call_policies.hpp @@ -7,10 +7,12 @@ # define DEFAULT_CALL_POLICIES_DWA2002131_HPP # include # include +# include +# include namespace boost { namespace python { -template struct to_python; +template struct to_python_value; namespace detail { @@ -49,7 +51,9 @@ struct default_result_converter typedef typename mpl::select_type< is_reference::value | is_pointer::value , detail::specify_a_result_policy_to_wrap_functions_returning - , to_python + , boost::python::to_python_value< + typename add_reference::type>::type + > >::type type; }; }; @@ -58,13 +62,13 @@ struct default_result_converter template <> struct default_result_converter::apply { - typedef boost::python::to_python type; + typedef boost::python::to_python_value type; }; template <> struct default_result_converter::apply { - typedef boost::python::to_python type; + typedef boost::python::to_python_value type; }; }} // namespace boost::python diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index 6f989256..90a5c12b 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -11,7 +11,6 @@ # include # include # include -# include # include # include # include @@ -22,7 +21,6 @@ namespace boost { namespace python { template objects::function* make_function(F f) { - converter::acquire_registrations(detail::signature(f)); return new objects::function( objects::py_function( ::boost::bind(detail::caller(), f, _1, _2, default_call_policies())) @@ -32,7 +30,6 @@ objects::function* make_function(F f) template objects::function* make_function(F f, Policies const& policies) { - converter::acquire_registrations(detail::signature(f)); return new objects::function( objects::py_function( ::boost::bind(detail::caller(), f, _1, _2, policies)) @@ -44,9 +41,6 @@ objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0) { enum { nargs = mpl::size::value }; - typedef typename mpl::push_front::sequence signature; - converter::acquire_registrations(signature()); - return new objects::function( objects::py_function( ::boost::bind(detail::caller(), From 25c56164b02dd578677b664191deebb6d6dca52b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Feb 2002 14:04:48 +0000 Subject: [PATCH 0219/1042] Last rewrite of the type conversion mechanism, I hope [SVN r12631] --- Jamfile | 1 - example/rwgk2.cpp | 50 ------ example/rwgk3.cpp | 101 ----------- .../builtin_to_python_converters.hpp | 89 ++++------ .../boost/python/converter/from_python.hpp | 55 ++++-- .../boost/python/converter/registration.hpp | 148 ---------------- include/boost/python/converter/registry.hpp | 62 +------ include/boost/python/converter/source.hpp | 32 ---- .../boost/python/converter/source_holder.hpp | 24 --- include/boost/python/converter/to_python.hpp | 116 ------------- .../python/converter/to_python_function.hpp | 17 +- include/boost/python/converter/type_id.hpp | 25 +-- .../boost/python/converter/wrapper_base.hpp | 28 --- include/boost/python/copy_const_reference.hpp | 2 +- .../boost/python/copy_non_const_reference.hpp | 2 +- include/boost/python/detail/caller.hpp | 20 --- include/boost/python/detail/msvc_typeinfo.hpp | 99 +++++++++++ include/boost/python/detail/returning.hpp | 7 - include/boost/python/make_function.hpp | 1 - include/boost/python/object/class_wrapper.hpp | 16 +- include/boost/python/to_python.hpp | 37 ---- src/converter/builtin_converters.cpp | 1 - src/converter/from_python.cpp | 11 +- src/converter/registry.cpp | 164 +++++------------- src/converter/to_python.cpp | 24 --- src/converter/type_id.cpp | 6 - src/object/class.cpp | 3 +- test/m1.cpp | 44 ++--- test/newtest.py | 36 ++-- 29 files changed, 305 insertions(+), 916 deletions(-) delete mode 100644 example/rwgk2.cpp delete mode 100644 example/rwgk3.cpp delete mode 100644 include/boost/python/converter/registration.hpp delete mode 100644 include/boost/python/converter/source.hpp delete mode 100644 include/boost/python/converter/source_holder.hpp delete mode 100644 include/boost/python/converter/to_python.hpp delete mode 100644 include/boost/python/converter/wrapper_base.hpp create mode 100644 include/boost/python/detail/msvc_typeinfo.hpp delete mode 100644 include/boost/python/to_python.hpp delete mode 100644 src/converter/to_python.cpp diff --git a/Jamfile b/Jamfile index 684c21d5..fec34d51 100644 --- a/Jamfile +++ b/Jamfile @@ -15,7 +15,6 @@ PYTHON_PROPERTIES dll bpl : src/converter/from_python.cpp - src/converter/to_python.cpp src/converter/registry.cpp src/converter/type_id.cpp src/object/class.cpp diff --git a/example/rwgk2.cpp b/example/rwgk2.cpp deleted file mode 100644 index 35dce88f..00000000 --- a/example/rwgk2.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - private: - std::string country; - public: - world(const std::string& country) { this->country = country; } - std::string greet() const { return "Hello from " + country + "!"; } - }; - - // A function taking a world object as an argument. - std::string invite(const world& w) { - return w.greet() + " Please come soon!"; - } -} - -#include - -// Python requires an exported function called init in every -// extension module. This is where we build the module contents. -BOOST_PYTHON_MODULE_INIT(example2) -{ - // Create an object representing this extension module. - py::Module this_module("example2"); - - // Create the Python type object for our extension class. - py::ClassWrapper world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(py::Constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - - // Add invite() as a regular function to the module. - this_module.def(invite, "invite"); - - // Even better, invite() can also be made a member of world_class!!! - world_class.def(invite, "invite"); -} - -// Win32 DLL boilerplate -#if defined(_WIN32) -#include -extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; } -#endif // _WIN32 diff --git a/example/rwgk3.cpp b/example/rwgk3.cpp deleted file mode 100644 index df17b28e..00000000 --- a/example/rwgk3.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include - -#define rangei(n) for (int i = 0; i < n; i++) - -namespace { // Avoid cluttering the global namespace. - - // A wrapper is used to define additional constructors. - // - struct vector_double_wrapper: std::vector - { - // Tell the compiler how to convert a base class object to - // this wrapper object. - vector_double_wrapper(PyObject*, const std::vector& vd) - : std::vector(vd) {} - - vector_double_wrapper(PyObject* self) - : std::vector() {} - - vector_double_wrapper(PyObject* self, const int n) - : std::vector(n) {} - - vector_double_wrapper(PyObject* self, py::Tuple tuple) - : std::vector(tuple.size()) - { - std::vector::iterator vd = begin(); - rangei(tuple.size()) - vd[i] = from_python(tuple[i].get(), py::Type()); // GCC BUG - } - }; - - double getitem(const std::vector& vd, const std::size_t key) { - return vd[key]; - } - - void setitem(std::vector& vd, const std::size_t key, - const double &d) { - std::vector::iterator vditer = vd.begin(); - vditer[key] = d; - } - - void delitem(std::vector& vd, const std::size_t key) { - std::vector::iterator vditer = vd.begin(); - vd.erase(&vditer[key]); - } - - // Convert vector_double to a regular Python tuple. - // - py::Tuple as_tuple(const std::vector& vd) - { - py::Tuple t(vd.size()); - rangei(vd.size()) t.set_item(i, py::Ptr(py::to_python(vd[i]))); // GCC BUG - return t; - } - - // Function returning a vector_double object to Python. - // - std::vector foo(const int n) - { - std::vector vd(n); - std::vector::iterator vditer = vd.begin(); - rangei(n) vditer[i] = double(i); - return vd; - } - - // Same as foo(), but avoid copying on return. - // - std::auto_ptr > bar(const int n) - { - std::auto_ptr > vdptr(new std::vector(n)); - std::vector::iterator vditer = vdptr->begin(); - rangei(n) vditer[i] = double(10 * i); - return vdptr; - } -} - -BOOST_PYTHON_MODULE_INIT(example3) -{ - py::Module this_module("example3"); - - py::ClassWrapper, vector_double_wrapper> - vector_double(this_module, "vector_double"); - - vector_double.def(py::Constructor<>()); - vector_double.def(py::Constructor()); - vector_double.def(py::Constructor()); - vector_double.def(&std::vector::size, "__len__"); - vector_double.def(getitem, "__getitem__"); - vector_double.def(setitem, "__setitem__"); - vector_double.def(delitem, "__delitem__"); - vector_double.def(as_tuple, "as_tuple"); - - this_module.def(foo, "foo"); - this_module.def(bar, "bar"); -} - -// Win32 DLL boilerplate -#if defined(_WIN32) -#include -extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) { return 1; } -#endif // _WIN32 diff --git a/include/boost/python/converter/builtin_to_python_converters.hpp b/include/boost/python/converter/builtin_to_python_converters.hpp index 4e9f89e3..89ad7b86 100644 --- a/include/boost/python/converter/builtin_to_python_converters.hpp +++ b/include/boost/python/converter/builtin_to_python_converters.hpp @@ -8,20 +8,41 @@ # include # include -namespace boost { namespace python { namespace converter { +namespace boost { namespace python { -template struct to_python_lookup; +// Provide specializations of to_python_value +template struct to_python_value; -template -struct to_python_int +namespace detail { - bool convertible() const { return true; } - PyObject* operator()(T x) const { return PyInt_FromLong(long(x)); } -}; + struct builtin_to_python + { + static bool convertible() { return true; } + }; +} -# define BOOST_PYTHON_TO_INT(T) \ - template <> struct to_python_lookup : to_python_int {}; \ - template <> struct to_python_lookup : to_python_int {}; +# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ + template <> struct to_python_value \ + : detail::builtin_to_python \ + { \ + PyObject* operator()(T const& x) const \ + { \ + return (expr); \ + } \ + }; \ + template <> struct to_python_value \ + : detail::builtin_to_python \ + { \ + PyObject* operator()(T const& x) const \ + { \ + return (expr); \ + } \ + }; + + +# define BOOST_PYTHON_TO_INT(T) \ + BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \ + BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x)) BOOST_PYTHON_TO_INT(char) BOOST_PYTHON_TO_INT(short) @@ -29,47 +50,13 @@ BOOST_PYTHON_TO_INT(int) BOOST_PYTHON_TO_INT(long) # undef BOOST_TO_PYTHON_INT -template <> -struct to_python_lookup -{ - bool convertible() const { return true; } - PyObject* operator()(char const* x) const { return PyString_FromString(x); } -}; - -template <> -struct to_python_lookup -{ - bool convertible() const { return true; } - PyObject* operator()(std::string const& x) const - { - return PyString_FromString(x.c_str()); - } -}; +BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, PyString_FromString(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str())) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x) -template <> -struct to_python_lookup -{ - bool convertible() const { return true; } - PyObject* operator()(float x) const { return PyFloat_FromDouble(x); } -}; - -template <> -struct to_python_lookup -{ - bool convertible() const { return true; } - PyObject* operator()(double x) const { return PyFloat_FromDouble(x); } -}; - -template <> -struct to_python_lookup -{ - bool convertible() const { return true; } - PyObject* operator()(long double x) const - { - return PyFloat_FromDouble(x); - } -}; - -}}} // namespace boost::python::converter +}} // namespace boost::python::converter #endif // BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index 234f61d1..ee16a741 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -11,7 +11,7 @@ # include # include # include -# include +# include # include namespace boost { namespace python { namespace converter { @@ -29,16 +29,21 @@ template struct from_python_lookup; struct BOOST_PYTHON_DECL from_python_converter_base : body { from_python_converter_base(type_id_t, from_python_check); // registers - ~from_python_converter_base(); // unregisters // Must return non-null iff the conversion will be successful. Any // non-null pointer is acceptable, and will be passed on to the // convert() function, so useful data can be stored there. inline void* convertible(PyObject*) const; -// inline type_id_t key() const; + + // Given the head of a from_python converter chain, find the + // converter which can convert p, leaving its intermediate data in + // data. + inline static from_python_converter_base const* + find(from_python_converter_base const*chain, PyObject* p, void*& data); + private: -// type_id_t m_key; from_python_check m_convertible; + from_python_converter_base* m_next; }; @@ -52,17 +57,24 @@ struct from_python_converter : from_python_converter_base from_python_converter(from_python_check, conversion_function, from_python_destructor = 0); T convert(PyObject*, from_python_data&) const; void destroy(from_python_data&) const; + + // Find a converter for converting p to a T. + static from_python_converter const* find(PyObject* p, void*& data); private: // data members conversion_function m_convert; from_python_destructor m_destroy; + + // Keeps the chain of converters which convert from PyObject* to T + static from_python_converter_base*const& chain; }; -// ------------------------------------------------------------------------- +// Initialized to refer to a common place in the registry. +template +from_python_converter_base*const& +from_python_converter::chain = registry::from_python_chain(type_id()); -//struct from_python_base -//{ -//}; +// ------------------------------------------------------------------------- // A class which implements from_python with a registry lookup. template @@ -95,12 +107,21 @@ inline void* from_python_converter_base::convertible(PyObject* o) const return m_convertible(o); } -# if 0 -inline type_id_t from_python_converter_base::key() const +inline from_python_converter_base const* +from_python_converter_base::find( + from_python_converter_base const* chain, PyObject* p, void*& data) { - return m_key; + for (from_python_converter_base const* q = chain; q != 0 ; q = q->m_next) + { + void* d = q->convertible(p); + if (d != 0) + { + data = d; + return q; + } + } + return 0; } -# endif template inline from_python_converter::from_python_converter( @@ -115,6 +136,14 @@ inline from_python_converter::from_python_converter( } +template +inline from_python_converter const* +from_python_converter::find(PyObject* p, void*& data) +{ + return static_cast const*>( + from_python_converter_base::find(chain, p, data)); +} + template inline T from_python_converter::convert(PyObject* src, from_python_data& data) const { @@ -133,7 +162,7 @@ inline void from_python_converter::destroy(from_python_data& data) const template inline from_python_lookup::from_python_lookup(PyObject* src) : m_converter( - registration::get_from_python( + from_python_converter::find( src, m_intermediate_data.stage1)) { } diff --git a/include/boost/python/converter/registration.hpp b/include/boost/python/converter/registration.hpp deleted file mode 100644 index 39223d8a..00000000 --- a/include/boost/python/converter/registration.hpp +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef REGISTRATION_DWA20011130_HPP -# define REGISTRATION_DWA20011130_HPP -# include -# include -# include -# include -# include -# include -# include -# include -# ifdef BOOST_PYTHON_TRACE -# include -# endif - -namespace boost { namespace python { namespace converter { - -template struct from_python_converter; -template struct target; -template struct source; - -// This class is really sort of a "templated namespace". It manages a -// static data member which refers to the registry entry for T. This -// reference is acquired once to reduce the burden of multiple -// dictionary lookups at runtime. -template -struct registration -{ - public: // member functions - // Return a converter which can convert the given Python object to - // T, or 0 if no such converter exists. Fill in data with - // the result of the converter's check function - static from_python_converter const* get_from_python(PyObject*, void*& data); - - // Return a converter which can convert T to a Python object, or 0 - // if no such converter exists - static to_python_function::type get_to_python(); - - static registry::entry* find_entry(); - private: // helper functions - static registry::entry* entry(); - static registry::entry* known_entry(); - - private: // data members - static registry::entry* m_registry_entry; -}; - -namespace detail -{ - // An MPL BinaryMetaFunction class which initializes the - // registration entry for the target type of its 2nd argument. - struct setup_target_registration - { - template struct apply - { - typedef T type; - static void execute() - { - typedef typename target::type target_t; - registration::find_entry(); - } - }; - }; - - template - struct find_return_value_entry - { - static void execute() { registration::find_entry(); } - }; - - template <> - struct find_return_value_entry - { - static void execute() {} - }; - -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 - template <> - struct find_return_value_entry - { - static void execute() {} - }; -# endif -} - -template -void acquire_registrations(Sequence signature) -{ - typedef typename mpl::pop_front::sequence args; - typedef typename mpl::front::type return_type; - - mpl::for_each::execute(); - - typedef typename source::type return_source_type; - detail::find_return_value_entry::execute(); -} - - -// because this is static POD data it will be initialized to zero -template -registry::entry* registration::m_registry_entry; - -template -registry::entry* registration::find_entry() -{ - return m_registry_entry = registry::find(type_id()); -} - -template -inline registry::entry* registration::entry() -{ - if (!m_registry_entry) - find_entry(); - return m_registry_entry; -} - -template -inline registry::entry* registration::known_entry() -{ - assert(m_registry_entry != 0); - return m_registry_entry; -} - -template -from_python_converter const* registration::get_from_python(PyObject* p, void*& data) -{ - return static_cast const*>( - known_entry()->get_from_python(p, data) - ); -} - -template -typename to_python_function::type registration::get_to_python() -{ -# ifdef BOOST_PYTHON_TRACE - std::cout << "retrieving wrapper for " << type_id() << std::endl; -# endif - return reinterpret_cast::type>( - known_entry()->get_to_python()); -} - -}}} // namespace boost::python::converter - -#endif // REGISTRATION_DWA20011130_HPP diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index 21f31692..bdb64254 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -5,72 +5,26 @@ // to its suitability for any purpose. #ifndef REGISTRY_DWA20011127_HPP # define REGISTRY_DWA20011127_HPP -# include # include # include +# include # include -# include -# include -# include namespace boost { namespace python { namespace converter { struct BOOST_PYTHON_DECL from_python_converter_base; -struct BOOST_PYTHON_DECL to_python_converter_base; // This namespace acts as a sort of singleton namespace registry { - // These are the elements stored in the registry - class BOOST_PYTHON_DECL entry - { - public: // member functions - entry(); - ~entry(); - - // Return a converter appropriate for converting the given - // Python object from_python to the C++ type with which this - // converter is associated in the registry, or 0 if no such - // converter exists. - from_python_converter_base const* get_from_python(PyObject*, void*& data) const; - - // Return a conversion function appropriate for converting a C++ - // object whose type this entry is associated with in the - // registry to a Python object, or 0 if no such converter - // exists. This function must be reinterpret_cast to the - // appropriate to_python_function type. - to_python_function_base get_to_python() const; - - // Conversion classes use these functions to register - // themselves. - void insert(from_python_converter_base&); - void remove(from_python_converter_base&); - - void insert(to_python_converter_base&); - void remove(to_python_converter_base&); - - private: // types - typedef std::vector from_python_converters; - - private: // helper functions - from_python_converters::iterator find(from_python_converter_base const&); - - private: // data members - - // The collection of from_python converters for the associated - // C++ type. - from_python_converters m_from_python_converters; - - // The unique to_python converter for the associated C++ type. - to_python_converter_base* m_to_python_converter; - }; - - BOOST_PYTHON_DECL entry* find(type_id_t); + BOOST_PYTHON_DECL to_python_value_function const& + to_python_function(undecorated_type_id_t); - BOOST_PYTHON_DECL void insert(to_python_converter_base& x); - BOOST_PYTHON_DECL void insert(from_python_converter_base& x); - BOOST_PYTHON_DECL void remove(to_python_converter_base& x); - BOOST_PYTHON_DECL void remove(from_python_converter_base& x); + BOOST_PYTHON_DECL void insert(to_python_value_function, undecorated_type_id_t); + + BOOST_PYTHON_DECL from_python_converter_base*& from_python_chain(type_id_t); + + BOOST_PYTHON_DECL PyTypeObject*& class_object(undecorated_type_id_t key); } }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/source.hpp b/include/boost/python/converter/source.hpp deleted file mode 100644 index 9abf245f..00000000 --- a/include/boost/python/converter/source.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SOURCE_DWA20011119_HPP -# define SOURCE_DWA20011119_HPP -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -// source -- -// -// This type generator (see -// ../../../more/generic_programming.html#type_generator) is used -// to select the argument type to use when converting T to a PyObject* - -template -struct source -{ - typedef - typename add_reference< - typename add_const::type - >::type - type; -}; - -}}} // namespace boost::python::converter - -#endif // SOURCE_DWA20011119_HPP diff --git a/include/boost/python/converter/source_holder.hpp b/include/boost/python/converter/source_holder.hpp deleted file mode 100644 index f2c774f9..00000000 --- a/include/boost/python/converter/source_holder.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SOURCE_HOLDER_DWA20011215_HPP -# define SOURCE_HOLDER_DWA20011215_HPP - -namespace boost { namespace python { namespace converter { - -struct source_holder_base -{ -}; - -template -struct source_holder : source_holder_base -{ - source_holder(T x) : value(x) {} - T value; -}; - -}}} // namespace boost::python::converter - -#endif // SOURCE_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/converter/to_python.hpp b/include/boost/python/converter/to_python.hpp deleted file mode 100644 index a1d6c28b..00000000 --- a/include/boost/python/converter/to_python.hpp +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TO_PYTHON_DWA2002127_HPP -# define TO_PYTHON_DWA2002127_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -template struct to_python_lookup; - -struct BOOST_PYTHON_DECL to_python_converter_base : body -{ - to_python_converter_base(type_id_t, to_python_function_base); // registers - ~to_python_converter_base(); // unregisters - -// inline type_id_t key() const; - inline to_python_function_base converter() const; - private: -// type_id_t m_key; - to_python_function_base m_convert; -}; - -template -struct to_python_converter : to_python_converter_base -{ - public: // types - typedef typename to_python_function::type converter_t; - - public: // member functions - to_python_converter(converter_t); - converter_t converter() const; - - private: // data members - converter_t m_convert; -}; - -// ------------------------------------------------------------------------- - -//struct to_python_base {}; - -template -struct to_python_lookup //: to_python_base -{ - public: // member functions - to_python_lookup(); - bool convertible() const; - PyObject* operator()(T) const; - private: - typename to_python_function::type m_convert; -}; - -// -// implementations -// -# if 0 -inline type_id_t -to_python_converter_base::key() const -{ - return m_key; -} -# endif - -inline to_python_function_base -to_python_converter_base::converter() const -{ - return m_convert; -} - -template -to_python_converter::to_python_converter(converter_t convert) - : to_python_converter_base( - type_id(), reinterpret_cast(convert)) -{ -} - -template -inline typename to_python_function::type -to_python_converter::converter() const -{ - return reinterpret_cast( - this->to_python_converter_base::converter()); -} - -template -inline to_python_lookup::to_python_lookup() - : m_convert( - registration::get_to_python()) -{ -} - -template -inline bool -to_python_lookup::convertible() const -{ - return m_convert != 0; -} - -template -inline PyObject* -to_python_lookup::operator()(T x) const -{ - return m_convert ? m_convert(x) : 0; -} - -}}} // namespace boost::python::converter - -#endif // TO_PYTHON_DWA2002127_HPP diff --git a/include/boost/python/converter/to_python_function.hpp b/include/boost/python/converter/to_python_function.hpp index 9d408749..a438ce0c 100644 --- a/include/boost/python/converter/to_python_function.hpp +++ b/include/boost/python/converter/to_python_function.hpp @@ -7,15 +7,24 @@ # define TO_PYTHON_FUNCTION_DWA2002128_HPP # include +# include namespace boost { namespace python { namespace converter { -typedef PyObject* (*to_python_function_base)(void); +// The type of stored function pointers which actually do conversion +// by-value. The void* points to the object to be converted, and +// type-safety is preserved through runtime registration. +typedef PyObject* (*to_python_value_function)(void const*); -template -struct to_python_function +// Given a typesafe to_python conversion function, produces a +// to_python_value_function which can be registered in the usual way. +template +struct as_to_python_value_function { - typedef PyObject*(*type)(T); + static PyObject* convert(void const* x) + { + return ToPython::convert(*(T const*)x); + } }; }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/type_id.hpp b/include/boost/python/converter/type_id.hpp index e5068604..015e55e9 100644 --- a/include/boost/python/converter/type_id.hpp +++ b/include/boost/python/converter/type_id.hpp @@ -7,8 +7,12 @@ # define TYPE_ID_DWA20011127_HPP # include # include +# include +# include +# include # include # include +# include # include # include # include @@ -16,13 +20,6 @@ namespace boost { namespace python { namespace converter { -// a portable mechanism for identifying types at runtime across modules. - -namespace detail -{ - template class dummy; -} - // for this compiler at least, cross-shared-library type_info // comparisons don't work, so use typeid(x).name() instead. It's not // yet clear what the best default strategy is. @@ -61,7 +58,7 @@ struct type_id_t : totally_ordered { enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 }; - type_id_t(undecorated_type_id_t, decoration decoration); + type_id_t(undecorated_type_id_t, decoration = decoration()); bool operator<(type_id_t const& rhs) const; bool operator==(type_id_t const& rhs) const; @@ -78,13 +75,19 @@ struct type_id_t : totally_ordered }; template -inline undecorated_type_id_t undecorated_type_id(detail::dummy* = 0) +inline undecorated_type_id_t undecorated_type_id(boost::type* = 0) { - return undecorated_type_id_t(typeid(T)); + return undecorated_type_id_t( +# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) + typeid(T) +# else // strip the decoration which msvc and Intel mistakenly leave in + python::detail::msvc_typeid() +# endif + ); } template -inline type_id_t type_id(detail::dummy* = 0) +inline type_id_t type_id(boost::type* = 0) { return type_id_t( undecorated_type_id() diff --git a/include/boost/python/converter/wrapper_base.hpp b/include/boost/python/converter/wrapper_base.hpp deleted file mode 100644 index 585959ae..00000000 --- a/include/boost/python/converter/wrapper_base.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef WRAPPER_BASE_DWA2002110_HPP -# define WRAPPER_BASE_DWA2002110_HPP -# include -# include - -namespace boost { namespace python { namespace converter { - -struct source_holder_base; -struct wrap_base; -template struct wrap_more_; - -struct BOOST_PYTHON_DECL wrapper_base : body -{ - public: - wrapper_base(type_id_t); // registers - ~wrapper_base(); // unregisters - - virtual PyObject* do_conversion(wrap_base const&, source_holder_base const&) const = 0; -}; - -}}} // namespace boost::python::converter - -#endif // WRAPPER_BASE_DWA2002110_HPP diff --git a/include/boost/python/copy_const_reference.hpp b/include/boost/python/copy_const_reference.hpp index 57c45fd4..b2fdd61f 100644 --- a/include/boost/python/copy_const_reference.hpp +++ b/include/boost/python/copy_const_reference.hpp @@ -7,7 +7,7 @@ # define COPY_CONST_REFERENCE_DWA2002131_HPP # include # include -# include +# include namespace boost { namespace python { diff --git a/include/boost/python/copy_non_const_reference.hpp b/include/boost/python/copy_non_const_reference.hpp index dead736f..6f53fbdc 100644 --- a/include/boost/python/copy_non_const_reference.hpp +++ b/include/boost/python/copy_non_const_reference.hpp @@ -7,7 +7,7 @@ # define COPY_NON_CONST_REFERENCE_DWA2002131_HPP # include # include -# include +# include namespace boost { namespace python { diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index fe022961..d0b01b6e 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -20,26 +20,6 @@ namespace boost { namespace python namespace boost { namespace python { namespace detail { -// for "readable" error messages -template struct must_use_a_result_handler_to_wrap_functions_returning -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) -{} -# endif -; - -struct to_python_generator -{ - template - struct apply - { - typedef typename mpl::select_type< - is_reference::value | is_pointer::value - , must_use_a_result_handler_to_wrap_functions_returning - , to_python - >::type type; - }; -}; - struct caller { typedef PyObject* result_type; diff --git a/include/boost/python/detail/msvc_typeinfo.hpp b/include/boost/python/detail/msvc_typeinfo.hpp new file mode 100644 index 00000000..2473023a --- /dev/null +++ b/include/boost/python/detail/msvc_typeinfo.hpp @@ -0,0 +1,99 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MSVC_TYPEINFO_DWA200222_HPP +# define MSVC_TYPEINFO_DWA200222_HPP + +#include +#include + +// +// Fix for MSVC's broken typeid() implementation which doesn't strip +// decoration. This fix doesn't handle cv-qualified array types. It +// could probably be done, but I haven't figured it out yet. +// + +# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 600 + +namespace boost { namespace python { namespace detail { + +typedef std::type_info const& typeinfo; + +templatestruct value_id_accessor; + +template<> +struct value_id_accessor<0> +{ + template + static typeinfo get(T*) { return typeid(T); } +}; + +template<> +struct value_id_accessor<1> +{ + template + static typeinfo get(T const*) { return typeid(T); } +}; + +template<> +struct value_id_accessor<2> +{ + template + static typeinfo get(T volatile*) { return typeid(T); } +}; + +template<> +struct value_id_accessor<3> +{ + template + static typeinfo get(T const volatile*) { return typeid(T); } +}; + +template struct bool_t{}; + +template +inline typeinfo typeid_nonref(boost::type* = 0) +{ + BOOST_STATIC_CONSTANT(bool, c = is_const::value); + BOOST_STATIC_CONSTANT(bool, v = is_volatile::value); + return value_id_accessor<(2 * v + c)>::get((T*)0); +} + +template +inline typeinfo typeid_ref(boost::type*, ...) +{ + return typeid_nonref(); +} + +template +inline typeinfo typeid_ref(boost::type*, T& (*)()) +{ + return typeid_nonref(); +} + +template +inline typeinfo typeid_array(bool_t, boost::type* = 0) +{ + typedef T (*x)(); + return typeid_ref((boost::type*)0, x(0)); +} + +template +inline typeinfo typeid_array(bool_t, boost::type* = 0) +{ + return typeid_nonref(); +} + +template +inline typeinfo msvc_typeid(boost::type* = 0) +{ + typedef bool_t::value> tag; + return typeid_array(tag(), (boost::type*)0); +} + +}}} // namespace boost::python::detail + +# endif // BOOST_MSVC +#endif // MSVC_TYPEINFO_DWA200222_HPP diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index c8533f9e..99bbc572 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -11,17 +11,10 @@ #ifndef RETURNING_DWA20011201_HPP # define RETURNING_DWA20011201_HPP -//# include # include # include # include # include -# include - -namespace boost { namespace python -{ - template struct to_python; -}} // namespace boost::python namespace boost { namespace python { namespace detail { diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index 90a5c12b..2943d96c 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -8,7 +8,6 @@ # include # include -# include # include # include # include diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index 26334bc7..4a52f290 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -6,21 +6,18 @@ #ifndef CLASS_WRAPPER_DWA20011221_HPP # define CLASS_WRAPPER_DWA20011221_HPP -# include # include # include -# include -# include +# include namespace boost { namespace python { namespace objects { template struct class_wrapper - : converter::to_python_converter + : to_python_converter > { class_wrapper(ref const& type_) - : converter::to_python_converter(convert) - , m_class_object_keeper(type_) + : m_class_object_keeper(type_) { assert(type_->ob_type == (PyTypeObject*)class_metatype().get()); m_class_object = (PyTypeObject*)type_.get(); @@ -31,9 +28,8 @@ struct class_wrapper // Don't call the type to do the construction, since that // would require the registration of an __init__ copy // constructor. Instead, just construct the object in place. - PyObject* raw_result = (PyObject*)PyObject_New( - instance, m_class_object); - + PyObject* raw_result = m_class_object->tp_alloc(m_class_object, 0); + if (raw_result == 0) return 0; @@ -41,6 +37,8 @@ struct class_wrapper // exceptions. ref result(raw_result, ref::allow_null()); + ((instance*)raw_result)->objects = 0; + // Build a value_holder to contain the object using the copy // constructor value_holder* p = new value_holder(raw_result, cref(x)); diff --git a/include/boost/python/to_python.hpp b/include/boost/python/to_python.hpp deleted file mode 100644 index e00346bb..00000000 --- a/include/boost/python/to_python.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TO_PYTHON_DWA2002128_HPP -# define TO_PYTHON_DWA2002128_HPP - -# include -# include - -namespace boost { namespace python { - -template -struct to_python - : converter::to_python_lookup::type> -{ -}; - -// specialization for PyObject* -template <> -struct to_python -{ - bool convertible() const { return true; } - PyObject* operator()(PyObject* source) const { return source; } -}; - -template <> -struct to_python -{ - bool convertible() const { return true; } - PyObject* operator()(PyObject* source) const { return source; } -}; - -}} // namespace boost::python - -#endif // TO_PYTHON_DWA2002128_HPP diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index c2ce3dae..26834635 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -200,7 +200,6 @@ namespace #define REGISTER_INT_CONVERTERS(U) register_int_converters() #define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U) - void initialize_builtin_converters() { REGISTER_INT_CONVERTERS2(char); diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 979ad935..2e844acf 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -5,6 +5,7 @@ // to its suitability for any purpose. #include +#include namespace boost { namespace python { namespace converter { @@ -14,14 +15,12 @@ from_python_converter_base::from_python_converter_base( ) : body(type) , m_convertible(checker) -{ - registry::insert(*this); -} -from_python_converter_base::~from_python_converter_base() { - if (can_unregister()) - registry::remove(*this); + // Insert this in the converter chain. + from_python_converter_base*& head = registry::from_python_chain(type); + m_next = head; + head = this; } }}} // namespace boost::python::converter diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index 5b4563a4..c90d709d 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -3,23 +3,32 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. - -# include -# include -# include -# include -# include -# include -# include -# ifdef BOOST_PYTHON_TRACE -# include -# endif +#include +#include +#include +#include namespace boost { namespace python { namespace converter { namespace // { - typedef std::map registry_t; + // These are the elements stored in the registry + struct entry + { + entry(); + + // The unique to_python converter for the associated C++ type. + to_python_value_function m_to_python_converter; + + // The collection of from_python converters for the associated + // C++ type. + from_python_converter_base* m_from_python_converters; + + // The class object associated with this type + PyTypeObject* m_class_object; + }; + + typedef std::map registry_t; registry_t& entries() { @@ -35,10 +44,7 @@ namespace // } return registry; } -} // namespace -namespace registry -{ entry* find(type_id_t type) { return &entries()[type]; @@ -46,128 +52,40 @@ namespace registry entry::entry() : m_to_python_converter(0) + , m_from_python_converters(0) + , m_class_object(0) { } +} // namespace - entry::~entry() +namespace registry +{ + to_python_value_function const& to_python_function( + undecorated_type_id_t key) { - if (m_to_python_converter != 0) - m_to_python_converter->m_can_unregister = false; - - for (from_python_converters::iterator p = m_from_python_converters.begin() - ; p != m_from_python_converters.end() - ; ++p) - { - (*p)->m_can_unregister = false; - } - } - - from_python_converter_base const* - entry::get_from_python(PyObject* p, void*& data_out) const - { - for (from_python_converters::const_iterator q = m_from_python_converters.begin(), - finish = m_from_python_converters.end(); - q != finish; - ++q) - { - void* const data = (*q)->convertible(p); - if (data != 0) - { - data_out = data; - return *q; - break; - } - } - return 0; + return find(key)->m_to_python_converter; } - to_python_function_base entry::get_to_python() const + void insert(to_python_value_function f, undecorated_type_id_t source_t) { - return m_to_python_converter - ? m_to_python_converter->converter() - : 0; - } - - entry::from_python_converters::iterator entry::find(from_python_converter_base const& x) - { - return std::find(m_from_python_converters.begin(), m_from_python_converters.end(), &x); - } - - void entry::insert(from_python_converter_base& x) - { - from_python_converters::iterator p = this->find(x); - - if (p != m_from_python_converters.end()) - { - assert(!"converter already registered"); - throw std::runtime_error( - "trying to register unrapper which is already registered"); - } - - m_from_python_converters.push_back(&x); - } - - void entry::remove(from_python_converter_base& x) - { - from_python_converters::iterator p = find(x); - - // Be sure we're not removing a converter which hasn't been - // registered. - if (p == m_from_python_converters.end()) - { - assert(!"trying to unregister from_python_converter which is not registered"); - throw std::runtime_error( - "trying to unregister from_python_converter which is not registered"); - } - m_from_python_converters.erase(p); - } - - void entry::insert(to_python_converter_base& x) - { - assert(m_to_python_converter == 0); // we have a problem otherwise - if (m_to_python_converter != 0) + to_python_value_function& slot = find(source_t)->m_to_python_converter; + assert(slot == 0); // we have a problem otherwise + if (slot != 0) { throw std::runtime_error( "trying to register to_python_converter for a type which already has a registered to_python_converter"); } - m_to_python_converter = &x; + slot = f; + } + + from_python_converter_base*& from_python_chain(type_id_t key) + { + return find(key)->m_from_python_converters; } - void entry::remove(to_python_converter_base& x) + PyTypeObject*& class_object(undecorated_type_id_t key) { - assert(m_to_python_converter == &x); - if (m_to_python_converter != &x) - { - throw std::runtime_error( - "trying to unregister a to_python_converter which is not registered"); - } - m_to_python_converter = 0; - } - - void insert(to_python_converter_base& w) - { -# ifdef BOOST_PYTHON_TRACE - std::cout << "inserting to_python_converter for " << w.key() << std::endl; -# endif - find(w.key())->insert(w); - } - - void insert(from_python_converter_base& u) - { -# ifdef BOOST_PYTHON_TRACE - std::cout << "inserting from_python_converter for " << u.key() << std::endl; -# endif - find(u.key())->insert(u); - } - - void remove(to_python_converter_base& w) - { - find(w.key())->remove(w); - } - - void remove(from_python_converter_base& u) - { - find(u.key())->remove(u); + return find(key)->m_class_object; } } // namespace registry diff --git a/src/converter/to_python.cpp b/src/converter/to_python.cpp deleted file mode 100644 index 9cede51d..00000000 --- a/src/converter/to_python.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include - -namespace boost { namespace python { namespace converter { - -to_python_converter_base::to_python_converter_base(type_id_t key, to_python_function_base convert) - : body(key) - , m_convert(convert) -{ - registry::insert(*this); -} - -to_python_converter_base::~to_python_converter_base() -{ - registry::remove(*this); -} - -}}} // namespace boost::python::converter diff --git a/src/converter/type_id.cpp b/src/converter/type_id.cpp index 688dd2bc..904f30d0 100644 --- a/src/converter/type_id.cpp +++ b/src/converter/type_id.cpp @@ -21,18 +21,12 @@ BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, undecorated_type_id BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_id_t const& x) { os << x.m_base_type; - // VC6 mistakenly distinguishes typeid(X) from typeid(X const) - // from typeid(X&)... so the name is already correct. I have it - // from Jason Shirk that VC7.0 has the same bug but it will be - // fixed in 7.1 -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 if (x.m_decoration & type_id_t::const_) os << " const"; if (x.m_decoration & type_id_t::volatile_) os << " volatile"; if (x.m_decoration & type_id_t::reference) os << "&"; -# endif return os; } diff --git a/src/object/class.cpp b/src/object/class.cpp index de3e32f5..5d1ecf01 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -122,7 +121,7 @@ PyTypeObject class_type_object = { 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ - 0, /* tp_alloc */ + PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew }; diff --git a/test/m1.cpp b/test/m1.cpp index b807dc43..b42742ab 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -105,26 +106,19 @@ PyObject* new_simple() // are selected. // using boost::python::converter::from_python_data; +using boost::python::to_python_converter; -// Wrap a simple by converting it to a Simple -PyObject* simple_to_python(simple const& x) +// Wrap a simple by copying it into a Simple +struct simple_to_python + : to_python_converter { - SimpleObject* p = PyObject_New(SimpleObject, &SimpleType); - p->x = x; - return (PyObject*)p; -} - - -// wrap a mutable reference to a simple by converting it to a -// Simple. Normally we wouldn't do it this way, since modifications to -// the result clearly don't change the original object, but here we're -// just proving that the mechanism works. -PyObject* simple_ref_to_python(simple& x) -{ - SimpleObject* p = PyObject_New(SimpleObject, &SimpleType); - p->x = x; - return (PyObject*)p; -} + static PyObject* convert(simple const& x) + { + SimpleObject* p = PyObject_New(SimpleObject, &SimpleType); + p->x = x; + return (PyObject*)p; + } +}; int noddy_to_int(PyObject* p, from_python_data&) { @@ -184,16 +178,15 @@ struct D : B, C int x; }; -int take_a(A const& a) { return a.x; } -int take_b(B const& b) { return b.x; } -int take_c(C const& c) { return c.x; } -int take_d(D const& d) { return d.x; } +A take_a(A const& a) { return a; } +B take_b(B const& b) { return b; } +C take_c(C const& c) { return c; } +D take_d(D const& d) { return d; } BOOST_PYTHON_MODULE_INIT(m1) { using boost::python::module; using boost::python::class_; - using boost::python::converter::to_python_converter; using boost::python::converter::from_python_converter; using boost::python::reference_from_python; using boost::python::value_from_python; @@ -204,7 +197,7 @@ BOOST_PYTHON_MODULE_INIT(m1) using boost::mpl::type_list; // Create the converters; they are self-registering/unregistering. - static to_python_converter c1(simple_to_python); + static simple_to_python c1; static from_python_converter c2( &(boost::python::type_from_python<&NoddyType>::convertible), noddy_to_int); @@ -219,10 +212,7 @@ BOOST_PYTHON_MODULE_INIT(m1) , extract_simple_object > unwrap_simple; - - static to_python_converter simple_ref_wrapper(simple_ref_to_python); - module m1("m1"); typedef boost::python::objects::pointer_holder_generator< diff --git a/test/newtest.py b/test/newtest.py index 0636641b..4e6de142 100644 --- a/test/newtest.py +++ b/test/newtest.py @@ -73,8 +73,8 @@ are a complicated constructor and member function, respectively. >>> d = D() ------ ->>> take_a(a) -0 +>>> take_a(a).name() +'A' >>> try: ... take_b(a) @@ -92,11 +92,11 @@ are a complicated constructor and member function, respectively. ... else: print 'no exception' ------ ->>> take_a(b) -0 +>>> take_a(b).name() +'A' ->>> take_b(b) -1 +>>> take_b(b).name() +'B' >>> try: ... take_c(b) @@ -109,16 +109,16 @@ are a complicated constructor and member function, respectively. ... else: print 'no exception' ------- ->>> take_a(c) -0 +>>> take_a(c).name() +'A' >>> try: ... take_b(c) ... except: pass ... else: print 'no exception' ->>> take_c(c) -2 +>>> take_c(c).name() +'C' >>> try: ... take_d(c) @@ -126,14 +126,14 @@ are a complicated constructor and member function, respectively. ... else: print 'no exception' ------- ->>> take_a(d) -0 ->>> take_b(d) -1 ->>> take_c(d) -2 ->>> take_d(d) -3 +>>> take_a(d).name() +'A' +>>> take_b(d).name() +'B' +>>> take_c(d).name() +'C' +>>> take_d(d).name() +'D' """ From 14917c9791997288a11bcc3b309ca78efe8f89fd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Feb 2002 14:31:07 +0000 Subject: [PATCH 0220/1042] initial checkin [SVN r12633] --- include/boost/python/to_python_converter.hpp | 39 +++++++++++++ include/boost/python/to_python_value.hpp | 58 ++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 include/boost/python/to_python_converter.hpp create mode 100644 include/boost/python/to_python_value.hpp diff --git a/include/boost/python/to_python_converter.hpp b/include/boost/python/to_python_converter.hpp new file mode 100644 index 00000000..6bea9822 --- /dev/null +++ b/include/boost/python/to_python_converter.hpp @@ -0,0 +1,39 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TO_PYTHON_CONVERTER_DWA200221_HPP +# define TO_PYTHON_CONVERTER_DWA200221_HPP + +# include +# include +# include + +namespace boost { namespace python { + +template +struct to_python_converter +{ + to_python_converter(); +}; + +// +// implementation +// + +template +to_python_converter::to_python_converter() +{ + typedef converter::as_to_python_value_function< + T, Derived + > normalized; + + converter::registry::insert( + &normalized::convert + , converter::undecorated_type_id()); +} + +}} // namespace boost::python + +#endif // TO_PYTHON_CONVERTER_DWA200221_HPP diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp new file mode 100644 index 00000000..a222e9a9 --- /dev/null +++ b/include/boost/python/to_python_value.hpp @@ -0,0 +1,58 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TO_PYTHON_VALUE_DWA200221_HPP +# define TO_PYTHON_VALUE_DWA200221_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +template +struct to_python_value +{ + typedef typename add_reference< + typename add_const::type + >::type argument_type; + + static bool convertible(); + PyObject* operator()(argument_type) const; + + private: + // Note that this is a pointer to a function pointer + static converter::to_python_value_function const* fconvert; +}; + + +template +converter::to_python_value_function const* +to_python_value::fconvert + = &converter::registry::to_python_function(converter::undecorated_type_id()); + + +template +bool to_python_value::convertible() +{ + // if this assert fires, our static variable hasn't been set up yet. + assert(fconvert != 0); + return *fconvert != 0; +} + +template +PyObject* to_python_value::operator()(argument_type x) const +{ + // This might be further optimized on platforms which dynamically + // link without specific imports/exports + converter::to_python_value_function f = *fconvert; + return f(&x); +} + +}} // namespace boost::python + +#endif // TO_PYTHON_VALUE_DWA200221_HPP From ecc8abcc50505b86d34693012486ec7c19824254 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Feb 2002 14:34:02 +0000 Subject: [PATCH 0221/1042] ice_ fixes for KCC [SVN r12634] --- include/boost/python/default_call_policies.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/boost/python/default_call_policies.hpp b/include/boost/python/default_call_policies.hpp index 475278e4..f0b69255 100644 --- a/include/boost/python/default_call_policies.hpp +++ b/include/boost/python/default_call_policies.hpp @@ -48,8 +48,10 @@ struct default_result_converter template struct apply { + BOOST_STATIC_CONSTANT(bool, is_illegal = is_reference::value || is_pointer::value); + typedef typename mpl::select_type< - is_reference::value | is_pointer::value + is_illegal , detail::specify_a_result_policy_to_wrap_functions_returning , boost::python::to_python_value< typename add_reference::type>::type From 7703f91ee26512c7e7c2c8c97b3ac5f971bc64a5 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 2 Feb 2002 15:17:37 +0000 Subject: [PATCH 0222/1042] fix typo [SVN r12636] --- src/objects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects.cpp b/src/objects.cpp index b447b262..8b5ac3dd 100644 --- a/src/objects.cpp +++ b/src/objects.cpp @@ -9,7 +9,7 @@ // TODO: Move inline implementations from objects.cpp here #ifndef BOOST_PYTHON_SOURCE -r# define BOOST_PYTHON_SOURCE +# define BOOST_PYTHON_SOURCE #endif #include From 71de2b5ec52421ed0fd1f717c89b88295e6c0502 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 2 Feb 2002 15:19:59 +0000 Subject: [PATCH 0223/1042] /Zm upgrade [SVN r12637] --- build/vc60.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/vc60.mak b/build/vc60.mak index 6f303791..1709073c 100644 --- a/build/vc60.mak +++ b/build/vc60.mak @@ -21,7 +21,7 @@ PYEXE="C:\Python21\python.exe" PYINC=/I"C:\Python21\include" PYLIB="C:\Python21\libs\python21.lib" -STDOPTS=/nologo /MD /GR /GX /Zm200 /DBOOST_PYTHON_STATIC_LIB +STDOPTS=/nologo /MD /GR /GX /Zm300 /DBOOST_PYTHON_STATIC_LIB WARNOPTS= OPTOPTS= From 6e5fc91885e622c4d513300e53a05477dd10892c Mon Sep 17 00:00:00 2001 From: Darin Adler Date: Sat, 2 Feb 2002 18:36:12 +0000 Subject: [PATCH 0224/1042] New smart pointer documentation. Related clean-up of the smart pointer library. Changing includes to include the new individual smart pointer headers. Replacing old smart pointer library with an include of the new smart pointer headers. Simplify ifdefs that involve the member templates macros now that BOOST_MSVC6_MEMBER_TEMPLATES is also guaranteed to bet set for platforms that have full member templates. [SVN r12647] --- include/boost/python/conversions.hpp | 2 +- include/boost/python/detail/extension_class.hpp | 2 +- include/boost/python/object/inheritance.hpp | 2 +- src/types.cpp | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/include/boost/python/conversions.hpp b/include/boost/python/conversions.hpp index aa07547f..24ac5614 100644 --- a/include/boost/python/conversions.hpp +++ b/include/boost/python/conversions.hpp @@ -19,7 +19,7 @@ # include # include # include -# include +# include # include # include diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 638217d1..dd6741d2 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -26,7 +26,7 @@ # include # include # include -# include +# include # include namespace boost { namespace python { diff --git a/include/boost/python/object/inheritance.hpp b/include/boost/python/object/inheritance.hpp index 60aeda58..ceeac8f9 100644 --- a/include/boost/python/object/inheritance.hpp +++ b/include/boost/python/object/inheritance.hpp @@ -7,7 +7,7 @@ # define INHERITANCE_DWA200216_HPP # include -# include +# include namespace boost { namespace python { namespace objects { diff --git a/src/types.cpp b/src/types.cpp index e76503d2..eae9adff 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include From 8cc9080d367448edc08d6c8725282d2d5c5d0657 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Feb 2002 20:48:37 +0000 Subject: [PATCH 0225/1042] Initial pointer adoption tests Have instances actually dispose of their held C++ objects! [SVN r12652] --- Jamfile | 20 +++++++++-- src/object/class.cpp | 19 +++++++++- test/test_builtin_converters.cpp | 2 -- test/test_pointer_adoption.cpp | 61 ++++++++++++++++++++++++++++++++ test/test_pointer_adoption.py | 29 +++++++++++++++ 5 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 test/test_pointer_adoption.cpp create mode 100644 test/test_pointer_adoption.py diff --git a/Jamfile b/Jamfile index fec34d51..e897b19f 100644 --- a/Jamfile +++ b/Jamfile @@ -29,17 +29,20 @@ PYTHON_PROPERTIES BOOST_PYTHON_SOURCE ; - extension m1 : test/m1.cpp bpl # BOOST_PYTHON_TRACE + # -------- general test ------- + extension m1 : test/m1.cpp bpl : : debug-python ; - extension m2 : test/m2.cpp bpl # BOOST_PYTHON_TRACE + extension m2 : test/m2.cpp bpl : : debug-python ; boost-python-runtest try : test/newtest.py m1 m2 : : debug-python ; + # ----------- builtin converters ----------- + extension builtin_converters_ext : test/test_builtin_converters.cpp bpl : : debug-python @@ -50,4 +53,17 @@ PYTHON_PROPERTIES : : debug-python ; + + # ----------- pointer adoption ----------- + + extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp bpl + : + : debug-python + ; + + boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py + test_pointer_adoption_ext + : + : debug-python + ; } diff --git a/src/object/class.cpp b/src/object/class.cpp index 5d1ecf01..6a839fb2 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -81,6 +81,22 @@ BOOST_PYTHON_DECL ref class_metatype() return ref((PyObject*)&class_metatype_object, ref::increment_count); } +extern "C" +{ + static void instance_dealloc(PyObject* inst) + { + instance* kill_me = (instance*)inst; + + for (instance_holder* p = kill_me->objects, *next; p != 0; p = next) + { + next = p->next(); + delete p; + } + + inst->ob_type->tp_free(inst); + } +} + // Do we really need this? I'm beginning to think we don't! PyTypeObject class_type_object = { PyObject_HEAD_INIT(0) //&class_metatype_object) @@ -88,7 +104,7 @@ PyTypeObject class_type_object = { "Boost.Python.instance", sizeof(instance), 0, - 0, /* tp_dealloc */ + instance_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -206,6 +222,7 @@ namespace m_impl.insert( boost::detail::lower_bound(start, finish, id) , entry(id, object)); + converter::registry::class_object(id) = (PyTypeObject*)object.get(); } } diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp index 6ffccdf9..7e21e046 100644 --- a/test/test_builtin_converters.cpp +++ b/test/test_builtin_converters.cpp @@ -5,8 +5,6 @@ // to its suitability for any purpose. #include #include -#include -#include template diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp new file mode 100644 index 00000000..a49be5e8 --- /dev/null +++ b/test/test_pointer_adoption.cpp @@ -0,0 +1,61 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include + +using namespace boost::python; +using boost::mpl::type_list; + +int a_instances = 0; + +int num_a_instances() { return a_instances; } + +struct A +{ + A(std::string const& s) + : s(s) + { + ++a_instances; + } + + ~A() + { + --a_instances; + } + + std::string content() const + { + return s; + } + + std::string s; +}; + +A* create(std::string const& s) +{ + return new A(s); +} + +BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) +{ + boost::python::module("test_pointer_adoption_ext") + .def("num_a_instances", num_a_instances) + + // Specify the manage_new_object return policy to take + // ownership of create's result + .def("create", create, return_value_policy()) + + .add( + class_() + .def("content", &A::content) + ) + + ; +} + diff --git a/test/test_pointer_adoption.py b/test/test_pointer_adoption.py new file mode 100644 index 00000000..264d69ce --- /dev/null +++ b/test/test_pointer_adoption.py @@ -0,0 +1,29 @@ +""" +>>> from test_pointer_adoption_ext import * + +>>> num_a_instances() +0 + +>>> a = create('dynamically allocated') +>>> num_a_instances() +1 + +>>> a.content() +'dynamically allocated' + +>>> a = None +>>> num_a_instances() +0 +""" +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 90647f30f856040c218b3605791c2bd96636ca0c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Feb 2002 20:54:06 +0000 Subject: [PATCH 0226/1042] Initial pointer adoption tests Have instances actually dispose of their held C++ objects! [SVN r12653] --- include/boost/python/class.hpp | 7 +- include/boost/python/class_fwd.hpp | 30 ++++++ include/boost/python/detail/cv_category.hpp | 34 +++++++ include/boost/python/detail/type_list.hpp | 16 ++++ include/boost/python/detail/unwind_type.hpp | 51 ++++++++++ include/boost/python/manage_new_object.hpp | 42 +++++++++ include/boost/python/module.hpp | 3 +- include/boost/python/object/class_object.hpp | 26 ++++++ include/boost/python/object/class_wrapper.hpp | 8 +- include/boost/python/to_python_owner.hpp | 93 +++++++++++++++++++ 10 files changed, 300 insertions(+), 10 deletions(-) create mode 100644 include/boost/python/class_fwd.hpp create mode 100644 include/boost/python/detail/cv_category.hpp create mode 100644 include/boost/python/detail/type_list.hpp create mode 100644 include/boost/python/detail/unwind_type.hpp create mode 100644 include/boost/python/manage_new_object.hpp create mode 100644 include/boost/python/object/class_object.hpp create mode 100644 include/boost/python/to_python_owner.hpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 0f8d2a69..b63236c8 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -6,6 +6,7 @@ #ifndef CLASS_DWA200216_HPP # define CLASS_DWA200216_HPP +# include # include # include # include @@ -14,7 +15,7 @@ # include # include # include -# include +# include namespace // put some convenience classes into the unnamed namespace for the user { @@ -80,8 +81,8 @@ namespace detail // template < class T // class being wrapped - , class Bases = mpl::type_list<>::type - , class HolderGenerator = objects::value_holder_generator + , class Bases + , class HolderGenerator > class class_ : private objects::class_base { diff --git a/include/boost/python/class_fwd.hpp b/include/boost/python/class_fwd.hpp new file mode 100644 index 00000000..6faf7aae --- /dev/null +++ b/include/boost/python/class_fwd.hpp @@ -0,0 +1,30 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CLASS_FWD_DWA200222_HPP +# define CLASS_FWD_DWA200222_HPP + +namespace boost { namespace python { + +namespace detail +{ + struct empty_list; +} + +namespace objects +{ + struct value_holder_generator; +} + +template < + class T // class being wrapped + , class Bases = detail::empty_list + , class HolderGenerator = objects::value_holder_generator + > +class class_; + +}} // namespace boost::python + +#endif // CLASS_FWD_DWA200222_HPP diff --git a/include/boost/python/detail/cv_category.hpp b/include/boost/python/detail/cv_category.hpp new file mode 100644 index 00000000..f4ac4b92 --- /dev/null +++ b/include/boost/python/detail/cv_category.hpp @@ -0,0 +1,34 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CV_CATEGORY_DWA200222_HPP +# define CV_CATEGORY_DWA200222_HPP +# include + +namespace boost { namespace python { namespace detail { + +template +struct cv_tag +{ + BOOST_STATIC_CONSTANT(bool, is_const = is_const_); + BOOST_STATIC_CONSTANT(bool, is_volatile = is_const_); +}; + +typedef cv_tag cv_unqualified; +typedef cv_tag const_; +typedef cv_tag volatile_; +typedef cv_tag const_volatile_; + +template +struct cv_category +{ + BOOST_STATIC_CONSTANT(bool, c = is_const::value); + BOOST_STATIC_CONSTANT(bool, v = is_volatile::value); + typedef cv_tag type; +}; + +}}} // namespace boost::python::detail + +#endif // CV_CATEGORY_DWA200222_HPP diff --git a/include/boost/python/detail/type_list.hpp b/include/boost/python/detail/type_list.hpp new file mode 100644 index 00000000..66ac3857 --- /dev/null +++ b/include/boost/python/detail/type_list.hpp @@ -0,0 +1,16 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TYPE_LIST_DWA200222_HPP +# define TYPE_LIST_DWA200222_HPP +# include + +namespace boost { namespace python { namespace detail { + +struct empty_list : boost::mpl::type_list<>::type {}; + +}}} // namespace boost::python::detail + +#endif // TYPE_LIST_DWA200222_HPP diff --git a/include/boost/python/detail/unwind_type.hpp b/include/boost/python/detail/unwind_type.hpp new file mode 100644 index 00000000..eb103be4 --- /dev/null +++ b/include/boost/python/detail/unwind_type.hpp @@ -0,0 +1,51 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef UNWIND_TYPE_DWA200222_HPP +# define UNWIND_TYPE_DWA200222_HPP + +# include + +namespace boost { namespace python { namespace detail { + +template +inline typename Generator::result_type +unwind_type_cv(U* p, cv_unqualified, Generator* = 0) +{ + return Generator::execute(p); +} + +template +inline typename Generator::result_type +unwind_type_cv(U const* p, const_, Generator* = 0) +{ + return unwind_type(const_cast(p), (Generator*)0); +} + +template +inline typename Generator::result_type +unwind_type_cv(U volatile* p, volatile_, Generator* = 0) +{ + return unwind_type(const_cast(p), (Generator*)0); +} + +template +inline typename Generator::result_type +unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0) +{ + return unwind_type(const_cast(p), (Generator*)0); +} + +template +inline typename Generator::result_type +unwind_type(U* p, Generator* = 0) +{ + typedef typename cv_category::type tag; + return unwind_type_cv(p, tag()); +} + +}}} // namespace boost::python::detail + +#endif // UNWIND_TYPE_DWA200222_HPP diff --git a/include/boost/python/manage_new_object.hpp b/include/boost/python/manage_new_object.hpp new file mode 100644 index 00000000..1c41a75d --- /dev/null +++ b/include/boost/python/manage_new_object.hpp @@ -0,0 +1,42 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MANAGE_NEW_OBJECT_DWA200222_HPP +# define MANAGE_NEW_OBJECT_DWA200222_HPP +# include +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + template + struct manage_new_object_requires_a_pointer_return_type +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} +# endif + ; +} + +template struct to_python_value; + +struct manage_new_object +{ + template + struct apply + { + typedef typename mpl::select_type< + boost::is_pointer::value + , to_python_owner + , detail::manage_new_object_requires_a_pointer_return_type + >::type type; + }; +}; + +}} // namespace boost::python + +#endif // MANAGE_NEW_OBJECT_DWA200222_HPP diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 3a243b06..1d4fdd6d 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -12,11 +12,10 @@ # include # include # include +# include namespace boost { namespace python { -template class class_; - class BOOST_PYTHON_DECL module_base { public: diff --git a/include/boost/python/object/class_object.hpp b/include/boost/python/object/class_object.hpp new file mode 100644 index 00000000..76960762 --- /dev/null +++ b/include/boost/python/object/class_object.hpp @@ -0,0 +1,26 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CLASS_OBJECT_DWA200222_HPP +# define CLASS_OBJECT_DWA200222_HPP + +# include +# include + +namespace boost { namespace python { namespace objects { + +template +struct class_object +{ + static PyTypeObject*& reference; +}; + +template +PyTypeObject*& class_object::reference = converter::registry::class_object( + converter::undecorated_type_id()); + +}}} // namespace boost::python::objects + +#endif // CLASS_OBJECT_DWA200222_HPP diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index 4a52f290..f8702205 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -25,9 +25,9 @@ struct class_wrapper static PyObject* convert(T const& x) { - // Don't call the type to do the construction, since that - // would require the registration of an __init__ copy - // constructor. Instead, just construct the object in place. + // Don't call the type directly to do the construction, since + // that would require the registration of an appropriate + // __init__ function. PyObject* raw_result = m_class_object->tp_alloc(m_class_object, 0); if (raw_result == 0) @@ -37,8 +37,6 @@ struct class_wrapper // exceptions. ref result(raw_result, ref::allow_null()); - ((instance*)raw_result)->objects = 0; - // Build a value_holder to contain the object using the copy // constructor value_holder* p = new value_holder(raw_result, cref(x)); diff --git a/include/boost/python/to_python_owner.hpp b/include/boost/python/to_python_owner.hpp new file mode 100644 index 00000000..7d3ee5ae --- /dev/null +++ b/include/boost/python/to_python_owner.hpp @@ -0,0 +1,93 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TO_PYTHON_OWNER_DWA200221_HPP +# define TO_PYTHON_OWNER_DWA200221_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +template +struct to_python_owner +{ + static bool convertible(); + PyObject* operator()(T ptr) const; + private: + static PyTypeObject* type(); +}; + +// +// implementations +// +namespace detail +{ + struct make_owning_holder + { + typedef objects::instance_holder* result_type; + template + static result_type execute(T* p) + { + return new objects::pointer_holder, T>( + std::auto_ptr(p)); + } + }; + + struct get_pointer_class + { + typedef PyTypeObject* result_type; + template + static result_type execute(T* p) + { + BOOST_STATIC_ASSERT(is_class::value); + return python::objects::class_object::reference; + } + }; +} + +template +inline bool to_python_owner::convertible() +{ + BOOST_STATIC_ASSERT(is_pointer::value); + return type() != 0; +} + +template +inline PyObject* to_python_owner::operator()(T x) const +{ + PyObject* raw_result = type()->tp_alloc(type(), 0); + + if (raw_result == 0) + return 0; + + // Everything's OK; Bypass NULL checks but guard against + // exceptions. + ref result(raw_result, ref::allow_null()); + + // Build a value_holder to contain the object using the copy + // constructor + objects::instance_holder* p = + detail::unwind_type(x); + + // Install it in the instance + p->install(raw_result); + + // Return the new result + return result.release(); +} + +template +inline PyTypeObject* to_python_owner::type() +{ + return detail::unwind_type(T(0)); +} + +}} // namespace boost::python + +#endif // TO_PYTHON_OWNER_DWA200221_HPP From 55a431883925c4acbd22fab58d880c59f68e2e21 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Feb 2002 01:07:10 +0000 Subject: [PATCH 0227/1042] Handle references too [SVN r12655] --- include/boost/python/detail/unwind_type.hpp | 70 ++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/unwind_type.hpp b/include/boost/python/detail/unwind_type.hpp index eb103be4..e3caa5fa 100644 --- a/include/boost/python/detail/unwind_type.hpp +++ b/include/boost/python/detail/unwind_type.hpp @@ -40,12 +40,80 @@ unwind_type_cv(U const volatile* p, const_volatile_, Generator* = 0) template inline typename Generator::result_type -unwind_type(U* p, Generator* = 0) +unwind_ptr_type(U* p, Generator* = 0) { typedef typename cv_category::type tag; return unwind_type_cv(p, tag()); } +template +struct unwind_helper +{ + template + static typename Generator::result_type + execute(U p, Generator* = 0) + { + return unwind_ptr_type(p, (Generator*)0); + } + + template + struct apply + { + static typename Generator::result_type + execute() + { + return unwind_ptr_type(U(0),(Generator*)0); + } + }; +}; + +template <> +struct unwind_helper +{ + template + static typename Generator::result_type + execute(U& p, Generator* = 0) + { + return unwind_ptr_type(&p, (Generator*)0); + } + + template + struct apply + { + static typename Generator::result_type + execute() + { + return unwind_ptr_type((U*)0,(Generator*)0); + } + }; +}; + +template +inline typename Generator::result_type +unwind_type(U& p, Generator* = 0) +{ + return unwind_helper::value>::execute(p, (Generator*)0); +} + +template +inline typename Generator::result_type +unwind_type(U const& p, Generator* = 0) +{ + return unwind_helper::value>::execute(p, (Generator*)0); +} + +// Call this one with both template parameters explicitly specified +// and no function arguments: +// +// return unwind_type(); +// +template +inline typename Generator::result_type +unwind_type(type*p = 0, Generator* = 0) +{ + return unwind_helper::value>::template apply::execute(); +} + }}} // namespace boost::python::detail #endif // UNWIND_TYPE_DWA200222_HPP From 021070f0666d9d38335a0f2a716b0f4d4b2d52c7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Feb 2002 01:07:29 +0000 Subject: [PATCH 0228/1042] Prepare to generalize [SVN r12656] --- include/boost/python/to_python_owner.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/to_python_owner.hpp b/include/boost/python/to_python_owner.hpp index 7d3ee5ae..bf92663b 100644 --- a/include/boost/python/to_python_owner.hpp +++ b/include/boost/python/to_python_owner.hpp @@ -85,7 +85,7 @@ inline PyObject* to_python_owner::operator()(T x) const template inline PyTypeObject* to_python_owner::type() { - return detail::unwind_type(T(0)); + return detail::unwind_type(); } }} // namespace boost::python From 7590d546f1d5d34f51d2479f80a486853c09c4c0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Feb 2002 03:05:01 +0000 Subject: [PATCH 0229/1042] initial checkin [SVN r12657] --- .../python/reference_existing_object.hpp | 45 ++++++++ include/boost/python/to_python_indirect.hpp | 102 ++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 include/boost/python/reference_existing_object.hpp create mode 100644 include/boost/python/to_python_indirect.hpp diff --git a/include/boost/python/reference_existing_object.hpp b/include/boost/python/reference_existing_object.hpp new file mode 100644 index 00000000..1f8a43d8 --- /dev/null +++ b/include/boost/python/reference_existing_object.hpp @@ -0,0 +1,45 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef REFERENCE_EXISTING_OBJECT_DWA200222_HPP +# define REFERENCE_EXISTING_OBJECT_DWA200222_HPP +# include +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + template + struct reference_existing_object_requires_a_pointer_or_reference_return_type +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} +# endif + ; +} + +template struct to_python_value; + +struct reference_existing_object +{ + template + struct apply + { + BOOST_STATIC_CONSTANT( + bool, ok = is_pointer::value || is_reference::value); + + typedef typename mpl::select_type< + ok + , to_python_indirect + , detail::reference_existing_object_requires_a_pointer_or_reference_return_type + >::type type; + }; +}; + +}} // namespace boost::python + +#endif // REFERENCE_EXISTING_OBJECT_DWA200222_HPP diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp new file mode 100644 index 00000000..e68eced0 --- /dev/null +++ b/include/boost/python/to_python_indirect.hpp @@ -0,0 +1,102 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TO_PYTHON_INDIRECT_DWA200221_HPP +# define TO_PYTHON_INDIRECT_DWA200221_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +template +struct to_python_indirect +{ + static bool convertible(); + PyObject* operator()(T ptr) const; + private: + static PyTypeObject* type(); +}; + +// +// implementations +// +namespace detail +{ + struct make_owning_holder + { + typedef objects::instance_holder* result_type; + template + static result_type execute(T* p) + { + return new objects::pointer_holder, T>( + std::auto_ptr(p)); + } + }; + + struct make_reference_holder + { + typedef objects::instance_holder* result_type; + template + static result_type execute(T* p) + { + return new objects::pointer_holder(p); + } + }; + + struct get_pointer_class + { + typedef PyTypeObject* result_type; + template + static result_type execute(T* p) + { + BOOST_STATIC_ASSERT(is_class::value); + return python::objects::class_object::reference; + } + }; +} + +template +inline bool to_python_indirect::convertible() +{ + return type() != 0; +} + +template +inline PyObject* to_python_indirect::operator()(T x) const +{ + PyObject* raw_result = type()->tp_alloc(type(), 0); + + if (raw_result == 0) + return 0; + + // Everything's OK; Bypass NULL checks but guard against + // exceptions. + ref result(raw_result, ref::allow_null()); + + // Build a value_holder to contain the object using the copy + // constructor + objects::instance_holder* p = + detail::unwind_type(x); + + // Install it in the instance + p->install(raw_result); + + // Return the new result + return result.release(); +} + +template +inline PyTypeObject* to_python_indirect::type() +{ + return detail::unwind_type(); +} + +}} // namespace boost::python + +#endif // TO_PYTHON_INDIRECT_DWA200221_HPP From 64239f1c04be4c18aa608e019c6a3b9ec5f0b1b1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Feb 2002 03:05:39 +0000 Subject: [PATCH 0230/1042] Allow indirect reference/pointer returns [SVN r12659] --- include/boost/python/class.hpp | 7 ++ .../boost/python/detail/indirect_traits.hpp | 68 +++++++++++++- include/boost/python/detail/unwind_type.hpp | 76 ++++++++++----- include/boost/python/manage_new_object.hpp | 4 +- include/boost/python/to_python_owner.hpp | 93 ------------------- test/test_pointer_adoption.cpp | 37 +++++++- test/test_pointer_adoption.py | 6 ++ 7 files changed, 165 insertions(+), 126 deletions(-) delete mode 100644 include/boost/python/to_python_owner.hpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index b63236c8..4f30dc8d 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -112,6 +112,13 @@ class class_ : private objects::class_base return *this; } + template + self& def(char const* name, Fn fn, CallPolicy policy) + { + this->def(name, boost::python::make_function(fn, policy)); + return *this; + } + // Define the constructor with the given Args, which should be an // MPL sequence of types. template diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index c76ffbc0..41681719 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -47,6 +47,36 @@ struct is_reference_to_volatile { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_reference_to_pointer +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_reference_to_pointer +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template +struct is_reference_to_pointer +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template +struct is_reference_to_pointer +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template +struct is_reference_to_pointer +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; # else typedef char (&inner_yes_type)[3]; @@ -74,8 +104,17 @@ struct is_volatile_help }; template -typename is_const_help::type reference_to_const_helper(V&); - +struct is_pointer_help +{ + typedef typename mpl::select_type< + is_pointer::value + , inner_yes_type + , inner_no_type + >::type type; +}; + +template +typename is_const_help::type reference_to_const_helper(V&); outer_no_type reference_to_const_helper(...); @@ -85,7 +124,8 @@ struct is_reference_to_const static T t; BOOST_STATIC_CONSTANT( bool, value - = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); + = (is_reference::value + && sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type))); }; template @@ -94,7 +134,8 @@ struct is_reference_to_non_const static T t; BOOST_STATIC_CONSTANT( bool, value - = sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)); + = (is_reference::value + && sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type))); }; template @@ -107,7 +148,24 @@ struct is_reference_to_volatile static T t; BOOST_STATIC_CONSTANT( bool, value - = sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)); + = (is_reference::value + && sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type))); +}; + + +template +typename is_pointer_help::type reference_to_pointer_helper(V&); +outer_no_type reference_to_pointer_helper(...); + +template +struct is_reference_to_pointer +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = (is_reference::value + && sizeof(reference_to_pointer_helper(t)) == sizeof(inner_yes_type)) + ); }; # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION diff --git a/include/boost/python/detail/unwind_type.hpp b/include/boost/python/detail/unwind_type.hpp index e3caa5fa..add3615a 100644 --- a/include/boost/python/detail/unwind_type.hpp +++ b/include/boost/python/detail/unwind_type.hpp @@ -55,16 +55,6 @@ struct unwind_helper { return unwind_ptr_type(p, (Generator*)0); } - - template - struct apply - { - static typename Generator::result_type - execute() - { - return unwind_ptr_type(U(0),(Generator*)0); - } - }; }; template <> @@ -76,16 +66,6 @@ struct unwind_helper { return unwind_ptr_type(&p, (Generator*)0); } - - template - struct apply - { - static typename Generator::result_type - execute() - { - return unwind_ptr_type((U*)0,(Generator*)0); - } - }; }; template @@ -102,16 +82,70 @@ unwind_type(U const& p, Generator* = 0) return unwind_helper::value>::execute(p, (Generator*)0); } +enum { direct_ = 0, pointer_ = 1, reference_ = 2, reference_to_pointer_ = 3 }; +template struct unwind_helper2; + +template <> +struct unwind_helper2 +{ + template + static typename Generator::result_type + execute(U(*)(), Generator* = 0) + { + return unwind_ptr_type((U*)0, (Generator*)0); + } +}; + +template <> +struct unwind_helper2 +{ + template + static typename Generator::result_type + execute(U*(*)(), Generator* = 0) + { + return unwind_ptr_type((U*)0, (Generator*)0); + } +}; + +template <> +struct unwind_helper2 +{ + template + static typename Generator::result_type + execute(U&(*)(), Generator* = 0) + { + return unwind_ptr_type((U*)0, (Generator*)0); + } +}; + +template <> +struct unwind_helper2 +{ + template + static typename Generator::result_type + execute(U&(*)(), Generator* = 0) + { + return unwind_ptr_type(U(0), (Generator*)0); + } +}; + // Call this one with both template parameters explicitly specified // and no function arguments: // // return unwind_type(); // +// Doesn't work if T is an array type; we could handle that case, but +// why bother? template inline typename Generator::result_type unwind_type(type*p = 0, Generator* = 0) { - return unwind_helper::value>::template apply::execute(); + BOOST_STATIC_CONSTANT(int, indirection + = (pointer_ * is_pointer::value) + | (reference_ * is_reference::value) + | (reference_to_pointer_ * is_reference_to_pointer::value)); + + return unwind_helper2::execute((U(*)())0,(Generator*)0); } }}} // namespace boost::python::detail diff --git a/include/boost/python/manage_new_object.hpp b/include/boost/python/manage_new_object.hpp index 1c41a75d..9c0912ab 100644 --- a/include/boost/python/manage_new_object.hpp +++ b/include/boost/python/manage_new_object.hpp @@ -7,7 +7,7 @@ # define MANAGE_NEW_OBJECT_DWA200222_HPP # include # include -# include +# include # include namespace boost { namespace python { @@ -31,7 +31,7 @@ struct manage_new_object { typedef typename mpl::select_type< boost::is_pointer::value - , to_python_owner + , to_python_indirect , detail::manage_new_object_requires_a_pointer_return_type >::type type; }; diff --git a/include/boost/python/to_python_owner.hpp b/include/boost/python/to_python_owner.hpp deleted file mode 100644 index bf92663b..00000000 --- a/include/boost/python/to_python_owner.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TO_PYTHON_OWNER_DWA200221_HPP -# define TO_PYTHON_OWNER_DWA200221_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -template -struct to_python_owner -{ - static bool convertible(); - PyObject* operator()(T ptr) const; - private: - static PyTypeObject* type(); -}; - -// -// implementations -// -namespace detail -{ - struct make_owning_holder - { - typedef objects::instance_holder* result_type; - template - static result_type execute(T* p) - { - return new objects::pointer_holder, T>( - std::auto_ptr(p)); - } - }; - - struct get_pointer_class - { - typedef PyTypeObject* result_type; - template - static result_type execute(T* p) - { - BOOST_STATIC_ASSERT(is_class::value); - return python::objects::class_object::reference; - } - }; -} - -template -inline bool to_python_owner::convertible() -{ - BOOST_STATIC_ASSERT(is_pointer::value); - return type() != 0; -} - -template -inline PyObject* to_python_owner::operator()(T x) const -{ - PyObject* raw_result = type()->tp_alloc(type(), 0); - - if (raw_result == 0) - return 0; - - // Everything's OK; Bypass NULL checks but guard against - // exceptions. - ref result(raw_result, ref::allow_null()); - - // Build a value_holder to contain the object using the copy - // constructor - objects::instance_holder* p = - detail::unwind_type(x); - - // Install it in the instance - p->install(raw_result); - - // Return the new result - return result.release(); -} - -template -inline PyTypeObject* to_python_owner::type() -{ - return detail::unwind_type(); -} - -}} // namespace boost::python - -#endif // TO_PYTHON_OWNER_DWA200221_HPP diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index a49be5e8..be10aebd 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -16,10 +17,24 @@ int a_instances = 0; int num_a_instances() { return a_instances; } +struct inner +{ + inner(std::string const& s) + : s(s) + {} + + void change(std::string const& new_s) + { + this->s = new_s; + } + + std::string s; +}; + struct A { A(std::string const& s) - : s(s) + : x(s) { ++a_instances; } @@ -31,10 +46,15 @@ struct A std::string content() const { - return s; + return x.s; } - - std::string s; + + inner& get_inner() + { + return x; + } + + inner x; }; A* create(std::string const& s) @@ -52,8 +72,15 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) .def("create", create, return_value_policy()) .add( + class_() - .def("content", &A::content) + .def("content", &A::content) + .def("get_inner", &A::get_inner, return_value_policy()) + ) + + .add( + class_() + .def("change", &inner::change) ) ; diff --git a/test/test_pointer_adoption.py b/test/test_pointer_adoption.py index 264d69ce..197a6df9 100644 --- a/test/test_pointer_adoption.py +++ b/test/test_pointer_adoption.py @@ -11,6 +11,12 @@ >>> a.content() 'dynamically allocated' +>>> innards = a.get_inner() +>>> innards.change('with an exposed reference') +>>> a.content() +'with an exposed reference' + +>>> innards = None >>> a = None >>> num_a_instances() 0 From 0a9d5f680fab9094049392618b10c1ec7734d959 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Feb 2002 05:02:46 +0000 Subject: [PATCH 0231/1042] initial checkin [SVN r12661] --- include/boost/python/object/life_support.hpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 include/boost/python/object/life_support.hpp diff --git a/include/boost/python/object/life_support.hpp b/include/boost/python/object/life_support.hpp new file mode 100644 index 00000000..c5276c06 --- /dev/null +++ b/include/boost/python/object/life_support.hpp @@ -0,0 +1,17 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef LIFE_SUPPORT_DWA200222_HPP +# define LIFE_SUPPORT_DWA200222_HPP +# include +# include + +namespace boost { namespace python { namespace objects { + +BOOST_PYTHON_DECL int make_nurse_and_patient(PyObject* nurse, PyObject* patient); + +}}} // namespace boost::python::object + +#endif // LIFE_SUPPORT_DWA200222_HPP From 262396d48b4183e3490d9478da758c045ebcf92b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Feb 2002 05:03:05 +0000 Subject: [PATCH 0232/1042] Object life support [SVN r12662] --- Jamfile | 1 + .../python/return_internal_reference.hpp | 32 +++++- src/object/life_support.cpp | 99 +++++++++++++++++++ test/test_pointer_adoption.cpp | 4 +- test/test_pointer_adoption.py | 8 +- 5 files changed, 137 insertions(+), 7 deletions(-) create mode 100644 src/object/life_support.cpp diff --git a/Jamfile b/Jamfile index e897b19f..ac32456b 100644 --- a/Jamfile +++ b/Jamfile @@ -20,6 +20,7 @@ PYTHON_PROPERTIES src/object/class.cpp src/object/function.cpp src/object/inheritance.cpp + src/object/life_support.cpp src/errors.cpp src/module.cpp src/objects.cpp diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp index ac7f3fbf..a1888229 100644 --- a/include/boost/python/return_internal_reference.hpp +++ b/include/boost/python/return_internal_reference.hpp @@ -7,7 +7,10 @@ # define RETURN_INTERNAL_REFERENCE_DWA2002131_HPP # include +# include # include +# include +# include namespace boost { namespace python { @@ -28,18 +31,39 @@ struct internal_reference_to_python_generator { typedef typename mpl::select_type< !is_object::value - , internal_reference_to_python - , detail::return_internal_reference_requires_a_pointer_or_reference_return_type + , to_python_indirect + , detail::return_internal_reference_requires_a_pointer_or_reference_return_type >::type type; }; }; -template +template struct return_internal_reference : Base { - typedef wrap_internal_reference result_converter; + typedef reference_existing_object result_converter; + static PyObject* postcall(PyObject* args, PyObject* result); }; +template +PyObject* return_internal_reference::postcall(PyObject* args_, PyObject* result) +{ + PyObject* patient = PyTuple_GetItem(args_, owner_arg - 1); + if (patient != 0) // Make sure the argument was in range. + { + result = Base::postcall(args_,result); + if (result != 0) + { + if (python::objects::make_nurse_and_patient(result, patient) == 0) + { + return result; + } + } + + } + Py_XDECREF(result); + return 0; +} + }} // namespace boost::python #endif // RETURN_INTERNAL_REFERENCE_DWA2002131_HPP diff --git a/src/object/life_support.cpp b/src/object/life_support.cpp new file mode 100644 index 00000000..f587eb42 --- /dev/null +++ b/src/object/life_support.cpp @@ -0,0 +1,99 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include + +namespace boost { namespace python { namespace objects { + +struct life_support +{ + PyObject_HEAD + PyObject* patient; +}; + +extern "C" +{ + static void + life_support_dealloc(PyObject* self) + { + self->ob_type->tp_free(self); + } + + static PyObject * + life_support_call(PyObject *self, PyObject *arg, PyObject *kw) + { + // Let the patient die now + Py_XDECREF(((life_support*)self)->patient); + // Also let the weak reference die. This probably kills us. + Py_XDECREF(PyTuple_GET_ITEM(arg, 0)); + return detail::none(); + } +} + +PyTypeObject life_support_type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "Boost.Python.life_support", + sizeof(life_support), + 0, + life_support_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, //(reprfunc)func_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + life_support_call, /* tp_call */ + 0, /* tp_str */ + 0, // PyObject_GenericGetAttr, /* tp_getattro */ + 0, // PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT /* | Py_TPFLAGS_HAVE_GC */,/* tp_flags */ + 0, /* tp_doc */ + 0, // (traverseproc)func_traverse, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, //offsetof(PyLife_SupportObject, func_weakreflist), /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, // func_memberlist, /* tp_members */ + 0, //func_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, //offsetof(PyLife_SupportObject, func_dict), /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, + 0 /* tp_new */ +}; + +int make_nurse_and_patient(PyObject* nurse, PyObject* patient) +{ + life_support* system = PyObject_New(life_support, &life_support_type); + if (!system) + return -1; + + // We're going to leak this reference, but don't worry; the + // life_support system decrements it when the nurse dies. + PyObject* weakref = PyWeakref_NewRef(nurse, (PyObject*)system); + if (!weakref) + { + Py_XDECREF(system); + return -1; + } + + system->patient = patient; + Py_XINCREF(patient); // hang on to the patient until death + return 0; +} + +}}} // namespace boost::python::objects diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index be10aebd..61cd49bd 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -75,7 +75,7 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) class_() .def("content", &A::content) - .def("get_inner", &A::get_inner, return_value_policy()) + .def("get_inner", &A::get_inner, return_internal_reference<>()) ) .add( diff --git a/test/test_pointer_adoption.py b/test/test_pointer_adoption.py index 197a6df9..28e160dc 100644 --- a/test/test_pointer_adoption.py +++ b/test/test_pointer_adoption.py @@ -16,10 +16,16 @@ >>> a.content() 'with an exposed reference' ->>> innards = None +# The a instance should be kept alive... >>> a = None >>> num_a_instances() +1 + +# ...until we're done with its innards +>>> innards = None +>>> num_a_instances() 0 + """ def run(args = None): import sys From bcf4401858ce9b6db3deebb65915ad73eb96b300 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Feb 2002 05:09:31 +0000 Subject: [PATCH 0233/1042] KCC ice workaround [SVN r12663] --- include/boost/python/return_internal_reference.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp index a1888229..8f60c476 100644 --- a/include/boost/python/return_internal_reference.hpp +++ b/include/boost/python/return_internal_reference.hpp @@ -30,9 +30,9 @@ struct internal_reference_to_python_generator struct apply { typedef typename mpl::select_type< - !is_object::value - , to_python_indirect + is_object::value , detail::return_internal_reference_requires_a_pointer_or_reference_return_type + , to_python_indirect >::type type; }; }; From 21d65ca0bf0f099e68a7d3c5e5a927b81f9a6083 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Feb 2002 06:34:15 +0000 Subject: [PATCH 0234/1042] arbitrary argument/result adoption [SVN r12664] --- include/boost/python/object/life_support.hpp | 2 +- include/boost/python/object/make_holder.hpp | 78 ++++++++++++++++++ .../python/return_internal_reference.hpp | 26 +----- .../boost/python/with_custodian_and_ward.hpp | 80 +++++++++++++++++++ src/object/life_support.cpp | 12 +-- test/test_pointer_adoption.cpp | 28 +++++++ test/test_pointer_adoption.py | 22 +++++ 7 files changed, 219 insertions(+), 29 deletions(-) create mode 100644 include/boost/python/with_custodian_and_ward.hpp diff --git a/include/boost/python/object/life_support.hpp b/include/boost/python/object/life_support.hpp index c5276c06..5d9587db 100644 --- a/include/boost/python/object/life_support.hpp +++ b/include/boost/python/object/life_support.hpp @@ -10,7 +10,7 @@ namespace boost { namespace python { namespace objects { -BOOST_PYTHON_DECL int make_nurse_and_patient(PyObject* nurse, PyObject* patient); +BOOST_PYTHON_DECL PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient); }}} // namespace boost::python::object diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 8a72a880..825e02b0 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -93,6 +93,84 @@ struct make_holder<3> }; }; +template <> +struct make_holder<4> +{ + template + struct apply + { + typedef typename detail::eval::type holder; + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + + static void execute( + PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3) + { + (new holder(p, f0(a0), f1(a1), f2(a2), f3(a3)))->install(p); + } + }; +}; + +template <> +struct make_holder<5> +{ + template + struct apply + { + typedef typename detail::eval::type holder; + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + + static void execute( + PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3, t4 a4) + { + (new holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4)))->install(p); + } + }; +}; + +template <> +struct make_holder<6> +{ + template + struct apply + { + typedef typename detail::eval::type holder; + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + typedef typename mpl::at<5,ArgList>::type t5; + typedef typename forward::type f5; + + static void execute( + PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) + { + (new holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4), f5(a5)))->install(p); + } + }; +}; + }}} // namespace boost::python::objects #endif // MAKE_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp index 8f60c476..2066b7a9 100644 --- a/include/boost/python/return_internal_reference.hpp +++ b/include/boost/python/return_internal_reference.hpp @@ -7,10 +7,10 @@ # define RETURN_INTERNAL_REFERENCE_DWA2002131_HPP # include -# include # include # include # include +# include namespace boost { namespace python { @@ -38,32 +38,12 @@ struct internal_reference_to_python_generator }; template -struct return_internal_reference : Base +struct return_internal_reference + : with_custodian_and_ward_postcall<0, owner_arg, Base> { typedef reference_existing_object result_converter; - static PyObject* postcall(PyObject* args, PyObject* result); }; -template -PyObject* return_internal_reference::postcall(PyObject* args_, PyObject* result) -{ - PyObject* patient = PyTuple_GetItem(args_, owner_arg - 1); - if (patient != 0) // Make sure the argument was in range. - { - result = Base::postcall(args_,result); - if (result != 0) - { - if (python::objects::make_nurse_and_patient(result, patient) == 0) - { - return result; - } - } - - } - Py_XDECREF(result); - return 0; -} - }} // namespace boost::python #endif // RETURN_INTERNAL_REFERENCE_DWA2002131_HPP diff --git a/include/boost/python/with_custodian_and_ward.hpp b/include/boost/python/with_custodian_and_ward.hpp new file mode 100644 index 00000000..4ae975af --- /dev/null +++ b/include/boost/python/with_custodian_and_ward.hpp @@ -0,0 +1,80 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP +# define WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP + +# include +# include + +namespace boost { namespace python { + +enum custodial_timing { pre_call, post_call }; + +template +struct with_custodian_and_ward : Base +{ + static bool precall(PyObject* args); +}; + +template +struct with_custodian_and_ward_postcall : Base +{ + static PyObject* postcall(PyObject* args, PyObject* result); +}; + +// +// implementations +// +template +bool with_custodian_and_ward::precall(PyObject* args_) +{ + BOOST_STATIC_ASSERT(custodian != ward); + BOOST_STATIC_ASSERT(custodian > 0); + BOOST_STATIC_ASSERT(ward > 0); + + PyObject* patient = PyTuple_GetItem(args_, ward - 1); + if (patient == 0) return false; + PyObject* nurse = PyTuple_GetItem(args_, custodian - 1); + if (nurse == 0) return false; + + PyObject* life_support = python::objects::make_nurse_and_patient(nurse, patient); + if (life_support == 0) + return false; + + bool result = Base::precall(args_); + + if (!result) + Py_XDECREF(life_support); + + return result; +} + +template +PyObject* with_custodian_and_ward_postcall::postcall(PyObject* args_, PyObject* result) +{ + BOOST_STATIC_ASSERT(custodian != ward); + + PyObject* patient = ward > 0 ? PyTuple_GetItem(args_, ward - 1) : result; + if (patient == 0) return 0; + + PyObject* nurse = custodian > 0 ? PyTuple_GetItem(args_, custodian - 1) : result; + if (nurse == 0) return 0; + + result = Base::postcall(args_, result); + if (result == 0) + return 0; + + if (python::objects::make_nurse_and_patient(nurse, patient) == 0) + { + Py_XDECREF(result); + return 0; + } + return result; +} + +}} // namespace boost::python + +#endif // WITH_CUSTODIAN_AND_WARD_DWA2002131_HPP diff --git a/src/object/life_support.cpp b/src/object/life_support.cpp index f587eb42..7507c71c 100644 --- a/src/object/life_support.cpp +++ b/src/object/life_support.cpp @@ -19,6 +19,7 @@ extern "C" static void life_support_dealloc(PyObject* self) { + Py_XDECREF(((life_support*)self)->patient); self->ob_type->tp_free(self); } @@ -27,7 +28,8 @@ extern "C" { // Let the patient die now Py_XDECREF(((life_support*)self)->patient); - // Also let the weak reference die. This probably kills us. + ((life_support*)self)->patient = 0; + // Let the weak reference die. This probably kills us. Py_XDECREF(PyTuple_GET_ITEM(arg, 0)); return detail::none(); } @@ -76,11 +78,11 @@ PyTypeObject life_support_type = { 0 /* tp_new */ }; -int make_nurse_and_patient(PyObject* nurse, PyObject* patient) +PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient) { life_support* system = PyObject_New(life_support, &life_support_type); if (!system) - return -1; + return 0; // We're going to leak this reference, but don't worry; the // life_support system decrements it when the nurse dies. @@ -88,12 +90,12 @@ int make_nurse_and_patient(PyObject* nurse, PyObject* patient) if (!weakref) { Py_XDECREF(system); - return -1; + return 0; } system->patient = patient; Py_XINCREF(patient); // hang on to the patient until death - return 0; + return weakref; } }}} // namespace boost::python::objects diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index 61cd49bd..87b3eaab 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -57,6 +57,21 @@ struct A inner x; }; +struct B +{ + B() : x(0) {} + + inner const* adopt(A* x) { this->x = x; return &x->get_inner(); } + + std::string a_content() + { + return x ? x->content() : std::string("empty"); + } + + A* x; +}; + + A* create(std::string const& s) { return new A(s); @@ -83,6 +98,19 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) .def("change", &inner::change) ) + .add( + class_("B") + .def_init() + + .def("adopt", &B::adopt + // Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self") + , return_internal_reference<2 + // Meanwhile, self holds a reference to the 2nd argument. + , with_custodian_and_ward<1,2> >() + ) + + .def("a_content", &B::a_content) + ) ; } diff --git a/test/test_pointer_adoption.py b/test/test_pointer_adoption.py index 28e160dc..075a640b 100644 --- a/test/test_pointer_adoption.py +++ b/test/test_pointer_adoption.py @@ -26,6 +26,28 @@ >>> num_a_instances() 0 +>>> b = B() +>>> a = create('another') +>>> b.a_content() +'empty' +>>> innards = b.adopt(a); +>>> b.a_content() +'another' +>>> num_a_instances() +1 +>>> del a # innards and b are both holding a reference +>>> num_a_instances() +1 +>>> innards.change('yet another') +>>> b.a_content() +'yet another' + +>>> del innards +>>> num_a_instances() # b still owns a reference to a +1 +>>> del b +>>> num_a_instances() +0 """ def run(args = None): import sys From d023d577b2bf22726cd79d839aac7e66592687b5 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 3 Feb 2002 22:33:11 +0000 Subject: [PATCH 0235/1042] extra semicolon removed (cxx 6.3 diag.) [SVN r12677] --- src/converter/builtin_converters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index 26834635..fcd7a2cd 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -194,7 +194,7 @@ namespace void register_int_converters(T* = 0) { static scalar_from_python x; - }; + } } #define REGISTER_INT_CONVERTERS(U) register_int_converters() From 1ec58c1161cde52eb1c7a70cd6dcbecc77977309 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Feb 2002 23:21:48 +0000 Subject: [PATCH 0236/1042] bug fix [SVN r12678] --- include/boost/python/detail/returning.hpp | 2 +- include/boost/python/object/value_holder.hpp | 110 +++++++++---------- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 99bbc572..599e5d37 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -1216,7 +1216,7 @@ struct returning # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template - static PyObject* call(R (*pf)(), PyObject*, PyObject*, P const& policies) + static PyObject* call(R (*pf)(), PyObject* args, PyObject*, P const& policies) { (*pf)(); diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 85e3797f..01431370 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -23,113 +23,113 @@ struct value_holder : instance_holder template value_holder(PyObject*, A1 a1) : m_held( - (unwrap_reference::type&)(a1) + (typename unwrap_reference::type&)(a1) ) {} template value_holder(PyObject*, A1 a1, A2 a2) : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3) : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) - , (unwrap_reference::type&)(a9) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) + , (typename unwrap_reference::type&)(a9) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : m_held( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) - , (unwrap_reference::type&)(a9) - , (unwrap_reference::type&)(a10) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) + , (typename unwrap_reference::type&)(a9) + , (typename unwrap_reference::type&)(a10) ) {} From 1dc6600b59b79a551f46f85dbf6197013a834465 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Feb 2002 23:51:16 +0000 Subject: [PATCH 0237/1042] kill extra ; [SVN r12679] --- include/boost/python/return_internal_reference.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp index 2066b7a9..d696c7fa 100644 --- a/include/boost/python/return_internal_reference.hpp +++ b/include/boost/python/return_internal_reference.hpp @@ -22,7 +22,7 @@ namespace detail {} # endif ; -}; +} struct internal_reference_to_python_generator { From 9f33aa2afc143ab78e4b049c55c1add37dee961a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Feb 2002 23:58:10 +0000 Subject: [PATCH 0238/1042] bug fix [SVN r12680] --- include/boost/python/class.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 4f30dc8d..978a226a 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -192,7 +192,9 @@ inline class_::class_(char const* name) template inline ref class_::object() const { - return this->class_base::object(); + typedef objects::class_base base; + + return this->base::object(); } }} // namespace boost::python From 47c77487071bf47bf73c5652bc62aeef552e8822 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 4 Feb 2002 01:42:47 +0000 Subject: [PATCH 0239/1042] bug fix [SVN r12681] --- .../boost/python/object/pointer_holder.hpp | 110 +++++++++--------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 81fcac0c..21fe8e96 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -28,113 +28,113 @@ struct pointer_holder : instance_holder template pointer_holder(PyObject*, A1 a1) : m_p(new Value( - (unwrap_reference::type&)(a1) + (typename unwrap_reference::type&)(a1) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2) : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3) : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) - , (unwrap_reference::type&)(a9) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) + , (typename unwrap_reference::type&)(a9) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : m_p(new Value( - (unwrap_reference::type&)(a1) - , (unwrap_reference::type&)(a2) - , (unwrap_reference::type&)(a3) - , (unwrap_reference::type&)(a4) - , (unwrap_reference::type&)(a5) - , (unwrap_reference::type&)(a6) - , (unwrap_reference::type&)(a7) - , (unwrap_reference::type&)(a8) - , (unwrap_reference::type&)(a9) - , (unwrap_reference::type&)(a10) + (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) + , (typename unwrap_reference::type&)(a9) + , (typename unwrap_reference::type&)(a10) )) {} From 80f697ef2a312ce49342c6ca7e387a6419f43104 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 4 Feb 2002 01:58:08 +0000 Subject: [PATCH 0240/1042] more bug fixes for really conformant compilers [SVN r12682] --- include/boost/python/value_from_python.hpp | 5 +++-- src/converter/builtin_converters.cpp | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/boost/python/value_from_python.hpp b/include/boost/python/value_from_python.hpp index 0ff80323..c835de45 100644 --- a/include/boost/python/value_from_python.hpp +++ b/include/boost/python/value_from_python.hpp @@ -16,6 +16,7 @@ namespace boost { namespace python { template struct value_from_python { + typedef value_from_python self; typedef converter::from_python_check from_python_check; value_from_python(from_python_check convertible) @@ -50,13 +51,13 @@ struct value_from_python // Mark successful construction static void constructed(converter::from_python_data& data) { - data.stage1 = get_storage(data); + data.stage1 = self::get_storage(data); } inline static void destroy(converter::from_python_data& data) { // Get the location of the storage for - void* storage = get_storage(data); + void* storage = self::get_storage(data); // Check for successful construction if (data.stage1 == storage) diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index fcd7a2cd..33e1cb50 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -91,7 +91,8 @@ namespace : value_from_python > { private: - typedef value_from_python > base; + typedef tp_cref_from_python self; + typedef value_from_python > base; public: tp_cref_from_python() @@ -102,7 +103,7 @@ namespace { unaryfunc converter = *(unaryfunc*)data.stage1; - void* storage = get_storage(data); + void* storage = self::get_storage(data); ref converted(converter(obj)); From 5d30ddac22c872e1413b3ea874edffc28f10ad8d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 4 Feb 2002 14:49:43 +0000 Subject: [PATCH 0241/1042] cxx 6.5 fixes [SVN r12689] --- include/boost/python/detail/unwind_type.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/boost/python/detail/unwind_type.hpp b/include/boost/python/detail/unwind_type.hpp index add3615a..e8ccd0c8 100644 --- a/include/boost/python/detail/unwind_type.hpp +++ b/include/boost/python/detail/unwind_type.hpp @@ -141,9 +141,12 @@ inline typename Generator::result_type unwind_type(type*p = 0, Generator* = 0) { BOOST_STATIC_CONSTANT(int, indirection - = (pointer_ * is_pointer::value) - | (reference_ * is_reference::value) - | (reference_to_pointer_ * is_reference_to_pointer::value)); + = (is_pointer::value ? pointer_ : 0) + + (is_reference_to_pointer::value + ? reference_to_pointer_ + : is_reference::value + ? reference_ + : 0)); return unwind_helper2::execute((U(*)())0,(Generator*)0); } From 8ff5450ece1658bdc973c01b58587e3182eb96c1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 4 Feb 2002 20:14:53 +0000 Subject: [PATCH 0242/1042] moved contents of builtin_to_python_converters.hpp to builtin_converters.hpp [SVN r12705] --- .../python/converter/builtin_converters.hpp | 60 +++++++++++++++++- .../builtin_to_python_converters.hpp | 62 ------------------- include/boost/python/to_python_value.hpp | 2 +- 3 files changed, 58 insertions(+), 66 deletions(-) delete mode 100644 include/boost/python/converter/builtin_to_python_converters.hpp diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index 9c19cbc5..a21fd27b 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -5,11 +5,65 @@ // to its suitability for any purpose. #ifndef BUILTIN_CONVERTERS_DWA2002124_HPP # define BUILTIN_CONVERTERS_DWA2002124_HPP +# include +# include -namespace boost { namespace python { namespace converter { +namespace boost { namespace python { -void initialize_builtin_converters(); +// Provide specializations of to_python_value +template struct to_python_value; -}}} // namespace boost::python::converter +namespace detail +{ + struct builtin_to_python + { + static bool convertible() { return true; } + }; +} + +# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ + template <> struct to_python_value \ + : detail::builtin_to_python \ + { \ + PyObject* operator()(T const& x) const \ + { \ + return (expr); \ + } \ + }; \ + template <> struct to_python_value \ + : detail::builtin_to_python \ + { \ + PyObject* operator()(T const& x) const \ + { \ + return (expr); \ + } \ + }; + + +# define BOOST_PYTHON_TO_INT(T) \ + BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \ + BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x)) + +BOOST_PYTHON_TO_INT(char) +BOOST_PYTHON_TO_INT(short) +BOOST_PYTHON_TO_INT(int) +BOOST_PYTHON_TO_INT(long) +# undef BOOST_TO_PYTHON_INT + +BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, PyString_FromString(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str())) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x) + +namespace converter +{ + + void initialize_builtin_converters(); + +} + +}} // namespace boost::python::converter #endif // BUILTIN_CONVERTERS_DWA2002124_HPP diff --git a/include/boost/python/converter/builtin_to_python_converters.hpp b/include/boost/python/converter/builtin_to_python_converters.hpp deleted file mode 100644 index 89ad7b86..00000000 --- a/include/boost/python/converter/builtin_to_python_converters.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP -# define BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP -# include -# include - -namespace boost { namespace python { - -// Provide specializations of to_python_value -template struct to_python_value; - -namespace detail -{ - struct builtin_to_python - { - static bool convertible() { return true; } - }; -} - -# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ - }; \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ - }; - - -# define BOOST_PYTHON_TO_INT(T) \ - BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \ - BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x)) - -BOOST_PYTHON_TO_INT(char) -BOOST_PYTHON_TO_INT(short) -BOOST_PYTHON_TO_INT(int) -BOOST_PYTHON_TO_INT(long) -# undef BOOST_TO_PYTHON_INT - -BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, PyString_FromString(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str())) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x) - -}} // namespace boost::python::converter - -#endif // BUILTIN_TO_PYTHON_CONVERTERS_DWA2002129_HPP diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp index a222e9a9..ecff5808 100644 --- a/include/boost/python/to_python_value.hpp +++ b/include/boost/python/to_python_value.hpp @@ -10,7 +10,7 @@ # include # include # include -# include +# include namespace boost { namespace python { From e37a97e2d57f3fd598ff222d1d4cbbfe5785e5f2 Mon Sep 17 00:00:00 2001 From: Darin Adler Date: Fri, 8 Feb 2002 20:08:15 +0000 Subject: [PATCH 0243/1042] Always say "private noncopyable" to avoid warnings. [SVN r12762] --- include/boost/python/classes.hpp | 2 +- include/boost/python/converter/handle.hpp | 2 +- include/boost/python/object/class.hpp | 4 ++-- test/comprehensive.hpp | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/python/classes.hpp b/include/boost/python/classes.hpp index 31af430f..2725ed7b 100644 --- a/include/boost/python/classes.hpp +++ b/include/boost/python/classes.hpp @@ -233,7 +233,7 @@ class BOOST_PYTHON_DECL_TEMPLATE meta_class boost::python::detail::getattrable< boost::python::detail::setattrable< boost::python::detail::type_object > > > > >, - boost::noncopyable + private boost::noncopyable { public: meta_class(); diff --git a/include/boost/python/converter/handle.hpp b/include/boost/python/converter/handle.hpp index bc06be38..82e085b0 100644 --- a/include/boost/python/converter/handle.hpp +++ b/include/boost/python/converter/handle.hpp @@ -16,7 +16,7 @@ struct BOOST_PYTHON_DECL body; // The common base class for unwrap_ and wrap_ handle objects. They // share a common base so that handles can be linked into a chain // within a function wrapper which is managed by a single object. -struct BOOST_PYTHON_DECL handle : boost::noncopyable +struct BOOST_PYTHON_DECL handle : private boost::noncopyable { public: // member functions diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 53d886fa..35280074 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -26,7 +26,7 @@ template struct holder; // To identify a class, we don't need cv/reference decorations typedef converter::undecorated_type_id_t class_id; -struct BOOST_PYTHON_DECL class_base : noncopyable +struct BOOST_PYTHON_DECL class_base : private noncopyable { // constructor class_base( @@ -44,7 +44,7 @@ struct BOOST_PYTHON_DECL class_base : noncopyable }; // Base class for all holders -struct BOOST_PYTHON_DECL instance_holder : noncopyable +struct BOOST_PYTHON_DECL instance_holder : private noncopyable { public: instance_holder(); diff --git a/test/comprehensive.hpp b/test/comprehensive.hpp index deb68a88..370f7d04 100644 --- a/test/comprehensive.hpp +++ b/test/comprehensive.hpp @@ -27,8 +27,8 @@ namespace bpl_test { // example: Foo, Bar, and Baz are C++ classes we want to wrap. // -class Foo // prohibit copying, proving that it doesn't choke - : boost::noncopyable // our generation of to_python(). +class Foo // prohibit copying, proving that it doesn't choke + : private boost::noncopyable // our generation of to_python(). { public: // constructor/destructor Foo(int x) : m_x(x) {} From 93735c7bf1538572018fedae9c76b05f46298d12 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 8 Feb 2002 22:04:01 +0000 Subject: [PATCH 0244/1042] Updated docs and provided backwards compatibility for handle_exception() [SVN r12764] --- doc/example1.html | 7 ------- doc/exporting_classes.html | 7 ------- doc/inheritance.html | 33 +++++++++++++-------------------- doc/overriding.html | 13 +++---------- example/getting_started1.cpp | 5 +++++ 5 files changed, 21 insertions(+), 44 deletions(-) diff --git a/doc/example1.html b/doc/example1.html index 402cc7a6..ee01e72c 100644 --- a/doc/example1.html +++ b/doc/example1.html @@ -37,19 +37,12 @@ namespace python = boost::python; BOOST_PYTHON_MODULE_INIT(getting_started1) { - try - { // Create an object representing this extension module. python::module_builder this_module("getting_started1"); // Add regular functions to the module. this_module.def(greet, "greet"); this_module.def(square, "square"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } }
  • diff --git a/doc/exporting_classes.html b/doc/exporting_classes.html index 61c5ef88..cbeb8a9e 100644 --- a/doc/exporting_classes.html +++ b/doc/exporting_classes.html @@ -47,8 +47,6 @@ namespace python = boost::python; BOOST_PYTHON_MODULE_INIT(getting_started2) { - try - { // Create an object representing this extension module. python::module_builder this_module("getting_started2"); @@ -65,11 +63,6 @@ BOOST_PYTHON_MODULE_INIT(getting_started2) // Even better, invite() can also be made a member of hello_class!!! hello_class.def(invite, "invite"); - } - catch(...) - { - python::handle_exception(); // Deal with the exception for Python - } }

    diff --git a/doc/inheritance.html b/doc/inheritance.html index cd95c744..3cceb0d0 100644 --- a/doc/inheritance.html +++ b/doc/inheritance.html @@ -78,26 +78,19 @@ namespace python = boost::python; BOOST_PYTHON_MODULE_INIT(my_module) { -    try -    { -       python::module_builder my_module("my_module"); - -       python::class_builder<Base> base_class(my_module, "Base"); -       base_class.def(python::constructor<void>()); - -       python::class_builder<Derived> derived_class(my_module, "Derived"); -       derived_class.def(python::constructor<void>()); - // Establish the inheritance relationship between Base and Derived - derived_class.declare_base(base_class); - - my_module.def(derived_as_base, "derived_as_base"); - my_module.def(get_name, "get_name"); - my_module.def(get_derived_x, "get_derived_x"); -    } -    catch(...) -    { -       python::handle_exception();    // Deal with the exception for Python -    } +    python::module_builder my_module("my_module"); + +    python::class_builder<Base> base_class(my_module, "Base"); +    base_class.def(python::constructor<void>()); + +    python::class_builder<Derived> derived_class(my_module, "Derived"); +    derived_class.def(python::constructor<void>()); + // Establish the inheritance relationship between Base and Derived + derived_class.declare_base(base_class); + + my_module.def(derived_as_base, "derived_as_base"); + my_module.def(get_name, "get_name"); + my_module.def(get_derived_x, "get_derived_x"); } diff --git a/doc/overriding.html b/doc/overriding.html index 02665be5..085d5a7f 100644 --- a/doc/overriding.html +++ b/doc/overriding.html @@ -151,16 +151,9 @@ struct baz_callback { BOOST_PYTHON_MODULE_INIT(foobar) { - try - { - boost::python::module_builder foobar("foobar"); - boost::python::class_builder<baz,baz_callback> baz_class("baz"); - baz_class.def(&baz::calls_pure, "calls_pure"); - } - catch(...) - { - boost::python::handle_exception(); // Deal with the exception for Python - } + boost::python::module_builder foobar("foobar"); + boost::python::class_builder<baz,baz_callback> baz_class("baz"); + baz_class.def(&baz::calls_pure, "calls_pure"); } diff --git a/example/getting_started1.cpp b/example/getting_started1.cpp index 2f180633..91a1f551 100644 --- a/example/getting_started1.cpp +++ b/example/getting_started1.cpp @@ -16,10 +16,15 @@ namespace python = boost::python; // extension module. This is where we build the module contents. BOOST_PYTHON_MODULE_INIT(getting_started1) { + try { // Create an object representing this extension module. python::module_builder this_module("getting_started1"); // Add regular functions to the module. this_module.def(greet, "greet"); this_module.def(square, "square"); + } + catch(...) { + boost::python::handle_exception(); + } } From 9e8273c7f7981d012b13a7d23310dc93ec0d80b1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Feb 2002 00:49:13 +0000 Subject: [PATCH 0245/1042] backward-compatibility hack for handle_exception() [SVN r12777] --- include/boost/python/errors.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp index b9eb4363..d0f71a24 100644 --- a/include/boost/python/errors.hpp +++ b/include/boost/python/errors.hpp @@ -28,6 +28,13 @@ bool handle_exception(T f) return handle_exception_impl(function0(boost::ref(f))); } +namespace detail { inline void rethrow() { throw; } } + +inline void handle_exception() +{ + handle_exception(detail::rethrow); +} + BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x); template From 44e43d3b47295269f67e6f1e17bfacca12af60bb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 14 Feb 2002 03:39:41 +0000 Subject: [PATCH 0246/1042] Initial checkin of V2 docs [SVN r12797] --- build/Jamfile | 2 +- doc/boost.css | 57 +++++ doc/v2/acknowledgments.html | 31 +++ doc/v2/bibliography.html | 31 +++ doc/v2/call.html | 62 +++++ doc/v2/class.html | 328 +++++++++++++++++++++++++++ doc/v2/class_hpp.py | 20 ++ doc/v2/configuration.html | 90 ++++++++ doc/v2/copy_const_reference.html | 118 ++++++++++ doc/v2/copy_non_const_reference.html | 119 ++++++++++ doc/v2/default_call_policies.html | 144 ++++++++++++ doc/v2/definitions.html | 34 +++ doc/v2/errors.html | 223 ++++++++++++++++++ doc/v2/faq.html | 38 ++++ doc/v2/foo.cpp | 142 ++++++++++++ doc/v2/from_python.html | 156 +++++++++++++ doc/v2/header.html | 181 +++++++++++++++ doc/v2/index.html | 41 ++++ doc/v2/overview.html | 47 ++++ doc/v2/rationale.html | 47 ++++ doc/v2/reference.html | 271 ++++++++++++++++++++++ 21 files changed, 2181 insertions(+), 1 deletion(-) create mode 100644 doc/boost.css create mode 100644 doc/v2/acknowledgments.html create mode 100644 doc/v2/bibliography.html create mode 100644 doc/v2/call.html create mode 100644 doc/v2/class.html create mode 100644 doc/v2/class_hpp.py create mode 100644 doc/v2/configuration.html create mode 100644 doc/v2/copy_const_reference.html create mode 100644 doc/v2/copy_non_const_reference.html create mode 100644 doc/v2/default_call_policies.html create mode 100644 doc/v2/definitions.html create mode 100644 doc/v2/errors.html create mode 100644 doc/v2/faq.html create mode 100644 doc/v2/foo.cpp create mode 100644 doc/v2/from_python.html create mode 100644 doc/v2/header.html create mode 100644 doc/v2/index.html create mode 100644 doc/v2/overview.html create mode 100644 doc/v2/rationale.html create mode 100644 doc/v2/reference.html diff --git a/build/Jamfile b/build/Jamfile index 1ea3665d..7dd6ecfe 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -9,7 +9,7 @@ # To run all tests with verbose output: jam -sPYTHON_TEST_ARGS=-v test # # Declares the following targets: -# 1. libboost_python, a static link library to be linked with all +# 1. libboost_python.dll/.so, a dynamic library to be linked with all # Boost.Python modules # # 2. pairs of test targets of the form .test and .run diff --git a/doc/boost.css b/doc/boost.css new file mode 100644 index 00000000..c382d4c6 --- /dev/null +++ b/doc/boost.css @@ -0,0 +1,57 @@ +H1 +{ + FONT-SIZE: 200% + COLOR: #00007f +} +H2 +{ + FONT-SIZE: 150%; +} +H3 +{ + FONT-SIZE: 125%; +} +H4 +{ + FONT-SIZE: 108%; +} +BODY +{ + FONT-SIZE: 100%; + BACKGROUND-COLOR: #ffffff +} +PRE +{ + MARGIN-LEFT: 2pc; + BACKGROUND-COLOR: #dfffff +} +CODE +{ + white-space: pre +} +.index +{ + TEXT-ALIGN: left +} +.page-index +{ + TEXT-ALIGN: left +} +.definition +{ + TEXT-ALIGN: left +} +.footnote +{ + FONT-SIZE: 66%; + VERTICAL-ALIGN: super; + TEXT-DECORATION: none +} +.function-semantics +{ + CLEAR: left +} +.metafunction-semantics +{ + CLEAR: left +} diff --git a/doc/v2/acknowledgments.html b/doc/v2/acknowledgments.html new file mode 100644 index 00000000..bd13fa79 --- /dev/null +++ b/doc/v2/acknowledgments.html @@ -0,0 +1,31 @@ + + + + +Boost.Python - Acknowledgments + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Acknowledgments

    +
    +


    +{{text}} +
    +

    Revised + + 05 November, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/bibliography.html b/doc/v2/bibliography.html new file mode 100644 index 00000000..e1be0141 --- /dev/null +++ b/doc/v2/bibliography.html @@ -0,0 +1,31 @@ + + + + +Boost.Python - Bibliography + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Bibliography

    +
    +
    +{{bibliographical information}} +
    +

    Revised + + 05 November, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/call.html b/doc/v2/call.html new file mode 100644 index 00000000..eb3e706c --- /dev/null +++ b/doc/v2/call.html @@ -0,0 +1,62 @@ + + + + +Boost.Python - <call.hpp> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Header <call.hpp>

    +
    +
    +

    Contents

    +
    +
    Introduction
    + +
    Functions
    +
    +
    call
    +
    + +
    Example(s)
    + +
    +
    +

    Introduction

    +

    {{Introductory text}}

    + +

    Functions

    +
    +call
    +
    +
    +
    Requires: {{text}}
    +
    Effects: {{text}}
    +
    Postconditions: {{text}}
    +
    Returns: {{text}}
    +
    Throws: {{text}}
    +
    Complexity: {{text}}
    +
    Rationale: {{text}}
    +
    + +

    Example(s)

    + +

    {{Example(s)}}

    +

    Revised + + 05 November, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/class.html b/doc/v2/class.html new file mode 100644 index 00000000..e6eee244 --- /dev/null +++ b/doc/v2/class.html @@ -0,0 +1,328 @@ + + + + +Boost.Python - <boost/python/class.hpp>, <boost/python/class_fwd.hpp> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Headers <boost/python/class.hpp>, <boost/python/class_fwd.hpp>

    +
    +
    +

    Contents

    +
    +
    Introduction
    + +
    Classes
    + +
    + +
    Class template class_
    +
    +
    Class class_ synopsis
    +
    Class class_ constructors
    +
    Class class_ modifier functions
    +
    Class class_ observer functions
    +
    + +
    Class template bases
    +
    +
    Class bases synopsis
    +
    + +
    Class template args
    +
    +
    Class args synopsis
    +
    + +
    + +
    Example(s)
    +
    +
    +

    Introduction

    + +

    <boost/python/class.hpp> defines the interface through + which users expose their C++ classes to Python. It declares the + class_ class template, which is parameterized on the + class type being exposed, and the args and + bases utility class templates in the anonymous + namespace (the latter definitions will probably be moved in a future + release). + +

    + <boost/python/class_fwd.hpp> contains a forward + declaration of the class_ class template. + + +

    Classes

    + +

    +Class template class_<T, Bases, HolderGenerator>

    + +

    Creates a Python class associated with the C++ type passed as its +first parameter. Its template arguments are: +

    + + + + + +
    Parameter + Description + Default +
    T + The class being exposed to Python +
    Bases + An MPL sequence of C++ base classes + An unspecified empty sequence +
    HolderGenerator + A type generator for the holder which +maintains the C++ object inside the Python instance. + boost::python::objects::value_holder_generator +
    + + + +

    Class template class_ synopsis

    +
    +namespace boost { namespace python
    +{
    +
    +  template <class T
    +            , class Bases = none
    +            , class HolderGenerator = objects::value_holder_generator>
    +  class class_
    +  {
    +    class_();
    +    class_(char const* name);
    +
    +    template <class F>
    +    class_& def(char const* name, F f);
    +
    +    template <class Fn, class CallPolicy>
    +    class_& def(char const* name, Fn fn, CallPolicy policy);
    +    
    +    template <class Args>
    +    class_& def_init(Args const& = Args());
    +
    +    class_& def_init();
    +
    +    ref object() const;
    +  };
    +}}
    +
    + +

    Class template class_ constructors

    +
    +class_()
    +
    +
    + +
    Requires: The platform's + std::type_info::name() implementation produces a string + which corresponds to the type's declaration in C++
    + +
    Effects: Constructs a class_ object which + generates a Boost.Python extension class with the same name as + T.
    + +
    Rationale: Many platforms can generate reasonable names + for Python classes without user intervention.
    + +
    + +
    +class_(char const* name)
    +
    +
    + +
    Requires: Name is a ntbs which conforms to Python's identifier + naming rules.
    + +
    Effects: Constructs a class_ object which + generates a Boost.Python extension class named + name.
    + +
    Rationale: Gives the user full control over class naming.
    + +
    + +

    Class template class_ modifier functions

    + +
    +template <class F>
    +class_& def(char const* name, F f)
    +
    +template <class Fn, class CallPolicy>
    +class_& def(char const* name, Fn fn, CallPolicy policy)
    +
    + +
    +
    Requires: + + f is a non-null pointer-to-function or + pointer-to-member-function. + + name is a ntbs which conforms to Python's identifier + naming rules. + + If supplied, policy conforms to the CallPolicy concept requirements. +
    + +
    Effects: Adds the result of make_function(f) + to the Boost.Python extension class being defined, with the given + name. If the extension class already has an attribute + named name, the usual overloading procedure applies. + +
    + +
    Returns: *this
    +
    + +
    +template <class Args>
    +class_& def_init(Args const& argument_types)
    +
    +class_& def_init()
    +
    + +
    + +
    Requires: in the first form, argument_types must be an MPL sequence of C++ + argument types (A1, A2,... AN) such that if + a1, a2... aN are objects of type + A1, A2,... AN respectively, the expression + T(a1, a2... aN) is + valid. In the second form, the expression T() must be + valid. +
    + +
    Effects: Adds the result of + make_constructor<T,Args,HolderGenerator>() to the + Boost.Python extension class being defined with the name + "__init__". If the 2nd form is used, an unspecified empty + MPL sequence type is + substituted for Args. + If the extension class already has an + "__init__" attribute, the usual overloading procedure applies. + +
    Returns: *this
    + +
    Rationale: Allows users to easily expose a class' + constructor to Python.
    +
    + + +

    Class template class_ observer +functions

    +
    +ref object() const;
    +
    +
    +
    Returns: A ref object which holds a + reference to the Boost.Python extension class object created by the + class_ constructor.
    + +
    Rationale: Mostly not needed by users, since module::add() uses this to + insert the extension class in the module.
    +
    + + +

    +Class template args<T1, T2,...TN>

    + +

    Essentially an alias for boost::mpl::type_list which +users can use in def_init calls to make their code more +readable. Currently it is in the global unnammed namespace, but that +will probably change. + +

    Class template args synopsis

    +
    +namespace
    +{
    +  template <T1 = unspecified,...TN = unspecified>
    +  struct args : ::boost::mpl::type_list<T1,...TN>::type
    +  {};
    +}
    +
    + +

    +Class template bases<T1, T2,...TN>

    + +

    Essentially an alias for boost::mpl::type_list which +users can use in class_<...> +instantiations to make their code more readable. Currently it is in +the global unnammed namespace, but that will probably change. + +

    Class template bases synopsis

    +
    +namespace
    +{
    +  template <T1 = unspecified,...TN = unspecified>
    +  struct bases : ::boost::mpl::type_list<T1,...TN>::type
    +  {};
    +}
    +
    + +

    Example(s)

    + +

    Given a C++ class declaration: + +

    +class Foo : public Bar, public Baz
    +{
    + public:
    +   Foo(int, char const*);
    +   Foo(double);
    +
    +   std::string const& name() { return m_name; }
    +   void name(char const*);
    + private:
    +   ...
    +};
    +
    + +A corresponding Boost.Python extension class can be created with: + +
    +using namespace boost::python;
    +ref foo =
    +class_<Foo,bases<Bar,Baz> >()
    +   .def_init(args<int,char const*>())
    +   .def_init(args<double>())
    +   .def("get_name", &Foo::get_name, return_internal_reference<>())
    +   .def("set_name", &Foo::set_name)
    +   .object();
    +
    + +

    + +

    Revised + + 05 November, 2001 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/class_hpp.py b/doc/v2/class_hpp.py new file mode 100644 index 00000000..9af2cb5c --- /dev/null +++ b/doc/v2/class_hpp.py @@ -0,0 +1,20 @@ +introduction = ''' +''' + +class boost(namespace): pass + +class python(boost): + + class class_(class_template): + T = type() + T.requires = 'a class type' + + Bases = concepts.mpl_sequence('class type') + HolderGenerator = concepts.HolderGenerator() + template_args = (T, Bases, HolderGenerator) + + class def_1(function_template): + name = "def" + args = (('char const*', 'name'), ('F', 'f')) + +class_template diff --git a/doc/v2/configuration.html b/doc/v2/configuration.html new file mode 100644 index 00000000..18b065d1 --- /dev/null +++ b/doc/v2/configuration.html @@ -0,0 +1,90 @@ + + + + +Boost.Python - Configuration + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Configuration

    +
    +
    +
    +
    Introduction
    +
    Application Defined Macros
    +
    Public Library Defined Macros
    +
    Library Defined Implementation Macros
    +
    +

    Introduction

    +

    Boost.Python uses several configuration macros in <boost/config.hpp>, + as well as configuration macros meant to be supplied by the application. These + macros are documented here.

    +

    Application Defined Macros

    +

    These are the macros that may be defined by an application using Boost.Python.

    + + + + + + + + + + + + + +
    MacroMeaning
    {{macro}}{{meaning}}
    {{macro}}{{meaning}}
    +

    Public Library Defined Macros

    +

    These macros are defined by Boost.Python but are expected to be used by application + code.

    + + + + + + + + + + + + + +
    MacroMeaning
    {{macro}}{{meaning}}
    {{macro}}{{meaning}}
    +

    Library Defined Implementation Macros

    +

    These macros are defined by Boost.Python and are implementation details of interest + only to implementers.

    + + + + + + + + + + + + + +
    MacroMeaning
    {{macro}}{{meaning}}
    {{macro}}{{meaning}}
    +
    +

    Revised + + 05 November, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/copy_const_reference.html b/doc/v2/copy_const_reference.html new file mode 100644 index 00000000..1ce94dbb --- /dev/null +++ b/doc/v2/copy_const_reference.html @@ -0,0 +1,118 @@ + + + + +Boost.Python - <boost/python/copy_const_reference.hpp> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Header <boost/python/copy_const_reference.hpp>

    +
    +
    +

    Contents

    +
    +
    Classes
    +
    +
    Class copy_const_reference
    +
    +
    Class copy_const_reference synopsis
    +
    Class copy_const_reference metafunctions
    +
    +
    + +
    Example
    +
    +
    + +

    Classes

    + +

    Class copy_const_reference

    +

    +copy_const_reference is a model of ResultConverterGenerator +which can be used to wrap C++ functions returning a reference-to-const +type such that the referenced value is copied into a new Python object. +

    + +

    Class copy_const_reference synopsis

    +
    +namespace boost { namespace python
    +{
    +    struct copy_const_reference
    +    {
    +        template <class T> struct apply;
    +    };
    +}}
    +
    +

    Class copy_const_reference metafunctions

    +
    +template <class T> struct apply
    +
    +
    +
    Requires: T is U const& for some U.
    +
    Returns: typedef to_python_value<T> type;
    +
    + +

    Example

    + +

    In C++: + +

    +#include <boost/python/module.hpp>
    +#include <boost/python/class.hpp>
    +#include <boost/python/copy_const_reference.hpp>
    +#include <boost/python/return_value_policy.hpp>
    +
    +// classes to wrap
    +struct Bar { int x; }
    +
    +struct Foo {
    +   Foo(int x) : { b.x = x; }
    +   Bar const& get_bar() const { return b; }
    + private:
    +   Bar b;
    +};
    +
    +// Wrapper code
    +using namespace boost::python;
    +BOOST_PYTHON_MODULE_INIT(my_module)
    +{
    +   module m("my_module")
    +      .add(
    +         class_<Bar>()
    +         )
    +      .add(
    +         class_<Foo>()
    +            .def_init(args<int>())
    +            .def("get_bar", &Foo::get_bar
    +                , return_value_policy<copy_const_reference>())
    +         );
    +}
    +
    + +In Python: + +
    +>>> from my_module import *
    +>>> f = Foo(3)         # create a Foo object
    +>>> b = f.get_bar()    # make a copy of the internal Bar object
    +
    + +

    Revised + + 05 November, 2001 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/copy_non_const_reference.html b/doc/v2/copy_non_const_reference.html new file mode 100644 index 00000000..c1ed50a3 --- /dev/null +++ b/doc/v2/copy_non_const_reference.html @@ -0,0 +1,119 @@ + + + + +Boost.Python - <boost/python/copy_non_const_reference.hpp> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Header <boost/python/copy_non_const_reference.hpp>

    +
    +
    +

    Contents

    +
    +
    Classes
    +
    +
    Class copy_non_const_reference
    +
    +
    Class copy_non_const_reference synopsis
    +
    Class copy_non_const_reference metafunctions
    +
    +
    + +
    Example
    +
    +
    + +

    Classes

    + +

    Class copy_non_const_reference

    +

    +copy_non_const_reference is a model of ResultConverterGenerator +which can be used to wrap C++ functions returning a reference-to-non-const +type such that the referenced value is copied into a new Python object. +

    + +

    Class copy_non_const_reference synopsis

    +
    +namespace boost { namespace python
    +{
    +    struct copy_non_const_reference
    +    {
    +        template <class T> struct apply;
    +    };
    +}}
    +
    + +

    Class copy_non_const_reference metafunctions

    +
    +template <class T> struct apply
    +
    +
    +
    Requires: T is U& for some non-const U.
    +
    Returns: typedef to_python_value<T> type;
    +
    + +

    Example

    + +

    C++ code: + +

    +#include <boost/python/module.hpp>
    +#include <boost/python/class.hpp>
    +#include <boost/python/copy_non_const_reference.hpp>
    +#include <boost/python/return_value_policy.hpp>
    +
    +// classes to wrap
    +struct Bar { int x; }
    +
    +struct Foo {
    +   Foo(int x) : { b.x = x; }
    +   Bar& get_bar() { return b; }
    + private:
    +   Bar b;
    +};
    +
    +// Wrapper code
    +using namespace boost::python;
    +BOOST_PYTHON_MODULE_INIT(my_module)
    +{
    +   module m("my_module")
    +      .add(
    +         class_<Bar>()
    +         )
    +      .add(
    +         class_<Foo>()
    +            .def_init(args<int>())
    +            .def("get_bar", &Foo::get_bar
    +                , return_value_policy<copy_non_const_reference>())
    +         );
    +}
    +
    + +Python Code: + +
    +>>> from my_module import *
    +>>> f = Foo(3)         # create a Foo object
    +>>> b = f.get_bar()    # make a copy of the internal Bar object
    +
    + +

    Revised + + 05 November, 2001 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/default_call_policies.html b/doc/v2/default_call_policies.html new file mode 100644 index 00000000..3e60fcc8 --- /dev/null +++ b/doc/v2/default_call_policies.html @@ -0,0 +1,144 @@ + + + + +Boost.Python - <boost/python/default_call_policies.hpp> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Header <boost/python/default_call_policies.hpp>

    +
    +
    +

    Contents

    +
    +
    Classes
    +
    + +
    Class default_call_policies
    +
    +
    Class default_call_policies synopsis
    +
    Class default_call_policies static functions
    +
    + +
    Class default_result_converter
    +
    +
    Class default_result_converter synopsis
    +
    Class default_result_converter metafunctions
    +
    + +
    + +
    Example
    +
    +
    + +

    Classes

    + +

    Class default_call_policies

    +

    +default_call_policies is a model of CallPolicies with no precall +or postcall behavior and a result_converter +which handles by-value returns. Wrapped C++ functions and member +functions use default_call_policies unless otherwise +specified. You may find it convenient to derive new models of CallPolicies from +default_call_policies. +

    + +

    Class default_call_policies synopsis

    +
    +namespace boost { namespace python
    +{
    +    struct default_call_policies
    +    {
    +        static bool precall(PyObject*);
    +        static PyObject* postcall(PyObject*, PyObject* result);
    +        typedef default_result_converter result_converter;
    +    };
    +}}
    +
    + +

    Class default_call_policies static functions

    +
    +bool precall(PyObject*);
    +
    +
    +
    Returns: true
    +
    Throws: nothing
    +
    + +
    +PyObject* postcall(PyObject*, PyObject* result);
    +
    +
    +
    Returns: result
    +
    Throws: nothing
    +
    + +

    Class default_result_converter

    +

    +default_result_converter is a model of ResultConverterGenerator +which can be used to wrap C++ functions returning non-pointer types, +char const*, and PyObject*, +by-value. +

    + +

    Class default_result_converter synopsis

    +
    +namespace boost { namespace python
    +{
    +    struct default_result_converter
    +    {
    +        template <class T> struct apply;
    +    };
    +}}
    +
    + +

    Class default_result_converter metafunctions

    +
    +template <class T> struct apply
    +
    +
    + +
    Requires: T is not a reference type. If + T is a pointer type, T is const + char* or PyObject*.
    + +
    Returns: typedef to_python_value<T const&> type;
    +
    + +

    Example

    + +

    This example comes from the Boost.Python implementation itself. Because the return_value_policy +class template does not implement precall or +postcall behavior, its default base class is default_call_policies: + +

    +template <class Handler, class Base = default_call_policies>
    +struct return_value_policy : Base
    +{
    +   typedef Handler result_converter;
    +};
    +
    + +

    Revised + + 05 November, 2001 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/definitions.html b/doc/v2/definitions.html new file mode 100644 index 00000000..dd917434 --- /dev/null +++ b/doc/v2/definitions.html @@ -0,0 +1,34 @@ + + + + +Boost.Python - Definitions + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Definitions

    +
    +
    +
    +
    {{term}}: {{definition}}
    +
    {{term}}: {{definition}}
    +
    +
    +

    Revised + + 05 November, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/errors.html b/doc/v2/errors.html new file mode 100644 index 00000000..b46de25c --- /dev/null +++ b/doc/v2/errors.html @@ -0,0 +1,223 @@ + + + + +Boost.Python - <{{header}}> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Header <boost/python/errors.hpp>

    +
    +
    +

    Contents

    +
    +
    Introduction
    + +
    Classes
    +
    + +
    Class error_already_set
    +
    +
    Class error_already_set synopsis
    +
    + +
    + +
    Functions
    +
    + +
    handle_exception
    +
    expect_non_null
    + +
    + +
    Examples
    +
    +
    + +

    Introduction

    +

    <boost/python/errors.hpp> provides types and +functions for managing and translating between Python and C++ +exceptions. This is relatively low-level functionality that is mostly +used internally by Boost.Python. Users should seldom need it. + +

    Classes

    + +

    Class error_already_set

    +

    +error_already_set is an exception type which can be +thrown to indicate that a Python error has occurred. If thrown, the +precondition is that PyErr_Occurred() +returns a value convertible to true. +

    + +

    Class error_already_set synopsis

    +
    +namespace boost { namespace python
    +{
    +    class error_already_set {};
    +}}
    +
    + + +

    Functions

    +
    template <class T> bool handle_exception(T f) throw();
    +
    +void handle_exception() throw();
    +
    +
    +
    Requires: The first form requires that the expression + function0<void>(f) + is valid. The second form requires that a C++ exception is currently + being handled (see section 15.1 in the C++ standard). +
    + +
    Effects: The first form calls f() inside a + try block whose catch clauses set an + appropriate Python exception for the C++ exception caught, returning + true if an exception was caught, false + otherwise. The second form passes a function which rethrows the + exception currently being handled to the first form.
    + +
    Postconditions: No exception is being handled
    + +
    Throws: nothing
    + +
    Rationale: At inter-language boundaries it is important + to ensure that no C++ exceptions escape, since the calling language + usually doesn't have the equipment neccessary to properly unwind the + stack. Use handle_exception to manage exception + translation whenever your C++ code is called directly from the + Python API. This is done for you automatically by the usual function + wrapping facilities: make_function(), make_constructor(), + module::def and class_::def). The second form can be + more convenient to use + (see the example below), but various + compilers have problems when exceptions are rethrown from within an + enclosing try block.
    +
    + +
    +PyObject* expect_non_null(PyObject* x);
    +
    +template <class T> T* expect_non_null(T* x);
    +
    +
    +
    Returns: x
    +
    Throws: error_already_set() iff x == 0.
    +
    Rationale: Simplifies error-handling when calling many + functions in the Python/C + API, which return 0 on error.
    +
    + +

    Examples

    +

    +

    +#include <string>
    +#include <boost/python/errors.hpp>
    +#include <boost/python/reference.hpp>
    +
    +// Returns a std::string which has the same value as obj's "__name__"
    +// attribute.
    +std::string get_name(boost::python::ref obj)
    +{
    +   // throws if there's no __name__ attribute
    +   PyObject* p = boost::python::expect_non_null(
    +      PyObject_GetAttrString(obj.get(), "__name__"));
    +
    +   // throws if it's not a Python string
    +   std::string result(
    +      boost::python::expect_non_null(
    +         PyString_AsString(p)));
    +
    +   Py_XDECREF(p); // Done with p
    +   
    +   return result;
    +}
    +
    +//
    +// Demonstrate form 1 of handle_exception
    +//
    +
    +// Place a Python Int object whose value is 1 if a and b have
    +// identical "__name__" attributes, 0 otherwise.
    +void same_name_impl(PyObject*& result, PyObject* a, PyObject* b)
    +{
    +   result = PyInt_FromLong(
    +      get_name(boost::python::ref(a1)) == get_name(boost::python::ref(a2)));
    +}
    +
    +// This is an example Python 'C' API interface function
    +extern "C" PyObject*
    +same_name(PyObject* args, PyObject* keywords)
    +{
    +   PyObject* a1;
    +   PyObject* a2;
    +   PyObject* result = 0;
    +
    +   if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
    +      return 0;
    +   
    +   // Use boost::bind to make an object compatible with
    +   // boost::Function0<void>
    +   if (boost::python::handle_exception(
    +         boost::bind<void>(same_name_impl, boost::ref(result), a1, a2)))
    +   {
    +      // an exception was thrown; the Python error was set by
    +      // handle_exception()
    +      return 0;
    +   }
    +
    +   return result;
    +}
    +
    +//
    +// Demonstrate form 2 of handle_exception. Not well-supported by all
    +// compilers.
    +//
    +extern "C" PyObject*
    +same_name2(PyObject* args, PyObject* keywords)
    +{
    +   PyObject* a1;
    +   PyObject* a2;
    +   PyObject* result = 0;
    +
    +   if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
    +      return 0;
    +   try {
    +      return PyInt_FromLong(
    +         get_name(boost::python::ref(a1)) == get_name(boost::python::ref(a2)));
    +   }
    +   catch(...)
    +   {
    +      // If an exception was thrown, translate it to Python
    +      boost::python::handle_exception();
    +      return 0;
    +   }
    +}
    +
    +

    +

    Revised + + 05 November, 2001 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/faq.html b/doc/v2/faq.html new file mode 100644 index 00000000..dae93fa5 --- /dev/null +++ b/doc/v2/faq.html @@ -0,0 +1,38 @@ + + + + +Boost.Python - FAQ + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Frequently Asked Questions (FAQs)

    +
    +
    +
    +
    {{question}}
    +
    {{question}}
    +
    +

    {{question}}

    +

    {{answer}}

    +

    {{question}}

    +

    {{answer}}

    +
    +

    Revised + + 05 November, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/foo.cpp b/doc/v2/foo.cpp new file mode 100644 index 00000000..e92c2d72 --- /dev/null +++ b/doc/v2/foo.cpp @@ -0,0 +1,142 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + + +#include +#include +#include +#include + +class Bar { int x; } + +class Foo +{ + public: + Foo(int x) : b(x) {} + Bar const& get_bar() const { return b; } + private: + Bar b; +}; + +using namespace boost::python; +BOOST_PYTHON_MODULE_INIT(my_module) +{ + module m("my_module") + .add( + class_() + ) + .add( + class_() + .def_init(args()) + .def("get_bar", &Foo::get_bar + , return_value_policy()) + ) +} + +using namespace boost::python; +ref foo = +class_ >() + .def_init(args()) + .def_init(args()) + .def("get_name", &Foo::get_name, return_internal_reference<>()) + .def("set_name", &Foo::set_name) + .object(); + + +
    +#include <string>
    +#include <boost/python/errors.hpp>
    +#include <boost/python/reference.hpp>
    +
    +// Returns a std::string which has the same value as obj's "__name__"
    +// attribute.
    +std::string get_name(boost::python::ref obj)
    +{
    +    // throws if there's no __name__ attribute
    +    PyObject* p = boost::python::expect_non_null(
    +        PyObject_GetAttrString(obj.get(), "__name__"));
    +
    +    // throws if it's not a Python string
    +    std::string result(
    +        boost::python::expect_non_null(
    +            PyString_AsString(p)));
    +
    +    Py_XDECREF(p); // Done with p
    +    
    +    return result;
    +}
    +
    +//
    +// Demonstrate form 1 of handle_exception
    +//
    +
    +// Place a Python Int object whose value is 1 if a and b have
    +// identical "__name__" attributes, 0 otherwise.
    +void same_name_impl(PyObject*& result, PyObject* a, PyObject* b)
    +{
    +    result = PyInt_FromLong(
    +        get_name(boost::python::ref(a1)) == get_name(boost::python::ref(a2)));
    +}
    +
    +// This is an example Python 'C' API interface function
    +extern "C" PyObject*
    +same_name(PyObject* args, PyObject* keywords)
    +{
    +    PyObject* a1;
    +    PyObject* a2;
    +    PyObject* result = 0;
    +
    +    if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
    +        return 0;
    +    
    +    // Use boost::bind to make an object compatible with
    +    // boost::Function0<void>
    +    if (boost::python::handle_exception(
    +            boost::bind<void>(same_name_impl, boost::ref(result), a1, a2)))
    +    {
    +        // an exception was thrown; the Python error was set by
    +        // handle_exception()
    +        return 0;
    +    }
    +
    +    return result;
    +}
    +
    +//
    +// Demonstrate form 2 of handle_exception. Not well-supported by all
    +// compilers.
    +//
    +extern "C" PyObject*
    +same_name2(PyObject* args, PyObject* keywords)
    +{
    +    PyObject* a1;
    +    PyObject* a2;
    +    PyObject* result = 0;
    +
    +    if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
    +        return 0;
    +    try {
    +        return PyInt_FromLong(
    +            get_name(boost::python::ref(a1)) == get_name(boost::python::ref(a2)));
    +    }
    +    catch(...)
    +    {
    +        // If an exception was thrown, translate it to Python
    +        boost::python::handle_exception();
    +        return 0;
    +    }
    +}
    +
    +
    + + +template +struct from_python +{ + from_python(PyObject*); + bool convertible() const; + X operator()(PyObject*) const; +}; diff --git a/doc/v2/from_python.html b/doc/v2/from_python.html new file mode 100644 index 00000000..94ae7019 --- /dev/null +++ b/doc/v2/from_python.html @@ -0,0 +1,156 @@ + + + + +Boost.Python - <boost/python/from_python.hpp> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Header <boost/python/from_python.hpp>

    +
    +
    +

    Contents

    +
    +
    Introduction
    + +
    Classes
    +
    + +
    Class Templatefrom_python
    +
    +
    Class Template from_python synopsis
    +
    Class Template from_python constructor
    +
    Class Template from_python observer functions
    +
    +
    +
    Example
    +
    +
    +

    Introduction

    +

    + +<boost/python/from_python.hpp> introduces a class +template from_python<T> for extracting a C++ object +of type T from a Python object. + +

    + + +

    Classes

    +

    Class Template from_python<class T>

    + +

    +from_python<T> is the type used internally by +Boost.Python to extract C++ function arguments from a Python argument +tuple when calling a wrapped function. It can also be used directly to +make similar conversions in other contexts. +

    + +

    Class Template from_python synopsis

    +
    +namespace boost { namespace python
    +{
    +   template <class T>
    +   struct from_python : private boost::noncopyable // Exposition only.
    +       // from_python<T> meets the NonCopyable requirements
    +   {
    +      from_python(PyObject*);
    +      bool convertible() const;
    +      convertible-to-T operator()(PyObject*) const;
    +   };
    +}
    +
    + +

    Class Template from_python constructor

    +
    +from_python(PyObject* p);
    +
    +
    +
    Requires: p != 0
    + +
    Effects: Constructs a from_python object + suitable for extracting a C++ object of type T from + p.
    +
    + +

    Class Template from_python observer functions

    + +
    +bool convertible() const;
    +
    +
    + +
    Returns: false if the conversion cannot succeed. This indicates that either: +
      +
    1. No from_python_converter was registered for +T, or + +
    2. any such converter rejected the constructor argument +p by returning 0 from its +convertible() function +
    + +Note that conversion may still fail in operator() due to an exception. + +
    + +
    Throws: nothing
    + +
    Rationale: Because from_python<> is used in + overload resolution, and throwing an exception can be slow, it is + useful to be able to rule out a broad class of unsuccessful + conversions without throwing an exception.
    +
    + +
    +convertible-to-T operator()(PyObject* p) const;
    +
    +
    + +
    Requires: *p refers to the same object which + was passed to the constructor, and convertible() + returns true.
    + +
    Effects: performs the conversion
    +
    Returns: an object convertible to T.
    +
    + +

    Example

    + +

    +

    +#include <string>
    +#include <boost/python/from_python.hpp>
    +
    +// If a std::string can be extracted from p, return its
    +// length. Otherwise, return 0.
    +std::size_t length_if_string(PyObject* p)
    +{
    +   from_python<std::string> converter(p);
    +   if (!converter.convertible())
    +      return 0;
    +   else
    +      return converter().size();
    +}
    +
    +

    + +

    Revised + + 05 November, 2001 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/header.html b/doc/v2/header.html new file mode 100644 index 00000000..c0fa972f --- /dev/null +++ b/doc/v2/header.html @@ -0,0 +1,181 @@ + + + + +Boost.Python - <{{header}}> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Header <{{header}}>

    +
    +
    +

    Contents

    +
    +
    Introduction
    +
    Macros
    +
    +
    {{macro name}}
    +
    +
    Values
    +
    +
    {{value name}}
    +
    +
    Types
    +
    +
    {{type name}}
    +
    +
    Classes
    +
    +
    Class {{class name}}
    +
    +
    Class {{class name}} synopsis
    +
    Class {{class name}} constructors and destructor
    +
    Class {{class name}} comparison functions
    +
    Class {{class name}} modifier functions
    +
    Class {{class name}} observer functions
    +
    Class {{class name}} static functions
    +
    +
    +
    Functions
    +
    +
    {{function name}}
    +
    +
    Objects
    +
    +
    {{object name}}
    +
    +
    Example(s)
    +
    +
    +

    Introduction

    +

    {{Introductory text}}

    +

    Macros

    +

    {{Macro specifications}}

    +

    Values

    +

    {{Value specifications}}

    +

    Types

    +

    {{Type specifications}}

    +

    Classes

    +

    Class {{name}}

    +

    {{class overview text}}

    +

    Class {{name}} synopsis

    +
    +namespace boost
    +{
    +    class {{name}}
    +	{
    +	};
    +};
    +
    +

    Class {{name}} constructors and destructor

    +
    +{{constructor}}
    +
    +
    +
    Requires: {{text}}
    +
    Effects: {{text}}
    +
    Postconditions: {{text}}
    +
    Returns: {{text}}
    +
    Throws: {{text}}
    +
    Complexity: {{text}}
    +
    Rationale: {{text}}
    +
    +
    +{{destructor}}
    +
    +
    +
    Requires: {{text}}
    +
    Effects: {{text}}
    +
    Postconditions: {{text}}
    +
    Returns: {{text}}
    +
    Throws: {{text}}
    +
    Complexity: {{text}}
    +
    Rationale: {{text}}
    +
    +

    Class {{name}} comparison functions

    +
    +{{function}}
    +
    +
    +
    Requires: {{text}}
    +
    Effects: {{text}}
    +
    Postconditions: {{text}}
    +
    Returns: {{text}}
    +
    Throws: {{text}}
    +
    Complexity: {{text}}
    +
    Rationale: {{text}}
    +
    +

    Class {{name}} modifier functions

    +
    +{{function}}
    +
    +
    +
    Requires: {{text}}
    +
    Effects: {{text}}
    +
    Postconditions: {{text}}
    +
    Returns: {{text}}
    +
    Throws: {{text}}
    +
    Complexity: {{text}}
    +
    Rationale: {{text}}
    +
    +

    Class {{name}} observer functions

    +
    +{{function}}
    +
    +
    +
    Requires: {{text}}
    +
    Effects: {{text}}
    +
    Postconditions: {{text}}
    +
    Returns: {{text}}
    +
    Throws: {{text}}
    +
    Complexity: {{text}}
    +
    Rationale: {{text}}
    +
    +

    Class {{name}} static functions

    +
    +{{function}}
    +
    +
    +
    Requires: {{text}}
    +
    Effects: {{text}}
    +
    Postconditions: {{text}}
    +
    Returns: {{text}}
    +
    Throws: {{text}}
    +
    Complexity: {{text}}
    +
    Rationale: {{text}}
    +
    +

    Functions

    +
    +{{function}}
    +
    +
    +
    Requires: {{text}}
    +
    Effects: {{text}}
    +
    Postconditions: {{text}}
    +
    Returns: {{text}}
    +
    Throws: {{text}}
    +
    Complexity: {{text}}
    +
    Rationale: {{text}}
    +
    +

    Objects

    +

    {{Object specifications}}

    +

    Example(s)

    +

    {{Example(s)}}

    +

    Revised + + 05 November, 2001 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/index.html b/doc/v2/index.html new file mode 100644 index 00000000..dea1db6e --- /dev/null +++ b/doc/v2/index.html @@ -0,0 +1,41 @@ + + + + +Boost.Python + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Index

    +
    +
    +

    Contents

    +
    +
    Overview
    +
    Reference
    +
    Configuration Information
    +
    Rationale
    +
    Definitions
    +
    Frequently Asked Questions (FAQs)
    +
    Bibliography
    +
    Acknowledgments
    +
    +
    +

    Revised + + 05 November, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/overview.html b/doc/v2/overview.html new file mode 100644 index 00000000..57d0e36e --- /dev/null +++ b/doc/v2/overview.html @@ -0,0 +1,47 @@ + + + + +Boost.Python - Overview + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Overview

    +
    +
    +
    +
    Introduction
    +
    First topic
    +
    Second topic
    +
    Footnotes
    +
    +

    Introduction

    +

    {{text}}

    +

    First Topic

    +

    {{text}}

    +

    Second Topic

    +

    {{text}}

    +

    Footnotes

    +
    +
    (1) {{text}}
    +
    (2) {{text}}
    +
    +
    +

    Revised + + 05 November, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/rationale.html b/doc/v2/rationale.html new file mode 100644 index 00000000..da7e9217 --- /dev/null +++ b/doc/v2/rationale.html @@ -0,0 +1,47 @@ + + + + +Boost.Python - Rationale + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Rationale

    +
    +
    +
    +
    Introduction
    +
    First topic
    +
    Second topic
    +
    Footnotes
    +
    +

    Introduction

    +

    {{text}}

    +

    First Topic

    +

    {{text}}

    +

    Second Topic

    +

    {{text}}

    +

    Footnotes

    +
    +
    (1) {{text}}
    +
    (2) {{text}}
    +
    +
    +

    Revised + + 05 November, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/reference.html b/doc/v2/reference.html new file mode 100644 index 00000000..0aa546e5 --- /dev/null +++ b/doc/v2/reference.html @@ -0,0 +1,271 @@ + + + + +Boost.Python - Reference + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Reference

    +
    +
    +

    Contents

    +
    +
    High Level Components
    +
    Framework Elements
    +
    Utilities
    +
    Index By Name
    +
    + +

    High Level Components

    +
    + +

    General Purpose

    +
    + +
    class.hpp/class_fwd.hpp
    +
    +
    Classes
    +
    +
    class_
    +
    bases
    +
    args
    +
    + + +
    + +
    errors.hpp
    +
    + +
    Classes
    +
    +
    error_already_set
    +
    +
    Functions
    +
    +
    handle_exception
    +
    expect_non_null
    +
    +
    + +
    make_function.hpp
    +
    +
    Functions
    +
    +
    make_function
    +
    make_constructor
    +
    +
    + +
    module.hpp
    +
    +
    Classes
    +
    +
    module
    +
    + +
    + +
    objects.hpp
    +
    +
    Classes
    +
    +
    not yet documented
    +
    + +
    + +
    reference.hpp
    +
    +
    Classes
    +
    +
    reference
    +
    + +
    Types
    +
    +
    ref
    +
    + +
    + + +
    + +

    To/From Python Type Conversion

    +
    + +
    from_python.hpp
    +
    +
    Classes
    +
    +
    from_python
    +
    +
    + +
    to_python_converter.hpp
    +
    +
    Classes
    +
    +
    to_python_converter
    +
    + +
    + +
    to_python_indirect.hpp
    +
    +
    Classes
    +
    +
    to_python_indirect
    +
    + +
    + +
    to_python_value.hpp
    +
    +
    Classes
    +
    +
    to_python_value
    +
    + +
    + +
    type_from_python.hpp
    +
    +
    Classes
    +
    +
    type_from_python
    +
    + +
    + + +
    value_from_python.hpp
    +
    +
    Classes
    +
    +
    value_from_python
    +
    + +
    + +
    + + +

    Models of CallPolicies

    +
    + +
    default_call_policies.hpp
    +
    +
    Classes
    +
    +
    default_call_policies
    +
    default_result_converter
    +
    + +
    + +
    return_internal_reference.hpp
    +
    +
    Classes
    +
    +
    return_internal_reference
    +
    + +
    + +
    return_value_policy.hpp
    +
    +
    Classes
    +
    +
    return_value_policy
    +
    + +
    + +
    with_custodian_and_ward.hpp
    +
    +
    Classes
    +
    +
    with_custodian_and_ward
    +
    with_custodian_and_ward_postcall
    +
    + +
    + +
    + +

    Models of ReturnHandlerGenerator

    +
    + +
    copy_const_reference.hpp
    +
    +
    Classes
    +
    +
    copy_const_reference
    +
    + +
    + +
    copy_non_const_reference.hpp
    +
    +
    Classes
    +
    +
    copy_non_const_reference
    +
    + +
    + + +
    manage_new_object.hpp
    +
    +
    Classes
    +
    +
    manage_new_object
    +
    + +
    + +
    reference_existing_object.hpp
    +
    +
    Classes
    +
    +
    reference_existing_object
    +
    + +
    + +
    reference_from_python.hpp
    +
    +
    Classes
    +
    +
    reference_from_python
    +
    get_member
    +
    + +
    + +
    + +
    + +
    +

    Revised + + 05 November, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + From 08c909fd410df8ea9d837996034e0edb6edd3dce Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Thu, 14 Feb 2002 04:08:20 +0000 Subject: [PATCH 0247/1042] Updated the basic Jamfiles for the new Boost.Build changes. [SVN r12798] --- build/Jamfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index 7dd6ecfe..c9f6fa75 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -66,7 +66,7 @@ local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_DYNAMIC_LIB ####################### rule bpl-test ( test-name : sources + ) { - boost-python-test $(test-name) : $(sources) libboost_python ; + boost-python-test $(test-name) : $(sources) boost_python ; } ####################### @@ -81,14 +81,14 @@ local CPP_SOURCES = init_function module_builder objects cross_module errors ; -lib libboost_python_static : ../src/$(CPP_SOURCES).cpp +lib boost_python_static : ../src/$(CPP_SOURCES).cpp # requirements : $(BOOST_PYTHON_INCLUDES) true BOOST_PYTHON_STATIC_LIB=1 $(PYTHON_PROPERTIES) ; -dll libboost_python +dll boost_python # $(SUFDLL[1]) : ../src/$(CPP_SOURCES).cpp # requirements @@ -104,7 +104,7 @@ bpl-test boost_python_test : ../test/comprehensive.cpp ; boost-python-runtest comprehensive - : ../test/comprehensive.py boost_python_test libboost_python ; + : ../test/comprehensive.py boost_python_test boost_python ; ############# simple tests from ../example ############ @@ -114,7 +114,7 @@ rule boost-python-example-runtest ( name ) : ../example/$(name).cpp ; boost-python-runtest $(name) - : ../example/test_$(name).py $(name) ; + : ../example/test_$(name).py $(name) ; } @@ -139,7 +139,7 @@ bpl-test noncopyable_import : ../example/noncopyable_import.cpp ; rule boost-python-multi-example-runtest ( test-name : modules + ) { boost-python-runtest $(test-name) - : ../example/tst_$(test-name).py $(modules) libboost_python + : ../example/tst_$(test-name).py $(modules) boost_python : : : $(PYTHON_VECT_ITERATIONS) ; } From 12c798145089290c17f101e7de8e028f8a025f48 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 14 Feb 2002 15:57:40 +0000 Subject: [PATCH 0248/1042] *** empty log message *** [SVN r12805] --- doc/v2/class.html | 17 +- doc/v2/errors.html | 2 +- doc/v2/foo.cpp | 142 ------------ doc/v2/make_function.html | 155 +++++++++++++ doc/v2/manage_new_object.html | 115 ++++++++++ include/boost/python/call.hpp | 210 ------------------ .../python/converter/builtin_converters.hpp | 6 +- .../boost/python/converter/from_python.hpp | 1 + include/boost/python/module.hpp | 4 +- src/converter/builtin_converters.cpp | 28 +++ test/test_builtin_converters.cpp | 2 + test/test_builtin_converters.py | 12 + 12 files changed, 331 insertions(+), 363 deletions(-) delete mode 100644 doc/v2/foo.cpp create mode 100644 doc/v2/make_function.html create mode 100644 doc/v2/manage_new_object.html delete mode 100644 include/boost/python/call.hpp diff --git a/doc/v2/class.html b/doc/v2/class.html index e6eee244..12ad5d23 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -76,19 +76,24 @@ first parameter. Its template arguments are: -
    Parameter - Description + Requirements Default
    T - The class being exposed to Python + A class type.
    Bases - An MPL sequence of C++ base classes + + An MPL + sequence of C++ base classes of T. + An unspecified empty sequence +
    HolderGenerator - A type generator for the holder which -maintains the C++ object inside the Python instance. + HolderGenerator + + A model of HolderGenerator. + boost::python::objects::value_holder_generator
    diff --git a/doc/v2/errors.html b/doc/v2/errors.html index b46de25c..e0bfa89d 100644 --- a/doc/v2/errors.html +++ b/doc/v2/errors.html @@ -78,7 +78,7 @@ void handle_exception() throw();
     convertible-to-T operator()(PyObject* p) const;
     
    -
    -
    Requires: *p refers to the same object which - was passed to the constructor, and convertible() - returns true.
    +
    +
    Requires: *p refers to the same object which was + passed to the constructor, and convertible() returns + true. -
    Effects: performs the conversion
    -
    Returns: an object convertible to T.
    -
    +
    Effects: performs the conversion -

    Example

    +
    Returns: an object convertible to T. +
    -

    +

    Example

     #include <string>
     #include <boost/python/from_python.hpp>
    @@ -143,14 +154,13 @@ std::size_t length_if_string(PyObject* p)
           return converter().size();
     }
     
    -

    -

    Revised - - 05 November, 2001 - -

    -

    © Copyright Dave Abrahams - 2002. All Rights Reserved.

    - - +

    Revised + + 05 November, 2001 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + diff --git a/doc/v2/header.html b/doc/v2/header.html index c0fa972f..7b36a65c 100644 --- a/doc/v2/header.html +++ b/doc/v2/header.html @@ -1,181 +1,293 @@ - - - - -Boost.Python - <{{header}}> - - - + + + + + Boost.Python - <{{header}}> + +
    - - - - -
    -

    C++ Boost

    -
    -

    Boost.Python

    -

    Header <{{header}}>

    -
    -


    -

    Contents

    -
    -
    Introduction
    -
    Macros
    -
    -
    {{macro name}}
    -
    -
    Values
    -
    -
    {{value name}}
    -
    -
    Types
    -
    -
    {{type name}}
    -
    -
    Classes
    -
    -
    Class {{class name}}
    -
    -
    Class {{class name}} synopsis
    -
    Class {{class name}} constructors and destructor
    -
    Class {{class name}} comparison functions
    -
    Class {{class name}} modifier functions
    -
    Class {{class name}} observer functions
    -
    Class {{class name}} static functions
    -
    -
    -
    Functions
    -
    -
    {{function name}}
    -
    -
    Objects
    -
    -
    {{object name}}
    -
    -
    Example(s)
    -
    -
    -

    Introduction

    -

    {{Introductory text}}

    -

    Macros

    -

    {{Macro specifications}}

    -

    Values

    -

    {{Value specifications}}

    -

    Types

    -

    {{Type specifications}}

    -

    Classes

    -

    Class {{name}}

    -

    {{class overview text}}

    -

    Class {{name}} synopsis

    + + +

    +

    + + +

    Boost.Python

    + +

    Header <{{header}}>

    + +
    + +

    Contents

    + +
    +
    Introduction + +
    Macros + +
    +
    +
    {{macro name}} +
    + +
    Values + +
    +
    +
    {{value name}} +
    + +
    Types + +
    +
    +
    {{type name}} +
    + +
    Classes + +
    +
    +
    Class {{class name}} + +
    +
    +
    Class {{class + name}} synopsis + +
    Class {{class name}} + constructors and destructor + +
    Class {{class + name}} comparison functions + +
    Class {{class + name}} modifier functions + +
    Class {{class + name}} observer functions + +
    Class {{class + name}} static functions +
    +
    + +
    Functions + +
    +
    +
    {{function name}} +
    + +
    Objects + +
    +
    +
    {{object name}} +
    + +
    Example(s) +
    +
    + +

    Introduction

    + +

    {{Introductory text}} + +

    Macros

    + +

    {{Macro specifications}} + +

    Values

    + +

    {{Value specifications}} + +

    Types

    + +

    {{Type specifications}} + +

    Classes

    + +

    Class {{name}}

    + +

    {{class overview text}} + +

    Class {{name}} synopsis

     namespace boost
     {
         class {{name}}
    -	{
    -	};
    +  {
    +  };
     };
     
    -

    Class {{name}} constructors and destructor

    + +

    Class {{name}} constructors and + destructor

     {{constructor}}
     
    -
    -
    Requires: {{text}}
    -
    Effects: {{text}}
    -
    Postconditions: {{text}}
    -
    Returns: {{text}}
    -
    Throws: {{text}}
    -
    Complexity: {{text}}
    -
    Rationale: {{text}}
    -
    + +
    +
    Requires: {{text}} + +
    Effects: {{text}} + +
    Postconditions: {{text}} + +
    Returns: {{text}} + +
    Throws: {{text}} + +
    Complexity: {{text}} + +
    Rationale: {{text}} +
     {{destructor}}
     
    -
    -
    Requires: {{text}}
    -
    Effects: {{text}}
    -
    Postconditions: {{text}}
    -
    Returns: {{text}}
    -
    Throws: {{text}}
    -
    Complexity: {{text}}
    -
    Rationale: {{text}}
    -
    -

    Class {{name}} comparison functions

    + +
    +
    Requires: {{text}} + +
    Effects: {{text}} + +
    Postconditions: {{text}} + +
    Returns: {{text}} + +
    Throws: {{text}} + +
    Complexity: {{text}} + +
    Rationale: {{text}} +
    + +

    Class {{name}} comparison + functions

     {{function}}
     
    -
    -
    Requires: {{text}}
    -
    Effects: {{text}}
    -
    Postconditions: {{text}}
    -
    Returns: {{text}}
    -
    Throws: {{text}}
    -
    Complexity: {{text}}
    -
    Rationale: {{text}}
    -
    -

    Class {{name}} modifier functions

    + +
    +
    Requires: {{text}} + +
    Effects: {{text}} + +
    Postconditions: {{text}} + +
    Returns: {{text}} + +
    Throws: {{text}} + +
    Complexity: {{text}} + +
    Rationale: {{text}} +
    + +

    Class {{name}} modifier + functions

     {{function}}
     
    -
    -
    Requires: {{text}}
    -
    Effects: {{text}}
    -
    Postconditions: {{text}}
    -
    Returns: {{text}}
    -
    Throws: {{text}}
    -
    Complexity: {{text}}
    -
    Rationale: {{text}}
    -
    -

    Class {{name}} observer functions

    + +
    +
    Requires: {{text}} + +
    Effects: {{text}} + +
    Postconditions: {{text}} + +
    Returns: {{text}} + +
    Throws: {{text}} + +
    Complexity: {{text}} + +
    Rationale: {{text}} +
    + +

    Class {{name}} observer + functions

     {{function}}
     
    -
    -
    Requires: {{text}}
    -
    Effects: {{text}}
    -
    Postconditions: {{text}}
    -
    Returns: {{text}}
    -
    Throws: {{text}}
    -
    Complexity: {{text}}
    -
    Rationale: {{text}}
    -
    -

    Class {{name}} static functions

    + +
    +
    Requires: {{text}} + +
    Effects: {{text}} + +
    Postconditions: {{text}} + +
    Returns: {{text}} + +
    Throws: {{text}} + +
    Complexity: {{text}} + +
    Rationale: {{text}} +
    + +

    Class {{name}} static functions

     {{function}}
     
    -
    -
    Requires: {{text}}
    -
    Effects: {{text}}
    -
    Postconditions: {{text}}
    -
    Returns: {{text}}
    -
    Throws: {{text}}
    -
    Complexity: {{text}}
    -
    Rationale: {{text}}
    -
    -

    Functions

    + +
    +
    Requires: {{text}} + +
    Effects: {{text}} + +
    Postconditions: {{text}} + +
    Returns: {{text}} + +
    Throws: {{text}} + +
    Complexity: {{text}} + +
    Rationale: {{text}} +
    + +

    Functions

    +
    +
     {{function}}
     
    -
    -
    Requires: {{text}}
    -
    Effects: {{text}}
    -
    Postconditions: {{text}}
    -
    Returns: {{text}}
    -
    Throws: {{text}}
    -
    Complexity: {{text}}
    -
    Rationale: {{text}}
    -
    -

    Objects

    -

    {{Object specifications}}

    -

    Example(s)

    -

    {{Example(s)}}

    -

    Revised - - 05 November, 2001 - -

    -

    © Copyright Dave Abrahams - 2002. All Rights Reserved.

    - - + +
    +
    Requires: {{text}} + +
    Effects: {{text}} + +
    Postconditions: {{text}} + +
    Returns: {{text}} + +
    Throws: {{text}} + +
    Complexity: {{text}} + +
    Rationale: {{text}} +
    + +

    Objects

    + +

    {{Object specifications}} + +

    Example(s)

    + +

    {{Example(s)}} + +

    Revised + + 05 November, 2001 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + diff --git a/doc/v2/make_function.html b/doc/v2/make_function.html index e7c4b421..7f40703b 100644 --- a/doc/v2/make_function.html +++ b/doc/v2/make_function.html @@ -1,116 +1,109 @@ - - - - -Boost.Python - <boost/python/make_function.hpp> - - - + + + + + Boost.Python - <boost/python/make_function.hpp> + +
    - - - - -
    -

    C++ Boost

    -
    -

    Boost.Python

    -

    Header <boost/python/make_function.hpp>

    -
    -


    -

    Contents

    -
    -
    Introduction
    + + +

    +

    -
    Functions
    -
    -
    make_function
    -
    make_constructor
    -
    + +

    Boost.Python

    -
    Example
    +

    Header <boost/python/make_function.hpp>

    + +
    -
    -
    -

    Introduction

    -

    +

    Contents

    -make_function() and -make_constructor() -are the functions used internally by class_<>::def, -class_<>::def, -and -class_<>::def_init -to produce Python callable objects which wrap C++ functions and member -functions. -

    +
    +
    Introduction -

    Functions

    +
    Functions +
    +
    +
    make_function + +
    make_constructor +
    + +
    Example +
    +
    + +

    Introduction

    + +

    make_function() and + make_constructor() are + the functions used internally by class_<>::def, class_<>::def, and + class_<>::def_init to produce Python + callable objects which wrap C++ functions and member functions. + +

    Functions

    -template <class F>
    +template <class F>
     objects::function* make_function(F f)</a>
     
     template <class F, class Policies>
     objects::function* make_function(F f, Policies const& policies)
     
    -
    -
    Requires: F is a function pointer or member - function pointer type
    +
    +
    Requires: F is a function pointer or member + function pointer type -
    Effects: Creates a Python callable object which, when - called from Python, converts its arguments to C++ and calls - f. If F is a pointer-to-member-function - type, the target object of the function call (*this) - will be taken from the first Python argument, and subsequent Python - arguments will be used as the arguments to f. If - policies are supplied, it must be a model of CallPolicies, and will be applied to - the function as described here.
    - -
    Returns: A pointer convertible to PyObject* - which refers to the new Python callable object.
    -
    +
    Effects: Creates a Python callable object which, when called + from Python, converts its arguments to C++ and calls f. If + F is a pointer-to-member-function type, the target object of + the function call (*this) will be taken from the first + Python argument, and subsequent Python arguments will be used as the + arguments to f. If policies are supplied, it + must be a model of CallPolicies, and will + be applied to the function as described here. +
    Returns: A pointer convertible to PyObject* which + refers to the new Python callable object. +
    -template <class T, class ArgList, class Generator>
    +template <class T, class ArgList, class Generator>
     objects::function* make_constructor();
     
    -
    -
    Requires: T is a class - type. ArgList is an MPL sequence of C++ - argument types (A1, A2,... AN) such that if - a1, a2... aN are objects of type - A1, A2,... AN respectively, the expression - new Generator::apply<T>::type(a1, a2... aN) is - valid. Generator is a model of HolderGenerator. -
    +
    +
    Requires: T is a class type. ArgList + is an MPL sequence of C++ + argument types (A1, A2,... AN) such that if + a1, a2... aN are objects of type + A1, A2,... AN respectively, the expression new + Generator::apply<T>::type(a1, a2... aN) is + valid. Generator is a model of HolderGenerator. -
    Effects: Creates a Python callable object which, when - called from Python, expects its first argument to be a Boost.Python - extension class object. It converts its remaining its arguments to - C++ and passes them to the constructor of a dynamically-allocated - Generator::apply<T>::type object. The result is - installed in the extension class object. +
    Effects: Creates a Python callable object which, when called + from Python, expects its first argument to be a Boost.Python extension + class object. It converts its remaining its arguments to C++ and passes + them to the constructor of a dynamically-allocated + Generator::apply<T>::type object. The result is + installed in the extension class object. -
    +
    Returns: The new Python callable object +
    -
    Returns: The new Python callable object
    - -
    - -

    Example

    - -

    C++ function exposed below returns a callable object wrapping one -of two functions. +

    Example

    +

    C++ function exposed below returns a callable object wrapping one of two + functions.

     #include <boost/python/make_function.hpp>
     #include <boost/python/module.hpp>
    @@ -132,8 +125,7 @@ BOOST_PYTHON_MODULE_INIT(make_function_test)
             .def("choose_function", choose_function);
     }
     
    -

    -It can be used this way in Python: + It can be used this way in Python:
     >>> from make_function_test import *
     >>> f = choose_function(1)
    @@ -144,12 +136,11 @@ It can be used this way in Python:
     'bar'
     
    -

    - -14 February 2002 - -

    -

    © Copyright Dave Abrahams - 2002. All Rights Reserved.

    - - +

    + + 14 February 2002 + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + diff --git a/doc/v2/manage_new_object.html b/doc/v2/manage_new_object.html index cc5aab2a..112e540f 100644 --- a/doc/v2/manage_new_object.html +++ b/doc/v2/manage_new_object.html @@ -1,50 +1,62 @@ - - - - -Boost.Python - <boost/python/manage_new_object.hpp> - - - + + + + + Boost.Python - <boost/python/manage_new_object.hpp> + +
    - - - - -
    -

    C++ Boost

    -
    -

    Boost.Python

    -

    Header <boost/python/manage_new_object.hpp>

    -
    -


    -

    Contents

    -
    -
    Classes
    -
    -
    Class manage_new_object
    -
    -
    Class manage_new_object synopsis
    -
    Class manage_new_object metafunctions
    -
    -
    + + +

    +

    -
    Example
    -
    -
    + +

    Boost.Python

    -

    Classes

    +

    Header + <boost/python/manage_new_object.hpp>

    + +
    -

    Class manage_new_object

    -

    -manage_new_object is a model of ResultConverterGenerator -which can be used to wrap C++ functions which return a pointer to an -object allocated with a new-expression, and expect the caller -to take responsibility for deleting that object. -

    +

    Contents

    -

    Class manage_new_object synopsis

    +
    +
    Classes + +
    +
    +
    Class + manage_new_object + +
    +
    +
    Class + manage_new_object synopsis + +
    Class + manage_new_object metafunctions +
    +
    + +
    Example +
    +
    + +

    Classes

    + +

    Class + manage_new_object

    + +

    manage_new_object is a model of ResultConverterGenerator which can be + used to wrap C++ functions which return a pointer to an object allocated + with a new-expression, and expect the caller to take responsibility + for deleting that object. + +

    Class + manage_new_object synopsis

     namespace boost { namespace python
     {
    @@ -54,19 +66,25 @@ namespace boost { namespace python
         };
     }}
     
    -

    Class manage_new_object metafunctions

    + +

    Class + manage_new_object metafunctions

     template <class T> struct apply
     
    -
    -
    Requires: T is U* for some U.
    -
    Returns: typedef to_python_indirect<T> type;
    -
    -

    Example

    +
    +
    Requires: T is U* for some + U. -

    In C++: +

    Returns: typedef to_python_indirect<T> + type; +
    +

    Example

    + +

    In C++:

     #include <boost/python/module.hpp>
     #include <boost/python/class.hpp>
    @@ -87,16 +105,14 @@ using namespace boost::python;
     BOOST_PYTHON_MODULE_INIT(my_module)
     {
        module m("my_module")
    -      .def("make_foo", make_foo)
    +      .def("make_foo", make_foo)
           .add(
              class_<Foo>()
    -            .def("get_x", &Foo::get_x)
    +            .def("get_x", &Foo::get_x)
              )
     }
     
    - -In Python: - +In Python:
     >>> from my_module import *
     >>> f = make_foo(3)     # create a Foo object
    @@ -104,12 +120,11 @@ In Python:
     3
     
    -

    Revised - - 14 February 2002 - -

    -

    © Copyright Dave Abrahams - 2002. All Rights Reserved.

    - - +

    Revised + + 14 February 2002 + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 0aa546e5..5e2e4463 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -1,271 +1,383 @@ - - - - -Boost.Python - Reference - - - + + + + + Boost.Python - Reference + +
    - - - - -
    -

    C++ Boost

    -
    -

    Boost.Python

    -

    Reference

    -
    -


    -

    Contents

    -
    -
    High Level Components
    -
    Framework Elements
    -
    Utilities
    -
    Index By Name
    -
    + + +

    +

    -

    High Level Components

    -
    + +

    Boost.Python

    -

    General Purpose

    -
    +

    Reference

    + +
    -
    class.hpp/class_fwd.hpp
    -
    -
    Classes
    -
    -
    class_
    -
    bases
    -
    args
    -
    +

    Contents

    + +
    +
    High Level Components + +
    Framework Elements + +
    Utilities + +
    Index By Name +
    + + +

    High Level Components

    + +
    +
    + + +

    General Purpose

    + +
    +
    class.hpp/class_fwd.hpp + +
    +
    +
    Classes + +
    +
    +
    class_ + +
    bases + +
    args +
    +
    + +
    errors.hpp + +
    +
    +
    Classes + +
    +
    +
    error_already_set +
    + +
    Functions + +
    +
    +
    handle_exception + +
    expect_non_null +
    +
    + +
    make_function.hpp + +
    +
    +
    Functions + +
    +
    +
    make_function + +
    make_constructor +
    +
    + +
    module.hpp + +
    +
    +
    Classes + +
    +
    +
    module +
    +
    + +
    objects.hpp + +
    +
    +
    Classes + +
    +
    +
    not yet documented +
    +
    + +
    reference.hpp + +
    +
    +
    Classes + +
    +
    +
    reference +
    + +
    Types + +
    +
    +
    ref +
    +
    +
    + + +

    To/From Python Type Conversion

    + +
    +
    from_python.hpp + +
    +
    +
    Classes + +
    +
    +
    from_python +
    +
    + +
    to_python_converter.hpp + +
    +
    +
    Classes + +
    +
    +
    to_python_converter +
    +
    + +
    to_python_indirect.hpp + +
    +
    +
    Classes + +
    +
    +
    to_python_indirect +
    +
    + +
    to_python_value.hpp + +
    +
    +
    Classes + +
    +
    +
    to_python_value +
    +
    + +
    type_from_python.hpp + +
    +
    +
    Classes + +
    +
    +
    type_from_python +
    +
    + +
    value_from_python.hpp + +
    +
    +
    Classes + +
    +
    +
    value_from_python +
    +
    +
    + + +

    Models of CallPolicies

    + +
    +
    default_call_policies.hpp + +
    +
    +
    Classes + +
    +
    +
    default_call_policies + +
    default_result_converter +
    +
    + +
    return_internal_reference.hpp + +
    +
    +
    Classes + +
    +
    +
    + return_internal_reference +
    +
    + +
    return_value_policy.hpp + +
    +
    +
    Classes + +
    +
    +
    return_value_policy +
    +
    + +
    with_custodian_and_ward.hpp + +
    +
    +
    Classes + +
    +
    +
    with_custodian_and_ward + +
    + with_custodian_and_ward_postcall +
    +
    +
    + + +

    Models of ReturnHandlerGenerator

    + +
    +
    copy_const_reference.hpp + +
    +
    +
    Classes + +
    +
    +
    copy_const_reference +
    +
    + +
    copy_non_const_reference.hpp + +
    +
    +
    Classes + +
    +
    +
    + copy_non_const_reference +
    +
    + +
    manage_new_object.hpp + +
    +
    +
    Classes + +
    +
    +
    manage_new_object +
    +
    + +
    reference_existing_object.hpp + +
    +
    +
    Classes + +
    +
    +
    + reference_existing_object +
    +
    + +
    reference_from_python.hpp + +
    +
    +
    Classes + +
    +
    +
    reference_from_python + +
    get_member +
    +
    +
    +
    +
    + +

    Revised + + 05 November, 2002 + -

    +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. -

    errors.hpp
    -
    - -
    Classes
    -
    -
    error_already_set
    -
    -
    Functions
    -
    -
    handle_exception
    -
    expect_non_null
    -
    -
    - -
    make_function.hpp
    -
    -
    Functions
    -
    -
    make_function
    -
    make_constructor
    -
    -
    - -
    module.hpp
    -
    -
    Classes
    -
    -
    module
    -
    - -
    - -
    objects.hpp
    -
    -
    Classes
    -
    -
    not yet documented
    -
    - -
    - -
    reference.hpp
    -
    -
    Classes
    -
    -
    reference
    -
    - -
    Types
    -
    -
    ref
    -
    - -
    - - -
    - -

    To/From Python Type Conversion

    -
    - -
    from_python.hpp
    -
    -
    Classes
    -
    -
    from_python
    -
    -
    - -
    to_python_converter.hpp
    -
    -
    Classes
    -
    -
    to_python_converter
    -
    - -
    - -
    to_python_indirect.hpp
    -
    -
    Classes
    -
    -
    to_python_indirect
    -
    - -
    - -
    to_python_value.hpp
    -
    -
    Classes
    -
    -
    to_python_value
    -
    - -
    - -
    type_from_python.hpp
    -
    -
    Classes
    -
    -
    type_from_python
    -
    - -
    - - -
    value_from_python.hpp
    -
    -
    Classes
    -
    -
    value_from_python
    -
    - -
    - -
    - - -

    Models of CallPolicies

    -
    - -
    default_call_policies.hpp
    -
    -
    Classes
    -
    -
    default_call_policies
    -
    default_result_converter
    -
    - -
    - -
    return_internal_reference.hpp
    -
    -
    Classes
    -
    -
    return_internal_reference
    -
    - -
    - -
    return_value_policy.hpp
    -
    -
    Classes
    -
    -
    return_value_policy
    -
    - -
    - -
    with_custodian_and_ward.hpp
    -
    -
    Classes
    -
    -
    with_custodian_and_ward
    -
    with_custodian_and_ward_postcall
    -
    - -
    - -
    - -

    Models of ReturnHandlerGenerator

    -
    - -
    copy_const_reference.hpp
    -
    -
    Classes
    -
    -
    copy_const_reference
    -
    - -
    - -
    copy_non_const_reference.hpp
    -
    -
    Classes
    -
    -
    copy_non_const_reference
    -
    - -
    - - -
    manage_new_object.hpp
    -
    -
    Classes
    -
    -
    manage_new_object
    -
    - -
    - -
    reference_existing_object.hpp
    -
    -
    Classes
    -
    -
    reference_existing_object
    -
    - -
    - -
    reference_from_python.hpp
    -
    -
    Classes
    -
    -
    reference_from_python
    -
    get_member
    -
    - -
    - -
    - -
    - -
    -

    Revised - - 05 November, 2002 - -

    -

    © Copyright Dave Abrahams - 2002. All Rights Reserved.

    - - diff --git a/doc/v2/reference_existing_object.html b/doc/v2/reference_existing_object.html index 3d19826a..c5d39756 100644 --- a/doc/v2/reference_existing_object.html +++ b/doc/v2/reference_existing_object.html @@ -1,62 +1,72 @@ - - - - -Boost.Python - <boost/python/reference_existing_object.hpp> - - - + + + + + Boost.Python - + <boost/python/reference_existing_object.hpp> + +
    - - - - -
    -

    C++ Boost

    -
    -

    Boost.Python

    -

    Header <boost/python/reference_existing_object.hpp>

    -
    -
    -

    Contents

    -
    -
    Classes
    -
    -
    Class reference_existing_object
    -
    -
    Class reference_existing_object synopsis
    -
    Class reference_existing_object metafunctions
    -
    -
    + + +

    +

    -
    Example
    -
    -
    + +

    Boost.Python

    -

    Classes

    +

    Header + <boost/python/reference_existing_object.hpp>

    + +
    -

    Class reference_existing_object

    -

    -reference_existing_object is a model of ResultConverterGenerator -which can be used to wrap C++ functions which return a reference or -pointer to a C++ object. When the wrapped function is called, the -value referenced by its return value is not copied. A new Python -object is created which contains a pointer to the referent, and no -attempt is made to ensure that the lifetime of the referent is at -least as long as that of the corresponding Python object. Thus, it can -be highly dangerous to use -reference_existing_object without additional lifetime -management from such models of CallPolicies as with_custodian_and_ward. This class is used in the implementation -of return_internal_reference. -

    +

    Contents

    -

    Class reference_existing_object synopsis

    +
    +
    Classes + +
    +
    +
    Class + reference_existing_object + +
    +
    +
    Class + reference_existing_object synopsis + +
    Class + reference_existing_object metafunctions +
    +
    + +
    Example +
    +
    + +

    Classes

    + +

    Class + reference_existing_object

    + +

    reference_existing_object is a model of ResultConverterGenerator which can be + used to wrap C++ functions which return a reference or pointer to a C++ + object. When the wrapped function is called, the value referenced by its + return value is not copied. A new Python object is created which contains a + pointer to the referent, and no attempt is made to ensure that the lifetime + of the referent is at least as long as that of the corresponding Python + object. Thus, it can be highly + dangerous to use reference_existing_object without + additional lifetime management from such models of CallPolicies as with_custodian_and_ward. + This class is used in the implementation of return_internal_reference. + +

    Class + reference_existing_object synopsis

     namespace boost { namespace python
     {
    @@ -66,27 +76,29 @@ namespace boost { namespace python
         };
     }}
     
    -

    Class reference_existing_object metafunctions

    + +

    Class + reference_existing_object metafunctions

     template <class T> struct apply
     
    -
    -
    Requires: T is U& or U*for some U.
    -
    Returns: typedef to_python_indirect<T,V> - type, where V is a which - constructs an instance holder containing an unowned - U* pointing to the referent of the wrapped function's - return value.
    +
    +
    Requires: T is U& or + U*for some U. -
    +
    Returns: typedef to_python_indirect<T,V> + type, where V is a HolderObjectGenerator + which constructs an instance holder containing an unowned + U* pointing to the referent of the wrapped function's return + value. +
    -

    Example

    - -

    In C++: +

    Example

    +

    In C++:

     #include <boost/python/module.hpp>
     #include <boost/python/class.hpp>
    @@ -119,16 +131,14 @@ using namespace boost::python;
     BOOST_PYTHON_MODULE_INIT(singleton)
     {
        module m("singleton")
    -      .def("get_it", get_it)
    +      .def("get_it", get_it)
           .add(
              class_<Singleton>()
    -            .def("exchange", &Singleton::exchange)
    +            .def("exchange", &Singleton::exchange)
              );
     }
     
    - -In Python: - + In Python:
     >>> import singleton
     >>> s1 = singleton.get_it()  
    @@ -141,12 +151,11 @@ In Python:
     42
     
    -

    Revised - - 14 February 2002 - -

    -

    © Copyright Dave Abrahams - 2002. All Rights Reserved.

    - - +

    Revised + + 14 February 2002 + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From 4481c3badae4cca6d0acc7d1e516b374378baa2b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Feb 2002 16:20:22 +0000 Subject: [PATCH 0252/1042] initial checkin [SVN r12818] --- doc/v2/lvalue_from_python.html | 278 +++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 doc/v2/lvalue_from_python.html diff --git a/doc/v2/lvalue_from_python.html b/doc/v2/lvalue_from_python.html new file mode 100644 index 00000000..74e94a23 --- /dev/null +++ b/doc/v2/lvalue_from_python.html @@ -0,0 +1,278 @@ + + + + + + Boost.Python - <boost/python/lvalue_from_python.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/lvalue_from_python.hpp>

    +
    +


    + +

    Contents

    + +
    +
    Introduction + + +
    Classes + +
    +
    +
    Class Template lvalue_from_python + +
    +
    + +
    Class Template + lvalue_from_python synopsis + +
    Class Template + lvalue_from_python constructor +
    +
    + +
    +
    Class Template get_member + +
    +
    + +
    Class Template + get_member synopsis + +
    Class Template + get_member static functions +
    +
    + +
    Example +
    +
    + +

    Introduction

    + + <boost/python/lvalue_from_python.hpp> supplies + a facility for extracting C++ objects from within instances of a + given Python type. This is typically useful for dealing with + "traditional" Python extension types. + +

    Classes

    + +

    Class template lvalue_from_python

    + +

    Class template lvalue_from_python will register + from_python converters which extract a references and pointers to + a C++ type which is held within an object of a given Python + type. Its template arguments are: + +

    + + + + + + + + + +
    + lvalue_from_python Requirements
    + + In the table below, x denotes an object of type PythonObject& + +
    Parameter + + Requirements + + Description + + Default + +
    python_type + + A compile-time constant PyTypeObject* + + The Python type of instances convertible by this + converter. Python subtypes are also convertible. + +
    Value + + A non-reference type. + + The C++ type to be extracted + +
    PythonObject + + initial sizeof(PyObject) bytes are + layout-compatible with PyObject. + + The C++ type used to hold Python instances of + python_type. + + Value + +
    Extract + + Value& v = Extract::execute(x); + + A type whose static execute function extracts a Value reference from within an object of type PythonObject. + + An unspecified type whose execute function consists of return x; +
    + + If only the first two template arguments are supplied, these + converters extract the entire PythonObject as a + whole. + +

    + + If the lifetime of the lvalue_from_python object ends + before the last attempt to convert to one its target types, the + behavior is undefined. The easiest way to ensure correct behavior + is to declare an lvalue_from_python instance as a + static local in a module init + function, as shown in the example + below. + +

    Class template lvalue_from_python synopsis

    +
    +namespace boost { namespace python
    +{
    +   template <
    +      PyTypeObject const* python_type
    +      , class Value
    +      , class PythonObject = Value
    +      , class Extract = unspecified
    +      >
    +   class lvalue_from_python
    +   {
    +      lvalue_from_python();
    +   };
    +}}
    +
    + +

    Class template lvalue_from_python constructor

    +
    +lvalue_from_python();
    +
    + +
    + +
    Effects: Registers from_python converters which + extract + Value&, Value const&, + Value*, or Value const* from Python + objects of type python_type using + Extract::execute(). + +
    + +

    Class template get_member

    + +

    get_member can be used with + lvalue_from_python in the common case where the C++ + type to be extracted is a member of the Python object. + +

    Class template get_member synopsis

    +
    +namespace boost { namespace python
    +{
    +  template <class Class, class Member, Member (Class::*mp)>
    +  struct get_member
    +  {
    +     static Member& execute(Class& c);
    +  };
    +}}
    +
    + +

    Class template get_member static functions

    +
    +Member& execute(Class& c);
    +
    + +
    + +
    Returns: c.*mp + +
    + + +

    Example(s)

    + +This example presumes that someone has implemented the standard noddy +example module from the Python documentation, and we want to build +a module which manipulates Noddys. Since +noddy_NoddyObject is so simple that it carries no +interesting information, the example is a bit contrived: it assumes +you want to keep track of one particular object for some reason. + +

    C++ module definition

    + +
    +#include <boost/python/reference.hpp>
    +#include <boost/python/module.hpp>
    +
    +// definition lifted from the Python docs
    +typedef struct {
    +   PyObject_HEAD
    +} noddy_NoddyObject;
    +
    +using namespace boost::python;
    +static ref cache;
    +
    +bool is_cached(noddy_NoddyObject* x)
    +{
    +   return x == cache.get();
    +}
    +
    +void set_cache(noddy_NoddyObject* x)
    +{
    +   cache.reset((PyObject*)x, ref::increment_count);
    +}
    +
    +BOOST_PYTHON_MODULE_INIT(noddy_cache)
    +{
    +   module noddy_cache("noddy_cache")
    +      .def("is_cached", is_cached)
    +      .def("set_cache", set_cache)
    +      ;
    +}
    +
    + +

    Python code

    + +
    +>>> import noddy
    +>>> n = noddy.new_noddy()
    +>>> import noddy_cache
    +>>> noddy_cache.is_cached(n)
    +0
    +>>> noddy_cache.set_cache(n)
    +>>> noddy_cache.is_cached(n)
    +1
    +>>> noddy_cache.is_cached(noddy.new_noddy())
    +0
    +
    + +

    Revised + + 05 November, 2001 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From 371723a5d4d2b3e94c57163a6adf0ed59bce6c43 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Feb 2002 16:37:00 +0000 Subject: [PATCH 0253/1042] little fixes [SVN r12819] --- doc/v2/lvalue_from_python.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/v2/lvalue_from_python.html b/doc/v2/lvalue_from_python.html index 74e94a23..03af54f8 100644 --- a/doc/v2/lvalue_from_python.html +++ b/doc/v2/lvalue_from_python.html @@ -98,7 +98,8 @@ python_type - A compile-time constant PyTypeObject* + A compile-time constant PyTypeObject* The Python type of instances convertible by this converter. Python subtypes are also convertible. @@ -209,7 +210,7 @@ Member& execute(Class& c); -

    Example(s)

    +

    Example

    This example presumes that someone has implemented the standard noddy From b303d49634423240d8a8e0190eb6d7ffcf620b4a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Feb 2002 16:59:39 +0000 Subject: [PATCH 0254/1042] remove defunct code [SVN r12820] --- .../python/return_internal_reference.hpp | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp index d696c7fa..2f567e55 100644 --- a/include/boost/python/return_internal_reference.hpp +++ b/include/boost/python/return_internal_reference.hpp @@ -7,36 +7,11 @@ # define RETURN_INTERNAL_REFERENCE_DWA2002131_HPP # include -# include # include -# include # include namespace boost { namespace python { -namespace detail -{ - template - struct return_internal_reference_requires_a_pointer_or_reference_return_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -struct internal_reference_to_python_generator -{ - template - struct apply - { - typedef typename mpl::select_type< - is_object::value - , detail::return_internal_reference_requires_a_pointer_or_reference_return_type - , to_python_indirect - >::type type; - }; -}; - template struct return_internal_reference : with_custodian_and_ward_postcall<0, owner_arg, Base> From 09d012a10b5b5c024743bc63faf7082668d3fb4a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Feb 2002 18:31:22 +0000 Subject: [PATCH 0255/1042] *** empty log message *** [SVN r12823] --- doc/v2/class.html | 9 +- doc/v2/header.html | 31 ++-- doc/v2/module.html | 12 +- doc/v2/reference.html | 8 +- doc/v2/return_internal_reference.html | 205 ++++++++++++++++++++++++++ 5 files changed, 236 insertions(+), 29 deletions(-) create mode 100644 doc/v2/return_internal_reference.html diff --git a/doc/v2/class.html b/doc/v2/class.html index 85e24993..fc64eabd 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -191,7 +191,7 @@ template <class F> class_& def(char const* name, F f) template <class Fn, class CallPolicy> -class_& def(char const* name, Fn fn, CallPolicy policy) +class_& def(char const* name, Fn f, CallPolicy policy)
    @@ -199,8 +199,11 @@ class_& def(char const* name, Fn fn, CallPolicy policy) pointer-to-member-function. name is a ntbs which conforms to Python's identifier - naming rules. If supplied, policy conforms to the CallPolicy concept requirements. + naming rules. In the first form, the return type of + f is not a reference and is not a pointer other + than char const* or PyObject*. In the + second form policy is a model of CallPolicies.
    Effects: Adds the result of make_function(f) to diff --git a/doc/v2/header.html b/doc/v2/header.html index 7b36a65c..7b65547d 100644 --- a/doc/v2/header.html +++ b/doc/v2/header.html @@ -49,27 +49,22 @@
    -
    Class {{class name}} +
    Class {{name}}
    -
    Class {{class - name}} synopsis +
    Class {{name}} synopsis -
    Class {{class name}} +
    Class {{name}} constructors and destructor -
    Class {{class - name}} comparison functions +
    Class {{name}} comparison functions -
    Class {{class - name}} modifier functions +
    Class {{name}} modifier functions -
    Class {{class - name}} observer functions +
    Class {{name}} observer functions -
    Class {{class - name}} static functions +
    Class {{name}} static functions
    @@ -113,7 +108,7 @@

    {{class overview text}} -

    Class {{name}} synopsis

    +

    Class {{name}} synopsis

     namespace boost
     {
    @@ -123,7 +118,7 @@ namespace boost
     };
     
    -

    Class {{name}} constructors and +

    Class {{name}} constructors and destructor

     {{constructor}}
    @@ -164,7 +159,7 @@ namespace boost
           
    Rationale: {{text}}
    -

    Class {{name}} comparison +

    Class {{name}} comparison functions

    Requires: The first form requires that the expression function0<void>(f) + href="../../../function/doc/reference.html#functionN">function0<void>(f) is valid. The second form requires that a C++ exception is currently being handled (see section 15.1 in the C++ standard).
    diff --git a/doc/v2/foo.cpp b/doc/v2/foo.cpp deleted file mode 100644 index e92c2d72..00000000 --- a/doc/v2/foo.cpp +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - - -#include -#include -#include -#include - -class Bar { int x; } - -class Foo -{ - public: - Foo(int x) : b(x) {} - Bar const& get_bar() const { return b; } - private: - Bar b; -}; - -using namespace boost::python; -BOOST_PYTHON_MODULE_INIT(my_module) -{ - module m("my_module") - .add( - class_() - ) - .add( - class_() - .def_init(args()) - .def("get_bar", &Foo::get_bar - , return_value_policy()) - ) -} - -using namespace boost::python; -ref foo = -class_ >() - .def_init(args()) - .def_init(args()) - .def("get_name", &Foo::get_name, return_internal_reference<>()) - .def("set_name", &Foo::set_name) - .object(); - - -
    -#include <string>
    -#include <boost/python/errors.hpp>
    -#include <boost/python/reference.hpp>
    -
    -// Returns a std::string which has the same value as obj's "__name__"
    -// attribute.
    -std::string get_name(boost::python::ref obj)
    -{
    -    // throws if there's no __name__ attribute
    -    PyObject* p = boost::python::expect_non_null(
    -        PyObject_GetAttrString(obj.get(), "__name__"));
    -
    -    // throws if it's not a Python string
    -    std::string result(
    -        boost::python::expect_non_null(
    -            PyString_AsString(p)));
    -
    -    Py_XDECREF(p); // Done with p
    -    
    -    return result;
    -}
    -
    -//
    -// Demonstrate form 1 of handle_exception
    -//
    -
    -// Place a Python Int object whose value is 1 if a and b have
    -// identical "__name__" attributes, 0 otherwise.
    -void same_name_impl(PyObject*& result, PyObject* a, PyObject* b)
    -{
    -    result = PyInt_FromLong(
    -        get_name(boost::python::ref(a1)) == get_name(boost::python::ref(a2)));
    -}
    -
    -// This is an example Python 'C' API interface function
    -extern "C" PyObject*
    -same_name(PyObject* args, PyObject* keywords)
    -{
    -    PyObject* a1;
    -    PyObject* a2;
    -    PyObject* result = 0;
    -
    -    if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
    -        return 0;
    -    
    -    // Use boost::bind to make an object compatible with
    -    // boost::Function0<void>
    -    if (boost::python::handle_exception(
    -            boost::bind<void>(same_name_impl, boost::ref(result), a1, a2)))
    -    {
    -        // an exception was thrown; the Python error was set by
    -        // handle_exception()
    -        return 0;
    -    }
    -
    -    return result;
    -}
    -
    -//
    -// Demonstrate form 2 of handle_exception. Not well-supported by all
    -// compilers.
    -//
    -extern "C" PyObject*
    -same_name2(PyObject* args, PyObject* keywords)
    -{
    -    PyObject* a1;
    -    PyObject* a2;
    -    PyObject* result = 0;
    -
    -    if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
    -        return 0;
    -    try {
    -        return PyInt_FromLong(
    -            get_name(boost::python::ref(a1)) == get_name(boost::python::ref(a2)));
    -    }
    -    catch(...)
    -    {
    -        // If an exception was thrown, translate it to Python
    -        boost::python::handle_exception();
    -        return 0;
    -    }
    -}
    -
    -
    - - -template -struct from_python -{ - from_python(PyObject*); - bool convertible() const; - X operator()(PyObject*) const; -}; diff --git a/doc/v2/make_function.html b/doc/v2/make_function.html new file mode 100644 index 00000000..e7c4b421 --- /dev/null +++ b/doc/v2/make_function.html @@ -0,0 +1,155 @@ + + + + +Boost.Python - <boost/python/make_function.hpp> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Header <boost/python/make_function.hpp>

    +
    +
    +

    Contents

    +
    +
    Introduction
    + +
    Functions
    +
    +
    make_function
    +
    make_constructor
    +
    + +
    Example
    + +
    +
    +

    Introduction

    +

    + +make_function() and +make_constructor() +are the functions used internally by class_<>::def, +class_<>::def, +and +class_<>::def_init +to produce Python callable objects which wrap C++ functions and member +functions. +

    + +

    Functions

    + +
    +template <class F>
    +objects::function* make_function(F f)</a>
    +
    +template <class F, class Policies>
    +objects::function* make_function(F f, Policies const& policies)
    +
    +
    + +
    Requires: F is a function pointer or member + function pointer type
    + +
    Effects: Creates a Python callable object which, when + called from Python, converts its arguments to C++ and calls + f. If F is a pointer-to-member-function + type, the target object of the function call (*this) + will be taken from the first Python argument, and subsequent Python + arguments will be used as the arguments to f. If + policies are supplied, it must be a model of CallPolicies, and will be applied to + the function as described here.
    + +
    Returns: A pointer convertible to PyObject* + which refers to the new Python callable object.
    +
    + +
    +template <class T, class ArgList, class Generator>
    +objects::function* make_constructor();
    +
    +
    + +
    Requires: T is a class + type. ArgList is an MPL sequence of C++ + argument types (A1, A2,... AN) such that if + a1, a2... aN are objects of type + A1, A2,... AN respectively, the expression + new Generator::apply<T>::type(a1, a2... aN) is + valid. Generator is a model of HolderGenerator. +
    + +
    Effects: Creates a Python callable object which, when + called from Python, expects its first argument to be a Boost.Python + extension class object. It converts its remaining its arguments to + C++ and passes them to the constructor of a dynamically-allocated + Generator::apply<T>::type object. The result is + installed in the extension class object. + +
    + +
    Returns: The new Python callable object
    + +
    + +

    Example

    + +

    C++ function exposed below returns a callable object wrapping one +of two functions. + +

    +#include <boost/python/make_function.hpp>
    +#include <boost/python/module.hpp>
    +
    +char const* foo() { return "foo"; }
    +char const* bar() { return "bar"; }
    +
    +PyObject* choose_function(bool selector)
    +{
    +    if (selector)
    +        return boost::python::make_function(foo);
    +    else
    +        return boost::python::make_function(bar);
    +}
    +
    +BOOST_PYTHON_MODULE_INIT(make_function_test)
    +{
    +    module("make_function_test")
    +        .def("choose_function", choose_function);
    +}
    +
    +

    +It can be used this way in Python: +
    +>>> from make_function_test import *
    +>>> f = choose_function(1)
    +>>> g = choose_function(0)
    +>>> f()
    +'foo'
    +>>> g()
    +'bar'
    +
    + +

    + +14 February 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/manage_new_object.html b/doc/v2/manage_new_object.html new file mode 100644 index 00000000..cc5aab2a --- /dev/null +++ b/doc/v2/manage_new_object.html @@ -0,0 +1,115 @@ + + + + +Boost.Python - <boost/python/manage_new_object.hpp> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Header <boost/python/manage_new_object.hpp>

    +
    +
    +

    Contents

    +
    +
    Classes
    +
    +
    Class manage_new_object
    +
    +
    Class manage_new_object synopsis
    +
    Class manage_new_object metafunctions
    +
    +
    + +
    Example
    +
    +
    + +

    Classes

    + +

    Class manage_new_object

    +

    +manage_new_object is a model of ResultConverterGenerator +which can be used to wrap C++ functions which return a pointer to an +object allocated with a new-expression, and expect the caller +to take responsibility for deleting that object. +

    + +

    Class manage_new_object synopsis

    +
    +namespace boost { namespace python
    +{
    +    struct manage_new_object
    +    {
    +        template <class T> struct apply;
    +    };
    +}}
    +
    +

    Class manage_new_object metafunctions

    +
    +template <class T> struct apply
    +
    +
    +
    Requires: T is U* for some U.
    +
    Returns: typedef to_python_indirect<T> type;
    +
    + +

    Example

    + +

    In C++: + +

    +#include <boost/python/module.hpp>
    +#include <boost/python/class.hpp>
    +#include <boost/python/manage_new_object.hpp>
    +#include <boost/python/return_value_policy.hpp>
    +
    +
    +struct Foo {
    +   Foo(int x) : x(x){}
    +   int get_x() { return x; }
    +   int x;
    +};
    +
    +Foo* make_foo(int x) { return new Foo(x); }
    +
    +// Wrapper code
    +using namespace boost::python;
    +BOOST_PYTHON_MODULE_INIT(my_module)
    +{
    +   module m("my_module")
    +      .def("make_foo", make_foo)
    +      .add(
    +         class_<Foo>()
    +            .def("get_x", &Foo::get_x)
    +         )
    +}
    +
    + +In Python: + +
    +>>> from my_module import *
    +>>> f = make_foo(3)     # create a Foo object
    +>>> f.get_x()
    +3
    +
    + +

    Revised + + 14 February 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp deleted file mode 100644 index b95a31d5..00000000 --- a/include/boost/python/call.hpp +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for 5-argument member functions and 6-argument free -// functions by gen_call.py - -#ifndef CALL_DWA20011214_HPP -# define CALL_DWA20011214_HPP - -# include - -namespace boost { namespace python { - -template -inline PyObject* call(R (*f)(), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0, A1), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -// Member functions -template -inline PyObject* call(R (A0::*f)(), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)() const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)() volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -template -inline PyObject* call(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - - -}} // namespace boost::python - -#endif // CALL_DWA20011214_HPP - diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index a21fd27b..8293b0a7 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -6,6 +6,7 @@ #ifndef BUILTIN_CONVERTERS_DWA2002124_HPP # define BUILTIN_CONVERTERS_DWA2002124_HPP # include +# include # include namespace boost { namespace python { @@ -44,18 +45,19 @@ namespace detail BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \ BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, PyInt_FromLong(x)) BOOST_PYTHON_TO_INT(char) BOOST_PYTHON_TO_INT(short) BOOST_PYTHON_TO_INT(int) BOOST_PYTHON_TO_INT(long) # undef BOOST_TO_PYTHON_INT -BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, PyString_FromString(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, x ? PyString_FromString(x) : detail::none()) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x ? x : detail::none()) namespace converter { diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index ee16a741..b6e1edc4 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -13,6 +13,7 @@ # include # include # include +# include namespace boost { namespace python { namespace converter { diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 1d4fdd6d..11b0b6c7 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -30,7 +30,7 @@ class BOOST_PYTHON_DECL module_base void add_type(ref); // Return a reference to the Python module object being built - ref module() const; + ref object() const; private: ref m_module; @@ -76,7 +76,7 @@ class module : public module_base // // inline implementations // -inline ref module_base::module() const +inline ref module_base::object() const { return m_module; } diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index 33e1cb50..9cf5f110 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -150,6 +150,31 @@ namespace } }; + extern "C" PyObject* identity_unaryfunc(PyObject* x) + { + Py_INCREF(x); + return x; + } + + unaryfunc non_null = identity_unaryfunc; + + struct convertible_to_bool + { + static unaryfunc* execute(PyObject* obj) + { + return &non_null; + } + }; + + struct py_object_as_bool + { + static bool execute(PyObject* obj) + { + return PyObject_IsTrue(obj); + } + }; + + struct convertible_to_double { static unaryfunc* execute(PyObject* obj) @@ -203,6 +228,9 @@ namespace void initialize_builtin_converters() { + static scalar_from_python< + bool, convertible_to_bool, py_object_as_bool> bool_from_python; + REGISTER_INT_CONVERTERS2(char); REGISTER_INT_CONVERTERS2(short); REGISTER_INT_CONVERTERS2(int); diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp index 7e21e046..f95ebe2b 100644 --- a/test/test_builtin_converters.cpp +++ b/test/test_builtin_converters.cpp @@ -29,6 +29,7 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters_ext) { boost::python::module("builtin_converters_ext") + .def("rewrap_value_bool", by_value::rewrap) .def("rewrap_value_signed_char", by_value::rewrap) .def("rewrap_value_unsigned_char", by_value::rewrap) .def("rewrap_value_int", by_value::rewrap) @@ -44,6 +45,7 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters_ext) .def("rewrap_value_cstring", by_value::rewrap) + .def("rewrap_const_reference_bool", by_const_reference::rewrap) .def("rewrap_const_reference_signed_char", by_const_reference::rewrap) .def("rewrap_const_reference_unsigned_char", by_const_reference::rewrap) .def("rewrap_const_reference_int", by_const_reference::rewrap) diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index 3941a29c..50b58ce6 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -1,5 +1,11 @@ """ >>> from builtin_converters_ext import * +>>> rewrap_value_bool(None) +0 +>>> rewrap_value_bool(0) +0 +>>> rewrap_value_bool(33) +1 >>> rewrap_value_signed_char(42) 42 >>> rewrap_value_unsigned_char(42) @@ -29,6 +35,12 @@ >>> rewrap_value_string('yo, wassup?') 'yo, wassup?' +>>> rewrap_const_reference_bool(None) +0 +>>> rewrap_const_reference_bool(0) +0 +>>> rewrap_const_reference_bool('yes') +1 >>> rewrap_const_reference_signed_char(42) 42 >>> rewrap_const_reference_unsigned_char(42) From 586b4db968d0951682125a9c8f8afc95192f1395 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 14 Feb 2002 18:12:50 +0000 Subject: [PATCH 0249/1042] initial checkin [SVN r12807] --- doc/v2/module.html | 258 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 doc/v2/module.html diff --git a/doc/v2/module.html b/doc/v2/module.html new file mode 100644 index 00000000..f39ff4e8 --- /dev/null +++ b/doc/v2/module.html @@ -0,0 +1,258 @@ + + + + + + Boost.Python - <boost/python/module.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/module.hpp>

    +
    +
    + +

    Contents

    + +
    +
    Introduction + +
    Macros + +
    +
    +
    BOOST_PYTHON_MODULE_INIT +
    + +
    Classes + +
    +
    +
    Class module + +
    +
    +
    Class module + synopsis + +
    Class module + constructor + +
    Class module + modifier functions + +
    Class module + observer functions +
    +
    + +
    Example(s) +
    +
    + +

    Introduction

    + +

    {{Introductory text}} + +

    Macros

    + +

    BOOST_PYTHON_MODULE_INIT(name) + is used to declare Python + module initialization functions. The name argument must + exactly match the name of the module to be initialized, and must conform to + Python's identifier naming + rules. Where you would normally write +

    +void initname()
    +{
    +   ...
    +
    + Boost.Python modules should be initialized with +
    +BOOST_PYTHON_MODULE_INIT(name)
    +{
    +   ...
    +
    + +

    Classes

    + +

    Class module

    + +

    This class represents the Python extension module under construction. It + provides functions for adding attributes and for retrieving the underlying + Python module object. + +

    Class module + synopsis

    +
    +namespace boost { namespace python
    +{
    +  class module : public module_base
    +  {
    +   public:
    +      module(const char* name);
    +
    +      // modifier functions
    +      module& setattr(const char* name, PyObject*);
    +      module& setattr(const char* name, PyTypeObject*);
    +      module& setattr(const char* name, ref const&);
    +
    +      module& add(PyTypeObject* x);
    +      template <class T, class Bases, class HolderGenerator>
    +      module& add(class_<T,Bases,HolderGenerator> const& c);
    +
    +      template <class Fn>
    +      module& def(char const* name, Fn fn);
    +      template <class Fn, class ResultHandler>
    +      module& def(char const* name, Fn fn, ResultHandler handler);
    +
    +      // observer function
    +      ref object() const;
    +  };
    +
    +}}
    +
    + +

    Class module + constructor

    +
    +module(const char* name);
    +
    + +
    +
    Requires: name is a ntbs whose value matches the + argument passed to BOOST_PYTHON_MODULE_INIT. + +
    Effects: Creates a module object representing a + Python module named name. +
    + +

    Class module modifier + functions

    +
    +module& setattr(const char* name, PyObject* obj);
    +module& setattr(const char* name, PyTypeObject* obj);
    +module& setattr(const char* name, ref const& r);
    +
    + +
    +
    Requires: name is a ntbs which conforms to + Python's identifier + naming rules. In the first two forms, obj is non-null. + In the third form, r.get() is non-null. + +
    Effects: Adds the given Python object to the module. If the + object is a product of make_function(), the + usual overloading procedure applies. + In the first two forms, ownership of a reference to obj is transferred + from caller to callee, even if an exception is thrown. + +
    Returns: *this +
    +
    +module& add(PyTypeObject* x);
    +
    +template <class T, class Bases, class HolderGenerator>
    +module& add(class_<T,Bases,HolderGenerator> const& c);
    +
    + +
    +
    Requires: In the first form, x is non-null + +
    Effects: The first form adds the Python type object named by + x to the Python module under construction, with the name + given by the type's tp_name + field. The second form adds the extension class object being constructed + by c to the module, with the same name that was passed to + c's constructor. + +
    Returns: *this + +
    Rationale: Provides a way to set type attributes in the module + without having to explicitly specify the name. +
    +
    +template <class Fn>
    +module& def(char const* name, Fn fn);
    +
    +template <class Fn, class ResultHandler>
    +module& def(char const* name, Fn fn, ResultHandler handler);
    +
    + +
    +
    Requires: f is a non-null pointer-to-function or + pointer-to-member-function. name is a ntbs which conforms to + Python's identifier + naming rules. If supplied, policy conforms to the CallPolicy concept requirements. + +
    Effects: Adds the result of make_function(f) to + the extension module being defined, with the given name. If + the module already has an attribute named name, the + usual overloading procedure applies. + +
    Returns: *this +
    + +

    Class module observer + functions

    +
    +ref object() const;
    +
    + +
    +
    Returns: A ref object which holds a reference to + the Python module object created by the module constructor. +
    + +

    Example(s)

    + +

    C++ module definition: +

    +#include <boost/python/module.hpp>
    +
    +char const* greet()
    +{
    +    return "hello, Boost.Python!";
    +}
    +
    +BOOST_PYTHON_MODULE_INIT(boost_greet)
    +{
    +    module("boost_greet")
    +        .def("greet", greet);
    +}
    +
    + +Interactive Python: +
    +>>> import boost_greet
    +>>> boost_greet.greet()
    +'hello, Boost.Python!'
    +
    + +

    Revised + + 14 February, 2002 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From ebc641440e076f581021621e2a4e809307e4f44b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 14 Feb 2002 19:44:11 +0000 Subject: [PATCH 0250/1042] initial checkin [SVN r12808] --- doc/v2/reference_existing_object.html | 152 ++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 doc/v2/reference_existing_object.html diff --git a/doc/v2/reference_existing_object.html b/doc/v2/reference_existing_object.html new file mode 100644 index 00000000..3d19826a --- /dev/null +++ b/doc/v2/reference_existing_object.html @@ -0,0 +1,152 @@ + + + + +Boost.Python - <boost/python/reference_existing_object.hpp> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Header <boost/python/reference_existing_object.hpp>

    +
    +


    +

    Contents

    +
    +
    Classes
    +
    +
    Class reference_existing_object
    +
    +
    Class reference_existing_object synopsis
    +
    Class reference_existing_object metafunctions
    +
    +
    + +
    Example
    +
    +
    + +

    Classes

    + +

    Class reference_existing_object

    +

    +reference_existing_object is a model of ResultConverterGenerator +which can be used to wrap C++ functions which return a reference or +pointer to a C++ object. When the wrapped function is called, the +value referenced by its return value is not copied. A new Python +object is created which contains a pointer to the referent, and no +attempt is made to ensure that the lifetime of the referent is at +least as long as that of the corresponding Python object. Thus, it can +be highly dangerous to use +reference_existing_object without additional lifetime +management from such models of CallPolicies as with_custodian_and_ward. This class is used in the implementation +of return_internal_reference. +

    + +

    Class reference_existing_object synopsis

    +
    +namespace boost { namespace python
    +{
    +    struct reference_existing_object
    +    {
    +        template <class T> struct apply;
    +    };
    +}}
    +
    +

    Class reference_existing_object metafunctions

    +
    +template <class T> struct apply
    +
    +
    +
    Requires: T is U& or U*for some U.
    + +
    Returns: typedef to_python_indirect<T,V> + type, where V is a which + constructs an instance holder containing an unowned + U* pointing to the referent of the wrapped function's + return value.
    + +
    + +

    Example

    + +

    In C++: + +

    +#include <boost/python/module.hpp>
    +#include <boost/python/class.hpp>
    +#include <boost/python/reference_existing_object.hpp>
    +#include <boost/python/return_value_policy.hpp>
    +#include <utility>
    +
    +// classes to wrap
    +struct Singleton
    +{
    +   Singleton() : x(0) {}
    +
    +   int exchange(int n)  // set x and return the old value
    +   {
    +        std::swap(n, x);
    +        return n;
    +   }
    +
    +   int x;
    +};
    +
    +Singleton& get_it()
    +{
    +   static Singleton just_one;
    +   return just_one;
    +}
    +
    +// Wrapper code
    +using namespace boost::python;
    +BOOST_PYTHON_MODULE_INIT(singleton)
    +{
    +   module m("singleton")
    +      .def("get_it", get_it)
    +      .add(
    +         class_<Singleton>()
    +            .def("exchange", &Singleton::exchange)
    +         );
    +}
    +
    + +In Python: + +
    +>>> import singleton
    +>>> s1 = singleton.get_it()  
    +>>> s2 = singleton.get_it()
    +>>> id(s1) == id(s2)  # s1 and s2 are not the same object
    +0
    +>>> s1.exchange(42)   # but they reference the same C++ Singleton
    +0
    +>>> s2.exchange(99)
    +42
    +
    + +

    Revised + + 14 February 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + From 70bb30b95af551390c3d9f5702dad1d6122b7386 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 14 Feb 2002 20:09:51 +0000 Subject: [PATCH 0251/1042] Tidy [SVN r12810] --- doc/v2/class.html | 389 ++++++++-------- doc/v2/copy_const_reference.html | 136 +++--- doc/v2/copy_non_const_reference.html | 136 +++--- doc/v2/default_call_policies.html | 208 +++++---- doc/v2/errors.html | 223 ++++----- doc/v2/from_python.html | 204 ++++---- doc/v2/header.html | 418 +++++++++++------ doc/v2/make_function.html | 191 ++++---- doc/v2/manage_new_object.html | 141 +++--- doc/v2/reference.html | 640 +++++++++++++++----------- doc/v2/reference_existing_object.html | 173 +++---- 11 files changed, 1588 insertions(+), 1271 deletions(-) diff --git a/doc/v2/class.html b/doc/v2/class.html index 12ad5d23..85e24993 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -1,105 +1,127 @@ - - - - -Boost.Python - <boost/python/class.hpp>, <boost/python/class_fwd.hpp> - - - + + + + + Boost.Python - <boost/python/class.hpp>, + <boost/python/class_fwd.hpp> + +
    - - - - -
    -

    C++ Boost

    -
    -

    Boost.Python

    -

    Headers <boost/python/class.hpp>, <boost/python/class_fwd.hpp>

    -
    -
    -

    Contents

    -
    -
    Introduction
    + + +

    +

    -
    Classes
    + +

    Boost.Python

    -
    +

    Headers <boost/python/class.hpp>, + <boost/python/class_fwd.hpp>

    + +
    -
    Class template class_
    -
    -
    Class class_ synopsis
    -
    Class class_ constructors
    -
    Class class_ modifier functions
    -
    Class class_ observer functions
    -
    +

    Contents

    -
    Class template bases
    -
    -
    Class bases synopsis
    -
    +
    +
    Introduction -
    Class template args
    -
    -
    Class args synopsis
    -
    +
    Classes -
    +
    +
    +
    Class template class_ -
    Example(s)
    -
    -
    -

    Introduction

    +
    +
    +
    Class class_ + synopsis -

    <boost/python/class.hpp> defines the interface through - which users expose their C++ classes to Python. It declares the - class_ class template, which is parameterized on the - class type being exposed, and the args and - bases utility class templates in the anonymous - namespace (the latter definitions will probably be moved in a future - release). +

    Class class_ + constructors -

    - <boost/python/class_fwd.hpp> contains a forward - declaration of the class_ class template. +

    Class class_ + modifier functions + +
    Class class_ + observer functions +
    + +
    Class template bases + +
    +
    +
    Class bases + synopsis +
    + +
    Class template args + +
    +
    +
    Class args + synopsis +
    +
    + +
    Example(s) +
    +
    + +

    Introduction

    + +

    <boost/python/class.hpp> defines the interface + through which users expose their C++ classes to Python. It declares the + class_ class template, which is parameterized on the class + type being exposed, and the args and bases + utility class templates in the anonymous namespace (the latter definitions + will probably be moved in a future release). + +

    <boost/python/class_fwd.hpp> contains a forward + declaration of the class_ class template. + +

    Classes

    + +

    Class template class_<T, Bases, HolderGenerator>

    + +

    Creates a Python class associated with the C++ type passed as its first + parameter. Its template arguments are:
    +
    -

    Classes

    - -

    -Class template class_<T, Bases, HolderGenerator>

    - -

    Creates a Python class associated with the C++ type passed as its -first parameter. Its template arguments are: -

    - - + + -
    Parameter - Requirements - Default -
    T - A class type. -
    Bases - An MPL - sequence of C++ base classes of T. + Requirements + + Default + +
    T + + A class type. + +
    Bases + + An MPL sequence of + C++ base classes of T. An unspecified empty sequence
    HolderGenerator + HolderGenerator - A model of HolderGenerator. + A model of HolderGenerator. - boost::python::objects::value_holder_generator -
    + boost::python::objects::value_holder_generator + - - -

    Class template class_ synopsis

    +

    Class template class_ + synopsis

     namespace boost { namespace python
     {
    @@ -128,44 +150,42 @@ namespace boost { namespace python
     }}
     
    -

    Class template class_ constructors

    +

    Class template class_ + constructors

     class_()
     
    -
    -
    Requires: The platform's - std::type_info::name() implementation produces a string - which corresponds to the type's declaration in C++
    +
    +
    Requires: The platform's std::type_info::name() + implementation produces a string which corresponds to the type's + declaration in C++ -
    Effects: Constructs a class_ object which - generates a Boost.Python extension class with the same name as - T.
    - -
    Rationale: Many platforms can generate reasonable names - for Python classes without user intervention.
    - -
    +
    Effects: Constructs a class_ object which + generates a Boost.Python extension class with the same name as + T. +
    Rationale: Many platforms can generate reasonable names for + Python classes without user intervention. +
     class_(char const* name)
     
    -
    -
    Requires: Name is a ntbs which conforms to Python's identifier - naming rules.
    +
    +
    Requires: name is a ntbs which conforms to + Python's identifier + naming rules. -
    Effects: Constructs a class_ object which - generates a Boost.Python extension class named - name.
    +
    Effects: Constructs a class_ object which + generates a Boost.Python extension class named name. -
    Rationale: Gives the user full control over class naming.
    - -
    - -

    Class template class_ modifier functions

    +
    Rationale: Gives the user full control over class naming. +
    +

    Class template class_ + modifier functions

     template <class F>
     class_& def(char const* name, F f)
    @@ -174,32 +194,23 @@ template <class Fn, class CallPolicy>
     class_& def(char const* name, Fn fn, CallPolicy policy)
     
    -
    -
    Requires: +
    +
    Requires: f is a non-null pointer-to-function or + pointer-to-member-function. name is a ntbs which conforms to + Python's identifier + naming rules. If supplied, policy conforms to the CallPolicy concept requirements. - f is a non-null pointer-to-function or - pointer-to-member-function. - - name is a ntbs which conforms to Python's identifier - naming rules. - - If supplied, policy conforms to the CallPolicy concept requirements. -
    - -
    Effects: Adds the result of make_function(f) - to the Boost.Python extension class being defined, with the given - name. If the extension class already has an attribute - named name, the usual overloading procedure applies. - -
    - -
    Returns: *this
    -
    +
    Effects: Adds the result of make_function(f) to + the Boost.Python extension class being defined, with the given + name. If the extension class already has an attribute named + name, the usual overloading procedure applies. +
    Returns: *this +
     template <class Args>
     class_& def_init(Args const& argument_types)
    @@ -207,61 +218,56 @@ class_& def_init(Args const& argument_types)
     class_& def_init()
     
    -
    +
    +
    Requires: in the first form, argument_types must be an MPL sequence of C++ argument + types (A1, A2,... AN) such that if + a1, a2... aN are objects of type + A1, A2,... AN respectively, the expression + T(a1, a2... aN) is valid. In the second form, + the expression T() must be valid. -
    Requires: in the first form, argument_types must be an MPL sequence of C++ - argument types (A1, A2,... AN) such that if - a1, a2... aN are objects of type - A1, A2,... AN respectively, the expression - T(a1, a2... aN) is - valid. In the second form, the expression T() must be - valid. -
    +
    Effects: Adds the result of make_constructor<T,Args,HolderGenerator>() + to the Boost.Python extension class being defined with the name + "__init__". If the 2nd form is used, an unspecified empty MPL sequence type is substituted + for Args. If the extension class already has an "__init__" + attribute, the usual overloading + procedure applies. -
    Effects: Adds the result of - make_constructor<T,Args,HolderGenerator>() to the - Boost.Python extension class being defined with the name - "__init__". If the 2nd form is used, an unspecified empty - MPL sequence type is - substituted for Args. - If the extension class already has an - "__init__" attribute, the usual overloading procedure applies. +
    Returns: *this -
    Returns: *this
    +
    Rationale: Allows users to easily expose a class' constructor + to Python. +
    -
    Rationale: Allows users to easily expose a class' - constructor to Python.
    -
    - - -

    Class template class_ observer -functions

    +

    Class template class_ + observer functions

     ref object() const;
     
    -
    -
    Returns: A ref object which holds a - reference to the Boost.Python extension class object created by the - class_ constructor.
    -
    Rationale: Mostly not needed by users, since module::add() uses this to - insert the extension class in the module.
    -
    +
    +
    Returns: A ref object which holds a reference to + the Boost.Python extension class object created by the + class_ constructor. +
    Rationale: Mostly not needed by users, since module::add() uses this to insert the + extension class in the module. +
    -

    -Class template args<T1, T2,...TN>

    +

    Class template + args<T1, T2,...TN>

    -

    Essentially an alias for boost::mpl::type_list which -users can use in def_init calls to make their code more -readable. Currently it is in the global unnammed namespace, but that -will probably change. +

    Essentially an alias for boost::mpl::type_list which users + can use in def_init calls to make their code more readable. + Currently it is in the global unnammed namespace, but that will probably + change. -

    Class template args synopsis

    +

    Class template args + synopsis

     namespace
     {
    @@ -271,15 +277,16 @@ namespace
     }
     
    -

    -Class template bases<T1, T2,...TN>

    +

    Class template + bases<T1, T2,...TN>

    -

    Essentially an alias for boost::mpl::type_list which -users can use in class_<...> -instantiations to make their code more readable. Currently it is in -the global unnammed namespace, but that will probably change. +

    Essentially an alias for boost::mpl::type_list which users + can use in class_<...> instantiations to + make their code more readable. Currently it is in the global unnammed + namespace, but that will probably change. -

    Class template bases synopsis

    +

    Class template bases + synopsis

     namespace
     {
    @@ -289,10 +296,9 @@ namespace
     }
     
    -

    Example(s)

    - -

    Given a C++ class declaration: +

    Example(s)

    +

    Given a C++ class declaration:

     class Foo : public Bar, public Baz
     {
    @@ -306,9 +312,7 @@ class Foo : public Bar, public Baz
        ...
     };
     
    - -A corresponding Boost.Python extension class can be created with: - + A corresponding Boost.Python extension class can be created with:
     using namespace boost::python;
     ref foo =
    @@ -319,15 +323,12 @@ class_<Foo,bases<Bar,Baz> >()
        .def("set_name", &Foo::set_name)
        .object();
     
    + Revised + + 05 November, 2001 + + -

    +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. -

    Revised - - 05 November, 2001 - -

    -

    © Copyright Dave Abrahams - 2002. All Rights Reserved.

    - - diff --git a/doc/v2/copy_const_reference.html b/doc/v2/copy_const_reference.html index 1ce94dbb..f80db61f 100644 --- a/doc/v2/copy_const_reference.html +++ b/doc/v2/copy_const_reference.html @@ -1,49 +1,61 @@ - - - - -Boost.Python - <boost/python/copy_const_reference.hpp> - - - + + + + + Boost.Python - <boost/python/copy_const_reference.hpp> + +
    - - - - -
    -

    C++ Boost

    -
    -

    Boost.Python

    -

    Header <boost/python/copy_const_reference.hpp>

    -
    -
    -

    Contents

    -
    -
    Classes
    -
    -
    Class copy_const_reference
    -
    -
    Class copy_const_reference synopsis
    -
    Class copy_const_reference metafunctions
    -
    -
    + + +

    +

    -
    Example
    -
    -
    + +

    Boost.Python

    -

    Classes

    +

    Header + <boost/python/copy_const_reference.hpp>

    + +
    -

    Class copy_const_reference

    -

    -copy_const_reference is a model of ResultConverterGenerator -which can be used to wrap C++ functions returning a reference-to-const -type such that the referenced value is copied into a new Python object. -

    +

    Contents

    -

    Class copy_const_reference synopsis

    +
    +
    Classes + +
    +
    +
    Class + copy_const_reference + +
    +
    +
    Class + copy_const_reference synopsis + +
    Class + copy_const_reference metafunctions +
    +
    + +
    Example +
    +
    + +

    Classes

    + +

    Class + copy_const_reference

    + +

    copy_const_reference is a model of ResultConverterGenerator which can be + used to wrap C++ functions returning a reference-to-const type such that + the referenced value is copied into a new Python object. + +

    Class + copy_const_reference synopsis

     namespace boost { namespace python
     {
    @@ -53,19 +65,25 @@ namespace boost { namespace python
         };
     }}
     
    -

    Class copy_const_reference metafunctions

    + +

    Class + copy_const_reference metafunctions

     template <class T> struct apply
     
    -
    -
    Requires: T is U const& for some U.
    -
    Returns: typedef to_python_value<T> type;
    -
    -

    Example

    +
    +
    Requires: T is U const& for some + U. -

    In C++: +

    Returns: typedef to_python_value<T> + type; +
    +

    Example

    + +

    In C++:

     #include <boost/python/module.hpp>
     #include <boost/python/class.hpp>
    @@ -98,21 +116,19 @@ BOOST_PYTHON_MODULE_INIT(my_module)
              );
     }
     
    - -In Python: - + In Python:
     >>> from my_module import *
     >>> f = Foo(3)         # create a Foo object
     >>> b = f.get_bar()    # make a copy of the internal Bar object
     
    -

    Revised - - 05 November, 2001 - -

    -

    © Copyright Dave Abrahams - 2002. All Rights Reserved.

    - - +

    Revised + + 05 November, 2001 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + diff --git a/doc/v2/copy_non_const_reference.html b/doc/v2/copy_non_const_reference.html index c1ed50a3..ea2a99c7 100644 --- a/doc/v2/copy_non_const_reference.html +++ b/doc/v2/copy_non_const_reference.html @@ -1,49 +1,62 @@ - - - - -Boost.Python - <boost/python/copy_non_const_reference.hpp> - - - + + + + + Boost.Python - + <boost/python/copy_non_const_reference.hpp> + +
    - - - - -
    -

    C++ Boost

    -
    -

    Boost.Python

    -

    Header <boost/python/copy_non_const_reference.hpp>

    -
    -


    -

    Contents

    -
    -
    Classes
    -
    -
    Class copy_non_const_reference
    -
    -
    Class copy_non_const_reference synopsis
    -
    Class copy_non_const_reference metafunctions
    -
    -
    + + +

    +

    -
    Example
    -
    -
    + +

    Boost.Python

    -

    Classes

    +

    Header + <boost/python/copy_non_const_reference.hpp>

    + +
    -

    Class copy_non_const_reference

    -

    -copy_non_const_reference is a model of ResultConverterGenerator -which can be used to wrap C++ functions returning a reference-to-non-const -type such that the referenced value is copied into a new Python object. -

    +

    Contents

    -

    Class copy_non_const_reference synopsis

    +
    +
    Classes + +
    +
    +
    Class + copy_non_const_reference + +
    +
    +
    Class + copy_non_const_reference synopsis + +
    Class + copy_non_const_reference metafunctions +
    +
    + +
    Example +
    +
    + +

    Classes

    + +

    Class + copy_non_const_reference

    + +

    copy_non_const_reference is a model of ResultConverterGenerator which can be + used to wrap C++ functions returning a reference-to-non-const type such + that the referenced value is copied into a new Python object. + +

    Class + copy_non_const_reference synopsis

     namespace boost { namespace python
     {
    @@ -54,19 +67,24 @@ namespace boost { namespace python
     }}
     
    -

    Class copy_non_const_reference metafunctions

    +

    Class + copy_non_const_reference metafunctions

     template <class T> struct apply
     
    -
    -
    Requires: T is U& for some non-const U.
    -
    Returns: typedef to_python_value<T> type;
    -
    -

    Example

    +
    +
    Requires: T is U& for some + non-const U. -

    C++ code: +

    Returns: typedef to_python_value<T> + type; +
    +

    Example

    + +

    C++ code:

     #include <boost/python/module.hpp>
     #include <boost/python/class.hpp>
    @@ -99,21 +117,19 @@ BOOST_PYTHON_MODULE_INIT(my_module)
              );
     }
     
    - -Python Code: - + Python Code:
     >>> from my_module import *
     >>> f = Foo(3)         # create a Foo object
     >>> b = f.get_bar()    # make a copy of the internal Bar object
     
    -

    Revised - - 05 November, 2001 - -

    -

    © Copyright Dave Abrahams - 2002. All Rights Reserved.

    - - +

    Revised + + 05 November, 2001 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + diff --git a/doc/v2/default_call_policies.html b/doc/v2/default_call_policies.html index 3e60fcc8..876baf7a 100644 --- a/doc/v2/default_call_policies.html +++ b/doc/v2/default_call_policies.html @@ -1,61 +1,78 @@ - - - - -Boost.Python - <boost/python/default_call_policies.hpp> - - - + + + + + Boost.Python - + <boost/python/default_call_policies.hpp> + +
    - - - - -
    -

    C++ Boost

    -
    -

    Boost.Python

    -

    Header <boost/python/default_call_policies.hpp>

    -
    -


    -

    Contents

    -
    -
    Classes
    -
    + + +

    +

    -
    Class default_call_policies
    -
    -
    Class default_call_policies synopsis
    -
    Class default_call_policies static functions
    -
    + +

    Boost.Python

    -
    Class default_result_converter
    -
    -
    Class default_result_converter synopsis
    -
    Class default_result_converter metafunctions
    -
    +

    Header + <boost/python/default_call_policies.hpp>

    + +
    -
    +

    Contents

    -
    Example
    -
    -
    +
    +
    Classes -

    Classes

    +
    +
    +
    Class + default_call_policies -

    Class default_call_policies

    -

    -default_call_policies is a model of CallPolicies with no precall -or postcall behavior and a result_converter -which handles by-value returns. Wrapped C++ functions and member -functions use default_call_policies unless otherwise -specified. You may find it convenient to derive new models of CallPolicies from -default_call_policies. -

    +
    +
    +
    Class + default_call_policies synopsis -

    Class default_call_policies synopsis

    +
    Class + default_call_policies static functions +
    + +
    Class + default_result_converter + +
    +
    +
    Class + default_result_converter synopsis + +
    Class + default_result_converter metafunctions +
    +
    + +
    Example +
    +
    + +

    Classes

    + +

    Class + default_call_policies

    + +

    default_call_policies is a model of CallPolicies with no precall or + postcall behavior and a result_converter which + handles by-value returns. Wrapped C++ functions and member functions use + default_call_policies unless otherwise specified. You may find + it convenient to derive new models of CallPolicies from + default_call_policies. + +

    Class + default_call_policies synopsis

     namespace boost { namespace python
     {
    @@ -63,38 +80,43 @@ namespace boost { namespace python
         {
             static bool precall(PyObject*);
             static PyObject* postcall(PyObject*, PyObject* result);
    -        typedef default_result_converter result_converter;
    +        typedef default_result_converter result_converter;
         };
     }}
     
    -

    Class default_call_policies static functions

    +

    Class + default_call_policies static functions

     bool precall(PyObject*);
     
    -
    -
    Returns: true
    -
    Throws: nothing
    -
    +
    +
    Returns: true + +
    Throws: nothing +
     PyObject* postcall(PyObject*, PyObject* result);
     
    -
    -
    Returns: result
    -
    Throws: nothing
    -
    -

    Class default_result_converter

    -

    -default_result_converter is a model of ResultConverterGenerator -which can be used to wrap C++ functions returning non-pointer types, -char const*, and PyObject*, -by-value. -

    +
    +
    Returns: result -

    Class default_result_converter synopsis

    +
    Throws: nothing +
    + +

    Class + default_result_converter

    + +

    default_result_converter is a model of ResultConverterGenerator which can be + used to wrap C++ functions returning non-pointer types, char + const*, and PyObject*, by-value. + +

    Class + default_result_converter synopsis

     namespace boost { namespace python
     {
    @@ -105,26 +127,30 @@ namespace boost { namespace python
     }}
     
    -

    Class default_result_converter metafunctions

    +

    Class + default_result_converter metafunctions

     template <class T> struct apply
     
    -
    -
    Requires: T is not a reference type. If - T is a pointer type, T is const - char* or PyObject*.
    +
    +
    Requires: T is not a reference type. If + T is a pointer type, T is const + char* or PyObject*. -
    Returns: typedef to_python_value<T const&> type;
    -
    +
    Returns: typedef to_python_value<T + const&> type; +
    -

    Example

    - -

    This example comes from the Boost.Python implementation itself. Because the return_value_policy -class template does not implement precall or -postcall behavior, its default base class is default_call_policies: +

    Example

    +

    This example comes from the Boost.Python implementation itself. Because + the return_value_policy + class template does not implement precall or + postcall behavior, its default base class is + default_call_policies:

     template <class Handler, class Base = default_call_policies>
     struct return_value_policy : Base
    @@ -133,12 +159,12 @@ struct return_value_policy : Base
     };
     
    -

    Revised - - 05 November, 2001 - -

    -

    © Copyright Dave Abrahams - 2002. All Rights Reserved.

    - - +

    Revised + + 05 November, 2001 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + diff --git a/doc/v2/errors.html b/doc/v2/errors.html index e0bfa89d..e52f29f7 100644 --- a/doc/v2/errors.html +++ b/doc/v2/errors.html @@ -1,132 +1,141 @@ - - - - -Boost.Python - <{{header}}> - - - + + + + + Boost.Python - <{{header}}> + +
    - - - - -
    -

    C++ Boost

    -
    -

    Boost.Python

    -

    Header <boost/python/errors.hpp>

    -
    -


    -

    Contents

    -
    -
    Introduction
    + + +

    +

    -
    Classes
    -
    + +

    Boost.Python

    -
    Class error_already_set
    -
    -
    Class error_already_set synopsis
    -
    +

    Header <boost/python/errors.hpp>

    + +
    -
    +

    Contents

    -
    Functions
    -
    +
    +
    Introduction -
    handle_exception
    -
    expect_non_null
    +
    Classes -
    +
    +
    +
    Class error_already_set -
    Examples
    -
    -
    +
    +
    +
    Class + error_already_set synopsis +
    +
    -

    Introduction

    -

    <boost/python/errors.hpp> provides types and -functions for managing and translating between Python and C++ -exceptions. This is relatively low-level functionality that is mostly -used internally by Boost.Python. Users should seldom need it. +

    Functions -

    Classes

    +
    +
    +
    handle_exception -

    Class error_already_set

    -

    -error_already_set is an exception type which can be -thrown to indicate that a Python error has occurred. If thrown, the -precondition is that PyErr_Occurred() -returns a value convertible to true. -

    +
    expect_non_null +
    -

    Class error_already_set synopsis

    +
    Examples +
    +
    + +

    Introduction

    + +

    <boost/python/errors.hpp> provides types and + functions for managing and translating between Python and C++ exceptions. + This is relatively low-level functionality that is mostly used internally + by Boost.Python. Users should seldom need it. + +

    Classes

    + +

    Class + error_already_set

    + +

    error_already_set is an exception type which can be thrown + to indicate that a Python error has occurred. If thrown, the precondition + is that PyErr_Occurred() + returns a value convertible to true. + +

    Class error_already_set synopsis

     namespace boost { namespace python
     {
    -    class error_already_set {};
    +    class error_already_set {};
     }}
     
    - -

    Functions

    -
    template <class T> bool handle_exception(T f) throw();
    +    

    Functions

    +
    +template <class T> bool handle_exception(T f) throw();
     
     void handle_exception() throw();
     
    -
    -
    Requires: The first form requires that the expression - function0<void>(f) - is valid. The second form requires that a C++ exception is currently - being handled (see section 15.1 in the C++ standard). -
    -
    Effects: The first form calls f() inside a - try block whose catch clauses set an - appropriate Python exception for the C++ exception caught, returning - true if an exception was caught, false - otherwise. The second form passes a function which rethrows the - exception currently being handled to the first form.
    +
    +
    Requires: The first form requires that the expression function0<void>(f) + is valid. The second form requires that a C++ exception is currently + being handled (see section 15.1 in the C++ standard). -
    Postconditions: No exception is being handled
    +
    Effects: The first form calls f() inside a + try block whose catch clauses set an + appropriate Python exception for the C++ exception caught, returning + true if an exception was caught, false + otherwise. The second form passes a function which rethrows the exception + currently being handled to the first form. -
    Throws: nothing
    +
    Postconditions: No exception is being handled -
    Rationale: At inter-language boundaries it is important - to ensure that no C++ exceptions escape, since the calling language - usually doesn't have the equipment neccessary to properly unwind the - stack. Use handle_exception to manage exception - translation whenever your C++ code is called directly from the - Python API. This is done for you automatically by the usual function - wrapping facilities: make_function(), make_constructor(), - module::def and class_::def). The second form can be - more convenient to use - (see the example below), but various - compilers have problems when exceptions are rethrown from within an - enclosing try block.
    -
    +
    Throws: nothing +
    Rationale: At inter-language boundaries it is important to + ensure that no C++ exceptions escape, since the calling language usually + doesn't have the equipment neccessary to properly unwind the stack. Use + handle_exception to manage exception translation whenever + your C++ code is called directly from the Python API. This is done for + you automatically by the usual function wrapping facilities: make_function(), make_constructor(), module::def and class_::def). The second form can be more + convenient to use (see the example below), but + various compilers have problems when exceptions are rethrown from within + an enclosing try block. +
     PyObject* expect_non_null(PyObject* x);
     
     template <class T> T* expect_non_null(T* x);
     
    -
    -
    Returns: x
    -
    Throws: error_already_set() iff x == 0.
    -
    Rationale: Simplifies error-handling when calling many - functions in the Python/C - API, which return 0 on error.
    -
    -

    Examples

    -

    +

    +
    Returns: x + +
    Throws: error_already_set() iff x == + 0. + +
    Rationale: Simplifies error-handling when calling many + functions in the Python/C API, which + return 0 on error. +
    + +

    Examples

     #include <string>
     #include <boost/python/errors.hpp>
    @@ -211,13 +220,13 @@ same_name2(PyObject* args, PyObject* keywords)
        }
     }
     
    -

    -

    Revised - - 05 November, 2001 - -

    -

    © Copyright Dave Abrahams - 2002. All Rights Reserved.

    - - + +

    Revised + + 05 November, 2001 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + diff --git a/doc/v2/from_python.html b/doc/v2/from_python.html index 94ae7019..d888bb38 100644 --- a/doc/v2/from_python.html +++ b/doc/v2/from_python.html @@ -1,68 +1,79 @@ - - - - -Boost.Python - <boost/python/from_python.hpp> - - - + + + + + Boost.Python - <boost/python/from_python.hpp> + +
    - - - - -
    -

    C++ Boost

    -
    -

    Boost.Python

    -

    Header <boost/python/from_python.hpp>

    -
    -


    -

    Contents

    -
    -
    Introduction
    + + +

    +

    -
    Classes
    -
    + +

    Boost.Python

    -
    Class Templatefrom_python
    -
    -
    Class Template from_python synopsis
    -
    Class Template from_python constructor
    -
    Class Template from_python observer functions
    -
    -
    -
    Example
    -
    -
    -

    Introduction

    -

    +

    Header <boost/python/from_python.hpp>

    + +
    -<boost/python/from_python.hpp> introduces a class -template from_python<T> for extracting a C++ object -of type T from a Python object. +

    Contents

    -

    +
    +
    Introduction +
    Classes -

    Classes

    -

    Class Template from_python<class T>

    +
    +
    +
    Class + Templatefrom_python -

    -from_python<T> is the type used internally by -Boost.Python to extract C++ function arguments from a Python argument -tuple when calling a wrapped function. It can also be used directly to -make similar conversions in other contexts. -

    +
    +
    +
    Class Template + from_python synopsis -

    Class Template from_python synopsis

    +
    Class Template + from_python constructor + +
    Class Template + from_python observer functions +
    +
    + +
    Example +
    +
    + +

    Introduction

    + +

    <boost/python/from_python.hpp> introduces a class + template from_python<T> for extracting a C++ object of + type T from a Python object. + +

    Classes

    + +

    Class Template + from_python<class T>

    + +

    from_python<T> is the type used internally by + Boost.Python to extract C++ function arguments from a Python argument tuple + when calling a wrapped function. It can also be used directly to make + similar conversions in other contexts. + +

    Class Template + from_python synopsis

     namespace boost { namespace python
     {
        template <class T>
        struct from_python : private boost::noncopyable // Exposition only.
    -       // from_python<T> meets the NonCopyable requirements
    +"../../../utility/utility.htm#Class noncopyable">boost::noncopyable // Exposition only.
    +       // from_python<T> meets the NonCopyable requirements
        {
           from_python(PyObject*);
           bool convertible() const;
    @@ -71,63 +82,63 @@ namespace boost { namespace python
     }
     
    -

    Class Template from_python constructor

    +

    Class Template + from_python constructor

     from_python(PyObject* p);
     
    -
    -
    Requires: p != 0
    -
    Effects: Constructs a from_python object - suitable for extracting a C++ object of type T from - p.
    -
    +
    +
    Requires: p != 0 -

    Class Template from_python observer functions

    +
    Effects: Constructs a from_python object suitable + for extracting a C++ object of type T from p. +
    +

    Class Template + from_python observer functions

     bool convertible() const;
     
    -
    -
    Returns: false if the conversion cannot succeed. This indicates that either: -
      -
    1. No from_python_converter was registered for -T, or +
      +
      Returns: false if the conversion cannot succeed. + This indicates that either: -
    2. any such converter rejected the constructor argument -p by returning 0 from its -convertible() function -
    +
    +
      +
    1. No from_python_converter was registered for + T, or -Note that conversion may still fail in operator() due to an exception. +
    2. any such converter rejected the constructor argument + p by returning 0 from its + convertible() function +
    + Note that conversion may still fail in operator() due to + an exception. - - -
    Throws: nothing
    - -
    Rationale: Because from_python<> is used in - overload resolution, and throwing an exception can be slow, it is - useful to be able to rule out a broad class of unsuccessful - conversions without throwing an exception.
    -
    +
    Throws: nothing +
    Rationale: Because from_python<> is used in + overload resolution, and throwing an exception can be slow, it is useful + to be able to rule out a broad class of unsuccessful conversions without + throwing an exception. +
    -
    Requires: f is a non-null pointer-to-function or - pointer-to-member-function. name is a ntbs which conforms to - Python's Requires: f is a non-null + pointer-to-function or pointer-to-member-function, or a callable + Python object passed as a PyObject* or ref. name + is a ntbs which conforms to Python's identifier naming rules. In the first form, the return type of f is not a reference and is not a pointer other @@ -350,7 +355,8 @@ class_& def(char const* name, Fn f, CallPolicies policies); href="CallPolicies.html">CallPolicies.
    Effects: Adds the result of make_function(f) to + "make_function.html#make_function-spec">make_function(f) or make_function(f, policies) to the Boost.Python extension class being defined, with the given name. If the extension class already has an attribute named name, the usual Returns: *this
    +
    +template <class F>
    +class_& setattr(char const* name, ref x);
    +
    + +
    +
    Requires: name is a ntbs which conforms to + Python's identifier + naming rules. + +
    Effects: PyObject_SetAttrString(this->object(), name, x.get()); + +
    Returns: *this +
    +
    -void add_property(char const* name, ref const&amp; fget);
    -void add_property(char const* name, ref const&amp; fget, ref const&amp; fset);
    +void add_property(char const* name, ref const& fget);
    +void add_property(char const* name, ref const& fget, ref const& fset);
     
    @@ -389,7 +411,7 @@ void add_property(char const* name, ref const&amp; fget, ref const&amp;
         template <class D>
    -    self& def_readonly(char const* name, D T::*pm);
    +    class_& def_readonly(char const* name, D T::*pm);
     
    @@ -415,7 +437,7 @@ this->add_property(name, ref(mak
     template <class D>
    -self& def_readwrite(char const* name, D T::*pm);
    +class_& def_readwrite(char const* name, D T::*pm);
     
    diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 10c54629..4d8d3bbe 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -39,10 +39,13 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable ref object() const { return m_object; } void add_property(char const* name, ref const& fget); void add_property(char const* name, ref const& fget, ref const& fset); + void setattr(char const* name, ref const&); private: ref m_object; }; +BOOST_PYTHON_DECL ref registered_class_object(class_id id); + // Base class for all holders struct BOOST_PYTHON_DECL instance_holder : private noncopyable { From 6c20af07f7f012c4454c3a71a3e503b3f29319ec Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 13 May 2002 16:40:34 +0000 Subject: [PATCH 0462/1042] Added setattr(), and the ability to query the class registry to see if a class has already been created [SVN r13842] --- src/object/class.cpp | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index c98a7414..2e1dca89 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -197,6 +197,7 @@ namespace { public: ref get(class_id id) const; + ref query(class_id id) const; void set(class_id, ref class_object); private: typedef detail::map_entry entry; @@ -209,7 +210,7 @@ namespace return x; } - ref class_registry::get(class_id id) const + inline ref class_registry::query(class_id id) const { std::vector::const_iterator start = m_impl.begin(); std::vector::const_iterator finish = m_impl.end(); @@ -217,17 +218,24 @@ namespace std::vector::const_iterator p = boost::detail::lower_bound(start, finish, id); - if (p == finish || p->key != id) + return (p == finish || p->key != id) ? ref() : p->value; + } + + inline ref class_registry::get(class_id id) const + { + ref result(this->query(id)); + + if (result.get() == 0) { string report("extension class wrapper for base class "); (report += id.name()) += " has not been created yet"; PyErr_SetObject(PyExc_RuntimeError, report.get()); throw_error_already_set(); } - return p->value; + return result; } - void class_registry::set(class_id id, ref object) + inline void class_registry::set(class_id id, ref object) { std::vector::iterator start = m_impl.begin(); std::vector::iterator finish = m_impl.end(); @@ -272,15 +280,24 @@ extern "C" void class_base::add_property(char const* name, ref const& fget) { ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.get())); - if (PyObject_SetAttrString(object().get(), const_cast(name), property.get()) < 0) - throw_error_already_set(); + setattr(name, property); } void class_base::add_property(char const* name, ref const& fget, ref const& fset) { ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.get(), fset.get())); - if (PyObject_SetAttrString(object().get(), const_cast(name), property.get()) < 0) + setattr(name, property); +} + +void class_base::setattr(char const* name, ref const& x) +{ + if (PyObject_SetAttrString(object().get(), const_cast(name), x.get()) < 0) throw_error_already_set(); } +BOOST_PYTHON_DECL ref registered_class_object(class_id id) +{ + return registry().query(id); +} + }}} // namespace boost::python::objects From 9fa89e8596981af46762b974cce1495a5f1bb25e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 13 May 2002 16:41:50 +0000 Subject: [PATCH 0463/1042] Added iterator support plus a minimal test to look for refcount problems. [SVN r13843] --- Jamfile | 1 + test/Jamfile | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/Jamfile b/Jamfile index 4a1af66f..73a0a047 100644 --- a/Jamfile +++ b/Jamfile @@ -18,6 +18,7 @@ dll bpl src/objects.cpp src/converter/builtin_converters.cpp src/converter/callback.cpp + src/object/iterator.cpp : $(BOOST_PYTHON_V2_PROPERTIES) BOOST_PYTHON_SOURCE diff --git a/test/Jamfile b/test/Jamfile index e684bcdd..96574a2f 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -51,6 +51,7 @@ rule bpl-test ( name ? : files * ) boost-python-runtest $(name) : $(py) $(modules) ; } +bpl-test minimal ; bpl-test try : newtest.py m1.cpp m2.cpp ; bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ; bpl-test test_pointer_adoption ; @@ -64,6 +65,8 @@ bpl-test bienstman1 ; bpl-test bienstman2 ; bpl-test bienstman3 ; bpl-test multi_arg_constructor ; +bpl-test iterator ; + if $(TEST_BIENSTMAN_NON_BUGS) { bpl-test bienstman4 ; @@ -98,6 +101,7 @@ unit-test select_holder unit-test select_from_python_test : select_from_python_test.cpp ../src/converter/type_id.cpp + ../src/errors.cpp : $(BOOST_ROOT) [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] From 3ff935d4c4aeae117506f9a477ec995559181a4f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 13 May 2002 17:03:05 +0000 Subject: [PATCH 0464/1042] initial commit [SVN r13844] --- src/object/iterator.cpp | 32 ++++++++++ test/iterator.cpp | 128 ++++++++++++++++++++++++++++++++++++++++ test/iterator.py | 60 +++++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 src/object/iterator.cpp create mode 100644 test/iterator.cpp create mode 100644 test/iterator.py diff --git a/src/object/iterator.cpp b/src/object/iterator.cpp new file mode 100644 index 00000000..6a927726 --- /dev/null +++ b/src/object/iterator.cpp @@ -0,0 +1,32 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include + +namespace boost { namespace python { namespace objects { + +static PyObject* identity(PyObject* args_, PyObject*) +{ + PyObject* x = PyTuple_GET_ITEM(args_,0); + Py_INCREF(x); + return x; +} + +BOOST_PYTHON_DECL ref identity_function() +{ + static ref result(new objects::function(py_function(&identity), 1)); + return result; +} + +void set_stop_iteration_error() +{ + PyErr_SetObject(PyExc_StopIteration, Py_None); +} + +}}} // namespace boost::python::objects diff --git a/test/iterator.cpp b/test/iterator.cpp new file mode 100644 index 00000000..1ea2196b --- /dev/null +++ b/test/iterator.cpp @@ -0,0 +1,128 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace boost::python; + +typedef std::list list_int; +typedef std::list list_list; + +void push_back(list_int& x, int y) +{ + x.push_back(y); +} + +void push_list_back(list_list& x, list_int const& y) +{ + x.push_back(y); +} + +int back(list_int& x) +{ + return x.back(); +} + +typedef std::pair list_range; + +list_range range(list_int& x) +{ + return list_range(x.begin(), x.end()); +} + +struct two_lists +{ + two_lists() + { + int primes[] = { 2, 3, 5, 7, 11, 13 }; + std::copy(primes, primes + sizeof(primes)/sizeof(*primes), std::back_inserter(one)); + int evens[] = { 2, 4, 6, 8, 10, 12 }; + std::copy(evens, evens + sizeof(evens)/sizeof(*evens), std::back_inserter(two)); + } + + struct two_start + { + typedef list_int::iterator result_type; + result_type operator()(two_lists& ll) const { return ll.two.begin(); } + }; + friend struct two_start; + + list_int::iterator one_begin() { return one.begin(); } + list_int::iterator two_begin() { return two.begin(); } + + list_int::iterator one_end() { return one.end(); } + list_int::iterator two_end() { return two.end(); } + +private: + list_int one; + list_int two; +}; + +BOOST_PYTHON_MODULE_INIT(iterator_ext) +{ + module("iterator_ext") + .def("range", &::range) + .add( + class_("list_int") + .def_init() + .def("push_back", push_back) + .def("back", back) + .def("__iter__", iterator()) + ) + .add( + class_("list_range") + + // We can specify data members + .def("__iter__" + , range(&list_range::first, &list_range::second)) + ) + .add( + class_("two_lists") + .def_init() + + // We can spcify member functions + .add_property( + "primes" + , range(&two_lists::one_begin, &two_lists::one_end)) + + // Prove that we can explicitly specify call policies + .add_property( + "evens" + , range >( + &two_lists::two_begin, &two_lists::two_end)) + + // Prove that we can specify call policies and target + .add_property( + "twosies" + , range, two_lists>( + // And we can use adaptable function objects when + // partial specialization is available. +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + two_lists::two_start() +# else + &two_lists::two_begin +# endif + , &two_lists::two_end)) + ) + .add( + class_("list_list") + .def_init() + .def("push_back", push_list_back) + .def("__iter__", iterator >()) + ) + ; +} + +#include "module_tail.cpp" diff --git a/test/iterator.py b/test/iterator.py new file mode 100644 index 00000000..4e6366ad --- /dev/null +++ b/test/iterator.py @@ -0,0 +1,60 @@ +''' +>>> from iterator_ext import * +>>> x = list_int() +>>> x.push_back(1) +>>> x.back() +1 +>>> x.push_back(3) +>>> x.push_back(5) +>>> for y in x: +... print y +1 +3 +5 +>>> z = range(x) +>>> for y in z: +... print y +1 +3 +5 +>>> l2 = two_lists() +>>> for y in l2.primes: +... print y +2 +3 +5 +7 +11 +13 +>>> for y in l2.evens: +... print y +2 +4 +6 +8 +10 +12 +>>> ll = list_list() +>>> ll.push_back(x) +>>> x.push_back(7) +>>> ll.push_back(x) +>>> for a in ll: +... for b in a: +... print b, +... print +... +1 3 5 +1 3 5 7 +''' +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 53c69e7ad5be16a90b10f25852f63b85a463d230 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 16 May 2002 00:56:42 +0000 Subject: [PATCH 0465/1042] Merged from RC_1_28_0 [SVN r13944] --- build/Jamfile | 17 +- build/__init__.py | 19 +- build/example1/example1.dsp | 136 --------- build/getting_started1/getting_started1.dsp | 136 --------- build/getting_started2/getting_started2.dsp | 135 --------- build/rwgk1/rwgk1.dsp | 135 --------- build/test/test.dsp | 145 --------- doc/building.html | 314 +++++++++++--------- doc/index.html | 15 + example/Attic/project.zip | Bin 0 -> 1469 bytes example/Jamfile | 39 +++ example/README | 3 - example/example1.cpp | 43 --- example/project.zip | Bin 0 -> 1469 bytes example/rwgk1.cpp | 24 -- include/boost/python/detail/pointee.hpp | 36 +++ 16 files changed, 293 insertions(+), 904 deletions(-) delete mode 100644 build/example1/example1.dsp delete mode 100644 build/getting_started1/getting_started1.dsp delete mode 100644 build/getting_started2/getting_started2.dsp delete mode 100644 build/rwgk1/rwgk1.dsp delete mode 100644 build/test/test.dsp create mode 100644 example/Attic/project.zip create mode 100644 example/Jamfile delete mode 100644 example/example1.cpp create mode 100644 example/project.zip delete mode 100644 example/rwgk1.cpp create mode 100644 include/boost/python/detail/pointee.hpp diff --git a/build/Jamfile b/build/Jamfile index 1f44ff7f..889a8a29 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -89,11 +89,12 @@ local CPP_SOURCES = ; lib boost_python_static : ../src/$(CPP_SOURCES).cpp - # requirements - : $(BOOST_PYTHON_INCLUDES) + # requirements + : $(BOOST_PYTHON_INCLUDES) true - BOOST_PYTHON_STATIC_LIB=1 - [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] + BOOST_PYTHON_STATIC_LIB=1 + [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] + : true # don't build this unless the user asks for it by name ; dll boost_python @@ -106,6 +107,14 @@ dll boost_python $(PYTHON_PROPERTIES) ; +stage bin-stage : boost_python + : + "_debug" + "_pydebug" + : + debug release + ; + ############# comprehensive module and test ########### bpl-test boost_python_test : ../test/comprehensive.cpp ; diff --git a/build/__init__.py b/build/__init__.py index f89be274..97b20d9c 100644 --- a/build/__init__.py +++ b/build/__init__.py @@ -3,15 +3,20 @@ if ! $(gNO_PYTHON_INSTALL) { - ECHO "Couldn't find Python $(PYTHON_VERSION) installation in $(PYTHON_ROOT)" ; + ECHO "---------------------------------------------------------------------" ; ECHO skipping Boost.Python library build ; ECHO You can configure the location of your python installation, by setting: ; - ECHO PYTHON_ROOT - currently \"$(PYTHON_ROOT)\" ; - ECHO PYTHON_VERSION - currently \"$(PYTHON_VERSION)\" ; + ECHO "PYTHON_ROOT - currently" \"$(PYTHON_ROOT:J=" ")\" ; + ECHO "PYTHON_VERSION - The 2-part python Major.Minor version number (e.g." ; + ECHO " \"2.2\", NOT \"2.2.1\") - currently" \"$(PYTHON_VERSION)\" ; ECHO ; - ECHO "The following are automatically configured from PYTHON_ROOT if not otherwise set" ; - ECHO " PYTHON_INCLUDES - path to Python #include directories; currently" \"$(PYTHON_INCLUDES)\" ; - ECHO " PYTHON_LIB_PATH - path to Python library; currently" \"$(PYTHON_LIB_PATH)\" ; - ECHO " PYTHON_STDLIB_PATH - path to Python standard library modules; currently" \"$(PYTHON_STDLIB_PATH)\" ; + ECHO "The following are automatically configured from PYTHON_ROOT if not" ; + ECHO "otherwise set:" ; + ECHO " PYTHON_INCLUDES - path to Python #include directories; currently" \"$(PYTHON_INCLUDES:J=" ")\" ; + ECHO " PYTHON_LIB_PATH - path to Python library; currently" ; + ECHO " " \"$(PYTHON_LIB_PATH:J=" ")\" ; + ECHO " PYTHON_STDLIB_PATH - path to Python standard library modules; currently" ; + ECHO " " \"$(PYTHON_STDLIB_PATH:J=" ")\" ; + ECHO "---------------------------------------------------------------------" ; } gNO_PYTHON_INSTALL ?= true ; diff --git a/build/example1/example1.dsp b/build/example1/example1.dsp deleted file mode 100644 index 4d95aa97..00000000 --- a/build/example1/example1.dsp +++ /dev/null @@ -1,136 +0,0 @@ -# Microsoft Developer Studio Project File - Name="example1" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=example1 - Win32 DebugPython -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "example1.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "example1.mak" CFG="example1 - Win32 DebugPython" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "example1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "example1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "example1 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "example1 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/hello.dll" /libpath:"c:\tools\python\libs" - -!ELSEIF "$(CFG)" == "example1 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug/hello.dll" /pdbtype:sept /libpath:"c:\tools\python\libs" - -!ELSEIF "$(CFG)" == "example1 - Win32 DebugPython" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "example1___Win32_DebugPython" -# PROP BASE Intermediate_Dir "example1___Win32_DebugPython" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "DebugPython" -# PROP Intermediate_Dir "DebugPython" -# PROP Ignore_Export_Lib 1 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /EHs /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug/hello.dll" /pdbtype:sept /libpath:"c:\tools\python\libs" -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"DebugPython/hello_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild" - -!ENDIF - -# Begin Target - -# Name "example1 - Win32 Release" -# Name "example1 - Win32 Debug" -# Name "example1 - Win32 DebugPython" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\example\example1.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/getting_started1/getting_started1.dsp b/build/getting_started1/getting_started1.dsp deleted file mode 100644 index a41eb057..00000000 --- a/build/getting_started1/getting_started1.dsp +++ /dev/null @@ -1,136 +0,0 @@ -# Microsoft Developer Studio Project File - Name="getting_started1" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=getting_started1 - Win32 DebugPython -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "getting_started1.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "getting_started1.mak" CFG="getting_started1 - Win32 DebugPython" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "getting_started1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "getting_started1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "getting_started1 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=xicl6.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "getting_started1 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /libpath:"c:\tools\python\libs" - -!ELSEIF "$(CFG)" == "getting_started1 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /GR /GX /ZI /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" - -!ELSEIF "$(CFG)" == "getting_started1 - Win32 DebugPython" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "DebugPython" -# PROP BASE Intermediate_Dir "DebugPython" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "DebugPython" -# PROP Intermediate_Dir "DebugPython" -# PROP Ignore_Export_Lib 1 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /pdb:"DebugPython/boost_python_test_d.pdb" /debug /machine:I386 /out:"DebugPython/getting_started1_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild" -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "getting_started1 - Win32 Release" -# Name "getting_started1 - Win32 Debug" -# Name "getting_started1 - Win32 DebugPython" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\example\getting_started1.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/getting_started2/getting_started2.dsp b/build/getting_started2/getting_started2.dsp deleted file mode 100644 index 284bab21..00000000 --- a/build/getting_started2/getting_started2.dsp +++ /dev/null @@ -1,135 +0,0 @@ -# Microsoft Developer Studio Project File - Name="getting_started2" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=getting_started2 - Win32 DebugPython -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "getting_started2.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "getting_started2.mak" CFG="getting_started2 - Win32 DebugPython" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "getting_started2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "getting_started2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "getting_started2 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "getting_started2" -# PROP Scc_LocalPath "." -CPP=xicl6.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "getting_started2 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /libpath:"c:\tools\python\libs" - -!ELSEIF "$(CFG)" == "getting_started2 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" - -!ELSEIF "$(CFG)" == "getting_started2 - Win32 DebugPython" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "getting_started2___Win32_DebugPython" -# PROP BASE Intermediate_Dir "getting_started2___Win32_DebugPython" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "getting_started2___Win32_DebugPython" -# PROP Intermediate_Dir "getting_started2___Win32_DebugPython" -# PROP Ignore_Export_Lib 1 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=xilink6.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"DebugPython/getting_started2_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\pcbuild" - -!ENDIF - -# Begin Target - -# Name "getting_started2 - Win32 Release" -# Name "getting_started2 - Win32 Debug" -# Name "getting_started2 - Win32 DebugPython" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\example\getting_started2.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/rwgk1/rwgk1.dsp b/build/rwgk1/rwgk1.dsp deleted file mode 100644 index 67476984..00000000 --- a/build/rwgk1/rwgk1.dsp +++ /dev/null @@ -1,135 +0,0 @@ -# Microsoft Developer Studio Project File - Name="rwgk1" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=rwgk1 - Win32 DebugPython -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "rwgk1.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "rwgk1.mak" CFG="rwgk1 - Win32 DebugPython" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "rwgk1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "rwgk1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "rwgk1 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "rwgk1 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /libpath:"c:\tools\python\libs" - -!ELSEIF "$(CFG)" == "rwgk1 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm- /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" - -!ELSEIF "$(CFG)" == "rwgk1 - Win32 DebugPython" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "rwgk1___Win32_DebugPython" -# PROP BASE Intermediate_Dir "rwgk1___Win32_DebugPython" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "DebugPython" -# PROP Intermediate_Dir "DebugPython" -# PROP Ignore_Export_Lib 1 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm- /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"DebugPython/rwgk1_d.dll" /pdbtype:sept /libpath:"C:\tools\python\src\PCbuild" - -!ENDIF - -# Begin Target - -# Name "rwgk1 - Win32 Release" -# Name "rwgk1 - Win32 Debug" -# Name "rwgk1 - Win32 DebugPython" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\example\rwgk1.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/test/test.dsp b/build/test/test.dsp deleted file mode 100644 index 4bd2822a..00000000 --- a/build/test/test.dsp +++ /dev/null @@ -1,145 +0,0 @@ -# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=test - Win32 DebugPython -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "test.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "test.mak" CFG="test - Win32 DebugPython" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "test - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "test - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /Zm200 /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/boost_python_test.dll" /libpath:"c:\tools\python\libs" - -!ELSEIF "$(CFG)" == "test - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug/boost_python_test.dll" /pdbtype:sept /libpath:"c:\tools\python\libs" -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "test - Win32 DebugPython" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "test___Win32_DebugPython" -# PROP BASE Intermediate_Dir "test___Win32_DebugPython" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "DebugPython" -# PROP Intermediate_Dir "DebugPython" -# PROP Ignore_Export_Lib 1 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c -# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /Zm200 /EHs /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs" -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"DebugPython/boost_python_test_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild" -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "test - Win32 Release" -# Name "test - Win32 Debug" -# Name "test - Win32 DebugPython" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\test\comprehensive.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\test\comprehensive.hpp -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/doc/building.html b/doc/building.html index f9458c42..cdca6b97 100644 --- a/doc/building.html +++ b/doc/building.html @@ -9,172 +9,214 @@ "../../../c++boost.gif" alt="c++boost.gif (8819 bytes)">Building an Extension Module -

    The build process for Boost is currently undergoing some evolution, - and, it is to be hoped, improvement. The following facts may help: +

    Building Boost.Python

    -
    - Makefiles for various platforms and a Visual Studio project - reside in the Boost subdirectory libs/python/build. - Build targets include: +

    Every Boost.Python extension module must be linked with the + boost_python shared library. To build + boost_python, use Boost.Build in the + usual way from the libs/python/build subdirectory + of your boost installation (if you have already built boost from + the top level this may have no effect, since the work is already + done). + +

    Configuration

    + You may need to configure the following variables to point Boost.Build at your Python installation: + + + + + + + + + + +
    Variable Name Semantics Default Notes +
    PYTHON_ROOT + The root directory of your Python installation + Windows: c:/tools/python + Unix: /usr/local + On Unix, this is the --with-prefix= directory + used to configure Python + +
    PYTHON_VERSION + The The 2-part python Major.Minor version number + Windows: 2.1 + Unix: 1.5 + Be sure not to include a third number, e.g. not + "2.2.1", even if that's the version you + have. + +
    PYTHON_INCLUDES + path to Python #include directories + Autoconfigured from PYTHON_ROOT + +
    PYTHON_LIB_PATH + path to Python library object. + Autoconfigured from PYTHON_ROOT + +
    PYTHON_STDLIB_PATH + path to Python standard library modules + Autoconfigured from PYTHON_ROOT + +
    CYGWIN_ROOT + path to the user's Cygwin installation + + Cygwin only. This and the following two settings are + useful when building with multiple toolsets on Windows, since + Cygwin requires a different build of Python. + +
    GCC_PYTHON_ROOT + path to the user's Cygwin Python installation + $(CYGWIN_ROOT)/usr/local + Cygwin only + +
    GCC_DEBUG_PYTHON_ROOT + path to the user's Cygwin pydebug build + $(CYGWIN_ROOT)/usr/local/pydebug + Cygwin only + +
    + +

    Results

    +

    The build process will create a + libs/python/build/bin-stage subdirectory of the + boost root (or of $(ALL_LOCATE_TARGET), + if you have set that variable), containing the built + libraries. The libraries are actually built to unique + directories for each toolset and variant elsewhere in the + filesystem, and copied to the + bin-stage directory as a convenience, so if you + build with multiple toolsets at once, the product of later + toolsets will overwrite that of earlier toolsets in + bin-stage. + +

    Testing

    +

    To build and test Boost.Python from within the + libs/python/build directory, invoke +

    +
    +bjam -sTOOLS=toolset test
    +
    +
    +This will +update all of the Boost.Python v1 test and example targets. The tests +are relatively quiet by default. To get more-verbose output, you might try +
    +
    +bjam -sTOOLS=toolset -sPYTHON_TEST_ARGS=-v test
    +
    +
    +which will print each test's Python code with the expected output as +it passes. + +

    Building your Extension Module

    + + Though there are other approaches, the easiest way to build an + extension module using Boost.Python is with Boost.Build. Until + Boost.Build v2 is released, cross-project build dependencies are + not supported, so it works most smoothly if you add a new + subproject to your boost installation. The + libs/python/example subdirectory of your boost + installation contains a minimal example (along with many extra + sources). To copy the example subproject: + +
      +
    1. Create a new subdirectory in, libs/python, say + libs/python/my_project. + +
    2. Copy libs/python/example/Jamfile + to your new directory. + +
    3. Edit the Jamfile as appropriate for your project. You'll + want to change the "subproject" rule + invocation at the top, and the names of some of the source files + and/or targets. + +
    + + If you can't modify or copy your boost installation, the + alternative is to create your own Boost.Build project. A similar + example you can use as a starting point is available in this archive. You'll + need to edit the Jamfile and Jamrules files, depending on the + relative location of your Boost installation and the new + project. Note that automatic testing of extension modules is not + available in this configuration. + +

    Build Variants

    + + Three variant + configurations of all python-related targets are supported, and + can be selected by setting the BUILD + variable:
      -
    • The boost_python library for static linking with your - extension module. On the various Unices, this library will be - called libboost_python.a. When using Visual C++, the - library will be called boost_python.lib. +
    • release (optimization, -DNDEBUG) -

      -

    • A comprehensive test of Boost.Python features. This test builds - a Boost.Python extension module, then runs Python to import the - module, and runs a series of tests on it using doctest. Source code for the module - and tests is available in the Boost subdirectory - libs/python/test. +
    • debug (no optimization -D_DEBUG) -

      -

    • Various examples from the Boost subdirectory - libs/python/example. - All these examples include a doctest modeled - on the comprehensive test above. - -
    - -
    - There is a group of makefiles with support for simultaneous - compilation on multiple platforms and a consistent set of - features that build the boost_python library for static - linking, the comprehensive test, and all examples in - libs/python/example: - - - Usage of these makefiles is described here. - -
    - There is another group of makefiles for GNU make. - These makefiles are less redundant than the makefiles - in the group above, - but the list of compilation targets is not as complete - and there is no support for simultaneous compilation - on multiple platforms. - - - -
    - A project workspace for Microsoft Visual Studio is provided at libs/python/build/build.dsw. The - include paths for this project may need to be changed for your - installation. They currently assume that python has been installed at - c:\tools\python. Three configurations of all targets are - supported: - -
      -
    • Release (optimization, -DNDEBUG) - -
    • Debug (no optimization -D_DEBUG) - -
    • DebugPython (no optimization, -D_DEBUG +
    • debug-python (no optimization, -D_DEBUG -DBOOST_DEBUG_PYTHON)
    -

    When extension modules are built with Visual C++ using +

    The first two variants of the boost_python + library are built by default, and are compatible with the + default Python distribution. The debug-python + variant corresponds to a specially-built debugging version of + Python. On Unix platforms, this python is built by adding + --with-pydebug when configuring the Python + build. On Windows, the debugging version of Python is generated + by the "Win32 Debug" target of the + PCBuild.dsw Visual C++ 6.0 project in the + PCBuild subdirectory of your Python distribution. + + Extension modules built with Python debugging enabled are not + link-compatible with a non-debug build of Python. Since few + people actually have a debug build of Python (it doesn't come + with the standard distribution), the normal + debug variant builds modules which are compatible + with ordinary Python. + + +

    On many windows compilers, when extension modules are built + with -D_DEBUG, Python defaults to force linking with a special debugging version of the Python DLL. Since this debug DLL isn't supplied with the default Python installation for Windows, Boost.Python uses boost/python/detail/wrap_python.hpp to temporarily undefine _DEBUG when Python.h is - #included. + #included - unless BOOST_DEBUG_PYTHON is defined. -

    If you want the extra runtime checks available with the debugging - version of the library, #define BOOST_DEBUG_PYTHON to - re-enable library forcing, and link with the DebugPython version of - boost_python.lib. You'll need to get the debugging version - of the Python executable (python_d.exe) and DLL - (python20_d.dll or python15_d.dll). The Python - sources include project files for building these. If you download them, change the name of the - top-level directory to src, and install it under - c:\tools\python, the workspace supplied by Boost.Python will - be able to use it without modification. Just open - c:\tools\python\src\pcbuild\pcbuild.dsw and invoke "build - all" to generate all the debugging targets. +

    If you want the extra runtime checks available with the + debugging version of the library, #define + BOOST_DEBUG_PYTHON to re-enable python debuggin, and link + with the debug-python variant of + boost_python.

    If you do not #define BOOST_DEBUG_PYTHON, be sure that - any source files #include <#include <boost/python/detail/wrap_python.hpp> instead of the usual Python.h, or you will have link incompatibilities.
    -


    - If your platform isn't directly supported, you can build a static - library from the following source files (in the Boost subdirectory - libs/python/src), or compile them directly and link the - resulting objects into your extension module: - - -
    Next: Wrapping Enums Previous: A Peek Under the Hood Up: Top
    -

    © Copyright David Abrahams 2000. Permission to copy, use, modify, +

    © Copyright David Abrahams 2002. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided ``as is'' without express or implied warranty, and with no claim as to its suitability for any purpose. -

    Updated: Apr 17, 2001 (R.W. Grosse-Kunstleve) +

    Updated: May 15, 2002 (David Abrahams) diff --git a/doc/index.html b/doc/index.html index 3d5f66c3..fffe13e9 100644 --- a/doc/index.html +++ b/doc/index.html @@ -18,6 +18,21 @@ should simply ``reflect'' your C++ classes and functions into Python. +

    + + +
    Note: this is the last official release of +Boost.Python v1. Development of this version of the library has +stopped; it will be retired soon in favor of the redesigned and +improved version 2. A summary of the development goals is available on +the Python C++-sig +page, which also serves as a mailing list for users of both versions +of the library. A preview of the v2 documentation is available here, +and instructions for getting started with a prerelease are available +upon request. +
    +

    Supported Platforms

    Boost.Python is known to have been tested against Python 2.2.1 using diff --git a/example/Attic/project.zip b/example/Attic/project.zip new file mode 100644 index 0000000000000000000000000000000000000000..d863defdb784ca6864f83a6ca22443b65259bda6 GIT binary patch literal 1469 zcmWIWW@Zs#U|`^2aL-z=bNJRCn;-@ThExUy25|-khJvE}tkmQZ{iOW-;u77Y(#)I` zy{yFC;4lt758rb>t3xzAbWR3noDA1E=@II2>b$;QpoiAkGoFDO>vZ%y&pv%x^yxc4 zUnl>k@BD!qLN8pt%&yFu9jCV;DYheN#*RAAx;np&b}kpB7!c0*nYCVr<@xLNO-u|7 zuB;3U{7BC5O3Y2m%t>txiS@tjAW+jk<^Kk+Ul+V?bbRY|TC!w8Q-~ekh-xlMm~)Kl=XCCX%Bmwa zJ??+)J&)AN_8(iU8IzDV_4v92v(_w~TPV$OD&OGBa;Aste>_*2dg_PFg{y5cQ!%Rh;e%O!zHU z=F3kDH@6Qzefsy)th(=i|JmH!B-`b*$vxC-=A2VOmUAN>{}8zTWaDk!$KUtun%1&q|%IrgyH9vOj*qP|t9e>?k zFKqkgr&rZ)=3f@CZ~a^S+L2c_Zrg(XKX1?Vxa&_iygRr-^U9SUF(ID>E`5=h9~v2H z^Y8j1ZnYwte|bH}C*99faoZGAP~-2sW!0nU(Uph0k3XLozOVP?ksFmeq_%bC&wZlx z#<*WBw0E;HU#Oa(=H{Lbd1rAq{wp&~XO}0e=BVKH+tvNuB6N59$@3-acLx1=R(1St z&C%39I}|HonO-?@wsdOR1YDk~87f`weBlK5xqm--J!ejv{Cw-PmbIaqT=qWNSE$sR zZZk>ZT47qup$oiRUE+`U5y^FB)_R@1rIH!yj0_A985tM^P?Kv>X-;afYk+U|VFRAM z;=knOQZ{_O@MYg!w%t5#$7cO55ZZdNU`dkp%U|!))is&pb@uA-W!f6|AXBNo+`Q#t z@SVJEvzgqLW~}OOPfNKk8)5ZJw_4i9PwGOZHJ{3}p3qa)M+Hh1J``L`@Z(8e-}`w+ zOu}`Q+z*`BF7xi4?IFi|j=ktEFYiPJwZ>=D7$fs~L>5fipHV6?r=xoH_8i&c}HD)t{a<}NprJAG4!c6I;i(?P6q^Ws*&im0y- z4c#04)?z_I=HDBFdgp!#ah9!HeV(ObbNh~xzpu*oTdv+ZYgSUC<@wb<$24CU{Etw} zeeUqWA|P8Th<%qr^S>o0Ydo?ng}-Mn|NryDoT4?JW$l|{4{>p_9a#Q*{V+3R&c zGz@bf1!{mdBa;XN?jj4Mhmk>nVOt}Jg`)sNHUwLN1JVjHq#em>Xz_!r8C&!tG@CIa ticqh_TySE5=*I0&kZw>i`tR7yg3uk{&B_LnVPRll_{PA%u#pAC0|1J>SqlIF literal 0 HcmV?d00001 diff --git a/example/Jamfile b/example/Jamfile new file mode 100644 index 00000000..05b97e14 --- /dev/null +++ b/example/Jamfile @@ -0,0 +1,39 @@ +# Specify our location in the boost project hierarchy +subproject libs/python/example ; + +# Declares the following targets: +# +# 1. an extension module called "getting_started1", which is +# built from "getting_started1.cpp". Built by default +# +# 2. A test target called my-test.test which runs +# test_getting_started1.py with the extension module above. Built +# when out-of date, but only if invoked by name or if the global +# "test" target is invoked. +# +# 3. A test target called my-test.run wihch runs the above test +# unconditionally. Built only when invoked by name. +# +# To see verbose test output, add "-sPYTHON_TEST_ARGS=-v" to the bjam +# command-line before the first target. +# + +# Include definitions needed for Python modules +SEARCH on python.jam = $(BOOST_BUILD_PATH) ; +include python.jam ; + +# Declare a Python extension called getting_started1 +extension getting_started1 +: # sources + getting_started1.cpp + + # dependencies + ../build/boost_python + ; + +# Declare a test for the extension module +boost-python-runtest my-test + : # Python test driver + test_getting_started1.py + # extension modules to use + getting_started1 ; \ No newline at end of file diff --git a/example/README b/example/README index 817facd0..ef7dc78f 100644 --- a/example/README +++ b/example/README @@ -19,6 +19,3 @@ Examples for the cross-module support are provided by: ivect.cpp See also: libs/python/doc/cross_module.html -The files example1.cpp and rwgk1.cpp are obsolete. They are only -included because the Visual Studio project in the build directory still -refers to them. diff --git a/example/example1.cpp b/example/example1.cpp deleted file mode 100644 index 7bc5a1b7..00000000 --- a/example/example1.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include - -namespace hello { - class world - { - public: - world(int) {} - ~world() {} - const char* get() const { return "hi, world"; } - }; - - size_t length(const world& x) { return strlen(x.get()); } -} - -#include - -// Python requires an exported function called init in every -// extension module. This is where we build the module contents. -BOOST_PYTHON_MODULE_INIT(hello) -{ - // create an object representing this extension module - boost::python::module_builder hello("hello"); - - // Create the Python type object for our extension class - boost::python::class_builder world_class(hello, "world"); - - // Add the __init__ function - world_class.def(boost::python::constructor()); - // Add a regular member function - world_class.def(&hello::world::get, "get"); - - // Add a regular function to the module - hello.def(hello::length, "length"); -} - -// Win32 DLL boilerplate -#if defined(_WIN32) -#include -extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) -{ - return 1; -} -#endif // _WIN32 diff --git a/example/project.zip b/example/project.zip new file mode 100644 index 0000000000000000000000000000000000000000..d863defdb784ca6864f83a6ca22443b65259bda6 GIT binary patch literal 1469 zcmWIWW@Zs#U|`^2aL-z=bNJRCn;-@ThExUy25|-khJvE}tkmQZ{iOW-;u77Y(#)I` zy{yFC;4lt758rb>t3xzAbWR3noDA1E=@II2>b$;QpoiAkGoFDO>vZ%y&pv%x^yxc4 zUnl>k@BD!qLN8pt%&yFu9jCV;DYheN#*RAAx;np&b}kpB7!c0*nYCVr<@xLNO-u|7 zuB;3U{7BC5O3Y2m%t>txiS@tjAW+jk<^Kk+Ul+V?bbRY|TC!w8Q-~ekh-xlMm~)Kl=XCCX%Bmwa zJ??+)J&)AN_8(iU8IzDV_4v92v(_w~TPV$OD&OGBa;Aste>_*2dg_PFg{y5cQ!%Rh;e%O!zHU z=F3kDH@6Qzefsy)th(=i|JmH!B-`b*$vxC-=A2VOmUAN>{}8zTWaDk!$KUtun%1&q|%IrgyH9vOj*qP|t9e>?k zFKqkgr&rZ)=3f@CZ~a^S+L2c_Zrg(XKX1?Vxa&_iygRr-^U9SUF(ID>E`5=h9~v2H z^Y8j1ZnYwte|bH}C*99faoZGAP~-2sW!0nU(Uph0k3XLozOVP?ksFmeq_%bC&wZlx z#<*WBw0E;HU#Oa(=H{Lbd1rAq{wp&~XO}0e=BVKH+tvNuB6N59$@3-acLx1=R(1St z&C%39I}|HonO-?@wsdOR1YDk~87f`weBlK5xqm--J!ejv{Cw-PmbIaqT=qWNSE$sR zZZk>ZT47qup$oiRUE+`U5y^FB)_R@1rIH!yj0_A985tM^P?Kv>X-;afYk+U|VFRAM z;=knOQZ{_O@MYg!w%t5#$7cO55ZZdNU`dkp%U|!))is&pb@uA-W!f6|AXBNo+`Q#t z@SVJEvzgqLW~}OOPfNKk8)5ZJw_4i9PwGOZHJ{3}p3qa)M+Hh1J``L`@Z(8e-}`w+ zOu}`Q+z*`BF7xi4?IFi|j=ktEFYiPJwZ>=D7$fs~L>5fipHV6?r=xoH_8i&c}HD)t{a<}NprJAG4!c6I;i(?P6q^Ws*&im0y- z4c#04)?z_I=HDBFdgp!#ah9!HeV(ObbNh~xzpu*oTdv+ZYgSUC<@wb<$24CU{Etw} zeeUqWA|P8Th<%qr^S>o0Ydo?ng}-Mn|NryDoT4?JW$l|{4{>p_9a#Q*{V+3R&c zGz@bf1!{mdBa;XN?jj4Mhmk>nVOt}Jg`)sNHUwLN1JVjHq#em>Xz_!r8C&!tG@CIa ticqh_TySE5=*I0&kZw>i`tR7yg3uk{&B_LnVPRll_{PA%u#pAC0|1J>SqlIF literal 0 HcmV?d00001 diff --git a/example/rwgk1.cpp b/example/rwgk1.cpp deleted file mode 100644 index ca8bd22f..00000000 --- a/example/rwgk1.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include - -namespace { // Avoid cluttering the global namespace. - - // A couple of simple C++ functions that we want to expose to Python. - std::string greet() { return "hello, world"; } - int square(int number) { return number * number; } -} - -#include - -namespace python = boost::python; - -// Python requires an exported function called init in every -// extension module. This is where we build the module contents. -BOOST_PYTHON_MODULE_INIT(rwgk1) -{ - // Create an object representing this extension module. - python::module_builder this_module("rwgk1"); - - // Add regular functions to the module. - this_module.def(greet, "greet"); - this_module.def(square, "square"); -} diff --git a/include/boost/python/detail/pointee.hpp b/include/boost/python/detail/pointee.hpp new file mode 100644 index 00000000..2af1535f --- /dev/null +++ b/include/boost/python/detail/pointee.hpp @@ -0,0 +1,36 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef POINTEE_DWA2002323_HPP +# define POINTEE_DWA2002323_HPP + +# include + +namespace boost { namespace python { namespace detail { + +template +struct pointee_impl +{ + template struct apply : remove_pointer {}; +}; + +template <> +struct pointee_impl +{ + template struct apply + { + typedef typename T::element_type type; + }; +}; + +template +struct pointee + : pointee_impl::value>::template apply +{ +}; + +}}} // namespace boost::python::detail + +#endif // POINTEE_DWA2002323_HPP From 313fe2c76c7c2420192fc2911a56f19f9e0e96e3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 17 May 2002 05:01:53 +0000 Subject: [PATCH 0466/1042] input iterator support [SVN r13960] --- include/boost/python/object/iterator.hpp | 9 +++++ test/Jamfile | 2 +- test/input_iterator.cpp | 50 ++++++++++++++++++++++++ test/iterator.cpp | 2 +- test/iterator.py | 12 ++++++ 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 test/input_iterator.cpp diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 3207d1d4..35073438 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -96,6 +96,15 @@ namespace detail typename mpl::apply1::type cr; if (!cr.convertible()) return 0; + return cr(x); + } + template + static PyObject* convert_result(ValueType const& x) + { + typedef typename Policies::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + return cr(x); } }; diff --git a/test/Jamfile b/test/Jamfile index 96574a2f..bb0b6d82 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -65,7 +65,7 @@ bpl-test bienstman1 ; bpl-test bienstman2 ; bpl-test bienstman3 ; bpl-test multi_arg_constructor ; -bpl-test iterator ; +bpl-test iterator : iterator.py iterator.cpp input_iterator.cpp ; if $(TEST_BIENSTMAN_NON_BUGS) { diff --git a/test/input_iterator.cpp b/test/input_iterator.cpp new file mode 100644 index 00000000..005d393d --- /dev/null +++ b/test/input_iterator.cpp @@ -0,0 +1,50 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace boost::python; + +typedef std::list list_int; + +// Prove that we can handle InputIterators which return rvalues. This +// input iterator example was stolen from the iterator_adaptors +// documentation +typedef std::binder1st > doubler; +typedef boost::transform_iterator_generator::type doubling_iterator; +typedef std::pair list_range2; +list_range2 range2(list_int& x) +{ + return list_range2( + boost::make_transform_iterator(x.begin(), std::bind1st(std::multiplies(),2)) + , boost::make_transform_iterator(x.end(), std::bind1st(std::multiplies(),2))); +} + +// We do this in a separate module from iterators_ext (iterators.cpp) +// to work around an MSVC6 linker bug, which causes it to complain +// about a "duplicate comdat" if the input iterator is instantiated in +// the same module with the others. +BOOST_PYTHON_MODULE_INIT(input_iterator) +{ + module("input_iterator") + .def("range2", &::range2) + .add( + class_("list_range2") + + // We can wrap InputIterators which return by-value + .def("__iter__" + , range(&list_range2::first, &list_range2::second)) + ) + ; +} + +#include "module_tail.cpp" diff --git a/test/iterator.cpp b/test/iterator.cpp index 1ea2196b..aeb35648 100644 --- a/test/iterator.cpp +++ b/test/iterator.cpp @@ -14,12 +14,12 @@ #include #include - using namespace boost::python; typedef std::list list_int; typedef std::list list_list; + void push_back(list_int& x, int y) { x.push_back(y); diff --git a/test/iterator.py b/test/iterator.py index 4e6366ad..2f2f8e02 100644 --- a/test/iterator.py +++ b/test/iterator.py @@ -1,5 +1,6 @@ ''' >>> from iterator_ext import * +>>> from input_iterator import * >>> x = list_int() >>> x.push_back(1) >>> x.back() @@ -17,6 +18,17 @@ 1 3 5 + + Range2 wraps a transform_iterator which doubles the elements it + traverses. This proves we can wrap input iterators + +>>> z2 = range2(x) +>>> for y in z2: +... print y +2 +6 +10 + >>> l2 = two_lists() >>> for y in l2.primes: ... print y From 9baefc2e568f8747a72fce0aa5495d5f664903b0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 17 May 2002 05:02:44 +0000 Subject: [PATCH 0467/1042] Documentation updates [SVN r13961] --- doc/v2/errors.html | 6 +- doc/v2/iterator.html | 364 ++++++++++++++++++++++++++++++++++++++++++ doc/v2/module.html | 3 +- doc/v2/reference.html | 25 ++- 4 files changed, 393 insertions(+), 5 deletions(-) create mode 100644 doc/v2/iterator.html diff --git a/doc/v2/errors.html b/doc/v2/errors.html index 603bd28b..e36224fb 100644 --- a/doc/v2/errors.html +++ b/doc/v2/errors.html @@ -3,7 +3,7 @@ - Boost.Python - <{{header}}> + Boost.Python - <boost/python/errors.hpp> @@ -68,7 +68,7 @@ "http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred() returns a value convertible to true. -

    Class error_already_set synopsis

    +

    Class error_already_set synopsis

     namespace boost { namespace python
     {
    @@ -223,7 +223,7 @@ same_name2(PyObject* args, PyObject* keywords)
     
         

    Revised - 05 November, 2001 + 17 November, 2002 diff --git a/doc/v2/iterator.html b/doc/v2/iterator.html new file mode 100644 index 00000000..702d59d4 --- /dev/null +++ b/doc/v2/iterator.html @@ -0,0 +1,364 @@ + + + + + + Boost.Python - <{{header}}> + +

    + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/iterator.hpp>

    +
    +


    + +

    Contents

    + +
    +
    Introduction + +
    Classes + +
    +
    +
    Class template iterator + +
    +
    +
    Class + iterator synopsis + +
    Class template iterator + constructor +
    +
    + +
    +
    Class template iterators + +
    +
    +
    Class + iterators synopsis +
    Class template + iterators nested types +
    Class template + iterators static functions +
    +
    + +
    Functions + +
    +
    +
    range +
    + +
    Examples +
    +
    + +

    Introduction

    + +

    <boost/python/iterator.hpp> provides types + and functions for creating Python + iterators from C++ + Containers and Iterators. Note + that if your class_ supports random-access iterators, + implementing + __getitem__ + (also known as the Sequence Protocol) may serve you better than + using this facility: Python will automatically create an iterator + type for you (see iter()), + and each access can be range-checked, leaving no possiblity of + accessing through an invalidated C++ iterator. + +

    Classes

    + +

    Class Template iterator

    + +

    Instances of iterator<C,P> hold a reference + to a callable Python object which, when invoked from Python, + expects a single argument c convertible to + C and creates a Python iterator that traverses + [c.begin(), + c.end()). The optional CallPolicies + P can be used to control how elements are returned + during iteration. + +

    In the table below, c is an instance of Container. + + + + + +
    Template Parameter + + Requirements + + Semantics + + Default + +
    Container + + [c.begin(),c.end()) is a valid Iterator + range. + + The result will convert its argument to + c and call + c.begin() and c.end() to acquire + iterators. To invoke Container's + const begin() and end() + functions, make it const. + + +
    NextPolicies + + A default-constructible model of CallPolicies. + + Applied to the resulting iterators' next() method. + + An unspecified model of CallPolicies + which always makes a copy of the + result of deferencing the underlying C++ iterator + +
    + +

    Class Template iterator synopsis

    +
    +namespace boost { namespace python
    +{
    +  template <class Container
    +             , class NextPolicies = unspecified>
    +  struct iterator : reference<PyObject*>
    +  {
    +      iterator();
    +  };
    +}}
    +
    +

    Class Template + iterator constructor

    + +
    +iterator()
    +
    + +
    +
    Effects: Initializes its base class with the result + of: +
    +range<NextPolicies>(&iterators<Container>::begin, &iterators<Container>::end)
    +
    + +
    Postconditions: this->get() points to + a Python callable object which creates a Python iterator as + described above. + +
    Rationale: Provides an easy way to create iterators + for the common case where a C++ class being wrapped provides + begin() and end(). +
    + + + +

    Class Template iterators

    + +

    A utility class template which provides a way to reliably call + its argument's begin() and end() member + functions. Note that there is no portable way to take the address + of a member function of a C++ standard library container, so + iterators<> can be particularly helpful when + wrapping them. + + +

    In the table below, x is an instance of C. + + + + + +
    Required Valid Expression + + Type + +
    x.begin() + + Convertible to C::const_iterator if C is a + const type; convertible to C::iterator otherwise. + +
    x.end() + + Convertible to C::const_iterator if C is a + const type; convertible to C::iterator otherwise. + +
    + +

    Class Template iterators synopsis

    +
    +namespace boost { namespace python
    +{
    +  template <class C>
    +  struct iterators
    +  {
    +      typedef typename C::[const_]iterator iterator;
    +      static iterator begin(C& x);
    +      static iterator end(C& x);
    +  };
    +}}
    +
    +
    +

    Class Template + iterators nested types

    + +If C is a const type, +
    +typedef typename C::const_iterator iterator;
    +
    +Otherwise: +
    +typedef typename C::iterator iterator;
    +
    + +

    Class Template + iterators static functions

    + +
    +static iterator begin(C&);
    +
    + +
    +
    Returns: x.begin() +
    + +
    +static iterator end(C&);
    +
    + +
    +
    Returns: x.end() +
    + + + +

    Functions

    +
    +template <class NextPolicies, class Target, class Accessor1, class Accessor2>
    +reference<PyObject*> range(Accessor1 start, Accessor2 finish);
    +
    +template <class NextPolicies, class Accessor1, class Accessor2>
    +reference<PyObject*> range(Accessor1 start, Accessor2 finish);
    +
    +template <class Accessor1, class Accessor2>
    +reference<PyObject*> range(Accessor1 start, Accessor2 finish);
    +
    + +
    +
    Requires: NextPolicies is a + default-constructible model of CallPolicies. + +
    Effects:
    + +The first form creates a Python callable + object which, when invoked, converts its argument to a + Target object + x, and creates a Python iterator which traverses + [bind(start,_1)(x)bind(finish,_1)(x)), + applying NextPolicies to the iterator's + next() function. +
    +
    The second form is identical to + the first, except that Target is deduced from + Accessor1 as follows: +
      +
    1. If Accessor1 is a function type, + Target is the type of its first argument. +
    2. If Accessor1 is a data member pointer of the + form R (T::*), Target is + identical to T. +
    3. If Accessor1 is a member function pointer of + the form + R (T::*)(arguments...) cv-opt, + where cv-opt is an optional cv-qualifier, + Target is identical to T. +
    +
    + +
    The third form is identical to the second, except that + NextPolicies is an unspecified model of CallPolicies + which always makes a copy of the + result of deferencing the underlying C++ iterator
    +
    + + +
    Rationale: The use of boost::bind() allows + C++ iterators to be accessed through functions, member functions + or data member pointers. Customization of + NextPolicies (e.g. using return_internal_reference) is useful when it is + expensive to copy sequence elements of a wrapped class + type. Customization of Target is useful when + Accessor1 is a function object, or when a base + class of the intended target type would otherwise be deduced. +
    + +

    Examples

    + +
    +#include <boost/python/module.hpp>
    +#include <boost/python/class.hpp>
    +#include <boost/python/return_internal_reference.hpp>
    +#include <vector>
    +
    +using namespace boost::python;
    +BOOST_PYTHON_MODULE_INIT(demo)
    +{
    +   module m("demo")
    +      .add(
    +         class_<std::vector<double> >("dvec")
    +            .def("__iter__", iterator<std::vector<double> >())
    +            ...
    +         )
    +      ;
    +}
    +
    + +A more comprehensive example can be found in: +
    +
    libs/python/test/iterator.cpp
    +
    libs/python/test/input_iterator.cpp
    +
    libs/python/test/input_iterator.py
    + + +

    Revised + + 17 November, 2002 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + diff --git a/doc/v2/module.html b/doc/v2/module.html index 3775e4d1..3685934c 100644 --- a/doc/v2/module.html +++ b/doc/v2/module.html @@ -60,7 +60,8 @@

    Introduction

    -

    {{Introductory text}} +

    This header provides the basic facilities needed to create an + extension module.

    Macros

    diff --git a/doc/v2/reference.html b/doc/v2/reference.html index a05186c8..e79e0a45 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -24,6 +24,7 @@
    Concepts
    +
    CallPolicies
    Dereferenceable
    ResultConverter
    ResultConverterGenerator
    @@ -131,6 +132,28 @@
    + +
    iterator.hpp +
    +
    +
    Classes +
    +
    +
    iterator +
    iterators +
    + +
    Functions + +
    +
    +
    range +
    +
    +
    make_function.hpp
    @@ -143,7 +166,7 @@ "make_function.html#make_function-spec">make_function
    make_constructor + "make_function.html#make_constructor-spec">make_constructor
    From c928eded74ae5ba7dcb13d7434014ed6dd029472 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 17 May 2002 05:04:37 +0000 Subject: [PATCH 0468/1042] bugfix [SVN r13962] --- doc/v2/iterator.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/iterator.html b/doc/v2/iterator.html index 702d59d4..fd5a1bae 100644 --- a/doc/v2/iterator.html +++ b/doc/v2/iterator.html @@ -3,7 +3,7 @@ - Boost.Python - <{{header}}> + Boost.Python - <boost/python/iterator.hpp> From ba2f18ce21735e30de6575c291c9fec8650f0c52 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 19 May 2002 04:57:44 +0000 Subject: [PATCH 0469/1042] Lots of documentation updates, plus the associated code shuffling needed to expose the right things to users [SVN r13975] --- doc/v2/HolderGenerator.html | 71 ++ doc/v2/class.html | 6 +- doc/v2/errors.html | 17 +- doc/v2/instance_holder.html | 209 +++++ doc/v2/iterator.html | 2 +- doc/v2/make_function.html | 19 +- doc/v2/reference.html | 777 ++++++++++-------- doc/v2/return_value_policy.html | 2 +- doc/v2/type_id.html | 219 +++++ include/boost/python/class.hpp | 8 +- include/boost/python/converter/callback.hpp | 1 - .../boost/python/converter/from_python.hpp | 1 + .../converter/lvalue_from_python_chain.hpp | 4 +- .../converter/pointee_to_python_function.hpp | 1 - .../python/converter/pointer_type_id.hpp | 26 +- include/boost/python/converter/registry.hpp | 18 +- .../converter/rvalue_from_python_chain.hpp | 3 +- .../python/converter/to_python_function.hpp | 4 +- include/boost/python/converter/type_id.hpp | 176 ---- .../boost/python/detail/decorated_type_id.hpp | 77 ++ include/boost/python/implicit.hpp | 4 +- include/boost/python/instance_holder.hpp | 43 + include/boost/python/make_function.hpp | 12 +- include/boost/python/object/class.hpp | 34 +- include/boost/python/object/class_object.hpp | 6 +- include/boost/python/object/find_instance.hpp | 12 +- include/boost/python/object/inheritance.hpp | 16 +- .../boost/python/object/pointer_holder.hpp | 24 +- include/boost/python/object/value_holder.hpp | 16 +- include/boost/python/to_python_converter.hpp | 4 +- include/boost/python/to_python_value.hpp | 1 - include/boost/python/type_from_python.hpp | 5 +- include/boost/python/type_id.hpp | 102 +++ src/converter/builtin_converters.cpp | 5 +- src/converter/registry.cpp | 20 +- src/converter/type_id.cpp | 31 +- src/object/class.cpp | 467 +++++------ src/object/inheritance.cpp | 4 +- test/pointer_type_id_test.cpp | 6 +- test/select_from_python_test.cpp | 15 +- 40 files changed, 1555 insertions(+), 913 deletions(-) create mode 100755 doc/v2/HolderGenerator.html create mode 100755 doc/v2/instance_holder.html create mode 100755 doc/v2/type_id.html delete mode 100644 include/boost/python/converter/type_id.hpp create mode 100755 include/boost/python/detail/decorated_type_id.hpp create mode 100755 include/boost/python/instance_holder.hpp create mode 100755 include/boost/python/type_id.hpp diff --git a/doc/v2/HolderGenerator.html b/doc/v2/HolderGenerator.html new file mode 100755 index 00000000..1b9b8d89 --- /dev/null +++ b/doc/v2/HolderGenerator.html @@ -0,0 +1,71 @@ + + + + +Boost.Python - Holder Concept + + +
    + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    HolderGenerator Concept

    +
    +
    +
    +
    Introduction
    +
    Concept Requirements
    +
    +
    HolderGenerator Concept
    +
    +
    + +

    Introduction

    + +

    A HolderGenerator is a unary metafunction class which returns types +suitable for holding instances of its argument in a wrapped C++ class +instance. + +

    Concept Requirements

    +

    HolderGenerator Concept

    + +

    In the table below, G denotes an type which +models HolderGenerator, and X denotes a class +type. + + + + + + + + + + + +
    ExpressionRequirements
    G::apply<X>::typeA concrete subclass of instance_holder + which can hold objects of type X. +
    + +


    +

    Revised + + 20 May, 2002 + +

    +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + +

    Permission to copy, use, modify, sell + and distribute this software is granted provided this copyright notice appears + in all copies. This software is provided "as is" without express or implied + warranty, and with no claim as to its suitability for any purpose. + + diff --git a/doc/v2/class.html b/doc/v2/class.html index 1c84c1c2..fd2b1434 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -319,9 +319,9 @@ class_& def_init(Args const& argument_types, CallPolicies policies); make_constructor<Args,Holder>(policies), respectively, to the Boost.Python extension class being defined under the name - "__init__". Holder is a model of Holder which contains the - HeldType. If the extension class + "__init__". Holder is a concrete subclass of instance_holder + which holds the HeldType. If the extension class already has an "__init__" attribute, the usual overloading procedure applies. diff --git a/doc/v2/errors.html b/doc/v2/errors.html index e36224fb..6e364e8f 100644 --- a/doc/v2/errors.html +++ b/doc/v2/errors.html @@ -28,7 +28,7 @@

    -
    Class error_already_set +
    Class error_already_set
    @@ -44,6 +44,7 @@
    handle_exception
    expect_non_null +
    throw_error_already_set
    Examples @@ -117,9 +118,7 @@ void handle_exception() throw(); an enclosing try block.
    -PyObject* expect_non_null(PyObject* x);
    -
    -template <class T> T* expect_non_null(T* x);
    +template <class T> T* expect_non_null(T* x);
     
    @@ -135,6 +134,16 @@ template <class T> T* expect_non_null(T* x); return 0 on error.
    +
    +void throw_error_already_set();
    +
    + +
    + +
    Effects: throw error_already_set(); +
    +

    Examples

     #include <string>
    diff --git a/doc/v2/instance_holder.html b/doc/v2/instance_holder.html
    new file mode 100755
    index 00000000..5f5a751a
    --- /dev/null
    +++ b/doc/v2/instance_holder.html
    @@ -0,0 +1,209 @@
    +
    +
    +    
    +    
    +    
    +
    +    Boost.Python - <boost/python/instance_holder.hpp>
    +
    +
    +    
    +      
    +        
    +

    C++ Boost

    + +
    +

    Boost.Python

    + +

    Header <boost/python/instance_holder.hpp>

    +
    +
    + +

    Contents

    + +
    +
    Introduction + +
    Classes + +
    +
    +
    Class + instance_holder + +
    +
    +
    Class + instance_holder synopsis + +
    Class + instance_holder destructor + +
    Class + instance_holder modifier functions + +
    Class + instance_holder observer functions +
    +
    + +
    Example +
    +
    + +

    Introduction

    + +

    <boost/python/instance_holder.hpp> provides + class instance_holder, the base class for types + which hold C++ instances of wrapped classes. + +

    Classes

    + +

    Class instance_holder

    + +

    instance_holder is an abstract base class whose + concrete derived classes hold C++ class instances within their + Python object wrappers. To allow multiple inheritance in Python + from C++ class wrappers, each such Python object contains a chain + of instance_holders. When an __init__ + function for a wrapped C++ class is invoked, a new + instance_holder instance is created and installed in + the Python object using its install() + function. Each concrete class derived from + instance_holder must provide a holds() + implementation which allows Boost.Python to query it for the + type(s) it is holding. In order to support the held type's wrapped + constructor(s), the class must also provide constructors that can + accept an initial PyObject* argument referring to the + owning Python object, and which forward the rest of their + arguments to the constructor of the held type. The initial + argument is needed to enable virtual function overriding in + Python, and may be ignored, depending on the specific + instance_holder subclass. + +

    Class instance_holder + synopsis

    +
    +namespace boost { namespace python
    +{
    +  class instance_holder : noncopyable
    +  {
    +   public:
    +      // destructor
    +      virtual ~instance_holder();
    +
    +      // instance_holder modifiers
    +      void install(PyObject* inst) throw();
    +
    +      // instance_holder observers
    +      virtual void* holds(type_info) = 0;
    +  };
    +}}
    +
    + +

    Class instance_holder + destructor

    +
    +virtual ~instance_holder();
    +
    + +
    +
    Effects: destroys the object +
    + +

    Class + instance_holder modifiers

    +
    +void install(PyObject* inst) throw();
    +
    + +
    +
    Requires: inst is a Python instance of a + wrapped C++ class type, or is a type derived from a wrapped C++ + class type. +
    Effects: installs the new instance at the head of the + Python object's chain of held instances. +
    Throws: nothing +
    + +

    Class instance_holder + observers

    +
    +virtual void* holds(type_info x) = 0;
    +
    + +
    +
    Returns: A pointer to an object of the type described + by x if *this contains such an object, + 0 otherwise. +
    + +

    Example

    + +The following is a simplified version of the instance holder template +used by Boost.Python to wrap classes held by smart pointers: +
    +template <class SmartPtr, class Value>
    +struct pointer_holder : instance_holder
    +{
    +   // construct from the SmartPtr type
    +   pointer_holder(SmartPtr p)
    +       :m_p(p)
    +
    +   // Forwarding constructors for the held type
    +   pointer_holder(PyObject*)
    +       :m_p(new Value())
    +   {
    +   }
    +
    +   template<class A0>
    +   pointer_holder(PyObject*,A0 a0)
    +       :m_p(new Value(a0))
    +   {
    +   }
    +
    +   template<class A0,class A1>
    +   pointer_holder(PyObject*,A0 a0,A1 a1)
    +       :m_p(new Value(a0,a1))
    +   {
    +   }
    +   ...
    +
    + private: // required holder implementation
    +   void* holds(type_info dst_t)
    +   {
    +       // holds an instance of the SmartPtr type...
    +       if (dst_t == python::type_id<SmartPtr>())
    +           return &this->m_p;
    +
    +       // ...and an instance of the SmartPtr's element_type, if the
    +       // pointer is non-null
    +       return python::type_id<Value>() == dst_t ? &*this->m_p : 0;
    +   }
    +
    + private: // data members
    +   SmartPtr m_p;
    +};
    +
    + +

    Revised + + 19 November, 2002 + + + +

    © Copyright Dave Abrahams 2002. All + Rights Reserved. + diff --git a/doc/v2/iterator.html b/doc/v2/iterator.html index fd5a1bae..944ccd29 100644 --- a/doc/v2/iterator.html +++ b/doc/v2/iterator.html @@ -95,7 +95,7 @@ C and creates a Python iterator that traverses [c.begin(), c.end()). The optional CallPolicies + href="CallPolicies.html">CallPolicies P can be used to control how elements are returned during iteration. diff --git a/doc/v2/make_function.html b/doc/v2/make_function.html index f3189672..c31144c9 100644 --- a/doc/v2/make_function.html +++ b/doc/v2/make_function.html @@ -78,12 +78,17 @@ objects::function* make_function(F f, Policies const& policies) template <class T, class ArgList, class Generator> objects::function* make_constructor(); + +template <class ArgList, class Generator, class Policies> +objects::function* make_constructor(Policies const& policies)

    -
    Requires: T is a class type. ArgList - is an MPL sequence of C++ - argument types (A1, A2,... AN) such that if +
    Requires: T is a class + type. Policies is a model of CallPolicies. ArgList + is an MPL sequence + of C++ argument types (A1, A2,... AN) such that if a1, a2... aN are objects of type A1, A2,... AN respectively, the expression new Generator::apply<T>::type(a1, a2... aN) is @@ -94,8 +99,12 @@ objects::function* make_constructor(); from Python, expects its first argument to be a Boost.Python extension class object. It converts its remaining its arguments to C++ and passes them to the constructor of a dynamically-allocated - Generator::apply<T>::type object. The result is - installed in the extension class object. + Generator::apply<T>::type object, which is + then installed in the extension class object. In the second + form, the policies are applied to the arguments and + result (None) + of the Python callable object
    Returns: The new Python callable object
    diff --git a/doc/v2/reference.html b/doc/v2/reference.html index e79e0a45..71191cee 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -1,21 +1,29 @@ + - + Boost.Python - Reference + - +
    -

    -

    +

    C++ Boost +

    -

    Boost.Python

    +

    Boost.Python

    -

    Reference

    +

    Reference


    @@ -23,209 +31,227 @@
    Concepts -
    -
    CallPolicies
    -
    Dereferenceable
    -
    ResultConverter
    -
    ResultConverterGenerator
    -
    High Level Components -
    Models of CallPolicies +
    Function Invocation and Creation -
    Models of ReturnHandlerGenerator +
    +
    +
    Models of + CallPolicies + +
    Models of + ResultConverterGenerator +
    To/From Python Type Conversion -
    Index By Name -
    - +
    Utility and Infrastructure -

    High Level Components

    +
    +
    + + +

    Concepts

    +
    +
    CallPolicies + +
    Dereferenceable + +
    HolderGenerator + +
    ResultConverter + +
    ResultConverterGenerator +
    + +

    High Level Components

    + +
    +
    class.hpp/class_fwd.hpp + +
    +
    +
    Classes + +
    +
    +
    class_ + +
    bases + +
    args +
    +
    + +
    errors.hpp + +
    +
    +
    Classes + +
    +
    +
    error_already_set +
    + +
    Functions + +
    +
    +
    handle_exception + +
    expect_non_null +
    +
    + +
    iterator.hpp + +
    +
    +
    Classes + +
    +
    +
    iterator + +
    iterators +
    + +
    Functions + +
    +
    +
    range +
    +
    + +
    module.hpp + +
    +
    +
    Classes + +
    +
    +
    module +
    +
    + +
    objects.hpp + +
    +
    +
    Classes + +
    +
    +
    not yet + documented +
    +
    +
    + +

    Function Invocation and Creation

    +
    call.hpp +
    - - -

    General Purpose

    -
    - -
    call.hpp -
    -
    -
    Functions - -
    -
    -
    call -
    -
    - -
    call_method.hpp -
    -
    -
    Functions - -
    -
    -
    call_method -
    -
    - -
    class.hpp/class_fwd.hpp +
    Functions
    -
    Classes - -
    -
    -
    class_ - -
    bases - -
    args -
    -
    - -
    data_members.hpp - -
    -
    -
    Functions - -
    -
    -
    make_getter - -
    make_setter -
    -
    - -
    errors.hpp - -
    -
    -
    Classes - -
    -
    -
    error_already_set -
    - -
    Functions - -
    -
    -
    handle_exception - -
    expect_non_null -
    -
    - - -
    iterator.hpp -
    -
    -
    Classes -
    -
    -
    iterator -
    iterators -
    - -
    Functions - -
    -
    -
    range -
    -
    - -
    make_function.hpp - -
    -
    -
    Functions - -
    -
    -
    make_function - -
    make_constructor -
    -
    - -
    module.hpp - -
    -
    -
    Classes - -
    -
    -
    module -
    -
    - -
    objects.hpp - -
    -
    -
    Classes - -
    -
    -
    not yet documented -
    -
    - -
    pointee.hpp -
    -
    -
    Classes - -
    -
    -
    class template pointee -
    -
    - -
    reference.hpp -
    -
    -
    Classes - -
    -
    -
    reference -
    - -
    Types - -
    -
    -
    ref -
    +
    call
    +
    call_method.hpp - +
    +
    +
    Functions + +
    +
    +
    call_method +
    +
    + +
    data_members.hpp + +
    +
    +
    Functions + +
    +
    +
    make_getter + +
    make_setter +
    +
    + +
    make_function.hpp + +
    +
    +
    Functions + +
    +
    +
    make_function + +
    make_constructor +
    +
    + +
    ptr.hpp + +
    +
    +
    Functions + +
    +
    +
    ptr +
    + +
    Classes + +
    +
    +
    pointer_wrapper +
    + +
    MetaFunctions + +
    +
    +
    is_pointer_wrapper + +
    unwrap_pointer +
    +
    +

    Models of CallPolicies

    @@ -235,15 +261,18 @@
    -
    Classes +
    Classes
    -
    default_call_policies +
    + default_call_policies -
    default_result_converter +
    + default_result_converter
    @@ -252,25 +281,28 @@
    -
    Classes +
    Classes
    -
    return_internal_reference
    -
    return_value_policy.hpp +
    return_value_policy.hpp
    -
    Classes +
    Classes
    -
    return_value_policy
    @@ -280,34 +312,39 @@
    -
    Classes +
    Classes
    -
    with_custodian_and_ward +
    + with_custodian_and_ward -
    with_custodian_and_ward_postcall
    - + -

    Models of ReturnHandlerGenerator

    +

    Models of ResultConverterGenerator

    -
    copy_const_reference.hpp +
    copy_const_reference.hpp
    -
    Classes +
    Classes
    -
    copy_const_reference +
    + copy_const_reference
    @@ -316,17 +353,19 @@
    -
    Classes +
    Classes
    -
    copy_non_const_reference
    -
    manage_new_object.hpp +
    manage_new_object.hpp
    @@ -334,7 +373,7 @@
    -
    manage_new_object
    @@ -344,11 +383,12 @@
    -
    Classes +
    Classes
    -
    reference_existing_object
    @@ -363,7 +403,7 @@
    -
    reference_from_python
    +
    - +

    To/From Python Type + Conversion

    -

    To/From Python Type Conversion

    +
    +
    from_python.hpp +
    -
    from_python.hpp +
    Classes
    -
    Classes - -
    -
    -
    from_python -
    -
    - -
    has_back_reference.hpp -
    -
    -
    Classes -
    -
    -
    has_back_reference -
    - -
    - - -
    implicit.hpp -
    -
    -
    Functions - -
    -
    -
    implicitly_convertible -
    -
    - -
    ptr.hpp - -
    -
    -
    Functions -
    -
    -
    ptr -
    - -
    Classes -
    -
    -
    pointer_wrapper -
    - -
    MetaFunctions -
    -
    -
    is_pointer_wrapper -
    unwrap_pointer -
    - -
    - -
    to_python_converter.hpp - -
    -
    -
    Classes - -
    -
    -
    to_python_converter -
    -
    - -
    to_python_indirect.hpp - -
    -
    -
    Classes - -
    -
    -
    to_python_indirect -
    -
    - -
    to_python_value.hpp - -
    -
    -
    Classes - -
    -
    -
    to_python_value -
    -
    - -
    type_from_python.hpp - -
    -
    -
    Classes - -
    -
    -
    type_from_python -
    -
    - -
    value_from_python.hpp - -
    -
    -
    Classes - -
    -
    -
    value_from_python -
    +
    from_python
    +
    implicit.hpp + +
    +
    +
    Functions + +
    +
    +
    implicitly_convertible +
    +
    + +
    to_python_converter.hpp + +
    +
    +
    Classes + +
    +
    +
    to_python_converter +
    +
    + +
    to_python_indirect.hpp + +
    +
    +
    Classes + +
    +
    +
    to_python_indirect +
    +
    + +
    to_python_value.hpp + +
    +
    +
    Classes + +
    +
    +
    to_python_value +
    +
    + +
    type_from_python.hpp + +
    +
    +
    Classes + +
    +
    +
    type_from_python +
    +
    + +
    value_from_python.hpp + +
    +
    +
    Classes + +
    +
    +
    value_from_python +
    +
    +
    + +

    Utility and Infrastructure

    + +
    +
    has_back_reference.hpp + +
    +
    +
    Classes + +
    +
    +
    has_back_reference +
    +
    + +
    instance_holder.hpp + +
    +
    +
    Classes + +
    +
    +
    + instance_holder +
    +
    + +
    pointee.hpp + +
    +
    +
    Classes + +
    +
    +
    class template pointee +
    +
    + +
    reference.hpp + +
    +
    +
    Classes + +
    +
    +
    reference +
    + +
    Types + +
    +
    +
    ref +
    +
    + +
    type_id.hpp + +
    +
    +
    Functions + +
    +
    +
    type_id +
    + +
    Classes + +
    +
    +
    type_info +
    +

    @@ -514,6 +602,7 @@ -

    © Copyright Dave - Abrahams 2002. All Rights Reserved. +

    © Copyright Dave Abrahams 2002. All + Rights Reserved. diff --git a/doc/v2/return_value_policy.html b/doc/v2/return_value_policy.html index 950b024b..88a72a0c 100644 --- a/doc/v2/return_value_policy.html +++ b/doc/v2/return_value_policy.html @@ -69,7 +69,7 @@ Default - ResultConverterGenerator + ResultConverterGenerator A model of ResultConverterGenerator. diff --git a/doc/v2/type_id.html b/doc/v2/type_id.html new file mode 100755 index 00000000..6407f913 --- /dev/null +++ b/doc/v2/type_id.html @@ -0,0 +1,219 @@ + + + + + + + Boost.Python - <boost/python/type_id.hpp> + + + + +
    +

    C++ Boost

    + +
    +

    Boost.Python

    + +

    Header <boost/python/type_id.hpp>

    +
    +


    + +

    Contents

    + +
    +
    Introduction + +
    Classes + +
    +
    +
    Class + type_info + +
    +
    +
    Class + type_info synopsis + +
    Class + type_info constructor + +
    Class + type_info comparison functions + +
    Class + type_info observer functions +
    +
    + +
    Functions + +
    +
    +
    type_id +
    + +
    Example +
    +
    + +

    Introduction

    + +

    <boost/python/type_id.hpp> provides types and + functions for runtime type identification like those of of + <typeinfo>. It exists mostly to work around + certain compiler bugs and platform-dependent interactions with + shared libraries. + +

    Classes

    + +

    Class type_info

    + +

    type_info instances identify a type. As + std::type_info is specified to (but unlike its + implementation in some compilers), + boost::python::type_info never represents top-level + references or cv-qualification (see section 5.2.8 in the C++ + standard). Unlike std::type_info, + boost::python::type_info instances are copyable, and + comparisons always work reliably across shared library boundaries. + +

    Class type_info + synopsis

    +
    +namespace boost { namespace python
    +{
    +  class type_info : totally_ordered<type_info>
    +  {
    +   public:
    +      // constructor
    +      type_info(std::type_info const& = typeid(void));
    +
    +      // comparisons
    +      bool operator<(type_info const& rhs) const;
    +      bool operator==(type_info const& rhs) const;
    +
    +      // observers
    +      char const* name() const;
    +  };
    +}}
    +
    + +

    Class type_info + constructor

    +
    +type_info(std::type_info const& = typeid(void));
    +
    + +
    +
    Effects: constructs a type_info object + which identifies the same type as its argument. + +
    Rationale: Since it is occasionally neccessary to make + an array of type_info objects a benign default + argument is supplied. Note: this + constructor does not correct for non-conformance of + compiler typeid() implementations. See type_id, below. +
    + +

    Class + type_info comparisons

    +
    +bool operator<(type_info const& rhs) const;
    +
    + +
    +
    Effects: yields a total order over + type_info objects. +
    +
    +bool operator==(type_info const& rhs) const;
    +
    + +
    +
    Returns: true iff the two values describe + the same type. +
    + +
    +
    Note: The use of totally_ordered<type_info> + as a private base class supplies operators <=, + >=, >, and != +
    + +

    Class type_info + observers

    +
    +char const* name() const;
    +
    + +
    +
    Returns: The result of calling name() on + the argument used to construct the object. +
    + +

    Functions

    +
    +std::ostream& operator<<(std::ostream&s, type_info const&x);
    +
    + +
    +
    Effects: Writes a description of the type described by + to x into s. + +
    Rationale: Not every C++ implementation provides a + truly human-readable type_info::name() string, but + for some we may be able to decode the string and produce a + reasonable representation. +
    +
    +template <class T> type_info type_id()
    +
    + +
    +
    Returns: type_info(typeid(T)) + +
    Note: On some non-conforming C++ implementations, the + code is not actually as simple as described above; the semantics + are adjusted to work as-if the C++ implementation were + conforming. +
    + +

    Example

    + The following example, though silly, illustrates how the + type_id facility might be used +
    +#include <boost/python/type_id.hpp>
    +
    +// Returns true iff the user passes an int argument
    +template <class T>
    +bool is_int(T x)
    +{
    +   using boost::python::type_id;
    +   return type_id<T>() == type_id<int>();
    +}
    +
    + +

    Revised + + 18 November, 2002 + + + +

    © Copyright Dave Abrahams 2002. All + Rights Reserved. + diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 16f6a4cf..50afba85 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -11,7 +11,7 @@ # include # include # include -# include +# include # include # include # include @@ -194,7 +194,7 @@ class class_ : public objects::class_base id_vector() { // Stick the derived class id into the first element of the array - ids[0] = converter::undecorated_type_id(); + ids[0] = type_id(); // Write the rest of the elements into succeeding positions. class_id* p = ids + 1; @@ -276,9 +276,9 @@ namespace detail typedef void type; // Here's the runtime behavior - static void execute(converter::undecorated_type_id_t** p) + static void execute(type_info** p) { - *(*p)++ = converter::undecorated_type_id(); + *(*p)++ = type_id(); } }; }; diff --git a/include/boost/python/converter/callback.hpp b/include/boost/python/converter/callback.hpp index 9e9c694f..ae399eed 100644 --- a/include/boost/python/converter/callback.hpp +++ b/include/boost/python/converter/callback.hpp @@ -6,7 +6,6 @@ #ifndef CALLBACK_DWA2002228_HPP # define CALLBACK_DWA2002228_HPP -# include # include # include # include diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index 40a75645..12740439 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -8,6 +8,7 @@ # include # include +# include # include # include # include diff --git a/include/boost/python/converter/lvalue_from_python_chain.hpp b/include/boost/python/converter/lvalue_from_python_chain.hpp index 2a86bcfa..7a064841 100644 --- a/include/boost/python/converter/lvalue_from_python_chain.hpp +++ b/include/boost/python/converter/lvalue_from_python_chain.hpp @@ -6,9 +6,11 @@ #ifndef LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP # define LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP +# include # include # include # include +# include namespace boost { namespace python { namespace converter { @@ -39,7 +41,7 @@ namespace detail template lvalue_from_python_registration*const& ref_lvalue_from_python_chain::value - = registry::lvalue_converters(undecorated_type_id()); + = registry::lvalue_converters(type_id()); template struct select_lvalue_from_python_chain diff --git a/include/boost/python/converter/pointee_to_python_function.hpp b/include/boost/python/converter/pointee_to_python_function.hpp index 0f1ae99e..039914a9 100644 --- a/include/boost/python/converter/pointee_to_python_function.hpp +++ b/include/boost/python/converter/pointee_to_python_function.hpp @@ -9,7 +9,6 @@ # include # include # include -# include # include # include # include diff --git a/include/boost/python/converter/pointer_type_id.hpp b/include/boost/python/converter/pointer_type_id.hpp index 79a30b02..01e55977 100644 --- a/include/boost/python/converter/pointer_type_id.hpp +++ b/include/boost/python/converter/pointer_type_id.hpp @@ -6,7 +6,7 @@ #ifndef POINTER_TYPE_ID_DWA2002222_HPP # define POINTER_TYPE_ID_DWA2002222_HPP -# include +# include # include namespace boost { namespace python { namespace converter { @@ -17,9 +17,9 @@ namespace detail struct pointer_typeid_select { template - static inline undecorated_type_id_t execute(T*(*)() = 0) + static inline type_info execute(T*(*)() = 0) { - return undecorated_type_id(); + return type_id(); } }; @@ -27,37 +27,37 @@ namespace detail struct pointer_typeid_select { template - static inline undecorated_type_id_t execute(T* const volatile&(*)() = 0) + static inline type_info execute(T* const volatile&(*)() = 0) { - return undecorated_type_id(); + return type_id(); } template - static inline undecorated_type_id_t execute(T*volatile&(*)() = 0) + static inline type_info execute(T*volatile&(*)() = 0) { - return undecorated_type_id(); + return type_id(); } template - static inline undecorated_type_id_t execute(T*const&(*)() = 0) + static inline type_info execute(T*const&(*)() = 0) { - return undecorated_type_id(); + return type_id(); } template - static inline undecorated_type_id_t execute(T*&(*)() = 0) + static inline type_info execute(T*&(*)() = 0) { - return undecorated_type_id(); + return type_id(); } }; } // Usage: pointer_type_id() // -// Returns an undecorated_type_id_t associated with the type pointed +// Returns a type_info associated with the type pointed // to by T, which may be a pointer or a reference to a pointer. template -undecorated_type_id_t pointer_type_id(T(*)() = 0) +type_info pointer_type_id(T(*)() = 0) { return detail::pointer_typeid_select< is_reference::value diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index 72676605..cf5daa5e 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -5,7 +5,7 @@ // to its suitability for any purpose. #ifndef REGISTRY_DWA20011127_HPP # define REGISTRY_DWA20011127_HPP -# include +# include # include # include # include @@ -19,22 +19,22 @@ struct rvalue_from_python_registration; // This namespace acts as a sort of singleton namespace registry { - BOOST_PYTHON_DECL lvalue_from_python_registration*& lvalue_converters(undecorated_type_id_t); - BOOST_PYTHON_DECL rvalue_from_python_registration*& rvalue_converters(undecorated_type_id_t); + BOOST_PYTHON_DECL lvalue_from_python_registration*& lvalue_converters(type_info); + BOOST_PYTHON_DECL rvalue_from_python_registration*& rvalue_converters(type_info); BOOST_PYTHON_DECL to_python_function_t const& - get_to_python_function(undecorated_type_id_t); + get_to_python_function(type_info); - BOOST_PYTHON_DECL void insert(to_python_function_t, undecorated_type_id_t); + BOOST_PYTHON_DECL void insert(to_python_function_t, type_info); // Insert an lvalue from_python converter - BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), undecorated_type_id_t); + BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), type_info); // Insert an rvalue from_python converter BOOST_PYTHON_DECL void insert( void* (*convertible)(PyObject*) , constructor_function - , undecorated_type_id_t + , type_info ); // Insert an rvalue from_python converter at the tail of the @@ -42,10 +42,10 @@ namespace registry BOOST_PYTHON_DECL void push_back( void* (*convertible)(PyObject*) , constructor_function - , undecorated_type_id_t + , type_info ); - BOOST_PYTHON_DECL PyTypeObject*& class_object(undecorated_type_id_t key); + BOOST_PYTHON_DECL PyTypeObject*& class_object(type_info key); } }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/rvalue_from_python_chain.hpp b/include/boost/python/converter/rvalue_from_python_chain.hpp index c57ef564..4576e7fc 100644 --- a/include/boost/python/converter/rvalue_from_python_chain.hpp +++ b/include/boost/python/converter/rvalue_from_python_chain.hpp @@ -5,6 +5,7 @@ // to its suitability for any purpose. #ifndef RVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP # define RVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP +# include # include # include # include @@ -21,7 +22,7 @@ namespace detail template rvalue_from_python_registration*const& rvalue_from_python_chain_impl::value - = registry::rvalue_converters(undecorated_type_id()); + = registry::rvalue_converters(type_id()); } template diff --git a/include/boost/python/converter/to_python_function.hpp b/include/boost/python/converter/to_python_function.hpp index ff3891e2..0112463e 100644 --- a/include/boost/python/converter/to_python_function.hpp +++ b/include/boost/python/converter/to_python_function.hpp @@ -9,7 +9,7 @@ # include # include # include -# include +# include # include # include @@ -32,7 +32,7 @@ namespace detail template to_python_function_t const& to_python_function_base::value - = converter::registry::get_to_python_function(undecorated_type_id()); + = converter::registry::get_to_python_function(type_id()); } template diff --git a/include/boost/python/converter/type_id.hpp b/include/boost/python/converter/type_id.hpp deleted file mode 100644 index 015e55e9..00000000 --- a/include/boost/python/converter/type_id.hpp +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TYPE_ID_DWA20011127_HPP -# define TYPE_ID_DWA20011127_HPP -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - - -namespace boost { namespace python { namespace converter { - -// for this compiler at least, cross-shared-library type_info -// comparisons don't work, so use typeid(x).name() instead. It's not -// yet clear what the best default strategy is. -# if defined(__GNUC__) && __GNUC__ >= 3 -# define BOOST_PYTHON_TYPE_ID_NAME -# endif - -// type ids which represent the same information as std::type_info -// (i.e. the top-level reference and cv-qualifiers are stripped), but -// which works across shared libraries. -struct undecorated_type_id_t : totally_ordered -{ - undecorated_type_id_t(std::type_info const&); - - // default constructor needed to build arrays, etc. - undecorated_type_id_t(); - - bool operator<(undecorated_type_id_t const& rhs) const; - bool operator==(undecorated_type_id_t const& rhs) const; - - char const* name() const; - friend BOOST_PYTHON_DECL std::ostream& operator<<( - std::ostream&, undecorated_type_id_t const&); - - private: // data members -# ifdef BOOST_PYTHON_TYPE_ID_NAME - typedef char const* base_id_t; -# else - typedef std::type_info const* base_id_t; -# endif - - base_id_t m_base_type; -}; - -struct type_id_t : totally_ordered -{ - enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 }; - - type_id_t(undecorated_type_id_t, decoration = decoration()); - - bool operator<(type_id_t const& rhs) const; - bool operator==(type_id_t const& rhs) const; - - friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&); - - operator undecorated_type_id_t const&() const; - private: // type - typedef undecorated_type_id_t base_id_t; - - private: // data members - decoration m_decoration; - base_id_t m_base_type; -}; - -template -inline undecorated_type_id_t undecorated_type_id(boost::type* = 0) -{ - return undecorated_type_id_t( -# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) - typeid(T) -# else // strip the decoration which msvc and Intel mistakenly leave in - python::detail::msvc_typeid() -# endif - ); -} - -template -inline type_id_t type_id(boost::type* = 0) -{ - return type_id_t( - undecorated_type_id() - , type_id_t::decoration( - (is_const::value || python::detail::is_reference_to_const::value - ? type_id_t::const_ : 0) - | (is_volatile::value || python::detail::is_reference_to_volatile::value - ? type_id_t::volatile_ : 0) - | (is_reference::value ? type_id_t::reference : 0) - ) - ); -} - -inline undecorated_type_id_t::undecorated_type_id_t(std::type_info const& id) - : m_base_type( -# ifdef BOOST_PYTHON_TYPE_ID_NAME - id.name() -# else - &id -# endif - ) -{ -} - -inline undecorated_type_id_t::undecorated_type_id_t() - : m_base_type() -{ -} - -inline type_id_t::type_id_t(undecorated_type_id_t base_t, decoration decoration) - : m_decoration(decoration) - , m_base_type(base_t) -{ -} - -inline bool undecorated_type_id_t::operator<(undecorated_type_id_t const& rhs) const -{ -# ifdef BOOST_PYTHON_TYPE_ID_NAME - return std::strcmp(m_base_type, rhs.m_base_type) < 0; -# else - return m_base_type->before(*rhs.m_base_type); -# endif -} - -inline bool type_id_t::operator<(type_id_t const& rhs) const -{ - return m_decoration < rhs.m_decoration - || m_decoration == rhs.m_decoration - && m_base_type < rhs.m_base_type; -} - -inline bool undecorated_type_id_t::operator==(undecorated_type_id_t const& rhs) const -{ -# ifdef BOOST_PYTHON_TYPE_ID_NAME - return !std::strcmp(m_base_type, rhs.m_base_type); -# else - return *m_base_type == *rhs.m_base_type; -# endif -} - -inline bool type_id_t::operator==(type_id_t const& rhs) const -{ - return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type; -} - -inline type_id_t::operator undecorated_type_id_t const&() const -{ - return m_base_type; -} - -inline char const* undecorated_type_id_t::name() const -{ -# ifdef BOOST_PYTHON_TYPE_ID_NAME - return m_base_type; -# else - return m_base_type->name(); -# endif -} - - -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, undecorated_type_id_t const&); -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_id_t const&); - -}}} // namespace boost::python::converter - -#endif // TYPE_ID_DWA20011127_HPP diff --git a/include/boost/python/detail/decorated_type_id.hpp b/include/boost/python/detail/decorated_type_id.hpp new file mode 100755 index 00000000..f70e369a --- /dev/null +++ b/include/boost/python/detail/decorated_type_id.hpp @@ -0,0 +1,77 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef DECORATED_TYPE_ID_DWA2002517_HPP +# define DECORATED_TYPE_ID_DWA2002517_HPP + +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +struct decorated_type_info : totally_ordered +{ + enum decoration { const_ = 0x1, volatile_ = 0x2, reference = 0x4 }; + + decorated_type_info(type_info, decoration = decoration()); + + bool operator<(decorated_type_info const& rhs) const; + bool operator==(decorated_type_info const& rhs) const; + + friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&); + + operator type_info const&() const; + private: // type + typedef type_info base_id_t; + + private: // data members + decoration m_decoration; + base_id_t m_base_type; +}; + +template +inline decorated_type_info decorated_type_id(boost::type* = 0) +{ + return decorated_type_info( + type_id() + , decorated_type_info::decoration( + (is_const::value || python::detail::is_reference_to_const::value + ? decorated_type_info::const_ : 0) + | (is_volatile::value || python::detail::is_reference_to_volatile::value + ? decorated_type_info::volatile_ : 0) + | (is_reference::value ? decorated_type_info::reference : 0) + ) + ); +} + +inline decorated_type_info::decorated_type_info(type_info base_t, decoration decoration) + : m_decoration(decoration) + , m_base_type(base_t) +{ +} + +inline bool decorated_type_info::operator<(decorated_type_info const& rhs) const +{ + return m_decoration < rhs.m_decoration + || m_decoration == rhs.m_decoration + && m_base_type < rhs.m_base_type; +} + +inline bool decorated_type_info::operator==(decorated_type_info const& rhs) const +{ + return m_decoration == rhs.m_decoration && m_base_type == rhs.m_base_type; +} + +inline decorated_type_info::operator type_info const&() const +{ + return m_base_type; +} + +BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&); + +}}} // namespace boost::python::detail + +#endif // DECORATED_TYPE_ID_DWA2002517_HPP diff --git a/include/boost/python/implicit.hpp b/include/boost/python/implicit.hpp index f7146e40..a6e73eba 100644 --- a/include/boost/python/implicit.hpp +++ b/include/boost/python/implicit.hpp @@ -8,7 +8,7 @@ # include # include # include -# include +# include namespace boost { namespace python { @@ -20,7 +20,7 @@ void implicitly_convertible(boost::type* = 0, boost::type* = 0) converter::registry::push_back( &functions::convertible , &functions::construct - , converter::undecorated_type_id()); + , type_id()); } }} // namespace boost::python diff --git a/include/boost/python/instance_holder.hpp b/include/boost/python/instance_holder.hpp new file mode 100755 index 00000000..eb148431 --- /dev/null +++ b/include/boost/python/instance_holder.hpp @@ -0,0 +1,43 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef INSTANCE_HOLDER_DWA2002517_HPP +# define INSTANCE_HOLDER_DWA2002517_HPP + +# include +# include + +namespace boost { namespace python { + +// Base class for all holders +struct BOOST_PYTHON_DECL instance_holder : private noncopyable +{ + public: + instance_holder(); + virtual ~instance_holder(); + + // return the next holder in a chain + instance_holder* next() const; + + virtual void* holds(type_info) = 0; + + void install(PyObject* inst) throw(); + private: + instance_holder* m_next; +}; +// This macro is needed for implementation of derived holders +# define BOOST_PYTHON_UNFORWARD(N,ignored) (typename unforward::type)(a##N) + +// +// implementation +// +inline instance_holder* instance_holder::next() const +{ + return m_next; +} + +}} // namespace boost::python + +#endif // INSTANCE_HOLDER_DWA2002517_HPP diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index 5ce5ec7d..47579fd5 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -35,8 +35,8 @@ objects::function* make_function(F f, Policies const& policies) , detail::arg_tuple_size::value); } -template -objects::function* make_constructor(Holder* = 0, ArgList* = 0) +template +objects::function* make_constructor(HolderGenerator* = 0, ArgList* = 0) { enum { nargs = mpl::size::value }; @@ -44,13 +44,13 @@ objects::function* make_constructor(Holder* = 0, ArgList* = 0) objects::py_function( ::boost::bind(detail::caller(), objects::make_holder - ::template apply::execute + ::template apply::execute , _1, _2, default_call_policies())) , nargs + 1); } -template -objects::function* make_constructor(Policies const& policies, Holder* = 0, ArgList* = 0) +template +objects::function* make_constructor(Policies const& policies, HolderGenerator* = 0, ArgList* = 0) { enum { nargs = mpl::size::value }; @@ -58,7 +58,7 @@ objects::function* make_constructor(Policies const& policies, Holder* = 0, ArgLi objects::py_function( ::boost::bind(detail::caller(), objects::make_holder - ::template apply::execute + ::template apply::execute , _1, _2, policies)) , nargs + 1); } diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 4d8d3bbe..466b6e44 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -9,8 +9,9 @@ # include # include # include -# include +# include # include +# include # include namespace boost { namespace python { @@ -19,10 +20,8 @@ class module; namespace objects { -template struct holder; - // To identify a class, we don't need cv/reference decorations -typedef converter::undecorated_type_id_t class_id; +typedef type_info class_id; struct BOOST_PYTHON_DECL class_base : private noncopyable { @@ -46,25 +45,6 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable BOOST_PYTHON_DECL ref registered_class_object(class_id id); -// Base class for all holders -struct BOOST_PYTHON_DECL instance_holder : private noncopyable -{ - public: - instance_holder(); - virtual ~instance_holder(); - - // return the next holder in a chain - instance_holder* next() const; - - virtual void* holds(converter::undecorated_type_id_t) = 0; - - void install(PyObject* inst) throw(); - private: - instance_holder* m_next; -}; -// This macro is needed for implementation of derived holders -# define BOOST_PYTHON_UNFORWARD(N,ignored) (typename unforward::type)(a##N) - // Each extension instance will be one of these struct instance { @@ -75,14 +55,6 @@ struct instance BOOST_PYTHON_DECL ref class_metatype(); BOOST_PYTHON_DECL ref class_type(); -// -// implementation -// -inline instance_holder* instance_holder::next() const -{ - return m_next; -} - }}} // namespace boost::python::objects #endif // CLASS_DWA20011214_HPP diff --git a/include/boost/python/object/class_object.hpp b/include/boost/python/object/class_object.hpp index 76960762..57a8ee5d 100644 --- a/include/boost/python/object/class_object.hpp +++ b/include/boost/python/object/class_object.hpp @@ -6,7 +6,7 @@ #ifndef CLASS_OBJECT_DWA200222_HPP # define CLASS_OBJECT_DWA200222_HPP -# include +# include # include namespace boost { namespace python { namespace objects { @@ -18,8 +18,8 @@ struct class_object }; template -PyTypeObject*& class_object::reference = converter::registry::class_object( - converter::undecorated_type_id()); +PyTypeObject*& class_object::reference + = converter::registry::class_object(python::type_id()); }}} // namespace boost::python::objects diff --git a/include/boost/python/object/find_instance.hpp b/include/boost/python/object/find_instance.hpp index 3db670fc..44c79550 100644 --- a/include/boost/python/object/find_instance.hpp +++ b/include/boost/python/object/find_instance.hpp @@ -6,14 +6,14 @@ #ifndef FIND_INSTANCE_DWA2002312_HPP # define FIND_INSTANCE_DWA2002312_HPP -# include +# include # include namespace boost { namespace python { namespace objects { -// Given an undecorated type_id, find the instance data which -// corresponds to it, or return 0 in case no such type is held. -BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::undecorated_type_id_t); +// Given a type_id, find the instance data which corresponds to it, or +// return 0 in case no such type is held. +BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, type_info); // This produces a function with the right signature for use in from_python conversions template @@ -21,14 +21,14 @@ struct instance_finder { instance_finder() { - converter::registry::insert(&execute, converter::undecorated_type_id()); + converter::registry::insert(&execute, python::type_id()); } static instance_finder const registration; private: static inline void* execute(PyObject* p) { - return find_instance_impl(p, converter::undecorated_type_id()); + return find_instance_impl(p, python::type_id()); } }; diff --git a/include/boost/python/object/inheritance.hpp b/include/boost/python/object/inheritance.hpp index ceeac8f9..5129e35e 100644 --- a/include/boost/python/object/inheritance.hpp +++ b/include/boost/python/object/inheritance.hpp @@ -6,13 +6,15 @@ #ifndef INHERITANCE_DWA200216_HPP # define INHERITANCE_DWA200216_HPP -# include +# include # include +# include +# include namespace boost { namespace python { namespace objects { -typedef converter::undecorated_type_id_t class_id; -using converter::undecorated_type_id; +typedef type_info class_id; +using python::type_id; // Types used to get address and id of most derived type typedef std::pair dynamic_id_t; @@ -70,7 +72,7 @@ struct non_polymorphic_id_generator { static dynamic_id_t execute(void* p_) { - return std::make_pair(p_, converter::undecorated_type_id()); + return std::make_pair(p_, python::type_id()); } }; @@ -91,7 +93,7 @@ void register_dynamic_id(T* = 0) { typedef typename dynamic_id_generator::type generator; register_dynamic_id_aux( - converter::undecorated_type_id(), &generator::execute); + python::type_id(), &generator::execute); } // @@ -154,8 +156,8 @@ inline void register_conversion( { typedef typename cast_generator::type generator; - add_cast(converter::undecorated_type_id() - , converter::undecorated_type_id() + add_cast(python::type_id() + , python::type_id() , &generator::execute , is_downcast); } diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index c3bffa2c..6d0ef81c 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -7,7 +7,7 @@ # define POINTER_HOLDER_DWA20011215_HPP # include -# include +# include # include # include # include @@ -46,7 +46,7 @@ struct pointer_holder : instance_holder BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER,nil) private: // required holder implementation - void* holds(converter::undecorated_type_id_t); + void* holds(type_info); private: // data members Pointer m_p; @@ -84,45 +84,45 @@ struct pointer_holder_back_reference : instance_holder BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER_BACK_REFERENCE,nil) private: // required holder implementation - void* holds(converter::undecorated_type_id_t); + void* holds(type_info); private: // data members Pointer m_p; }; template -pointer_holder::pointer_holder(Pointer p) +inline pointer_holder::pointer_holder(Pointer p) : m_p(p) { } template -pointer_holder_back_reference::pointer_holder_back_reference(Pointer p) +inline pointer_holder_back_reference::pointer_holder_back_reference(Pointer p) : m_p(p) { } template -void* pointer_holder::holds(converter::undecorated_type_id_t dst_t) +void* pointer_holder::holds(type_info dst_t) { - if (dst_t == converter::undecorated_type_id()) + if (dst_t == python::type_id()) return &this->m_p; - converter::type_id_t src_t = converter::undecorated_type_id(); + type_info src_t = python::type_id(); return src_t == dst_t ? &*this->m_p : find_dynamic_type(&*this->m_p, src_t, dst_t); } template -void* pointer_holder_back_reference::holds(converter::undecorated_type_id_t dst_t) +void* pointer_holder_back_reference::holds(type_info dst_t) { - if (dst_t == converter::undecorated_type_id()) + if (dst_t == python::type_id()) return &this->m_p; - if (dst_t == converter::undecorated_type_id()) + if (dst_t == python::type_id()) return &*this->m_p; - converter::type_id_t src_t = converter::undecorated_type_id(); + type_info src_t = python::type_id(); Value* p = &*this->m_p; return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t); } diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 49251921..3543d61b 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -8,7 +8,7 @@ # include # include -# include +# include # include # include # include @@ -40,7 +40,7 @@ struct value_holder : instance_holder BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER,nil) private: // required holder implementation - void* holds(converter::undecorated_type_id_t); + void* holds(type_info); private: // data members Held m_held; @@ -72,32 +72,32 @@ struct value_holder_back_reference : instance_holder BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER_BACK_REFERENCE,nil) private: // required holder implementation - void* holds(converter::undecorated_type_id_t); + void* holds(type_info); private: // data members BackReferenceType m_held; }; template -void* value_holder::holds(converter::undecorated_type_id_t dst_t) +void* value_holder::holds(type_info dst_t) { - converter::undecorated_type_id_t src_t = converter::undecorated_type_id(); + type_info src_t = python::type_id(); return src_t == dst_t ? &m_held : find_static_type(&m_held, src_t, dst_t); } template void* value_holder_back_reference::holds( - converter::undecorated_type_id_t dst_t) + type_info dst_t) { - converter::undecorated_type_id_t src_t = converter::undecorated_type_id(); + type_info src_t = python::type_id(); if (src_t == dst_t) { Held* x = &m_held; return x; } - src_t = converter::undecorated_type_id(); + src_t = python::type_id(); return src_t == dst_t ? &m_held : find_static_type(&m_held, src_t, dst_t); diff --git a/include/boost/python/to_python_converter.hpp b/include/boost/python/to_python_converter.hpp index 47473419..f5155e58 100644 --- a/include/boost/python/to_python_converter.hpp +++ b/include/boost/python/to_python_converter.hpp @@ -8,7 +8,7 @@ # include # include -# include +# include namespace boost { namespace python { @@ -31,7 +31,7 @@ to_python_converter::to_python_converter() converter::registry::insert( &normalized::convert - , converter::undecorated_type_id()); + , type_id()); } }} // namespace boost::python diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp index ffb68ada..8f3b0e22 100644 --- a/include/boost/python/to_python_value.hpp +++ b/include/boost/python/to_python_value.hpp @@ -7,7 +7,6 @@ # define TO_PYTHON_VALUE_DWA200221_HPP # include -# include # include # include # include diff --git a/include/boost/python/type_from_python.hpp b/include/boost/python/type_from_python.hpp index 38d2ceea..9fcd1f8f 100644 --- a/include/boost/python/type_from_python.hpp +++ b/include/boost/python/type_from_python.hpp @@ -6,6 +6,7 @@ #ifndef TYPE_FROM_PYTHON_DWA2002130_HPP # define TYPE_FROM_PYTHON_DWA2002130_HPP +# include # include # include @@ -16,9 +17,9 @@ namespace detail // Given a pointer-to-function of 1 parameter returning a reference // type, return the type_id of the function's return type. template - inline converter::undecorated_type_id_t extractor_type_id(T&(*)(U)) + inline type_info extractor_type_id(T&(*)(U)) { - return converter::undecorated_type_id(); + return type_id(); } // A function generator whose static execute() function is an lvalue diff --git a/include/boost/python/type_id.hpp b/include/boost/python/type_id.hpp new file mode 100755 index 00000000..fbceec66 --- /dev/null +++ b/include/boost/python/type_id.hpp @@ -0,0 +1,102 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TYPE_ID_DWA2002517_HPP +# define TYPE_ID_DWA2002517_HPP + +# include +# include +# include +# include + +namespace boost { namespace python { + +// for this compiler at least, cross-shared-library type_info +// comparisons don't work, so use typeid(x).name() instead. It's not +// yet clear what the best default strategy is. +# if defined(__GNUC__) && __GNUC__ >= 3 +# define BOOST_PYTHON_TYPE_ID_NAME +# endif + +// type ids which represent the same information as std::type_info +// (i.e. the top-level reference and cv-qualifiers are stripped), but +// which works across shared libraries. +struct type_info : private totally_ordered +{ + type_info(std::type_info const& = typeid(void)); + + bool operator<(type_info const& rhs) const; + bool operator==(type_info const& rhs) const; + + char const* name() const; + friend BOOST_PYTHON_DECL std::ostream& operator<<( + std::ostream&, type_info const&); + + private: // data members +# ifdef BOOST_PYTHON_TYPE_ID_NAME + typedef char const* base_id_t; +# else + typedef std::type_info const* base_id_t; +# endif + + base_id_t m_base_type; +}; + +template +inline type_info type_id(boost::type* = 0) +{ + return type_info( +# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) + typeid(T) +# else // strip the decoration which msvc and Intel mistakenly leave in + python::detail::msvc_typeid() +# endif + ); +} + +inline type_info::type_info(std::type_info const& id) + : m_base_type( +# ifdef BOOST_PYTHON_TYPE_ID_NAME + id.name() +# else + &id +# endif + ) +{ +} + +inline bool type_info::operator<(type_info const& rhs) const +{ +# ifdef BOOST_PYTHON_TYPE_ID_NAME + return std::strcmp(m_base_type, rhs.m_base_type) < 0; +# else + return m_base_type->before(*rhs.m_base_type); +# endif +} + +inline bool type_info::operator==(type_info const& rhs) const +{ +# ifdef BOOST_PYTHON_TYPE_ID_NAME + return !std::strcmp(m_base_type, rhs.m_base_type); +# else + return *m_base_type == *rhs.m_base_type; +# endif +} + +inline char const* type_info::name() const +{ +# ifdef BOOST_PYTHON_TYPE_ID_NAME + return m_base_type; +# else + return m_base_type->name(); +# endif +} + + +BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, type_info const&); + +}} // namespace boost::python + +#endif // TYPE_ID_DWA2002517_HPP diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index cad00ba5..f0aa9b7c 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,7 @@ namespace registry::insert( &slot_rvalue_from_python::convertible , &slot_rvalue_from_python::construct - , undecorated_type_id() + , type_id() ); } @@ -280,7 +281,7 @@ void initialize_builtin_converters() slot_rvalue_from_python,complex_rvalue_from_python>(); // Add an lvalue converter for char which gets us char const* - registry::insert(convert_to_cstring,undecorated_type_id()); + registry::insert(convert_to_cstring,type_id()); // Register by-value converters to std::string slot_rvalue_from_python(); diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index 822812e3..3e0afdc2 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -30,7 +30,7 @@ namespace // PyTypeObject* m_class_object; }; - typedef std::map registry_t; + typedef std::map registry_t; registry_t& entries() { @@ -50,7 +50,7 @@ namespace // return registry; } - entry* find(undecorated_type_id_t type) + entry* find(type_info type) { return &entries()[type]; } @@ -67,12 +67,12 @@ namespace // namespace registry { to_python_function_t const& get_to_python_function( - undecorated_type_id_t key) + type_info key) { return find(key)->m_to_python_converter; } - void insert(to_python_function_t f, undecorated_type_id_t source_t) + void insert(to_python_function_t f, type_info source_t) { to_python_function_t& slot = find(source_t)->m_to_python_converter; assert(slot == 0); // we have a problem otherwise @@ -85,7 +85,7 @@ namespace registry } // Insert an lvalue from_python converter - void insert(void* (*convert)(PyObject*), undecorated_type_id_t key) + void insert(void* (*convert)(PyObject*), type_info key) { entry* found = find(key); lvalue_from_python_registration *registration = new lvalue_from_python_registration; @@ -99,7 +99,7 @@ namespace registry // Insert an rvalue from_python converter void insert(void* (*convertible)(PyObject*) , constructor_function construct - , undecorated_type_id_t key) + , type_info key) { entry* found = find(key); rvalue_from_python_registration *registration = new rvalue_from_python_registration; @@ -112,7 +112,7 @@ namespace registry // Insert an rvalue from_python converter void push_back(void* (*convertible)(PyObject*) , constructor_function construct - , undecorated_type_id_t key) + , type_info key) { rvalue_from_python_registration** found = &find(key)->m_rvalue_from_python; while (*found != 0) @@ -125,17 +125,17 @@ namespace registry *found = registration; } - PyTypeObject*& class_object(undecorated_type_id_t key) + PyTypeObject*& class_object(type_info key) { return find(key)->m_class_object; } - lvalue_from_python_registration*& lvalue_converters(undecorated_type_id_t key) + lvalue_from_python_registration*& lvalue_converters(type_info key) { return find(key)->m_lvalue_from_python; } - rvalue_from_python_registration*& rvalue_converters(undecorated_type_id_t key) + rvalue_from_python_registration*& rvalue_converters(type_info key) { return find(key)->m_rvalue_from_python; } diff --git a/src/converter/type_id.cpp b/src/converter/type_id.cpp index 904f30d0..74bcd39b 100644 --- a/src/converter/type_id.cpp +++ b/src/converter/type_id.cpp @@ -4,30 +4,33 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include #if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT # include #else # include #endif -namespace boost { namespace python { namespace converter { +namespace boost { namespace python { -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, undecorated_type_id_t const& x) +BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_info const& x) { return os << x.name(); } -BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_id_t const& x) +namespace detail { - os << x.m_base_type; - if (x.m_decoration & type_id_t::const_) - os << " const"; - if (x.m_decoration & type_id_t::volatile_) - os << " volatile"; - if (x.m_decoration & type_id_t::reference) - os << "&"; - return os; + BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, detail::decorated_type_info const& x) + { + os << x.m_base_type; + if (x.m_decoration & decorated_type_info::const_) + os << " const"; + if (x.m_decoration & decorated_type_info::volatile_) + os << " volatile"; + if (x.m_decoration & decorated_type_info::reference) + os << "&"; + return os; + } } - -}}} // namespace boost::python::converter +}} // namespace boost::python::converter diff --git a/src/object/class.cpp b/src/object/class.cpp index 2e1dca89..85fcb7d7 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -12,7 +12,7 @@ #include #include -namespace boost { namespace python { namespace objects { +namespace boost { namespace python { instance_holder::instance_holder() : m_next(0) @@ -35,269 +35,272 @@ type_is_gc(PyTypeObject *python_type) return python_type->tp_flags & Py_TPFLAGS_HEAPTYPE; } -PyTypeObject class_metatype_object = { +static PyTypeObject class_metatype_object = { PyObject_HEAD_INIT(0)//&PyType_Type) - 0, - "Boost.Python.class", - PyType_Type.tp_basicsize, - 0, - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + 0, + "Boost.Python.class", + PyType_Type.tp_basicsize, + 0, + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, //&PyType_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, // filled in with type_new /* tp_new */ - 0, // filled in with __PyObject_GC_Del /* tp_free */ - (inquiry)type_is_gc, /* tp_is_gc */ + | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, //&PyType_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, // filled in with type_new /* tp_new */ + 0, // filled in with __PyObject_GC_Del /* tp_free */ + (inquiry)type_is_gc, /* tp_is_gc */ }; -// Get the metatype object for all extension classes. -BOOST_PYTHON_DECL ref class_metatype() -{ - if (class_metatype_object.tp_dict == 0) - { - class_metatype_object.ob_type = &PyType_Type; - class_metatype_object.tp_base = &PyType_Type; - if (PyType_Ready(&class_metatype_object)) - return ref(); - } - return ref((PyObject*)&class_metatype_object, ref::increment_count); -} - -extern "C" -{ - static void instance_dealloc(PyObject* inst) - { - instance* kill_me = (instance*)inst; - - for (instance_holder* p = kill_me->objects, *next; p != 0; p = next) - { - next = p->next(); - delete p; - } - - inst->ob_type->tp_free(inst); - } -} - -// Do we really need this? I'm beginning to think we don't! -PyTypeObject class_type_object = { - PyObject_HEAD_INIT(0) //&class_metatype_object) - 0, - "Boost.Python.instance", - sizeof(instance), - 0, - instance_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, //&PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew -}; - -BOOST_PYTHON_DECL ref class_type() -{ - if (class_type_object.tp_dict == 0) - { - class_type_object.ob_type = (PyTypeObject*)class_metatype().release(); - class_type_object.tp_base = &PyBaseObject_Type; - if (PyType_Ready(&class_type_object)) - return ref(); - } - return ref((PyObject*)&class_type_object, ref::increment_count); -} - // Install the instance data for a C++ object into a Python instance // object. void instance_holder::install(PyObject* self) throw() { assert(self->ob_type->ob_type == &class_metatype_object); - m_next = ((instance*)self)->objects; - ((instance*)self)->objects = this; + m_next = ((objects::instance*)self)->objects; + ((objects::instance*)self)->objects = this; } -BOOST_PYTHON_DECL void* -find_instance_impl(PyObject* inst, converter::undecorated_type_id_t type) -{ - if (inst->ob_type->ob_type != &class_metatype_object) - return 0; - - instance* self = reinterpret_cast(inst); - for (instance_holder* match = self->objects; match != 0; match = match->next()) - { - void* const found = match->holds(type); - if (found) - return found; - } - return 0; -} - -namespace +namespace objects { - struct class_registry +// Get the metatype object for all extension classes. + BOOST_PYTHON_DECL ref class_metatype() { - public: - ref get(class_id id) const; - ref query(class_id id) const; - void set(class_id, ref class_object); - private: - typedef detail::map_entry entry; - std::vector m_impl; + if (class_metatype_object.tp_dict == 0) + { + class_metatype_object.ob_type = &PyType_Type; + class_metatype_object.tp_base = &PyType_Type; + if (PyType_Ready(&class_metatype_object)) + return ref(); + } + return ref((PyObject*)&class_metatype_object, ref::increment_count); + } + extern "C" + { + static void instance_dealloc(PyObject* inst) + { + instance* kill_me = (instance*)inst; + + for (instance_holder* p = kill_me->objects, *next; p != 0; p = next) + { + next = p->next(); + delete p; + } + + inst->ob_type->tp_free(inst); + } + } + + + static PyTypeObject class_type_object = { + PyObject_HEAD_INIT(0) //&class_metatype_object) + 0, + "Boost.Python.instance", + sizeof(instance), + 0, + instance_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC + | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, //&PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew }; - class_registry& registry() + BOOST_PYTHON_DECL ref class_type() { - static class_registry x; - return x; - } - - inline ref class_registry::query(class_id id) const - { - std::vector::const_iterator start = m_impl.begin(); - std::vector::const_iterator finish = m_impl.end(); - - std::vector::const_iterator p - = boost::detail::lower_bound(start, finish, id); - - return (p == finish || p->key != id) ? ref() : p->value; - } - - inline ref class_registry::get(class_id id) const - { - ref result(this->query(id)); - - if (result.get() == 0) + if (class_type_object.tp_dict == 0) { - string report("extension class wrapper for base class "); - (report += id.name()) += " has not been created yet"; - PyErr_SetObject(PyExc_RuntimeError, report.get()); - throw_error_already_set(); + class_type_object.ob_type = (PyTypeObject*)class_metatype().release(); + class_type_object.tp_base = &PyBaseObject_Type; + if (PyType_Ready(&class_type_object)) + return ref(); } - return result; + return ref((PyObject*)&class_type_object, ref::increment_count); } - inline void class_registry::set(class_id id, ref object) + BOOST_PYTHON_DECL void* + find_instance_impl(PyObject* inst, type_info type) { - std::vector::iterator start = m_impl.begin(); - std::vector::iterator finish = m_impl.end(); - m_impl.insert( - boost::detail::lower_bound(start, finish, id) - , entry(id, object)); - converter::registry::class_object(id) = (PyTypeObject*)object.get(); + if (inst->ob_type->ob_type != &class_metatype_object) + return 0; + + instance* self = reinterpret_cast(inst); + + for (instance_holder* match = self->objects; match != 0; match = match->next()) + { + void* const found = match->holds(type); + if (found) + return found; + } + return 0; } -} -class_base::class_base( - char const* name, std::size_t num_types, class_id const* const types) -{ - class_registry& r = registry(); - assert(num_types >= 1); - tuple bases(std::max(num_types - 1, static_cast(1))); - if (num_types > 1) + namespace + { + struct class_registry { - for (std::size_t i = 1; i < num_types; ++i) - bases.set_item(i - 1, r.get(types[i])); - } - else + public: + ref get(class_id id) const; + ref query(class_id id) const; + void set(class_id, ref class_object); + private: + typedef detail::map_entry entry; + std::vector m_impl; + }; + + class_registry& registry() { - bases.set_item(0, class_type()); + static class_registry x; + return x; } + + inline ref class_registry::query(class_id id) const + { + std::vector::const_iterator start = m_impl.begin(); + std::vector::const_iterator finish = m_impl.end(); + + std::vector::const_iterator p + = boost::detail::lower_bound(start, finish, id); + + return (p == finish || p->key != id) ? ref() : p->value; + } + + inline ref class_registry::get(class_id id) const + { + ref result(this->query(id)); + + if (result.get() == 0) + { + string report("extension class wrapper for base class "); + (report += id.name()) += " has not been created yet"; + PyErr_SetObject(PyExc_RuntimeError, report.get()); + throw_error_already_set(); + } + return result; + } + + inline void class_registry::set(class_id id, ref object) + { + std::vector::iterator start = m_impl.begin(); + std::vector::iterator finish = m_impl.end(); + m_impl.insert( + boost::detail::lower_bound(start, finish, id) + , entry(id, object)); + converter::registry::class_object(id) = (PyTypeObject*)object.get(); + } + } + + class_base::class_base( + char const* name, std::size_t num_types, class_id const* const types) + { + class_registry& r = registry(); + assert(num_types >= 1); + tuple bases(std::max(num_types - 1, static_cast(1))); + if (num_types > 1) + { + for (std::size_t i = 1; i < num_types; ++i) + bases.set_item(i - 1, r.get(types[i])); + } + else + { + bases.set_item(0, class_type()); + } - tuple args(3); - args.set_item(0, string(name).reference()); - args.set_item(1, bases.reference()); - args.set_item(2, dictionary().reference()); + tuple args(3); + args.set_item(0, string(name).reference()); + args.set_item(1, bases.reference()); + args.set_item(2, dictionary().reference()); - m_object = ref(PyObject_CallObject(class_metatype().get(), args.get())); - r.set(types[0], m_object); -} + m_object = ref(PyObject_CallObject(class_metatype().get(), args.get())); + r.set(types[0], m_object); + } -extern "C" -{ - // This declaration needed due to broken Python 2.2 headers - extern DL_IMPORT(PyTypeObject) PyProperty_Type; -} + extern "C" + { + // This declaration needed due to broken Python 2.2 headers + extern DL_IMPORT(PyTypeObject) PyProperty_Type; + } -void class_base::add_property(char const* name, ref const& fget) -{ - ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.get())); - setattr(name, property); -} + void class_base::add_property(char const* name, ref const& fget) + { + ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.get())); + setattr(name, property); + } -void class_base::add_property(char const* name, ref const& fget, ref const& fset) -{ - ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.get(), fset.get())); - setattr(name, property); -} + void class_base::add_property(char const* name, ref const& fget, ref const& fset) + { + ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.get(), fset.get())); + setattr(name, property); + } -void class_base::setattr(char const* name, ref const& x) -{ - if (PyObject_SetAttrString(object().get(), const_cast(name), x.get()) < 0) - throw_error_already_set(); -} + void class_base::setattr(char const* name, ref const& x) + { + if (PyObject_SetAttrString(object().get(), const_cast(name), x.get()) < 0) + throw_error_already_set(); + } -BOOST_PYTHON_DECL ref registered_class_object(class_id id) -{ - return registry().query(id); -} + BOOST_PYTHON_DECL ref registered_class_object(class_id id) + { + return registry().query(id); + } +} // namespace objects -}}} // namespace boost::python::objects +}} // namespace boost::python diff --git a/src/object/inheritance.cpp b/src/object/inheritance.cpp index 91a37f02..6725b95d 100644 --- a/src/object/inheritance.cpp +++ b/src/object/inheritance.cpp @@ -4,7 +4,7 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #include -#include +#include #include #include #include @@ -45,7 +45,7 @@ namespace // Here we put together the low-level data structures of the // casting graph representation. // - typedef python::converter::undecorated_type_id_t class_id; + typedef python::type_info class_id; // represents a graph of available casts diff --git a/test/pointer_type_id_test.cpp b/test/pointer_type_id_test.cpp index 24035709..e3314e0b 100644 --- a/test/pointer_type_id_test.cpp +++ b/test/pointer_type_id_test.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -6,8 +6,8 @@ int main() { using namespace boost::python::converter; - undecorated_type_id_t x - = undecorated_type_id(); + boost::python::type_info x + = boost::python::type_id(); assert(pointer_type_id() == x); diff --git a/test/select_from_python_test.cpp b/test/select_from_python_test.cpp index 7063767e..b5648447 100644 --- a/test/select_from_python_test.cpp +++ b/test/select_from_python_test.cpp @@ -1,15 +1,22 @@ #include -//#include -//#include -#include +#include #include +#if defined(__GNUC__) && __GNUC__ < 3 // 2.95.x linker seems to demand this definition +namespace boost { namespace python { +BOOST_PYTHON_DECL bool handle_exception_impl(function0) +{ + return true; +} +}} +#endif + int result; #define ASSERT_SAME(T1,T2) \ if (!is_same< T1, T2 >::value) { \ std::cout << "*********************\n"; \ - std::cout << type_id< T1 >() << " != " << type_id< T2 >() << "\n"; \ + std::cout << python::type_id< T1 >() << " != " << python::type_id< T2 >() << "\n"; \ std::cout << "*********************\n"; \ result = 1; \ } From beb6cca88d5f8871bb164114e63216672a1ec5bd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 19 May 2002 14:06:16 +0000 Subject: [PATCH 0470/1042] initial commit [SVN r13976] --- doc/v2/CallPolicies.html | 103 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 doc/v2/CallPolicies.html diff --git a/doc/v2/CallPolicies.html b/doc/v2/CallPolicies.html new file mode 100644 index 00000000..db358ec6 --- /dev/null +++ b/doc/v2/CallPolicies.html @@ -0,0 +1,103 @@ + + + + +Boost.Python - CallPolicies Concept + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    CallPolicies Concept

    +
    +


    +
    +
    Introduction
    +
    Concept Requirements
    +
    +
    CallPolicies Concept
    +
    +
    + +

    Introduction

    + +

    Models of the CallPolicies concept are used to specialize the +behavior of Python callable objects generated by Boost.Python to +wrapped C++ objects like function and member function +pointers, providing three behaviors: +

      +
    1. precall - Python argument tuple management before +the wrapped object is invoked +
    2. result_converter - C++ return value handling +
    3. postcall - Python argument tuple and result +management after the wrapped object is invoked +
    + +

    Concept Requirements

    +

    CallPolicies Concept

    + +

    In the table below, x denotes an object whose +type P is a model of CallPolicies, +a denotes a PyObject* pointing to +a Python argument tuple object, and r denotes a +PyObject* referring to a "preliminary" result +object. + + + + + + + + + + + + + + + +
    ExpressionTypeResult/Semantics
    x.precall(a)convertible to bool + returns false and PyErr_Occurred() != 0 + upon failure, true otherwise. + +
    P::result_converterA model of ResultConverterGenerator. + An MPL unarymetafunction object used produce the + "preliminary" result object. + +
    x.postcall(a, r)convertible to PyObject* + 0 0 and PyErr_Occurred() != 0 + upon failure. Must "conserve references" even in the + event of an exception. In other words, if r is not + returned, its reference count must be decremented; if another + existing object is returned, its reference count must be + incremented. +
    + +Models of CallPolicies are required to be CopyConstructible. + +


    +

    Revised + + 19 May, 2002 + +

    +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + +

    Permission to copy, use, modify, sell + and distribute this software is granted provided this copyright notice appears + in all copies. This software is provided "as is" without express or implied + warranty, and with no claim as to its suitability for any purpose. + + From dde6c42421490e7164e4fbdeda5156b75ffa9a11 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 19 May 2002 20:23:00 +0000 Subject: [PATCH 0471/1042] initial commit [SVN r13979] --- doc/v2/with_custodian_and_ward.html | 278 ++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 doc/v2/with_custodian_and_ward.html diff --git a/doc/v2/with_custodian_and_ward.html b/doc/v2/with_custodian_and_ward.html new file mode 100644 index 00000000..ebcbcaa0 --- /dev/null +++ b/doc/v2/with_custodian_and_ward.html @@ -0,0 +1,278 @@ + + + + + + Boost.Python - <boost/python/with_custodian_and_ward.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/with_custodian_and_ward.hpp>

    +
    +


    + +

    Contents

    + +
    +
    Introduction + + +
    Classes + +
    +
    +
    Class Template with_custodian_and_ward + +
    +
    + +
    Class Template + with_custodian_and_ward synopsis + +
    Class + with_custodian_and_ward static functions +
    +
    + + +
    Example +
    +
    + +

    Introduction

    + + This header provides faciliites for establishing a lifetime + dependency between two of a function's Python argument or result + objects. The ward object will not be destroyed until after + the custodian as long as the custodian object supports weak + references (Boost.Python extension classes all support weak + references). The two class templates + with_custodian_and_ward and + with_custodian_and_ward_postcall differ in the point + at which they take effect. + +

    In order to reduce the chance of inadvertently + creating dangling pointers, the default is to do lifetime binding + before the underlying C++ object is invoked. However, + before invocation the result object is not available, so + with_custodian_and_ward_postcall is provided to bind + lifetimes after invocation. Also, if a C++ exception is thrown + after with_custodian_and_ward<>::precall but + before the underlying C++ object actually stores a pointer, the + lifetime of the custodian and ward objects will be artificially + bound together, so one might choose + with_custodian_and_ward_postcall instead, depending + on the semantics of the function being wrapped. + +

    Classes

    + +

    Class template with_custodian_and_ward

    + + + + + + + + +
    + with_custodian_and_ward template parameters +
    Parameter + + Requirements + + Description + + Default + +
    custodian + + A positive compile-time constant of type + std::size_t. + + The 1-based index of the parameter which is the dependency in the + lifetime relationship to be established. If used to + wrap a member function, parameter 1 is the target object + (*this). Note that if the target Python object + type doesn't support weak references, a Python + TypeError exception will be raised when the + C++ object being wrapped is called. + + +
    ward + + A positive compile-time constant of type + std::size_t. + + The 1-based index of the parameter which is the dependent in the + lifetime relationship to be established. If used to + wrap a member function, parameter 1 is the target object + (*this). + + +
    Base + + A model of CallPolicies + + Used for policy composition. + + default_call_policies + +
    + +

    Class template with_custodian_and_ward synopsis

    +
    +namespace boost { namespace python
    +{
    +   template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
    +   struct with_custodian_and_ward : Base
    +   {
    +      static bool precall(PyObject* args);
    +   };
    +}}
    +
    + +

    Class + default_call_policies static functions

    + +
    +bool precall(PyObject* args);
    +
    + +
    +
    Requires: PyTuple_Check(args) != 0 +
    Effects: Makes the lifetime of the argument indicated + by ward dependent on the lifetime of the argument + indicated by custodian. + +
    Returns: false and PyErr_Occurred() != 0 + upon failure, true otherwise. +
    + + + + +

    Class template with_custodian_and_ward_postcall

    + + + + + + + + +
    + with_custodian_and_ward_postcall template parameters +
    Parameter + + Requirements + + Description + + Default + +
    custodian + + A compile-time constant of type + std::size_t. + + The index of the parameter which is the dependency in the + lifetime relationship to be established. Zero indicates the + result object; 1 indicates the first argument. If used to wrap + a member function, parameter 1 is the target object + (*this). Note that if the target Python object + type doesn't support weak references, a Python + TypeError exception will be raised when the + C++ object being wrapped is called. + + +
    ward + + A compile-time constant of type std::size_t. + + The index of the parameter which is the dependent in the + lifetime relationship to be established. Zero indicates the + result object; 1 indicates the first argument. If used to wrap + a member function, parameter 1 is the target object + (*this). + +
    Base + + A model of CallPolicies + + Used for policy + composition. + + default_call_policies + +
    + +

    Class template with_custodian_and_ward_postcall synopsis

    +
    +namespace boost { namespace python
    +{
    +   template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
    +   struct with_custodian_and_ward_postcall : Base
    +   {
    +      static PyObject* postcall(PyObject* args, PyObject* result);
    +   };
    +}}
    +
    + +

    Class + default_call_policies static functions

    + +
    +PyObject* postcall(PyObject* args, PyObject* result);
    +
    + +
    +
    Requires: PyTuple_Check(args) + != 0, result != 0. + +
    Effects: Makes the lifetime of the object indicated + by ward dependent on the lifetime of the object + indicated by custodian. + +
    Returns: 0 and PyErr_Occurred() != 0 + upon failure, true otherwise. +
    + + + +

    Example

    + +The following example shows how +with_custodian_and_ward_postcall is used by the library +to implement return_internal_reference + +
    +template 
    +struct return_internal_reference
    +    : with_custodian_and_ward_postcall<0, owner_arg, Base>
    +{
    +   typedef reference_existing_object result_converter;
    +};
    +
    + +

    Revised + + 19 February, 2002 + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From b63434ce2e3fe24bcbcb35beadd5fbc785fb08d2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 19 May 2002 20:29:40 +0000 Subject: [PATCH 0472/1042] Added composition [SVN r13980] --- doc/v2/CallPolicies.html | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/v2/CallPolicies.html b/doc/v2/CallPolicies.html index db358ec6..3c2b98fd 100644 --- a/doc/v2/CallPolicies.html +++ b/doc/v2/CallPolicies.html @@ -20,6 +20,7 @@


    Introduction
    +
    CallPolicies Composition
    Concept Requirements
    CallPolicies Concept
    @@ -40,6 +41,26 @@ the wrapped object is invoked management after the wrapped object is invoked +

    CallPolicies Composition

    + +In order to allow the use of multiple models of CallPolicies in the +same callable object, Boost.Python's CallPolicies class templates +provide a chaining interface which allows them to be recursively +composed. This interface takes the form of an optional template +parameter, Base which defaults to +default_call_policies. By convention, the +precall function of the +Base is invoked after the precall +function supplied by the outer template, and the postcall +function of the Base is invoked before the +postcall function of the outer template. If a +result_converter is supplied by the outer template, it +replaces any result_converter supplied by the +Base. For an example, see +return_internal_reference. +

    Concept Requirements

    CallPolicies Concept

    From 91e2e6f20773835c42d5f716a52646ee214289e4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 19 May 2002 20:29:56 +0000 Subject: [PATCH 0473/1042] Bugfixes [SVN r13981] --- doc/v2/Apr2002.html | 3 ++- doc/v2/Mar2002.html | 3 ++- doc/v2/acknowledgments.html | 3 ++- doc/v2/bibliography.html | 3 ++- doc/v2/call.html | 3 ++- doc/v2/call_method.html | 3 ++- doc/v2/callbacks.html | 3 ++- doc/v2/configuration.html | 3 ++- doc/v2/definitions.html | 3 ++- doc/v2/faq.html | 3 ++- doc/v2/feb2002.html | 5 ++--- doc/v2/index.html | 3 ++- doc/v2/overview.html | 3 ++- doc/v2/rationale.html | 3 ++- 14 files changed, 28 insertions(+), 16 deletions(-) diff --git a/doc/v2/Apr2002.html b/doc/v2/Apr2002.html index cd71d66f..a51e46c2 100644 --- a/doc/v2/Apr2002.html +++ b/doc/v2/Apr2002.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/Mar2002.html b/doc/v2/Mar2002.html index 5b7a3a58..0425c3e5 100644 --- a/doc/v2/Mar2002.html +++ b/doc/v2/Mar2002.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/acknowledgments.html b/doc/v2/acknowledgments.html index bd13fa79..071919e3 100644 --- a/doc/v2/acknowledgments.html +++ b/doc/v2/acknowledgments.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/bibliography.html b/doc/v2/bibliography.html index e1be0141..b59320d9 100644 --- a/doc/v2/bibliography.html +++ b/doc/v2/bibliography.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/call.html b/doc/v2/call.html index 6c1e2e39..e959b1ce 100644 --- a/doc/v2/call.html +++ b/doc/v2/call.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/call_method.html b/doc/v2/call_method.html index 2aa50c39..f2c52a9b 100644 --- a/doc/v2/call_method.html +++ b/doc/v2/call_method.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/callbacks.html b/doc/v2/callbacks.html index d47d290a..f001984d 100644 --- a/doc/v2/callbacks.html +++ b/doc/v2/callbacks.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/configuration.html b/doc/v2/configuration.html index 18b065d1..bb6b7344 100644 --- a/doc/v2/configuration.html +++ b/doc/v2/configuration.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/definitions.html b/doc/v2/definitions.html index dd917434..839608bc 100644 --- a/doc/v2/definitions.html +++ b/doc/v2/definitions.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/faq.html b/doc/v2/faq.html index dae93fa5..78a3940f 100644 --- a/doc/v2/faq.html +++ b/doc/v2/faq.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/feb2002.html b/doc/v2/feb2002.html index 423244ba..e7bc3dd9 100644 --- a/doc/v2/feb2002.html +++ b/doc/v2/feb2002.html @@ -16,9 +16,8 @@ "100%" summary="header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/index.html b/doc/v2/index.html index dea1db6e..f47747f7 100644 --- a/doc/v2/index.html +++ b/doc/v2/index.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/overview.html b/doc/v2/overview.html index 57d0e36e..e6bf820a 100644 --- a/doc/v2/overview.html +++ b/doc/v2/overview.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    diff --git a/doc/v2/rationale.html b/doc/v2/rationale.html index da7e9217..fb5304d8 100644 --- a/doc/v2/rationale.html +++ b/doc/v2/rationale.html @@ -9,7 +9,8 @@ "header"> -

    C++ Boost

    +

    +

    Boost.Python

    From cf46535b66389ab1e2e78eb077333ca768bf088e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 21 May 2002 16:16:25 +0000 Subject: [PATCH 0474/1042] instance_holder moved to boost::python [SVN r13994] --- include/boost/python/to_python_indirect.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index a636ff66..5d468c9f 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -31,7 +31,7 @@ namespace detail { struct make_owning_holder { - typedef objects::instance_holder* result_type; + typedef instance_holder* result_type; template static result_type execute(T* p) { @@ -49,7 +49,7 @@ namespace detail struct make_reference_holder { - typedef objects::instance_holder* result_type; + typedef instance_holder* result_type; template static result_type execute(T* p) { @@ -110,7 +110,7 @@ inline PyObject* to_python_indirect::operator()(T x) const // Build a value_holder to contain the object using the copy // constructor - objects::instance_holder* p = + instance_holder* p = detail::unwind_type(x); // Install it in the instance From 49c2dbd4a7fd923e82b32c4c72d778f584a84a32 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 21 May 2002 16:35:49 +0000 Subject: [PATCH 0475/1042] respect [SVN r13997] --- test/Jamfile | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/test/Jamfile b/test/Jamfile index bb0b6d82..60dce22a 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -75,35 +75,34 @@ if $(TEST_BIENSTMAN_NON_BUGS) # --- unit tests of library components --- unit-test indirect_traits_test - : indirect_traits_test.cpp : $(BOOST_ROOT) ; + : indirect_traits_test.cpp : $(BOOST_ROOT) ; unit-test destroy_test - : destroy_test.cpp : $(BOOST_ROOT) ; + : destroy_test.cpp : $(BOOST_ROOT) ; unit-test pointer_type_id_test - : pointer_type_id_test.cpp : $(BOOST_ROOT) ; + : pointer_type_id_test.cpp : $(BOOST_ROOT) ; unit-test member_function_cast - : member_function_cast.cpp : $(BOOST_ROOT) ; + : member_function_cast.cpp : $(BOOST_ROOT) ; unit-test bases - : bases.cpp : $(BOOST_ROOT) ; + : bases.cpp : $(BOOST_ROOT) ; unit-test if_else - : if_else.cpp : $(BOOST_ROOT) ; + : if_else.cpp : $(BOOST_ROOT) ; unit-test pointee - : pointee.cpp : $(BOOST_ROOT) ; + : pointee.cpp : $(BOOST_ROOT) ; unit-test select_holder : select_holder.cpp - : $(BOOST_ROOT) BOOST_PYTHON_STATIC_LIB $(PYTHON_PROPERTIES) + : $(BOOST_ROOT) BOOST_PYTHON_STATIC_LIB $(PYTHON_PROPERTIES) ; unit-test select_from_python_test : select_from_python_test.cpp ../src/converter/type_id.cpp - ../src/errors.cpp - : $(BOOST_ROOT) + : $(BOOST_ROOT) [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] BOOST_PYTHON_STATIC_LIB ; From 7ecd7e84d99133fb3c5be3cfd4434b40fb65ee2d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 21 May 2002 16:37:30 +0000 Subject: [PATCH 0476/1042] Cleaned up internals and generalized detail::target() [SVN r13998] --- include/boost/python/detail/target.hpp | 95 +---- include/boost/python/iterator.hpp | 18 +- include/boost/python/object/iterator.hpp | 4 +- include/boost/python/preprocessed/target.hpp | 402 +++++++++++++++++++ 4 files changed, 435 insertions(+), 84 deletions(-) create mode 100755 include/boost/python/preprocessed/target.hpp diff --git a/include/boost/python/detail/target.hpp b/include/boost/python/detail/target.hpp index e0c693dd..e6869140 100644 --- a/include/boost/python/detail/target.hpp +++ b/include/boost/python/detail/target.hpp @@ -3,87 +3,36 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef TARGET_DWA2002513_HPP -# define TARGET_DWA2002513_HPP +#ifndef TARGET_DWA2002521_HPP +# define TARGET_DWA2002521_HPP +# include +# include +# include +# include +# include # include -namespace boost { namespace python { namespace detail { +namespace boost { namespace python { namespace detail { -// -// target(x) - deduce the type of the first argument when bind(x) is -// invoked. -// +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif -// functions -template -boost::type* target(R (*)(Target)) { return 0; } +# define BOOST_PYTHON_FIRST_ARGUMENT_PF(args, ignored) \ +template \ +boost::type* target(BOOST_PYTHON_FN(*,0,args)) { return 0; } -template -boost::type* target(R (*)(Target, A1)) { return 0; } - -template -boost::type* target(R (*)(Target, A1, A2)) { return 0; } - -template -boost::type* target(R (*)(Target, A1, A2, A3)) { return 0; } +# define BOOST_PYTHON_FIRST_ARGUMENT_PMF(args, cv) \ +template \ +boost::type* target(BOOST_PYTHON_FN(A0::*,1,args)cv()) { return 0; } -// data member pointers -template -boost::type* target(R (Target::*)) { return 0; } +BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_FIRST_ARGUMENT_PF, nil) +BOOST_PYTHON_REPEAT_MF_CV_2ND(BOOST_PYTHON_FIRST_ARGUMENT_PMF) -// member Functions -template -boost::type* target(R (Target::*)()) { return 0; } - -template -boost::type* target(R (Target::*)(A1)) { return 0; } - -template -boost::type* target(R (Target::*)(A1,A2)) { return 0; } - -template -boost::type* target(R (Target::*)(A1,A2,A3)) { return 0; } - -// const member functions -template -boost::type* target(R (Target::*)() const) { return 0; } - -template -boost::type* target(R (Target::*)(A1) const) { return 0; } - -template -boost::type* target(R (Target::*)(A1,A2) const) { return 0; } - -template -boost::type* target(R (Target::*)(A1,A2,A3) const) { return 0; } - -// volatile member functions -template -boost::type* target(R (Target::*)() volatile) { return 0; } - -template -boost::type* target(R (Target::*)(A1) volatile) { return 0; } - -template -boost::type* target(R (Target::*)(A1,A2) volatile) { return 0; } - -template -boost::type* target(R (Target::*)(A1,A2,A3) volatile) { return 0; } - -// const volatile member functions -template -boost::type* target(R (Target::*)() const volatile) { return 0; } - -template -boost::type* target(R (Target::*)(A1) const volatile) { return 0; } - -template -boost::type* target(R (Target::*)(A1,A2) const volatile) { return 0; } - -template -boost::type* target(R (Target::*)(A1,A2,A3) const volatile) { return 0; } +template +boost::type* target(R (T::*)) { return 0; } }}} // namespace boost::python::detail -#endif // TARGET_DWA2002513_HPP +#endif // TARGET_DWA2002521_HPP diff --git a/include/boost/python/iterator.hpp b/include/boost/python/iterator.hpp index 0f1e8eeb..a31954aa 100644 --- a/include/boost/python/iterator.hpp +++ b/include/boost/python/iterator.hpp @@ -18,15 +18,14 @@ namespace detail // Adds an additional layer of binding to // objects::make_iterator(...), which allows us to pass member // function and member data pointers. - template + template inline ref make_iterator( - Accessor1 get_start, Accessor2 get_finish, NextPolicies* = 0, boost::type* target = 0) + Accessor1 get_start, Accessor2 get_finish, boost::type* target = 0, NextPolicies* = 0) { - return objects::make_iterator_function( + return objects::make_iterator_function( boost::protect(boost::bind(get_start, _1)) , boost::protect(boost::bind(get_finish, _1)) - , (NextPolicies*)0 - , target); + ); } // Guts of template class iterators<>, below. @@ -71,7 +70,9 @@ struct iterators template ref range(Accessor1 start, Accessor2 finish) { - return detail::make_iterator(start, finish, (objects::default_iterator_call_policies*)0, detail::target(start)); + return detail::make_iterator( + start, finish + , detail::target(start)); } // Create an iterator-building function which uses the given accessors @@ -79,7 +80,7 @@ ref range(Accessor1 start, Accessor2 finish) template ref range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) { - return detail::make_iterator(start, finish, (NextPolicies*)0, detail::target(start)); + return detail::make_iterator(start, finish, detail::target(start)); } // Create an iterator-building function which uses the given accessors @@ -88,8 +89,7 @@ template ref range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type* = 0) { typedef typename add_reference::type target; - return detail::make_iterator(start, finish, (NextPolicies*)0, - (boost::type*)0); + return detail::make_iterator(start, finish); } // A Python callable object which produces an iterator traversing diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 35073438..1319425f 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -119,7 +119,7 @@ namespace detail // Check the registry. If one is already registered, return it. ref result( - objects::registered_class_object(converter::undecorated_type_id())); + objects::registered_class_object(python::type_id())); if (result.get() == 0) { @@ -189,7 +189,7 @@ namespace detail template inline ref make_iterator_function( Accessor1 const& get_start, Accessor2 const& get_finish - , NextPolicies* , boost::type*) + , boost::type* = 0, NextPolicies* = 0) { typedef typename Accessor1::result_type result_type; diff --git a/include/boost/python/preprocessed/target.hpp b/include/boost/python/preprocessed/target.hpp new file mode 100755 index 00000000..f2a23cee --- /dev/null +++ b/include/boost/python/preprocessed/target.hpp @@ -0,0 +1,402 @@ +template +boost::type*target(R(*)()) +{ + return 0; +} +template +boost::type*target(R(*)(A0)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3,A4)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3,A4,A5)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)) +{ + return 0; +} +template +boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)) +{ + return 0; +} + +template +boost::type*target(R(A0::*)()) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)) +{ + return 0; +} +template +boost::type*target(R(A0::*)()const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const) +{ + return 0; +} +template +boost::type*target(R(A0::*)()volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)()const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile) +{ + return 0; +} +template +boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile) +{ + return 0; +} + From 00b27c20da9e2832b76101a0c966208a8d01265b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 21 May 2002 23:18:58 +0000 Subject: [PATCH 0477/1042] Added detail/result.hpp and tests [SVN r14000] --- include/boost/python/detail/result.hpp | 88 ++++ include/boost/python/preprocessed/result.hpp | 412 +++++++++++++++++++ 2 files changed, 500 insertions(+) create mode 100755 include/boost/python/detail/result.hpp create mode 100755 include/boost/python/preprocessed/result.hpp diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp new file mode 100755 index 00000000..d8bf1358 --- /dev/null +++ b/include/boost/python/detail/result.hpp @@ -0,0 +1,88 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef RESULT_DWA2002521_HPP +# define RESULT_DWA2002521_HPP + +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +// Defines a family of overloaded function which, given x, a function +// pointer, member [function] pointer, or an AdaptableFunction object, +// returns a pointer to type*, where R is the result type of +// invoking the result of bind(x). +// +// In order to work around bugs in deficient compilers, if x might be +// an AdaptableFunction object, you must pass OL as a second argument +// to get this to work portably. + +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif + +# define BOOST_PYTHON_FIRST_ARGUMENT_PF(args, ignored) \ +template \ +boost::type* result(BOOST_PYTHON_FN(*,0,args), long = 0) { return 0; } + +# define BOOST_PYTHON_FIRST_ARGUMENT_PMF(args, cv) \ +template \ +boost::type* result(BOOST_PYTHON_FN(A0::*,1,args)cv(), long = 0) { return 0; } + +BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_FIRST_ARGUMENT_PF, nil) +BOOST_PYTHON_REPEAT_MF_CV_2ND(BOOST_PYTHON_FIRST_ARGUMENT_PMF) + +template +boost::type* result(R (T::*), long = 0) { return 0; } + + +# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 /* it almost works with VC6, but not VC7 */ \ + || (defined(BOOST_MSVC) && _MSC_FULL_VER == 13012108) /* or the VC7.01 alpha */ \ + || defined(__GNUC__) && __GNUC__ < 3 \ + || defined(__MWERKS__) && __MWERKS__ < 3000 +// This code actually works on all implementations, but why use it when we don't have to? +template +struct get_result_type +{ + typedef boost::type type; +}; + +struct void_type +{ + typedef void type; +}; + +template +struct result_result +{ + typedef typename mpl::select_type< + is_class::value + , get_result_type + , void_type + >::type t1; + + typedef typename t1::type* type; +}; +template +typename result_result::type +result(X const&, int = 0) { return 0; } + +# else // Simpler code for more-capable compilers + +template +boost::type* +result(X const&, int = 0) { return 0; } + +# endif + +}}} // namespace boost::python::detail + +#endif // RESULT_DWA2002521_HPP diff --git a/include/boost/python/preprocessed/result.hpp b/include/boost/python/preprocessed/result.hpp new file mode 100755 index 00000000..f9eb99c6 --- /dev/null +++ b/include/boost/python/preprocessed/result.hpp @@ -0,0 +1,412 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef RESULT2_DWA2002521_HPP +# define RESULT2_DWA2002521_HPP + +template +boost::type*result(R(*)(),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3,A4),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),long=0) +{ + return 0; +} +template +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),long=0) +{ + return 0; +} + +template +boost::type*result(R(A0::*)(),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)()const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)()volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)()const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,long=0) +{ + return 0; +} +template +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,long=0) +{ + return 0; +} + + +#endif // RESULT2_DWA2002521_HPP From aa2b0090d3643ad4f317f6ca2e66e168db4816c2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 23 May 2002 16:17:53 +0000 Subject: [PATCH 0478/1042] bugfix [SVN r14022] --- doc/v2/manage_new_object.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/manage_new_object.html b/doc/v2/manage_new_object.html index 879cdc5e..8630dfa5 100644 --- a/doc/v2/manage_new_object.html +++ b/doc/v2/manage_new_object.html @@ -105,7 +105,7 @@ using namespace boost::python; BOOST_PYTHON_MODULE_INIT(my_module) { module("my_module") - .def("make_foo", make_foo) + .def("make_foo", make_foo, return_value_policy<manage_new_object>) .add( class_<Foo>() .def("get_x", &Foo::get_x) From 0f7c12b517bc895bfd0fd3e72851056d989b8b08 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 23 May 2002 16:25:45 +0000 Subject: [PATCH 0479/1042] Added result() test [SVN r14025] --- test/Jamfile | 3 ++ test/result.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100755 test/result.cpp diff --git a/test/Jamfile b/test/Jamfile index 60dce22a..f5421f9b 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -93,6 +93,9 @@ unit-test if_else unit-test pointee : pointee.cpp : $(BOOST_ROOT) ; +unit-test result + : result.cpp : $(BOOST_ROOT) ; + unit-test select_holder : select_holder.cpp : $(BOOST_ROOT) BOOST_PYTHON_STATIC_LIB $(PYTHON_PROPERTIES) diff --git a/test/result.cpp b/test/result.cpp new file mode 100755 index 00000000..caf0ec27 --- /dev/null +++ b/test/result.cpp @@ -0,0 +1,112 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include + +using boost::python::detail::result; +using boost::type; + +void expect_int(type*) {} +void expect_string(type*) {} + +struct X {}; + +int main() +{ + // Test the usage which works for functions, member functions, and data members + expect_int( + result((int(*)())0) + ); + + expect_int( + result((int(*)(char))0) + ); + + expect_int( + result((int(X::*)())0) + ); + + expect_int( + result((int(X::*)(char))0) + ); + + expect_int( + result((int(X::*))0) + ); + + expect_string( + result((char*(*)())0) + ); + + expect_string( + result((char*(*)(char))0) + ); + + expect_string( + result((char*(X::*)())0) + ); + + expect_string( + result((char*(X::*)(char))0) + ); + + expect_string( + result((char*(X::*))0) + ); + + // Show that we can use the general version that works for + // AdaptableFunctions + expect_int( + result((int(*)())0,0L) + ); + + expect_int( + result((int(*)(char))0,0L) + ); + + expect_int( + result((int(X::*)())0,0L) + ); + + expect_int( + result((int(X::*)(char))0,0L) + ); + + expect_int( + result((int(X::*))0,0L) + ); + + expect_int( + result(std::plus(), 0L) + ); + + expect_string( + result((char*(*)())0,0L) + ); + + expect_string( + result((char*(*)(char))0,0L) + ); + + expect_string( + result((char*(X::*)())0,0L) + ); + + expect_string( + result((char*(X::*)(char))0,0L) + ); + + expect_string( + result((char*(X::*))0,0L) + ); + + expect_string( + result(std::plus(), 0L) + ); + + return 0; +} From 051994bdf4579171dc3013d0ad32bcc7d3097bc3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 23 May 2002 16:28:37 +0000 Subject: [PATCH 0480/1042] initial commit [SVN r14027] --- include/boost/python/lvalue_from_pytype.hpp | 104 ++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100755 include/boost/python/lvalue_from_pytype.hpp diff --git a/include/boost/python/lvalue_from_pytype.hpp b/include/boost/python/lvalue_from_pytype.hpp new file mode 100755 index 00000000..ae01a6bd --- /dev/null +++ b/include/boost/python/lvalue_from_pytype.hpp @@ -0,0 +1,104 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef LVALUE_FROM_PYTYPE_DWA2002130_HPP +# define LVALUE_FROM_PYTYPE_DWA2002130_HPP + +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + // Given a pointer-to-function of 1 parameter returning a reference + // type, return the type_id of the function's return type. + template + inline type_info extractor_type_id(T&(*)(U)) + { + return type_id(); + } + + // A function generator whose static execute() function is an lvalue + // from_python converter using the given Extractor. U is expected to + // be the actual type of the PyObject instance from which the result + // is being extracted. + template + struct normalized_extractor + { + static inline void* execute(PyObject* op) + { + typedef typename boost::add_reference::type param; + return &Extractor::execute( + boost::python::detail::void_ptr_to_reference( + op, (param(*)())0 ) + ); + } + }; + + // Given an Extractor type and a pointer to its execute function, + // return a new object whose static execute function does the same + // job but is a conforming lvalue from_python conversion function. + // + // usage: normalize(&Extractor::execute) + template + inline normalized_extractor + normalize(T(*)(U), Extractor* = 0) + { + return normalized_extractor(); + } +} + +// An Extractor which extracts the given member from a Python object +// whose instances are stored as InstanceType. +template +struct extract_member +{ + static MemberType& execute(InstanceType& c) + { + (void)c.ob_type; // static assertion + return c.*member; + } +}; + +// An Extractor which simply extracts the entire python object +// instance of InstanceType. +template +struct extract_identity +{ + static InstanceType& execute(InstanceType& c) + { + (void)c.ob_type; // static assertion + return c; + } +}; + +// Registers a from_python conversion which extracts lvalues using +// Extractor's static execute function from Python objects whose type +// object is python_type. +template +struct lvalue_from_pytype +{ + lvalue_from_pytype() + { + converter::registry::insert( + &extract, detail::extractor_type_id(&Extractor::execute)); + } + private: + static void* extract(PyObject* op) + { + return PyObject_TypeCheck(op, const_cast(python_type)) + ? const_cast( + static_cast( + detail::normalize(&Extractor::execute).execute(op))) + : 0 + ; + } +}; + +}} // namespace boost::python + +#endif // LVALUE_FROM_PYTYPE_DWA2002130_HPP From 67b3cdc7b7610ae0cfd5d9706b73c8983bed0cc2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 23 May 2002 16:38:44 +0000 Subject: [PATCH 0481/1042] lvalue_from_pytype + documentation [SVN r14030] --- doc/v2/Extractor.html | 93 +++++++++++ doc/v2/lvalue_from_pytype.html | 283 +++++++++++++++++++++++++++++++++ doc/v2/reference.html | 47 +++--- test/m1.cpp | 18 +-- 4 files changed, 410 insertions(+), 31 deletions(-) create mode 100755 doc/v2/Extractor.html create mode 100755 doc/v2/lvalue_from_pytype.html diff --git a/doc/v2/Extractor.html b/doc/v2/Extractor.html new file mode 100755 index 00000000..97ef6fd4 --- /dev/null +++ b/doc/v2/Extractor.html @@ -0,0 +1,93 @@ + + + + +Boost.Python - Extractor Concept + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Extractor Concept

    +
    +
    +
    +
    Introduction
    +
    Concept Requirements
    +
    +
    Extractor Concept
    +
    +
    Notes
    +
    + +

    Introduction

    + +

    An Extractor is a class which Boost.Python can use to extract C++ +objects from Python objects, and is typically used by facilities that +define from_python conversions for +"traditional" Python extension types. + +

    Concept Requirements

    +

    Extractor Concept

    + +

    In the table below, X denotes a model of +Extractor and a denotes an instance of a Python +object type. + + + + + + + + + + + + + + + + + + +
    ExpressionTypeSemantics
    X::execute(a)non-void + Returns the C++ object being extracted. The + execute function must not be overloaded. +
    &a.ob_type + PyTypeObject** + Points to the ob_type field of an object which is + layout-compatible with PyObject +
    + +

    Notes

    + +Informally, an Extractor's execute member must be a +non-overloaded static function whose single argument is a Python +object type. Acceptable Python object types include those publicly (and +unambiguously) derived from PyObject, and POD types which +are layout-compatible with PyObject. + +
    +

    Revised + + 22 May, 2002 + +

    +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + +

    Permission to copy, use, modify, sell + and distribute this software is granted provided this copyright notice appears + in all copies. This software is provided "as is" without express or implied + warranty, and with no claim as to its suitability for any purpose. + + diff --git a/doc/v2/lvalue_from_pytype.html b/doc/v2/lvalue_from_pytype.html new file mode 100755 index 00000000..8b3cb49e --- /dev/null +++ b/doc/v2/lvalue_from_pytype.html @@ -0,0 +1,283 @@ + + + + + + Boost.Python - <boost/python/lvalue_from_python.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/lvalue_from_pytype.hpp>

    +
    +


    + +

    Contents

    + +
    +
    Introduction + + +
    Classes + +
    +
    +
    Class Template lvalue_from_pytype + +
    +
    + +
    Class Template + lvalue_from_pytype synopsis + +
    Class Template + lvalue_from_pytype constructor +
    +
    + +
    +
    Class Template extract_identity +
    +
    + +
    Class Template + extract_identity synopsis + +
    Class Template + extract_identity static functions +
    +
    Class Template extract_member +
    +
    + +
    Class Template + extract_member synopsis + +
    Class Template + extract_member static functions +
    +
    + +
    Example +
    +
    + +

    Introduction

    + + <boost/python/lvalue_from_pytype.hpp> supplies + a facility for extracting C++ objects from within Python instances + of a given type. This is typically useful for dealing with + "traditional" Python extension types. + +

    Classes

    + +

    Class template lvalue_from_pytype

    + +

    Class template lvalue_from_pytype will register + from_python converters which, given an object of the given Python + type, can extract references and pointers to a particular C++ + type. Its template arguments are: + +

    + + + + + + + +
    + lvalue_from_pytype Requirements
    + + In the table below, x denotes an object of type PythonObject& + +
    Parameter + + Requirements + + Semantics + +
    Extractor + + a model of Extractor whose + execute function returns a reference type. + + Extracts the lvalue from the Python object once its type has been confirmed + +
    python_type + + A compile-time constant PyTypeObject* + + The Python type of instances convertible by this + converter. Python subtypes are also convertible. + +
    + +

    Class template lvalue_from_pytype synopsis

    +
    +namespace boost { namespace python
    +{
    +   template <class Extractor, PyTypeObject const* python_type>
    +   struct lvalue_from_pytype
    +   {
    +       lvalue_from_pytype();
    +   };
    +}}
    +
    + +

    Class template lvalue_from_pytype constructor

    +
    +lvalue_from_pytype();
    +
    + +
    + +
    Effects: Registers converters which can convert + Python objects of the given type to lvalues of the type returned + by Extractor::execute. + +
    + +

    Class template extract_identity

    + +

    extract_identity is a model of Extractor which can be + used in the common case where the C++ type to be extracted is the + same as the Python object type. + +

    Class template + extract_identity synopsis

    +
    +namespace boost { namespace python
    +{
    +   template <class InstanceType>
    +   struct extract_identity
    +   {
    +      static InstanceType& execute(InstanceType& c);
    +   };
    +}}
    +
    + +

    Class template extract_identity static functions

    +
    +InstanceType& execute(InstanceType& c);
    +
    + +
    + +
    Returns: c + +
    + + +

    Class template extract_member

    + +

    extract_member is a model of Extractor which can be + used in the common case in the common case where the C++ + type to be extracted is a member of the Python object. + +

    Class template extract_member synopsis

    +
    +namespace boost { namespace python
    +{
    +   template <class InstanceType, class MemberType, MemberType (InstanceType::*member)>
    +   struct extract_member
    +   {
    +      static MemberType& execute(InstanceType& c);
    +   };
    +}}
    +
    + +

    Class template extract_member static functions

    +
    +static MemberType& execute(InstanceType& c);
    +
    + +
    + +
    Returns: c.*member + +
    + +

    Example

    + +This example presumes that someone has implemented the standard noddy +example module from the Python documentation, and we want to build +a module which manipulates Noddys. Since +noddy_NoddyObject is so simple that it carries no +interesting information, the example is a bit contrived: it assumes +you want to keep track of one particular object for some reason. This +module would have to be dynamically linked to the module which defines +noddy_NoddyType. + +

    C++ module definition

    + +
    +#include <boost/python/reference.hpp>
    +#include <boost/python/module.hpp>
    +
    +// definition lifted from the Python docs
    +typedef struct {
    +   PyObject_HEAD
    +} noddy_NoddyObject;
    +
    +using namespace boost::python;
    +static reference<PyObject> cache;
    +
    +bool is_cached(noddy_NoddyObject* x)
    +{
    +   return x == cache.get();
    +}
    +
    +void set_cache(noddy_NoddyObject* x)
    +{
    +   cache.reset((PyObject*)x, ref::increment_count);
    +}
    +
    +BOOST_PYTHON_MODULE_INIT(noddy_cache)
    +{
    +   module noddy_cache("noddy_cache")
    +      .def("is_cached", is_cached)
    +      .def("set_cache", set_cache)
    +      ;
    +
    +   // register Noddy lvalue converter
    +   lvalue_from_pytype<extract_identity<noddy_NoddyObject>,&noddy_NoddyType>();
    +}
    +
    + +

    Python code

    + +
    +>>> import noddy
    +>>> n = noddy.new_noddy()
    +>>> import noddy_cache
    +>>> noddy_cache.is_cached(n)
    +0
    +>>> noddy_cache.set_cache(n)
    +>>> noddy_cache.is_cached(n)
    +1
    +>>> noddy_cache.is_cached(noddy.new_noddy())
    +0
    +
    + +

    Revised + + 05 November, 2001 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 71191cee..06fc346f 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -61,6 +61,9 @@

    Dereferenceable +
    Extractor +
    HolderGenerator @@ -350,7 +353,6 @@
    copy_non_const_reference.hpp -
    manage_new_object.hpp -
    Classes @@ -380,7 +381,6 @@
    reference_existing_object.hpp -
    -
    reference_from_python.hpp - -
    -
    -
    Classes - -
    -
    -
    reference_from_python - -
    get_member -
    -
    @@ -443,6 +427,23 @@
    +
    lvalue_from_pytype.hpp +
    +
    +
    Classes + +
    +
    +
    lvalue_from_pytype +
    extract_identity +
    extract_member +
    +
    +
    to_python_converter.hpp @@ -483,16 +484,18 @@
    -
     {{function}}
    @@ -186,7 +181,7 @@ namespace boost
           
    Rationale: {{text}} -

    Class {{name}} modifier +

    Class {{name}} modifier functions

     {{function}}
    @@ -208,7 +203,7 @@ namespace boost
           
    Rationale: {{text}} -

    Class {{name}} observer +

    Class {{name}} observer functions

     {{function}}
    @@ -230,7 +225,7 @@ namespace boost
           
    Rationale: {{text}} -

    Class {{name}} static functions

    +

    Class {{name}} static functions

     {{function}}
     
    diff --git a/doc/v2/module.html b/doc/v2/module.html index f39ff4e8..0e3516ed 100644 --- a/doc/v2/module.html +++ b/doc/v2/module.html @@ -188,19 +188,23 @@ module& add(class_<T,Bases,HolderGenerator> const& c);
     template <class Fn>
    -module& def(char const* name, Fn fn);
    +module& def(char const* name, Fn f);
     
     template <class Fn, class ResultHandler>
    -module& def(char const* name, Fn fn, ResultHandler handler);
    +module& def(char const* name, Fn f, ResultHandler handler);
     
    +
    Requires: f is a non-null pointer-to-function or pointer-to-member-function. name is a ntbs which conforms to Python's identifier - naming rules. If supplied, policy conforms to the CallPolicy concept requirements. + naming rules. In the first form, the return type of + f is not a reference and is not a pointer other + than char const* or PyObject*. In the + second form policy is a model of CallPolicy.
    Effects: Adds the result of make_function(f) to diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 5e2e4463..5f82fe4d 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -353,19 +353,19 @@
    reference_from_python.hpp + "lvalue_from_python.html">reference_from_python.hpp
    -
    Classes +
    Classes
    reference_from_python + "lvalue_from_python.html#reference_from_python-spec">reference_from_python
    get_member + "lvalue_from_python.html#get_member-spec">get_member
    diff --git a/doc/v2/return_internal_reference.html b/doc/v2/return_internal_reference.html new file mode 100644 index 00000000..c1b62a56 --- /dev/null +++ b/doc/v2/return_internal_reference.html @@ -0,0 +1,205 @@ + + + + + + Boost.Python - <boost/python/return_internal_reference.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/return_internal_reference.hpp>

    +
    +
    + +

    Contents

    + +
    +
    Introduction + + +
    Classes + +
    +
    +
    Class Template return_internal_reference + +
    +
    + +
    Class Template + return_internal_reference synopsis + +
    Class + return_internal_reference static functions +
    +
    + + +
    Example +
    +
    + +

    Introduction

    + + return_internal_reference instantiations are models of CallPolicies which allow pointers and + references to objects held internally by a free or member function + argument or from the target of a member function to be returned + safely without making a copy of the referent. The default for its + first template argument handles the common case where the + containing object is the target (*this) of a wrapped member function. + +

    Classes

    + +

    Class template return_internal_reference

    + + + + + + + +
    + return_internal_reference template parameters +
    Parameter + + Requirements + + Description + + Default + +
    owner_arg + + A positive compile-time constant of type + std::size_t. + + The index of the parameter which contains the object to + which the reference or pointer is being returned. If used to + wrap a member function, parameter 1 is the target object + (*this). + + 1 + +
    Base + + A model of CallPolicies + + Used for policy composition. Any + result_converter it supplies will be overridden by + return_internal_reference, but its + precall and postcall policies are + composed as described here CallPolicies. + + default_call_policies + +
    + +

    Class template return_internal_reference synopsis

    +
    +namespace boost { namespace python {
    +   template <std::size_t owner_arg = 1, class Base = default_call_policies>
    +   struct return_internal_reference : Base
    +   {
    +      static PyObject* postcall(PyObject*, PyObject* result);
    +      typedef reference_existing_object result_converter;
    +   };
    +}}
    +
    + +

    Class + default_call_policies static functions

    + +
    +PyObject* postcall(PyObject* args, PyObject* result);
    +
    + +
    +
    Requires: PyTuple_Check(args) != 0 + +
    Returns: make_custodian_and_ward_postcall::postcall(args, result) +
    + + +

    Example

    + +

    C++ module definition

    + +
    +#include <boost/python/module.hpp>
    +#include <boost/python/class.hpp>
    +#include <boost/python/return_internal_reference.hpp>
    +
    +class Bar
    +{
    +   Bar(int x) : x(x) {}
    +   int get_x() const { return x; }
    +   void set_x(int x) { this->x = x; }
    + private:
    +   int x;
    +}
    +
    +class Foo
    +{
    + public:
    +   Foo(int x) : b(x) {}
    +
    +   // Returns an internal reference
    +   Bar const& get_bar() const { return b; }
    +
    + private:
    +   Bar b;
    +};
    +
    +using namespace boost::python;
    +BOOST_PYTHON_MODULE_INIT(internal_refs)
    +{
    +   module m("internal_refs")
    +      .add(
    +         class_<Bar>()
    +            .def("get_x", &Bar::get_x)
    +            .def("set_x", &Bar::set_x)
    +         )
    +      .add(
    +         class_<Foo>()
    +            .def_init(args<int>())
    +            .def("get_bar", &Foo::get_bar
    +                , return_internal_reference<>())
    +         )
    +      ;
    +}
    +
    + +

    Python code

    + +
    +>>> from internal_refs import *
    +>>> f = Foo(3)
    +>>> b1 = f.get_bar()
    +>>> b2 = f.get_bar()
    +>>> b1.get_x()
    +3
    +>>> b2.get_x()
    +3
    +>>> b1.set_x(42)
    +>>> b2.get_x()
    +42
    +
    + +

    Revised + + 15 February, 2002 + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From 607631604f065cbb5d038ea8fc14d2e29a2c1ad4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Feb 2002 18:32:57 +0000 Subject: [PATCH 0256/1042] *** empty log message *** [SVN r12824] --- doc/v2/return_internal_reference.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/v2/return_internal_reference.html b/doc/v2/return_internal_reference.html index c1b62a56..8cbfc167 100644 --- a/doc/v2/return_internal_reference.html +++ b/doc/v2/return_internal_reference.html @@ -106,7 +106,8 @@

    Class template return_internal_reference synopsis

    -namespace boost { namespace python {
    +namespace boost { namespace python
    +{
        template <std::size_t owner_arg = 1, class Base = default_call_policies>
        struct return_internal_reference : Base
        {
    
    From f697d2daa17746ef6aee87c5e8317bd5d02ecc28 Mon Sep 17 00:00:00 2001
    From: Dave Abrahams 
    Date: Fri, 15 Feb 2002 18:53:55 +0000
    Subject: [PATCH 0257/1042] *** empty log message ***
    
    [SVN r12825]
    ---
     doc/v2/copy_const_reference.html |   9 +-
     doc/v2/return_value_policy.html  | 148 +++++++++++++++++++++++++++++++
     2 files changed, 153 insertions(+), 4 deletions(-)
     create mode 100644 doc/v2/return_value_policy.html
    
    diff --git a/doc/v2/copy_const_reference.html b/doc/v2/copy_const_reference.html
    index f80db61f..ec76fa1a 100644
    --- a/doc/v2/copy_const_reference.html
    +++ b/doc/v2/copy_const_reference.html
    @@ -83,7 +83,7 @@ template <class T> struct apply
     
         

    Example

    -

    In C++: +

    C++ Module Definition

     #include <boost/python/module.hpp>
     #include <boost/python/class.hpp>
    @@ -113,10 +113,11 @@ BOOST_PYTHON_MODULE_INIT(my_module)
                 .def_init(args<int>())
                 .def("get_bar", &Foo::get_bar
                     , return_value_policy<copy_const_reference>())
    -         );
    +         )
    +       ;
     }
     
    - In Python: +

    Python Code

     >>> from my_module import *
     >>> f = Foo(3)         # create a Foo object
    @@ -125,7 +126,7 @@ BOOST_PYTHON_MODULE_INIT(my_module)
     
         

    Revised - 05 November, 2001 + 15 February, 2002 diff --git a/doc/v2/return_value_policy.html b/doc/v2/return_value_policy.html new file mode 100644 index 00000000..5741be8f --- /dev/null +++ b/doc/v2/return_value_policy.html @@ -0,0 +1,148 @@ + + + + + + Boost.Python - <boost/python/return_value_policy.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/return_value_policy.hpp>

    +
    +


    + +

    Contents

    + +
    +
    Introduction + + +
    Classes + +
    +
    +
    Class Template return_value_policy + +
    +
    + +
    Class Template + return_value_policy synopsis +
    +
    + + +
    Example +
    +
    + +

    Introduction

    + + return_value_policy instantiations are simply models + of CallPolicies which are composed of a ResultConverterGenerator and optional Base CallPolicies. + +

    Classes

    + +

    Class template return_value_policy

    + + + + + + + +
    + return_value_policy template parameters +
    Parameter + + Requirements + + Default + +
    ResultConverterGenerator + + A model of ResultConverterGenerator. + +
    Base + + A model of CallPolicies + + default_call_policies + +
    + +

    Class template return_value_policy synopsis

    +
    +namespace boost { namespace python
    +{
    +  template <class ResultConverterGenerator, class Base = default_call_policies>
    +  struct return_value_policy : Base
    +  {
    +      typedef ResultConverterGenerator result_converter;
    +  };
    +}}
    +
    + +

    Example

    + +

    C++ Module Definition

    +
    +#include <boost/python/module.hpp>
    +#include <boost/python/class.hpp>
    +#include <boost/python/copy_const_reference.hpp>
    +#include <boost/python/return_value_policy.hpp>
    +
    +// classes to wrap
    +struct Bar { int x; }
    +
    +struct Foo {
    +   Foo(int x) : { b.x = x; }
    +   Bar const& get_bar() const { return b; }
    + private:
    +   Bar b;
    +};
    +
    +// Wrapper code
    +using namespace boost::python;
    +BOOST_PYTHON_MODULE_INIT(my_module)
    +{
    +   module m("my_module")
    +      .add(
    +         class_<Bar>()
    +         )
    +      .add(
    +         class_<Foo>()
    +            .def_init(args<int>())
    +            .def("get_bar", &Foo::get_bar
    +                , return_value_policy<copy_const_reference>())
    +         )
    +       ;
    +}
    +
    +

    Python Code

    +
    +>>> from my_module import *
    +>>> f = Foo(3)         # create a Foo object
    +>>> b = f.get_bar()    # make a copy of the internal Bar object
    +
    + +

    Revised + + 15 February, 2002 + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From 39646acf5bab3252b1ca14bc60c20404171741c4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Feb 2002 00:25:16 +0000 Subject: [PATCH 0258/1042] updates to be compatible with Rene's new system [SVN r12831] --- Jamfile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Jamfile b/Jamfile index ac32456b..aa804505 100644 --- a/Jamfile +++ b/Jamfile @@ -31,39 +31,39 @@ PYTHON_PROPERTIES ; # -------- general test ------- - extension m1 : test/m1.cpp bpl + extension m1 : test/m1.cpp bpl : : debug-python ; - extension m2 : test/m2.cpp bpl + extension m2 : test/m2.cpp bpl : : debug-python ; - boost-python-runtest try : test/newtest.py m1 m2 : : debug-python ; + boost-python-runtest try : test/newtest.py m1 m2 : : debug-python ; # ----------- builtin converters ----------- - extension builtin_converters_ext : test/test_builtin_converters.cpp bpl + extension builtin_converters_ext : test/test_builtin_converters.cpp bpl : : debug-python ; boost-python-runtest test_builtin_converters : test/test_builtin_converters.py - builtin_converters_ext + builtin_converters_ext : : debug-python ; # ----------- pointer adoption ----------- - extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp bpl + extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp bpl : : debug-python ; boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py - test_pointer_adoption_ext + test_pointer_adoption_ext : : debug-python ; From edd93c80a1f15c35b9a2b0dfd550d66b8eb9e521 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Feb 2002 15:42:09 +0000 Subject: [PATCH 0259/1042] inital checkin [SVN r12835] --- doc/v2/to_python_converter.html | 189 ++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 doc/v2/to_python_converter.html diff --git a/doc/v2/to_python_converter.html b/doc/v2/to_python_converter.html new file mode 100644 index 00000000..63db8c71 --- /dev/null +++ b/doc/v2/to_python_converter.html @@ -0,0 +1,189 @@ + + + + + + Boost.Python - <boost/python/to_python_converter.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/to_python_converter.hpp>

    +
    +


    + +

    Contents

    + +
    +
    Introduction + + +
    Classes + +
    +
    +
    Class Template to_python_converter + +
    +
    + +
    Class Template + to_python_converter synopsis + +
    Class Template + to_python_converter constructor +
    +
    + +
    Example +
    +
    + +

    Introduction

    + + to_python_converter registers a conversion from + objects of a given C++ type into a Python object. + +

    Classes

    + +

    Class template to_python_converter

    + + to_python_converter adds a wrapper around a static + member function of its second template parameter, handling + low-level details such as insertion into the converter registry. + + + + + + + +
    + to_python_converter template parameters
    +In the table below, x denotes an object of type T +
    Parameter + + Requirements + + Description + +
    T + + + + The C++ type of the source object in the conversion + +
    Conversion + + PyObject* p = Conversion::convert(x),
    + if p == 0, PyErr_Occurred() != 0. + +
    A class type whose static member function + convert does the real work of the conversion. + +
    + +

    Class template to_python_converter synopsis

    +
    +namespace boost { namespace python
    +{
    +  template <class T, class Conversion>
    +  struct to_python_converter
    +  {
    +      to_python_converter();
    +  };
    +}}
    +
    + +

    Class template to_python_converter constructor

    +
    +to_python_converter();
    +
    + +
    + +
    Effects: Registers a to_python converter which uses + Conversion::convert() to do its work. + +
    + +

    Example

    + +This example presumes that someone has implemented the standard noddy example +module from the Python documentation, and placed the corresponding +declarations in "noddy.h". Because +noddy_NoddyObject is the ultimate trivial extension type, +the example is a bit contrived: it wraps a function for which all +information is contained in the type of its return value. + +

    C++ module definition

    + +
    +#include <boost/python/reference.hpp>
    +#include <boost/python/module.hpp>
    +#include "noddy.h"
    +
    +struct tag {};
    +tag make_tag() { return tag(); }
    +
    +using namespace boost::python;
    +
    +struct tag_to_noddy
    +{
    +    static PyObject* convert(tag const& x)
    +    {
    +        return PyObject_New(noddy_NoddyObject, &noddy_NoddyType);
    +    }
    +};
    +
    +BOOST_PYTHON_MODULE_INIT(to_python_converter)
    +{
    +    module to_python("to_python_converter")
    +        .def("make_tag", make_tag)
    +        ;
    +    to_python_converter<tag, tag_to_noddy>();
    +}
    +
    + +

    Python code

    + +
    +>>> import to_python_converter
    +>>> def always_none():
    +...     return None
    +...
    +>>> def choose_function(x):
    +...     if (x % 2 != 0):
    +...         return to_python_converter.make_tag
    +...     else:
    +...         return always_none
    +...
    +>>> a = [ choose_function(x) for x in range(5) ]
    +>>> b = [ f() for f in a ]
    +>>> type(b[0])
    +<type 'NoneType'>
    +>>> type(b[1])
    +<type 'Noddy'>
    +>>> type(b[2])
    +<type 'NoneType'>
    +>>> type(b[3])
    +<type 'Noddy'>
    +
    + +

    Revised + + 05 November, 2001 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From 80effaa541f56a973a8f03e03b444500d1af4ece Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Feb 2002 16:01:37 +0000 Subject: [PATCH 0260/1042] *** empty log message *** [SVN r12836] --- doc/boost.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/boost.css b/doc/boost.css index c382d4c6..cf5c8a97 100644 --- a/doc/boost.css +++ b/doc/boost.css @@ -23,10 +23,12 @@ BODY PRE { MARGIN-LEFT: 2pc; + FONT-SIZE: 80%; BACKGROUND-COLOR: #dfffff } CODE { + FONT-SIZE: 95%; white-space: pre } .index From dcae0eadd5af2bdc631d0428ff0c5dfc2ede0c4d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Feb 2002 16:42:26 +0000 Subject: [PATCH 0261/1042] *** empty log message *** [SVN r12839] --- doc/v2/return_internal_reference.html | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/v2/return_internal_reference.html b/doc/v2/return_internal_reference.html index 8cbfc167..42b8c97e 100644 --- a/doc/v2/return_internal_reference.html +++ b/doc/v2/return_internal_reference.html @@ -55,7 +55,8 @@ argument or from the target of a member function to be returned safely without making a copy of the referent. The default for its first template argument handles the common case where the - containing object is the target (*this) of a wrapped member function. + containing object is the target (*this) of a wrapped + member function.

    Classes

    @@ -84,7 +85,10 @@ The index of the parameter which contains the object to which the reference or pointer is being returned. If used to wrap a member function, parameter 1 is the target object - (*this). + (*this). Note that if the target Python object + type doesn't support weak references, a Python + TypeError exception will be raised when the + function being wrapped is called. 1 @@ -125,7 +129,7 @@ PyObject* postcall(PyObject* args, PyObject* result);
    -
    Requires: PyTuple_Check(args) != 0 +
    Requires: PyTuple_Check(args) != 0
    Returns: make_custodian_and_ward_postcall::postcall(args, result)
    From aeccf45d4e0041c6a4a56ce31d4e8fc2f1ef8fce Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Feb 2002 18:10:30 +0000 Subject: [PATCH 0262/1042] *** empty log message *** [SVN r12840] --- doc/v2/to_python_indirect.html | 194 +++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 doc/v2/to_python_indirect.html diff --git a/doc/v2/to_python_indirect.html b/doc/v2/to_python_indirect.html new file mode 100644 index 00000000..8910cd97 --- /dev/null +++ b/doc/v2/to_python_indirect.html @@ -0,0 +1,194 @@ + + + + + + Boost.Python - <boost/python/to_python_indirect.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/to_python_indirect.hpp>

    +
    +
    + +

    Contents

    + +
    +
    Introduction + + +
    Classes + +
    +
    +
    Class Template to_python_indirect + +
    +
    + +
    Class Template + to_python_indirect synopsis + +
    Class Template + to_python_indirect observer functions + +
    Class Template + to_python_indirect static functions +
    +
    + +
    Example +
    +
    + +

    Introduction

    + + <boost/python/to_python_indirect.hpp> supplies + a way to construct new Python objects that hold wrapped C++ class + instances via a pointer or smart pointer. + +

    Classes

    + +

    Class template to_python_indirect

    +

    Class template to_python_indirect converts objects +of its first argument type to python as extension class instances, using the ownership policy provided by its 2nd argument. + +

    + + + + + + + +
    + to_python_indirect Requirements
    + + In the table below, x denotes an object of + type T, h denotes an + object of type + boost::python::objects::instance_holder*, and + p denotes an object of type + U*. + +
    Parameter + + Requirements + + Description + +
    T + + Either U cv& + (where cv is any optional cv-qualification) or a Dereferenceable type such that + *x is convertible to U const&, where + U is a class type. + + A type deferencing a C++ class exposed to Python using + class template class_. + +
    MakeHolder + + h = MakeHolder::execute(p); + + A class whose static execute() creates an + instance_holder. + +
    + + Instantiations of to_python_indirect are models of ResultConverter. + + +

    Class template to_python_indirect synopsis

    +
    +namespace boost { namespace python
    +{
    +  template <class T, class MakeHolder>
    +  struct to_python_indirect
    +  {
    +     static bool convertible();
    +     PyObject* operator()(T ptr_or_reference) const;
    +   private:
    +     static PyTypeObject* type();
    +  };
    +}}
    +
    + +

    Class template to_python_indirect observers

    +
    +PyObject* operator()(T x) const;
    +
    + +
    + +
    Requires: x refers to an object (if it + is a pointer type, it is non-null). convertible() == + true. + +
    Effects: Creates an appropriately-typed Boost.Python + extension class instance, uses MakeHolder to create + an instance_holder from x, installs + the instance_holder in the new extension class + instance, and returns a pointer to it. + +
    + + +

    Class template to_python_indirect statics

    +
    +bool convertible();
    +
    + +
    Effects: Returns true iff any module has + registered a Python type corresponding to U. + +

    Example

    + +This example replicates the functionality of reference_existing_object, +but without some of the compile-time error checking. + + +
    +
    +struct make_reference_holder
    +{
    +   typedef boost::python::objects::instance_holder* result_type;
    +   template <class T>
    +   static result_type execute(T* p)
    +   {
    +      return new boost::python::objects::pointer_holder<T*, T>(p);
    +   }
    +};
    +
    +struct reference_existing_object
    +{
    +   // metafunction returning the ResultConverter
    +   template <class T>
    +   struct apply
    +   {
    +      typedef boost::python::to_python_indirect<T,make_reference_holder> type;
    +   };
    +};
    +
    + +

    Revised + + 16 February, 2002 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From ca872af3c8147c8fc3eef2594698b08a8b147a7d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Feb 2002 18:11:24 +0000 Subject: [PATCH 0263/1042] HolderGenerator renamed to MakeHolder [SVN r12841] --- include/boost/python/to_python_indirect.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index e68eced0..306b3246 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -14,7 +14,7 @@ namespace boost { namespace python { -template +template struct to_python_indirect { static bool convertible(); @@ -61,14 +61,14 @@ namespace detail }; } -template -inline bool to_python_indirect::convertible() +template +inline bool to_python_indirect::convertible() { return type() != 0; } -template -inline PyObject* to_python_indirect::operator()(T x) const +template +inline PyObject* to_python_indirect::operator()(T x) const { PyObject* raw_result = type()->tp_alloc(type(), 0); @@ -82,7 +82,7 @@ inline PyObject* to_python_indirect::operator()(T x) const // Build a value_holder to contain the object using the copy // constructor objects::instance_holder* p = - detail::unwind_type(x); + detail::unwind_type(x); // Install it in the instance p->install(raw_result); @@ -91,8 +91,8 @@ inline PyObject* to_python_indirect::operator()(T x) const return result.release(); } -template -inline PyTypeObject* to_python_indirect::type() +template +inline PyTypeObject* to_python_indirect::type() { return detail::unwind_type(); } From 8af49161fbe031ebe59458123c133fe37bd4ef87 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 17 Feb 2002 04:37:35 +0000 Subject: [PATCH 0264/1042] no message [SVN r12845] --- doc/v2/class.html | 4 ++-- doc/v2/class_hpp.py | 20 -------------------- doc/v2/errors.html | 4 ++-- doc/v2/lvalue_from_python.html | 4 ++-- doc/v2/module.html | 10 +++++----- 5 files changed, 11 insertions(+), 31 deletions(-) delete mode 100644 doc/v2/class_hpp.py diff --git a/doc/v2/class.html b/doc/v2/class.html index fc64eabd..393510eb 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -175,7 +175,7 @@ class_(char const* name)

    Requires: name is a ntbs which conforms to Python's identifier + "http://www.python.org/doc/2.2/ref/identifiers.html">identifier naming rules.
    Effects: Constructs a class_ object which @@ -198,7 +198,7 @@ class_& def(char const* name, Fn f, CallPolicy policy)
    Requires: f is a non-null pointer-to-function or pointer-to-member-function. name is a ntbs which conforms to Python's identifier + "http://www.python.org/doc/2.2/ref/identifiers.html">identifier naming rules. In the first form, the return type of f is not a reference and is not a pointer other than char const* or PyObject*. In the diff --git a/doc/v2/class_hpp.py b/doc/v2/class_hpp.py deleted file mode 100644 index 9af2cb5c..00000000 --- a/doc/v2/class_hpp.py +++ /dev/null @@ -1,20 +0,0 @@ -introduction = ''' -''' - -class boost(namespace): pass - -class python(boost): - - class class_(class_template): - T = type() - T.requires = 'a class type' - - Bases = concepts.mpl_sequence('class type') - HolderGenerator = concepts.HolderGenerator() - template_args = (T, Bases, HolderGenerator) - - class def_1(function_template): - name = "def" - args = (('char const*', 'name'), ('F', 'f')) - -class_template diff --git a/doc/v2/errors.html b/doc/v2/errors.html index e52f29f7..603bd28b 100644 --- a/doc/v2/errors.html +++ b/doc/v2/errors.html @@ -65,7 +65,7 @@

    error_already_set is an exception type which can be thrown to indicate that a Python error has occurred. If thrown, the precondition is that PyErr_Occurred() + "http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred() returns a value convertible to true.

    Class error_already_set synopsis

    @@ -131,7 +131,7 @@ template <class T> T* expect_non_null(T* x);
    Rationale: Simplifies error-handling when calling many functions in the Python/C API, which + "http://www.python.org/doc/2.2/api/api.html">Python/C API, which return 0 on error.
    diff --git a/doc/v2/lvalue_from_python.html b/doc/v2/lvalue_from_python.html index 03af54f8..a0591128 100644 --- a/doc/v2/lvalue_from_python.html +++ b/doc/v2/lvalue_from_python.html @@ -99,7 +99,7 @@ python_type A compile-time constant PyTypeObject* + href="http://www.python.org/doc/2.2/ext/dnt-type-methods.html">PyTypeObject* The Python type of instances convertible by this converter. Python subtypes are also convertible. @@ -213,7 +213,7 @@ Member& execute(Class& c);

    Example

    This example presumes that someone has implemented the standard noddy +href="http://www.python.org/doc/2.2/ext/dnt-basics.html">noddy example module from the Python documentation, and we want to build a module which manipulates Noddys. Since noddy_NoddyObject is so simple that it carries no diff --git a/doc/v2/module.html b/doc/v2/module.html index 0e3516ed..847ff017 100644 --- a/doc/v2/module.html +++ b/doc/v2/module.html @@ -67,11 +67,11 @@

    BOOST_PYTHON_MODULE_INIT(name) is used to declare Python + "http://www.python.org/doc/2.2/ext/methodTable.html#SECTION003400000000000000000"> module initialization functions. The name argument must exactly match the name of the module to be initialized, and must conform to Python's identifier naming + "http://www.python.org/doc/2.2/ref/identifiers.html">identifier naming rules. Where you would normally write

     void initname()
    @@ -150,7 +150,7 @@ module& setattr(const char* name, ref const& r);
         
    Requires: name is a ntbs which conforms to Python's identifier + "http://www.python.org/doc/2.2/ref/identifiers.html">identifier naming rules. In the first two forms, obj is non-null. In the third form, r.get() is non-null. @@ -176,7 +176,7 @@ module& add(class_<T,Bases,HolderGenerator> const& c);
    Effects: The first form adds the Python type object named by x to the Python module under construction, with the name given by the type's tp_name + "http://www.python.org/doc/2.2/ext/dnt-type-methods.html">tp_name field. The second form adds the extension class object being constructed by c to the module, with the same name that was passed to c's constructor. @@ -199,7 +199,7 @@ module& def(char const* name, Fn f, ResultHandler handler);
    Requires: f is a non-null pointer-to-function or pointer-to-member-function. name is a ntbs which conforms to Python's identifier + "http://www.python.org/doc/2.2/ref/identifiers.html">identifier naming rules. In the first form, the return type of f is not a reference and is not a pointer other than char const* or PyObject*. In the From b75d11da3ac1165a607633624963b615abcce54c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 17 Feb 2002 22:29:43 +0000 Subject: [PATCH 0265/1042] Bug fix thanks to Min Xu [SVN r12849] --- src/object/class.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index 6a839fb2..60a803f9 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -205,7 +205,7 @@ namespace std::vector::const_iterator p = boost::detail::lower_bound(start, finish, id); - if (p == finish && p->key != id) + if (p == finish || p->key != id) { string report("extension class wrapper for base class "); (report += id.name()) += " has not been created yet"; From 622ff9d764e8ddbc94af41260f579a1525ed0b62 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 18 Feb 2002 23:00:06 +0000 Subject: [PATCH 0266/1042] *** empty log message *** [SVN r12855] --- doc/v2/class.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/class.html b/doc/v2/class.html index 393510eb..c28f0317 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -210,7 +210,7 @@ class_& def(char const* name, Fn f, CallPolicy policy) the Boost.Python extension class being defined, with the given name. If the extension class already has an attribute named name, the usual overloading procedure applies. + "overloading.html">overloading procedure applies.
    Returns: *this
    From 266923d9e8fbdaa65bdb2e63850a41f37393c5cc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Feb 2002 05:12:47 +0000 Subject: [PATCH 0267/1042] Removed useless default arg -- it was confusing MSVC [SVN r12860] --- include/boost/python/class.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 978a226a..8dede0e3 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -122,7 +122,7 @@ class class_ : private objects::class_base // Define the constructor with the given Args, which should be an // MPL sequence of types. template - self& def_init(Args const& = Args()) + self& def_init(Args const&) { def("__init__", make_constructor()); return *this; From 07abc9fac480b6674702a8317186ee718e9b20c6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Feb 2002 05:13:24 +0000 Subject: [PATCH 0268/1042] initial checkin [SVN r12861] --- include/boost/python/lvalue_from_python.hpp | 96 +++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 include/boost/python/lvalue_from_python.hpp diff --git a/include/boost/python/lvalue_from_python.hpp b/include/boost/python/lvalue_from_python.hpp new file mode 100644 index 00000000..c5d09ff5 --- /dev/null +++ b/include/boost/python/lvalue_from_python.hpp @@ -0,0 +1,96 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef LVALUE_FROM_PYTHON_DWA2002130_HPP +# define LVALUE_FROM_PYTHON_DWA2002130_HPP + +# include +# include + +namespace boost { namespace python { + +// Utility which produces a member extractor function on platforms +// other than VC6. +template +struct get_member +{ + static Member& execute(Class& c) + { + return c.*mp; + } +}; + +namespace detail +{ + template + struct extract_identity + { + static Class& execute(Class& c) + { + return c; + } + }; +} + +template < + PyTypeObject const* python_type + , class Value + , class PythonObject = Value + , class Extract = detail::extract_identity + > +class lvalue_from_python +{ + typedef type_from_python convertible_t; + public: + + lvalue_from_python() + : m_mutable_converter( + &convertible_t::convertible, convert_mutable) + + , m_const_converter( + &convertible_t::convertible, convert_const) + + , m_mutable_pointer_converter( + &convertible_t::convertible, convert_mutable_pointer) + + , m_const_pointer_converter( + &convertible_t::convertible, convert_const_pointer) + {} + + private: + static Value& convert_mutable(PyObject* op, converter::from_python_data&) + { + return Extract::execute(*(PythonObject*)op); + } + + static Value const& convert_const(PyObject* op, converter::from_python_data&) + { + return Extract::execute(*(PythonObject*)op); + } + + static Value* convert_mutable_pointer(PyObject* op, converter::from_python_data&) + { + return &Extract::execute(*(PythonObject*)op); + } + + static Value const* convert_const_pointer(PyObject* op, converter::from_python_data&) + { + return &Extract::execute(*(PythonObject*)op); + } + + typedef converter::from_python_converter mutable_converter; + typedef converter::from_python_converter const_converter; + typedef converter::from_python_converter mutable_pointer_converter; + typedef converter::from_python_converter const_pointer_converter; + + mutable_converter m_mutable_converter; + const_converter m_const_converter; + mutable_pointer_converter m_mutable_pointer_converter; + const_pointer_converter m_const_pointer_converter; +}; + +}} // namespace boost::python + +#endif // LVALUE_FROM_PYTHON_DWA2002130_HPP From 47c1c6288ccd4a92fbb6f856ddf484640897c094 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Feb 2002 05:14:41 +0000 Subject: [PATCH 0269/1042] Added error checking [SVN r12862] --- .../python/return_internal_reference.hpp | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp index 2f567e55..356bc9ed 100644 --- a/include/boost/python/return_internal_reference.hpp +++ b/include/boost/python/return_internal_reference.hpp @@ -9,14 +9,32 @@ # include # include # include +# include namespace boost { namespace python { +namespace detail +{ + template + struct return_internal_reference_owner_arg_must_be_greater_than_zero +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} +# endif + ; +} + template struct return_internal_reference : with_custodian_and_ward_postcall<0, owner_arg, Base> { - typedef reference_existing_object result_converter; + private: + BOOST_STATIC_CONSTANT(bool, legal = owner_arg > 0); + public: + typedef typename mpl::select_type< + legal + , reference_existing_object + , detail::return_internal_reference_owner_arg_must_be_greater_than_zero + >::type result_converter; }; }} // namespace boost::python From 361455678a781b9629c1730ef1b2e490d1c2d93d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Feb 2002 05:15:14 +0000 Subject: [PATCH 0270/1042] updated concept names [SVN r12864] --- include/boost/python/return_value_policy.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/return_value_policy.hpp b/include/boost/python/return_value_policy.hpp index 0beec47b..6a2036d7 100644 --- a/include/boost/python/return_value_policy.hpp +++ b/include/boost/python/return_value_policy.hpp @@ -9,10 +9,10 @@ namespace boost { namespace python { -template +template struct return_value_policy : Base { - typedef Handler result_converter; + typedef ResultConverterGenerator result_converter; }; }} // namespace boost::python From 7f420361b1efa72126ce74632dea921677ad542e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Feb 2002 05:15:40 +0000 Subject: [PATCH 0271/1042] updated template parameter names [SVN r12865] --- include/boost/python/to_python_converter.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/to_python_converter.hpp b/include/boost/python/to_python_converter.hpp index 6bea9822..7e46c505 100644 --- a/include/boost/python/to_python_converter.hpp +++ b/include/boost/python/to_python_converter.hpp @@ -12,7 +12,7 @@ namespace boost { namespace python { -template +template struct to_python_converter { to_python_converter(); @@ -22,11 +22,11 @@ struct to_python_converter // implementation // -template -to_python_converter::to_python_converter() +template +to_python_converter::to_python_converter() { typedef converter::as_to_python_value_function< - T, Derived + T, Conversion > normalized; converter::registry::insert( From 43bcbf771e822acffe8244edf96e42e13f06909b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Feb 2002 05:18:12 +0000 Subject: [PATCH 0272/1042] added more-rigorous tests [SVN r12866] --- test/m1.cpp | 40 ++++++++++++++++++++++++++++++++++++---- test/newtest.py | 12 ++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/test/m1.cpp b/test/m1.cpp index b42742ab..723b471d 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -141,6 +141,26 @@ int f(simple const& s) return strlen(s.s); } +int f_mutable_ref(simple& s) +{ + return strlen(s.s); +} + +int f_mutable_ptr(simple* s) +{ + return strlen(s->s); +} + +int f_const_ptr(simple const* s) +{ + return strlen(s->s); +} + +int f2(SimpleObject const& s) +{ + return strlen(s.x.s); +} + // A trivial passthru function for simple objects simple const& g(simple const& x) { @@ -188,7 +208,7 @@ BOOST_PYTHON_MODULE_INIT(m1) using boost::python::module; using boost::python::class_; using boost::python::converter::from_python_converter; - using boost::python::reference_from_python; + using boost::python::lvalue_from_python; using boost::python::value_from_python; using boost::python::type_from_python; using boost::python::get_member; @@ -205,14 +225,21 @@ BOOST_PYTHON_MODULE_INIT(m1) static from_python_converter c3( &(boost::python::type_from_python<&NoddyType>::convertible), noddy_to_int_ref); - static boost::python::reference_from_python< + static boost::python::lvalue_from_python< &SimpleType , simple , SimpleObject +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + , boost::python::get_member +#else , extract_simple_object +#endif > unwrap_simple; + static boost::python::lvalue_from_python<&SimpleType, SimpleObject> + unwrap_simple2; + module m1("m1"); typedef boost::python::objects::pointer_holder_generator< @@ -229,9 +256,14 @@ BOOST_PYTHON_MODULE_INIT(m1) .def("new_noddy", new_noddy) .def("new_simple", new_simple) - // Expose f() + // Expose f() in all its variations .def("f", f) + .def("f_mutable_ref", f_mutable_ref) + .def("f_mutable_ptr", f_mutable_ptr) + .def("f_const_ptr", f_const_ptr) + .def("f2", f2) + // Expose g() .def("g", g , return_value_policy() ) diff --git a/test/newtest.py b/test/newtest.py index 4e6de142..b89764d1 100644 --- a/test/newtest.py +++ b/test/newtest.py @@ -57,6 +57,18 @@ try: wrap_int_ref(n) >>> f(g(s)) 12 +>>> f_mutable_ref(g(s)) +12 + +>>> f_const_ptr(g(s)) +12 + +>>> f_mutable_ptr(g(s)) +12 + +>>> f2(g(s)) +12 + Create an extension class which wraps "complicated" (init1 and get_n) are a complicated constructor and member function, respectively. From d660c12a745d840c6a81221b2da7a562275158f2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Feb 2002 05:19:39 +0000 Subject: [PATCH 0273/1042] editorial fix [SVN r12867] --- doc/v2/return_internal_reference.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/return_internal_reference.html b/doc/v2/return_internal_reference.html index 42b8c97e..347db88c 100644 --- a/doc/v2/return_internal_reference.html +++ b/doc/v2/return_internal_reference.html @@ -131,7 +131,7 @@ PyObject* postcall(PyObject* args, PyObject* result);
    Requires: PyTuple_Check(args) != 0 -
    Returns: make_custodian_and_ward_postcall::postcall(args, result) +
    Returns: with_custodian_and_ward_postcall::postcall(args, result)
    From d965b41bddee5db615ff7c10d87baa7d1c05c00c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 21 Feb 2002 01:24:28 +0000 Subject: [PATCH 0274/1042] Fix GC problems [SVN r12869] --- src/object/class.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index 60a803f9..d35a7b5e 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -45,8 +45,8 @@ PyTypeObject class_metatype_object = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC + | Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -119,8 +119,8 @@ PyTypeObject class_type_object = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC + | Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ From 6c7d3e1eab3b1b166c8f1ea5ed96373e0a84fb62 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 23 Feb 2002 21:26:55 +0000 Subject: [PATCH 0275/1042] inital checkin [SVN r12915] --- .../python/converter/pointer_type_id.hpp | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 include/boost/python/converter/pointer_type_id.hpp diff --git a/include/boost/python/converter/pointer_type_id.hpp b/include/boost/python/converter/pointer_type_id.hpp new file mode 100644 index 00000000..79a30b02 --- /dev/null +++ b/include/boost/python/converter/pointer_type_id.hpp @@ -0,0 +1,69 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef POINTER_TYPE_ID_DWA2002222_HPP +# define POINTER_TYPE_ID_DWA2002222_HPP + +# include +# include + +namespace boost { namespace python { namespace converter { + +namespace detail +{ + template + struct pointer_typeid_select + { + template + static inline undecorated_type_id_t execute(T*(*)() = 0) + { + return undecorated_type_id(); + } + }; + + template <> + struct pointer_typeid_select + { + template + static inline undecorated_type_id_t execute(T* const volatile&(*)() = 0) + { + return undecorated_type_id(); + } + + template + static inline undecorated_type_id_t execute(T*volatile&(*)() = 0) + { + return undecorated_type_id(); + } + + template + static inline undecorated_type_id_t execute(T*const&(*)() = 0) + { + return undecorated_type_id(); + } + + template + static inline undecorated_type_id_t execute(T*&(*)() = 0) + { + return undecorated_type_id(); + } + }; +} + +// Usage: pointer_type_id() +// +// Returns an undecorated_type_id_t associated with the type pointed +// to by T, which may be a pointer or a reference to a pointer. +template +undecorated_type_id_t pointer_type_id(T(*)() = 0) +{ + return detail::pointer_typeid_select< + is_reference::value + >::execute((T(*)())0); +} + +}}} // namespace boost::python::converter + +#endif // POINTER_TYPE_ID_DWA2002222_HPP From a04cbd111c85a64acf4f4a70d2f1b8589765636b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Feb 2002 04:47:48 +0000 Subject: [PATCH 0276/1042] bug fix [SVN r12922] --- include/boost/python/detail/indirect_traits.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index 41681719..8c096a2f 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -27,13 +27,13 @@ struct is_reference_to_const template struct is_reference_to_non_const { - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -template -struct is_reference_to_non_const -{ - BOOST_STATIC_CONSTANT(bool, value = true); + BOOST_STATIC_CONSTANT( + bool, value = ( + ::boost::type_traits::ice_and< + ::boost::is_reference::value + , !::boost::python::detail::is_reference_to_const::value + >::value) + ); }; template From e11b457b79093b038ee1edcf0ec6ed021cf6a067 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Feb 2002 05:24:48 +0000 Subject: [PATCH 0277/1042] Major rearchitecture of from_python mechanism [SVN r12924] --- Jamfile | 34 +- doc/v2/module.html | 2 +- include/boost/python/converter/body.hpp | 62 --- include/boost/python/converter/class.hpp | 75 ---- .../python/converter/find_from_python.hpp | 25 ++ .../boost/python/converter/from_python.hpp | 386 +++++++++++------- .../python/converter/from_python_data.hpp | 89 ++-- .../python/converter/from_python_function.hpp | 9 +- .../converter/from_python_stage1_data.hpp | 21 + .../boost/python/converter/registrations.hpp | 28 ++ include/boost/python/converter/registry.hpp | 19 +- include/boost/python/converter/target.hpp | 191 --------- .../boost/python/converter/unwrapper_base.hpp | 36 -- include/boost/python/detail/destroy.hpp | 83 ++++ include/boost/python/from_python.hpp | 5 +- include/boost/python/lvalue_from_python.hpp | 96 ----- include/boost/python/object/class.hpp | 18 +- .../boost/python/object/class_converters.hpp | 7 +- .../boost/python/object/pointer_holder.hpp | 8 +- include/boost/python/object/value_holder.hpp | 6 +- .../boost/python/reference_from_python.hpp | 62 --- include/boost/python/type_from_python.hpp | 87 +++- include/boost/python/value_from_python.hpp | 73 ---- src/converter/body.cpp | 18 - src/converter/builtin_converters.cpp | 247 +++++------ src/converter/from_python.cpp | 43 +- src/converter/handle.cpp | 35 -- src/converter/registry.cpp | 53 ++- src/converter/unwrap.cpp | 36 -- src/converter/unwrapper.cpp | 31 -- src/converter/wrapper.cpp | 41 -- src/object/class.cpp | 2 +- test/destroy_test.cpp | 81 ++++ test/indirect_traits_test.cpp | 48 +++ test/m1.cpp | 51 +-- test/pointer_type_id_test.cpp | 39 ++ 36 files changed, 929 insertions(+), 1218 deletions(-) delete mode 100644 include/boost/python/converter/body.hpp delete mode 100644 include/boost/python/converter/class.hpp create mode 100644 include/boost/python/converter/find_from_python.hpp create mode 100644 include/boost/python/converter/from_python_stage1_data.hpp create mode 100644 include/boost/python/converter/registrations.hpp delete mode 100644 include/boost/python/converter/target.hpp delete mode 100644 include/boost/python/converter/unwrapper_base.hpp create mode 100644 include/boost/python/detail/destroy.hpp delete mode 100644 include/boost/python/lvalue_from_python.hpp delete mode 100644 include/boost/python/reference_from_python.hpp delete mode 100644 include/boost/python/value_from_python.hpp delete mode 100644 src/converter/body.cpp delete mode 100644 src/converter/handle.cpp delete mode 100644 src/converter/unwrap.cpp delete mode 100644 src/converter/unwrapper.cpp delete mode 100644 src/converter/wrapper.cpp create mode 100644 test/destroy_test.cpp create mode 100644 test/indirect_traits_test.cpp create mode 100644 test/pointer_type_id_test.cpp diff --git a/Jamfile b/Jamfile index aa804505..79dfd9e5 100644 --- a/Jamfile +++ b/Jamfile @@ -4,14 +4,18 @@ subproject libs/python ; SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; -PYTHON_PROPERTIES - += <*>"-inline deferred" - <*>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers - BOOST_PYTHON_DYNAMIC_LIB - BOOST_PYTHON_V2 - ; { + local BOOST_PYTHON_V2_PROPERTIES + = $(PYTHON_PROPERTIES) + <*>"-inline deferred" + <*>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers + BOOST_PYTHON_DYNAMIC_LIB + BOOST_PYTHON_V2 + ; + + local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) ; + dll bpl : src/converter/from_python.cpp @@ -26,7 +30,7 @@ PYTHON_PROPERTIES src/objects.cpp src/converter/builtin_converters.cpp : - $(PYTHON_PROPERTIES) + $(BOOST_PYTHON_V2_PROPERTIES) BOOST_PYTHON_SOURCE ; @@ -67,4 +71,20 @@ PYTHON_PROPERTIES : : debug-python ; + } + +unit-test indirect_traits_test + : test/indirect_traits_test.cpp : $(BOOST_ROOT) ; +unit-test destroy_test + : test/destroy_test.cpp : $(BOOST_ROOT) ; +unit-test pointer_type_id_test + : test/pointer_type_id_test.cpp : $(BOOST_ROOT) ; + +unit-test select_from_python_test + : test/select_from_python_test.cpp + src/converter/type_id.cpp + src/converter/registry.cpp # MWerks needs this for some reason + : $(PYTHON_PROPERTIES) + ; + diff --git a/doc/v2/module.html b/doc/v2/module.html index 847ff017..3775e4d1 100644 --- a/doc/v2/module.html +++ b/doc/v2/module.html @@ -157,7 +157,7 @@ module& setattr(const char* name, ref const& r);
    Effects: Adds the given Python object to the module. If the object is a product of make_function(), the - usual overloading procedure applies. + usual overloading procedure applies. In the first two forms, ownership of a reference to obj is transferred from caller to callee, even if an exception is thrown. diff --git a/include/boost/python/converter/body.hpp b/include/boost/python/converter/body.hpp deleted file mode 100644 index d9170839..00000000 --- a/include/boost/python/converter/body.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef BODY_DWA2001127_HPP -# define BODY_DWA2001127_HPP -# include -# include - -namespace boost { namespace python { namespace converter { - -namespace registry -{ - class entry; -} - -struct BOOST_PYTHON_DECL body -{ - public: - body(type_id_t key); - virtual ~body() {} - - type_id_t key() const; - - protected: - // true iff the registry is still alive - bool can_unregister() const; - - private: - // called when the registry is destroyed, to prevent it from being - // unregistered. - void do_not_unregister(); - friend class registry::entry; - - private: - type_id_t m_key; - bool m_can_unregister; -}; - -// -// implementations -// -inline body::body(type_id_t key) - : m_key(key) - , m_can_unregister(true) -{ -} - -inline type_id_t body::key() const -{ - return m_key; -} - -inline bool body::can_unregister() const -{ - return m_can_unregister; -} - -}}} // namespace boost::python::converter - -#endif // BODY_DWA2001127_HPP diff --git a/include/boost/python/converter/class.hpp b/include/boost/python/converter/class.hpp deleted file mode 100644 index 67de6fad..00000000 --- a/include/boost/python/converter/class.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_DWA20011215_HPP -# define CLASS_DWA20011215_HPP - -# include -# include - -namespace boost { namespace python { namespace converter { - -template -struct class_from_python_converter -{ - class_from_python_converter(); - - static void* convertible(PyObject*); - static T& convert_ref(PyObject*, from_python_data&); - static T const& convert_cref(PyObject*, from_python_data&); - static T* convert_ptr(PyObject*, from_python_data&); - static T const* convert_cptr(PyObject*, from_python_data&); - - from_python_converter to_ref; - from_python_converter to_cref; - from_python_converter to_ptr; - from_python_converter to_cptr; -}; - -// -// implementations -// -template -class_from_python_converter::class_from_python_converter() - : to_ref(convertible, convert_ref) - , to_cref(convertible, convert_cref) - , to_ptr(convertible, convert_ptr) - , to_cptr(convertible, convert_cptr) -{} - -template -T& class_from_python_converter::convert_ref(PyObject*, from_python_data& x) -{ - return *static_cast(x.stage1); -} - -template -T const& class_from_python_converter::convert_cref(PyObject*, from_python_data& x) -{ - return *static_cast(x.stage1); -} - - -template -T* class_from_python_converter::convert_ptr(PyObject*, from_python_data& x) -{ - return static_cast(x.stage1); -} - -template -T const* class_from_python_converter::convert_cptr(PyObject*, from_python_data& x) -{ - return static_cast(x.stage1); -} - -template -void* class_from_python_converter::convertible(PyObject* p) -{ - return objects::find_instance(p); -} - -}}} // namespace boost::python::converter - -#endif // CLASS_DWA20011215_HPP diff --git a/include/boost/python/converter/find_from_python.hpp b/include/boost/python/converter/find_from_python.hpp new file mode 100644 index 00000000..863c44a6 --- /dev/null +++ b/include/boost/python/converter/find_from_python.hpp @@ -0,0 +1,25 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FIND_FROM_PYTHON_DWA2002223_HPP +# define FIND_FROM_PYTHON_DWA2002223_HPP + +# include +# include + +namespace boost { namespace python { namespace converter { + +struct lvalue_from_python_registration; +struct rvalue_from_python_registration; +struct rvalue_stage1_data; + +BOOST_PYTHON_DECL void* find( + PyObject* source, lvalue_from_python_registration const*); +BOOST_PYTHON_DECL void* find( + PyObject* source, rvalue_from_python_registration const*, rvalue_stage1_data&); + +}}} // namespace boost::python::converter + +#endif // FIND_FROM_PYTHON_DWA2002223_HPP diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index b6e1edc4..0881a06a 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -6,193 +6,279 @@ #ifndef FROM_PYTHON_DWA2002127_HPP # define FROM_PYTHON_DWA2002127_HPP -# include -# include -# include -# include -# include -# include +# include # include -# include +# include +# include +# include +# include +# include +# include -namespace boost { namespace python { namespace converter { +namespace boost { namespace python { namespace converter { -// The type of convertibility checking functions -typedef void* (*from_python_check)(PyObject*); -typedef void (*from_python_destructor)(from_python_data&); - -// forward declaration -template struct from_python_lookup; - -// from_python -- -// A body class representing a conversion from python to C++. - -struct BOOST_PYTHON_DECL from_python_converter_base : body +struct from_python_base { - from_python_converter_base(type_id_t, from_python_check); // registers + public: // member functions + from_python_base(void* result); + from_python_base(PyObject*, lvalue_from_python_registration const* chain); + bool convertible() const; + + protected: // member functions + void*const& result() const; + + private: // data members + void* m_result; +}; - // Must return non-null iff the conversion will be successful. Any - // non-null pointer is acceptable, and will be passed on to the - // convert() function, so useful data can be stored there. - inline void* convertible(PyObject*) const; - - // Given the head of a from_python converter chain, find the - // converter which can convert p, leaving its intermediate data in - // data. - inline static from_python_converter_base const* - find(from_python_converter_base const*chain, PyObject* p, void*& data); +// Used when T == U*const& +template +struct pointer_const_reference_from_python +{ + pointer_const_reference_from_python(PyObject*); + T operator()(PyObject*) const; + bool convertible() const; private: - from_python_check m_convertible; - from_python_converter_base* m_next; + detail::referent_storage::type m_result; + + static lvalue_from_python_registration*& chain; }; - +// Used when T == U* template -struct from_python_converter : from_python_converter_base +struct pointer_from_python : from_python_base { - public: // types - typedef typename from_python_function::type conversion_function; + pointer_from_python(PyObject*); + T operator()(PyObject*) const; - public: // member functions - from_python_converter(from_python_check, conversion_function, from_python_destructor = 0); - T convert(PyObject*, from_python_data&) const; - void destroy(from_python_data&) const; - - // Find a converter for converting p to a T. - static from_python_converter const* find(PyObject* p, void*& data); - - private: // data members - conversion_function m_convert; - from_python_destructor m_destroy; - - // Keeps the chain of converters which convert from PyObject* to T - static from_python_converter_base*const& chain; + static lvalue_from_python_registration*& chain; }; -// Initialized to refer to a common place in the registry. +// Used when T == U& and (T != V const& or T == W volatile&) template -from_python_converter_base*const& -from_python_converter::chain = registry::from_python_chain(type_id()); - -// ------------------------------------------------------------------------- - -// A class which implements from_python with a registry lookup. -template -struct from_python_lookup // : from_python_base +struct reference_from_python : from_python_base { - public: // types + reference_from_python(PyObject*); + T operator()(PyObject*) const; - public: // member functions - from_python_lookup(PyObject* source); - ~from_python_lookup(); + static lvalue_from_python_registration*& chain; +}; +// ------- rvalue converters --------- + +// Used for the case where T is a non-pointer, non-reference type OR +// is a const non-volatile reference to a non-pointer type. +template +class rvalue_from_python +{ + typedef typename boost::add_reference< + typename boost::add_const::type + >::type result_type; + + public: + rvalue_from_python(PyObject*); + ~rvalue_from_python(); bool convertible() const; - T operator()(PyObject*); - - public: // functions for use by conversion implementations - // Get the converter object - from_python_converter const* converter() const; - private: // data members - typedef typename from_python_intermediate_data::type intermediate_t; - mutable intermediate_t m_intermediate_data; - from_python_converter const* m_converter; + result_type operator()(PyObject*); + + private: + rvalue_data m_data; + static rvalue_from_python_registration*& chain; +}; + +template +struct select_from_python +{ + BOOST_STATIC_CONSTANT( + bool, ptr = is_pointer::value); + + BOOST_STATIC_CONSTANT( + bool, ptr_cref + = boost::python::detail::is_reference_to_pointer::value + && boost::python::detail::is_reference_to_const::value + && !boost::python::detail::is_reference_to_volatile::value); + + + BOOST_STATIC_CONSTANT( + bool, ref = + boost::python::detail::is_reference_to_non_const::value + || boost::python::detail::is_reference_to_volatile::value); + + typedef typename mpl::select_type< + ptr + , pointer_from_python + , typename mpl::select_type< + ptr_cref + , pointer_const_reference_from_python + , typename mpl::select_type< + ref + , reference_from_python + , rvalue_from_python + >::type + >::type + >::type type; }; // // implementations // -inline void* from_python_converter_base::convertible(PyObject* o) const +inline from_python_base::from_python_base(void* result) + : m_result(result) { - return m_convertible(o); } -inline from_python_converter_base const* -from_python_converter_base::find( - from_python_converter_base const* chain, PyObject* p, void*& data) +inline from_python_base::from_python_base( + PyObject* const source + , lvalue_from_python_registration const* chain) + : m_result(find(source, chain)) { - for (from_python_converter_base const* q = chain; q != 0 ; q = q->m_next) - { - void* d = q->convertible(p); - if (d != 0) - { - data = d; - return q; - } - } - return 0; +} + +inline bool from_python_base::convertible() const +{ + return m_result != 0; +} + +inline void*const& from_python_base::result() const +{ + return m_result; +} + +// -------- + +namespace detail +{ + template + inline U& void_ptr_to_reference(void const volatile* p, U&(*)()) + { + return *(U*)p; + } + + template + struct null_ptr_owner + { + static T value; + }; + template T null_ptr_owner::value = 0; + + template + inline U& null_ptr_reference(U&(*)()) + { + return null_ptr_owner::value; + } + + template + inline void write_void_ptr(void const volatile* storage, void* ptr, T*) + { + *(T**)storage = (T*)ptr; + } + + // writes U(ptr) into the storage + template + inline void write_void_ptr_reference(void const volatile* storage, void* ptr, U&(*)()) + { + write_void_ptr(storage, ptr, U(0)); + } } template -inline from_python_converter::from_python_converter( - from_python_check checker - , conversion_function converter - , from_python_destructor destructor // = 0 - ) - : from_python_converter_base(type_id(), checker) - , m_convert(converter) - , m_destroy(destructor) +inline pointer_const_reference_from_python::pointer_const_reference_from_python(PyObject* p) { + detail::write_void_ptr_reference( + m_result.bytes + , p == Py_None ? p : find(p, chain) + , (T(*)())0); +} + +template +inline bool pointer_const_reference_from_python::convertible() const +{ + return detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0; +} +template +inline T pointer_const_reference_from_python::operator()(PyObject* p) const +{ + return (p == Py_None) + ? detail::null_ptr_reference((T(*)())0) + : detail::void_ptr_to_reference(m_result.bytes, (T(*)())0); +} + +template +lvalue_from_python_registration*& pointer_const_reference_from_python::chain + = registry::lvalue_converters(pointer_type_id()); + +// -------- + +template +inline pointer_from_python::pointer_from_python(PyObject* p) + : from_python_base(p == Py_None ? p : find(p, chain)) +{ +} + +template +inline T pointer_from_python::operator()(PyObject* p) const +{ + return (p == Py_None) ? 0 : T(result()); +} + +template +lvalue_from_python_registration*& pointer_from_python::chain + = registry::lvalue_converters(pointer_type_id()); + +// -------- + +template +inline reference_from_python::reference_from_python(PyObject* p) + : from_python_base(find(p,chain)) +{ +} + +template +inline T reference_from_python::operator()(PyObject*) const +{ + return detail::void_ptr_to_reference(result(), (T(*)())0); +} + +template +lvalue_from_python_registration*& reference_from_python::chain + = registry::lvalue_converters(undecorated_type_id()); + +// ------- + +template +inline rvalue_from_python::rvalue_from_python(PyObject* obj) +{ + find(obj, chain, m_data.stage1); +} + +template +inline rvalue_from_python::~rvalue_from_python() +{ + if (m_data.stage1.convertible == m_data.storage.bytes) + python::detail::destroy_reference(m_data.storage.bytes); +} + +template +inline bool rvalue_from_python::convertible() const +{ + return m_data.stage1.convertible != 0; +} + +template +inline typename rvalue_from_python::result_type +rvalue_from_python::operator()(PyObject* p) +{ + if (m_data.stage1.construct != 0) + m_data.stage1.construct(p, &m_data.stage1); + return detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0); } template -inline from_python_converter const* -from_python_converter::find(PyObject* p, void*& data) -{ - return static_cast const*>( - from_python_converter_base::find(chain, p, data)); -} - -template -inline T from_python_converter::convert(PyObject* src, from_python_data& data) const -{ - return this->m_convert(src, data); -} - -template -inline void from_python_converter::destroy(from_python_data& data) const -{ - if (this->m_destroy) - { - this->m_destroy(data); - } -} - -template -inline from_python_lookup::from_python_lookup(PyObject* src) - : m_converter( - from_python_converter::find( - src, m_intermediate_data.stage1)) -{ -} - -template -inline from_python_lookup::~from_python_lookup() -{ - if (m_converter != 0) - m_converter->destroy(m_intermediate_data); -} - -template -inline bool from_python_lookup::convertible() const -{ - return this->m_converter != 0; -} - -template -inline T from_python_lookup::operator()(PyObject* obj) -{ - return this->m_converter->convert(obj, m_intermediate_data); -} - -template -inline from_python_converter const* -from_python_lookup::converter() const -{ - return this->m_converter; -} +rvalue_from_python_registration*& rvalue_from_python::chain + = registry::rvalue_converters(undecorated_type_id()); }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp index 3edcbad7..57a3d76e 100644 --- a/include/boost/python/converter/from_python_data.hpp +++ b/include/boost/python/converter/from_python_data.hpp @@ -9,26 +9,20 @@ # include # include # include -# include +# include +# include +# include +# include // Keep these for the metaprogram which EDG is choking on. # if !defined(__EDG__) || (__EDG_VERSION__ > 245) # include # include -# include # include # endif namespace boost { namespace python { namespace converter { -// A POD which is layout-compatible with the real intermediate data -// for all from_python conversions. There may be additional storage if -// we are converting a reference type. -struct from_python_data -{ - void* stage1; -}; - namespace detail { template struct referent_alignment; @@ -74,8 +68,8 @@ namespace detail template struct referent_size { - static T t; - BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(t)); + static T f(); + BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(f())); }; # endif @@ -130,17 +124,13 @@ namespace detail #endif // EDG is too slow template - struct aligned_storage + union aligned_storage { - typedef Align align_t; - union - { - Align align; - char bytes[size - // this is just a STATIC_ASSERT. For some reason - // MSVC was barfing on the boost one. - - (is_same::value ? size : 0)]; - }; + Align align; + char bytes[size + // this is just a STATIC_ASSERT. For some reason + // MSVC was barfing on the boost one. + - (is_same::value ? size : 0)]; }; template @@ -151,56 +141,39 @@ namespace detail typedef mpl::for_each< align_types , unknown_alignment - , best_alignment_type::value> + , best_alignment_type< + referent_alignment::value + > > loop; + typedef typename loop::state align_t; #else // The Python source makes the assumption that double has // maximal alignment anyway typedef double align_t; -#endif - + +#endif + BOOST_STATIC_CONSTANT(std::size_t, alignment1 = alignment_of::value); + BOOST_STATIC_CONSTANT(std::size_t, alignment2 = referent_alignment::value); + + BOOST_STATIC_ASSERT(alignment1 >= alignment2); + BOOST_STATIC_ASSERT(alignment1 % alignment2 == 0); + typedef aligned_storage::value> type; }; - - template - struct intermediate_data : from_python_data - { - typename referent_storage::type stage2; - }; - - template <> - struct intermediate_data : from_python_data - { - }; - + } -// ------------------------------------------------------------------------- -// Auxiliary POD storage where the convertible and/or convert functions of a -// from_python object may place arbitrary data. -// -// Always starts with a void* -// -// For references, we produce additional aligned storage sufficient to -// store the referent - template -struct from_python_intermediate_data +struct rvalue_data { - typedef typename mpl::select_type< - is_reference::value, T, void>::type just_reference_t; - - typedef detail::intermediate_data type; + rvalue_stage1_data stage1; + + typename detail::referent_storage< + typename add_reference::type + >::type storage; }; -template -void* get_storage(from_python_data& x, boost::type* = 0) -{ - typedef typename from_python_intermediate_data::type layout; - return static_cast(&x)->stage2.bytes; -} - }}} // namespace boost::python::converter #endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP diff --git a/include/boost/python/converter/from_python_function.hpp b/include/boost/python/converter/from_python_function.hpp index 0cf90459..eea96372 100644 --- a/include/boost/python/converter/from_python_function.hpp +++ b/include/boost/python/converter/from_python_function.hpp @@ -10,13 +10,8 @@ namespace boost { namespace python { namespace converter { -struct from_python_data; - -template -struct from_python_function -{ - typedef T (*type)(PyObject*, from_python_data&); -}; +struct rvalue_stage1_data; +typedef void (*constructor_function)(PyObject* source, rvalue_stage1_data*); }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/from_python_stage1_data.hpp b/include/boost/python/converter/from_python_stage1_data.hpp new file mode 100644 index 00000000..50fd74ad --- /dev/null +++ b/include/boost/python/converter/from_python_stage1_data.hpp @@ -0,0 +1,21 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FROM_PYTHON_STAGE1_DATA_DWA2002223_HPP +# define FROM_PYTHON_STAGE1_DATA_DWA2002223_HPP + +# include + +namespace boost { namespace python { namespace converter { + +struct rvalue_stage1_data +{ + void* convertible; + constructor_function construct; +}; + +}}} // namespace boost::python::converter + +#endif // FROM_PYTHON_STAGE1_DATA_DWA2002223_HPP diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp new file mode 100644 index 00000000..8a27741c --- /dev/null +++ b/include/boost/python/converter/registrations.hpp @@ -0,0 +1,28 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef REGISTRATIONS_DWA2002223_HPP +# define REGISTRATIONS_DWA2002223_HPP + +# include + +namespace boost { namespace python { namespace converter { + +struct lvalue_from_python_registration +{ + void* (*convert)(PyObject* source); + lvalue_from_python_registration* next; +}; + +struct rvalue_from_python_registration +{ + void* (*convertible)(PyObject*); + constructor_function construct; + rvalue_from_python_registration* next; +}; + +}}} // namespace boost::python::converter + +#endif // REGISTRATIONS_DWA2002223_HPP diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index bdb64254..a511a1a4 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -9,20 +9,33 @@ # include # include # include +# include namespace boost { namespace python { namespace converter { -struct BOOST_PYTHON_DECL from_python_converter_base; +struct lvalue_from_python_registration; +struct rvalue_from_python_registration; // This namespace acts as a sort of singleton namespace registry { + BOOST_PYTHON_DECL lvalue_from_python_registration*& lvalue_converters(undecorated_type_id_t); + BOOST_PYTHON_DECL rvalue_from_python_registration*& rvalue_converters(undecorated_type_id_t); + BOOST_PYTHON_DECL to_python_value_function const& to_python_function(undecorated_type_id_t); BOOST_PYTHON_DECL void insert(to_python_value_function, undecorated_type_id_t); - - BOOST_PYTHON_DECL from_python_converter_base*& from_python_chain(type_id_t); + + // Insert an lvalue from_python converter + BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), undecorated_type_id_t); + + // Insert an rvalue from_python converter + BOOST_PYTHON_DECL void insert( + void* (*convertible)(PyObject*) + , constructor_function + , undecorated_type_id_t + ); BOOST_PYTHON_DECL PyTypeObject*& class_object(undecorated_type_id_t key); } diff --git a/include/boost/python/converter/target.hpp b/include/boost/python/converter/target.hpp deleted file mode 100644 index f8f33171..00000000 --- a/include/boost/python/converter/target.hpp +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#ifndef TARGET_DWA20011119_HPP -# define TARGET_DWA20011119_HPP -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -// target -- -// -// This type generator (see -// ../../../more/generic_programming.html#type_generator) is used -// to select the return type of the appropriate converter for -// unwrapping a given type. - -// Strategy: -// -// 1. reduce everything to a common, un-cv-qualified reference -// type where possible. This will save on registering many different -// converter types. -// -// 2. Treat built-in types specially: when unwrapping a value or -// constant reference to one of these, use a value for the target -// type. It will bind to a const reference if neccessary, and more -// importantly, avoids having to dynamically allocate room for -// an lvalue of types which can be cheaply copied. -// - -// Target Source -// int int -// int const& int -// int& int& -// int volatile& int volatile& -// int const volatile& int const volatile& - -// On compilers supporting partial specialization: -// -// Target Source -// T T const& -// T& T& -// T const& T const& -// T volatile T& -// T const volatile& T const& -// T* T* -// T const* T const* -// T volatile T* -// T const volatile* T const* -// T cv*const& same as T cv* -// T cv*& T*& <- should this be legal? -// T cv*volatile& T*& <- should this be legal? -// T cv*const volatile& T*& <- should this be legal? - -// On others: -// -// Target Source -// T T& -// T cv& T cv& -// T cv* T cv* -// T cv*cv& T cv*cv& - -// As you can see, in order to handle the same range of types without -// partial specialization, more converters need to be registered. - -template -struct target -{ - // Some pointer types are handled in a more sophisticated way on - // compilers supporting partial specialization. - BOOST_STATIC_CONSTANT(bool, use_identity = (::boost::is_scalar::value)); - - typedef typename mpl::select_type< - use_identity - , T - , typename add_reference< - typename add_const< - typename remove_volatile::type - >::type - >::type - >::type type; -}; - -// When partial specialization is not present, we'll simply need to -// register many more converters. -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -template -struct target -{ - typedef typename remove_volatile::type& type; -}; - -template -struct target -{ - typedef typename boost::mpl::select_type< - is_scalar::value - , typename remove_cv::type - , typename remove_volatile::type const& - >::type type; -}; - -template -struct target -{ - typedef typename remove_volatile::type* type; -}; - -// Handle T*-cv for completeness. Function arguments in a signature -// are never actually cv-qualified, but who knows how these converters -// might be used, or whether compiler bugs lurk which make it seem -// otherwise? -template -struct target -{ - typedef typename remove_volatile::type* type; -}; - -template -struct target -{ - typedef typename remove_volatile::type* type; -}; - -template -struct target -{ - typedef typename remove_volatile::type* type; -}; - -// non-const references to pointers should be handled by the -// specialization for T&, above. -template -struct target -{ - typedef typename remove_volatile::type* type; -}; -# endif - -// Fortunately, we can handle T const& where T is an arithmetic type -// by explicit specialization. These specializations will cause value -// and const& arguments to be converted to values, rather than to -// references. -# define BOOST_PYTHON_UNWRAP_VALUE(T) \ -template <> \ -struct target \ -{ \ - typedef T type; \ -}; \ -template <> \ -struct target \ -{ \ - typedef T type; \ -}; \ -template <> \ -struct target \ -{ \ - typedef T type; \ -}; \ -template <> \ -struct target \ -{ \ - typedef T type; \ -}; \ -template <> \ -struct target \ -{ \ - typedef T type; \ -} - -BOOST_PYTHON_UNWRAP_VALUE(char); -BOOST_PYTHON_UNWRAP_VALUE(unsigned char); -BOOST_PYTHON_UNWRAP_VALUE(signed char); -BOOST_PYTHON_UNWRAP_VALUE(unsigned int); -BOOST_PYTHON_UNWRAP_VALUE(signed int); -BOOST_PYTHON_UNWRAP_VALUE(unsigned short); -BOOST_PYTHON_UNWRAP_VALUE(signed short); -BOOST_PYTHON_UNWRAP_VALUE(unsigned long); -BOOST_PYTHON_UNWRAP_VALUE(signed long); -BOOST_PYTHON_UNWRAP_VALUE(char const*); - -}}} // namespace boost::python::converter - -#endif // TARGET_DWA20011119_HPP diff --git a/include/boost/python/converter/unwrapper_base.hpp b/include/boost/python/converter/unwrapper_base.hpp deleted file mode 100644 index ea437eb2..00000000 --- a/include/boost/python/converter/unwrapper_base.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef UNWRAPPER_BASE_DWA20011215_HPP -# define UNWRAPPER_BASE_DWA20011215_HPP -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct BOOST_PYTHON_DECL unwrapper_base : body -{ - public: - unwrapper_base(type_id_t); // registers - ~unwrapper_base(); // unregisters - - // Must return non-null iff the conversion will be successful. Any - // non-null pointer is acceptable, and will be passed on to the - // convert() function, so useful data can be stored there. - virtual void* can_convert(PyObject*) const = 0; - - protected: - // this is an arbitrary non-null pointer you can use to indicate success - static void* const non_null; - - private: // body required interface implementation - void destroy_handle(handle*) const {} -}; - -}}} // namespace boost::python::converter - -#endif // UNWRAPPER_BASE_DWA20011215_HPP diff --git a/include/boost/python/detail/destroy.hpp b/include/boost/python/detail/destroy.hpp new file mode 100644 index 00000000..07738e2f --- /dev/null +++ b/include/boost/python/detail/destroy.hpp @@ -0,0 +1,83 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef DESTROY_DWA2002221_HPP +# define DESTROY_DWA2002221_HPP + +# include +# include + +namespace boost { namespace python { namespace detail { + +template struct value_destroyer; + +template <> +struct value_destroyer +{ + template + static void execute(T const volatile* p) + { + p->T::~T(); + } +}; + +template <> +struct value_destroyer +{ + template + static void execute(A*, T const volatile* const first) + { + for (T const volatile* p = first; p != first + sizeof(A)/sizeof(T); ++p) + value_destroyer< + boost::is_array::value + ,boost::has_trivial_destructor::value + >::execute(p); + } + + template + static void execute(T const volatile* p) + { + execute(p, *p); + } +}; + +template <> +struct value_destroyer +{ + template + static void execute(T const volatile* p) + { + } +}; + +template <> +struct value_destroyer +{ + template + static void execute(T const volatile* p) + { + } +}; + +template +inline void destroy_reference_impl(void* p, T& (*)()) +{ + // note: cv-qualification needed for MSVC6 + // must come *before* T for metrowerks + value_destroyer< + (boost::is_array::value) + , (boost::has_trivial_destructor::value) + >::execute((const volatile T*)p); +} + +template +inline void destroy_reference(void* p, T(*)() = 0) +{ + destroy_reference_impl(p, (T(*)())0); +} + +}}} // namespace boost::python::detail + +#endif // DESTROY_DWA2002221_HPP diff --git a/include/boost/python/from_python.hpp b/include/boost/python/from_python.hpp index 995f7877..62b340f1 100644 --- a/include/boost/python/from_python.hpp +++ b/include/boost/python/from_python.hpp @@ -7,15 +7,14 @@ # define FROM_PYTHON_DWA2002128_HPP # include -# include namespace boost { namespace python { template struct from_python - : converter::from_python_lookup::type> + : converter::select_from_python::type { - typedef converter::from_python_lookup::type> base; + typedef typename converter::select_from_python::type base; from_python(PyObject*); }; diff --git a/include/boost/python/lvalue_from_python.hpp b/include/boost/python/lvalue_from_python.hpp deleted file mode 100644 index c5d09ff5..00000000 --- a/include/boost/python/lvalue_from_python.hpp +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef LVALUE_FROM_PYTHON_DWA2002130_HPP -# define LVALUE_FROM_PYTHON_DWA2002130_HPP - -# include -# include - -namespace boost { namespace python { - -// Utility which produces a member extractor function on platforms -// other than VC6. -template -struct get_member -{ - static Member& execute(Class& c) - { - return c.*mp; - } -}; - -namespace detail -{ - template - struct extract_identity - { - static Class& execute(Class& c) - { - return c; - } - }; -} - -template < - PyTypeObject const* python_type - , class Value - , class PythonObject = Value - , class Extract = detail::extract_identity - > -class lvalue_from_python -{ - typedef type_from_python convertible_t; - public: - - lvalue_from_python() - : m_mutable_converter( - &convertible_t::convertible, convert_mutable) - - , m_const_converter( - &convertible_t::convertible, convert_const) - - , m_mutable_pointer_converter( - &convertible_t::convertible, convert_mutable_pointer) - - , m_const_pointer_converter( - &convertible_t::convertible, convert_const_pointer) - {} - - private: - static Value& convert_mutable(PyObject* op, converter::from_python_data&) - { - return Extract::execute(*(PythonObject*)op); - } - - static Value const& convert_const(PyObject* op, converter::from_python_data&) - { - return Extract::execute(*(PythonObject*)op); - } - - static Value* convert_mutable_pointer(PyObject* op, converter::from_python_data&) - { - return &Extract::execute(*(PythonObject*)op); - } - - static Value const* convert_const_pointer(PyObject* op, converter::from_python_data&) - { - return &Extract::execute(*(PythonObject*)op); - } - - typedef converter::from_python_converter mutable_converter; - typedef converter::from_python_converter const_converter; - typedef converter::from_python_converter mutable_pointer_converter; - typedef converter::from_python_converter const_pointer_converter; - - mutable_converter m_mutable_converter; - const_converter m_const_converter; - mutable_pointer_converter m_mutable_pointer_converter; - const_pointer_converter m_const_pointer_converter; -}; - -}} // namespace boost::python - -#endif // LVALUE_FROM_PYTHON_DWA2002130_HPP diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 35280074..04f0e992 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -53,7 +53,7 @@ struct BOOST_PYTHON_DECL instance_holder : private noncopyable // return the next holder in a chain instance_holder* next() const; - virtual void* holds(converter::type_id_t) = 0; + virtual void* holds(converter::undecorated_type_id_t) = 0; void install(PyObject* inst) throw(); @@ -85,15 +85,19 @@ struct instance instance_holder* objects; }; -// Given a type_id, find the instance data which corresponds to it, or -// return 0 in case no such type is held. -BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::type_id_t); +// Given an undecorated type_id, find the instance data which +// corresponds to it, or return 0 in case no such type is held. +BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::undecorated_type_id_t); +// This produces a function with the right signature for use in from_python conversions template -T* find_instance(PyObject* p, T* = 0) +struct instance_finder { - return static_cast(find_instance_impl(p, converter::type_id())); -} + static inline void* execute(PyObject* p) + { + return find_instance_impl(p, converter::undecorated_type_id()); + } +}; BOOST_PYTHON_DECL ref class_metatype(); BOOST_PYTHON_DECL ref class_type(); diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index d5978af7..540565bf 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -6,10 +6,10 @@ #ifndef CLASS_CONVERTERS_DWA2002119_HPP # define CLASS_CONVERTERS_DWA2002119_HPP -# include # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -24,7 +24,6 @@ struct class_converters class_converters(ref const& python_class); private: // data members - converter::class_from_python_converter m_unwrapper; class_wrapper m_wrapper; }; @@ -90,6 +89,10 @@ template class_converters::class_converters(ref const& type_object) : m_wrapper(type_object) { + converter::registry::insert( + &instance_finder::execute + , converter::undecorated_type_id()); + // register all up/downcasts here register_dynamic_id(); diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 21fe8e96..c307f019 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -139,7 +139,7 @@ struct pointer_holder : instance_holder {} private: // required holder implementation - void* holds(converter::type_id_t); + void* holds(converter::undecorated_type_id_t); private: // data members Pointer m_p; @@ -186,12 +186,12 @@ pointer_holder::pointer_holder(Pointer p) } template -void* pointer_holder::holds(converter::type_id_t dst_t) +void* pointer_holder::holds(converter::undecorated_type_id_t dst_t) { - if (dst_t == converter::type_id()) + if (dst_t == converter::undecorated_type_id()) return &this->m_p; - converter::type_id_t src_t = converter::type_id(); + converter::type_id_t src_t = converter::undecorated_type_id(); return src_t == dst_t ? &*this->m_p : find_dynamic_type(&*this->m_p, src_t, dst_t); } diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 01431370..6533bc39 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -134,7 +134,7 @@ struct value_holder : instance_holder {} private: // required holder implementation - void* holds(converter::type_id_t); + void* holds(converter::undecorated_type_id_t); private: // data members Held m_held; @@ -151,9 +151,9 @@ struct value_holder_generator }; template -void* value_holder::holds(converter::type_id_t dst_t) +void* value_holder::holds(converter::undecorated_type_id_t dst_t) { - converter::type_id_t src_t = converter::type_id(); + converter::undecorated_type_id_t src_t = converter::undecorated_type_id(); return src_t == dst_t ? &m_held : find_static_type(&m_held, src_t, dst_t); } diff --git a/include/boost/python/reference_from_python.hpp b/include/boost/python/reference_from_python.hpp deleted file mode 100644 index a9631dc5..00000000 --- a/include/boost/python/reference_from_python.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef REFERENCE_FROM_PYTHON_DWA2002130_HPP -# define REFERENCE_FROM_PYTHON_DWA2002130_HPP - -# include -# include - -namespace boost { namespace python { - -// Utility which produces a member extractor function on platforms -// other than VC6. -template -struct get_member -{ - static Member& execute(Class* c) - { - return c->*mp; - } -}; - -template < - PyTypeObject const* python_type - , class Value - , class PythonObject - , class Extract - > -struct reference_from_python -{ - typedef type_from_python convertible_t; - - reference_from_python() - : m_mutable_converter( - &convertible_t::convertible, convert_mutable) - - , m_const_converter( - &convertible_t::convertible, convert_const) - {} - - static Value& convert_mutable(PyObject* op, converter::from_python_data&) - { - return Extract::execute(*(PythonObject*)op); - } - - static Value const& convert_const(PyObject* op, converter::from_python_data&) - { - return Extract::execute(*(PythonObject*)op); - } - - private: - typedef converter::from_python_converter mutable_converter; - typedef converter::from_python_converter const_converter; - mutable_converter m_mutable_converter; - const_converter m_const_converter; -}; - -}} // namespace boost::python - -#endif // REFERENCE_FROM_PYTHON_DWA2002130_HPP diff --git a/include/boost/python/type_from_python.hpp b/include/boost/python/type_from_python.hpp index 46d59d13..16b8da81 100644 --- a/include/boost/python/type_from_python.hpp +++ b/include/boost/python/type_from_python.hpp @@ -6,15 +6,94 @@ #ifndef TYPE_FROM_PYTHON_DWA2002130_HPP # define TYPE_FROM_PYTHON_DWA2002130_HPP +# include + namespace boost { namespace python { -template +namespace detail +{ + // Given a pointer-to-function of 1 parameter returning a reference + // type, return the type_id of the function's return type. + template + inline converter::undecorated_type_id_t extractor_type_id(T&(*)(U)) + { + return converter::undecorated_type_id(); + } + + // A function generator whose static execute() function is an lvalue + // from_python converter using the given Extractor. U is exepcted to + // be the actual type of the PyObject instance from which the result + // is being extracted. + template + struct normalized_extractor + { + static inline void* execute(PyObject* op) + { + typedef typename boost::add_reference::type param; + return &Extractor::execute( + boost::python::converter::detail::void_ptr_to_reference( + op, (param(*)())0 ) + ); + } + }; + + // Given an Extractor type and a pointer to its execute function, + // return a new object whose static execute function does the same + // job but is a conforming lvalue from_python conversion function. + // + // usage: normalize(&Extractor::execute) + template + inline normalized_extractor + normalize(T(*)(U), Extractor* = 0) + { + return normalized_extractor(); + } +} + +// An Extractor which extracts the given member from a Python object +// whose instances are stored as InstanceType. +template +struct member_extractor +{ + static MemberType& execute(InstanceType& c) + { + (void)c.ob_type; // static assertion + return c.*member; + } +}; + +// An Extractor which simply extracts the entire python object +// instance of InstanceType. +template +struct identity_extractor +{ + static InstanceType& execute(InstanceType& c) + { + (void)c.ob_type; // static assertion + return c; + } +}; + +// Registers a from_python conversion which extracts lvalues using +// Extractor's static execute function from Python objects whose type +// object is python_type. +template struct type_from_python { - static void* convertible(PyObject* op) + type_from_python() { - return PyObject_TypeCheck( - op, const_cast(python_type)) ? op : 0; + converter::registry::insert( + &extract, detail::extractor_type_id(&Extractor::execute)); + } + + static void* extract(PyObject* op) + { + return PyObject_TypeCheck(op, const_cast(python_type)) + ? const_cast( + static_cast( + detail::normalize(&Extractor::execute).execute(op))) + : 0 + ; } }; diff --git a/include/boost/python/value_from_python.hpp b/include/boost/python/value_from_python.hpp deleted file mode 100644 index c835de45..00000000 --- a/include/boost/python/value_from_python.hpp +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef VALUE_FROM_PYTHON_DWA2002130_HPP -# define VALUE_FROM_PYTHON_DWA2002130_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -template -struct value_from_python -{ - typedef value_from_python self; - typedef converter::from_python_check from_python_check; - - value_from_python(from_python_check convertible) - : m_converter( - convertible - , &Derived::convert - - // Change this to a compile-time check later to avoid - // generating destroy function - , has_trivial_destructor::value ? 0 : &Derived::destroy - ) - { - } - - value_from_python() - : m_converter( - &Derived::convertible - , &Derived::convert - - // Change this to a compile-time check later to avoid - // generating destroy function - , has_trivial_destructor::value ? 0 : &Derived::destroy - ) - { - } - - static void* get_storage(converter::from_python_data& data) - { - return converter::get_storage(data); - } - - // Mark successful construction - static void constructed(converter::from_python_data& data) - { - data.stage1 = self::get_storage(data); - } - - inline static void destroy(converter::from_python_data& data) - { - // Get the location of the storage for - void* storage = self::get_storage(data); - - // Check for successful construction - if (data.stage1 == storage) - static_cast(storage)->~T(); - } - - private: - converter::from_python_converter m_converter; -}; - -}} // namespace boost::python - -#endif // VALUE_FROM_PYTHON_DWA2002130_HPP diff --git a/src/converter/body.cpp b/src/converter/body.cpp deleted file mode 100644 index 637f8c3e..00000000 --- a/src/converter/body.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include - -namespace boost { namespace python { namespace converter { - -// default implementation is a no-op. Most handles will not hold any -// data that needs to be managed. Unwrap objects which convert -// by-value are an exception. Fortunately, the concrete body subclass -// has that knowledge. -void body::destroy_handle(handle*) const -{ -} - -}}} // namespace boost::python::converter diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index 9cf5f110..8db20586 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -7,177 +7,120 @@ #include #include #include -#include -#include #include +#include #include #include -//#include #include namespace boost { namespace python { namespace converter { namespace { - // Only an object which we know is holding a char const* can be - // converted to one - struct convertible_to_cstring + // An lvalue conversion function which extracts a char const* from a + // Python String. + void* convert_to_cstring(PyObject* obj) { - static unaryfunc* execute(PyObject* obj) - { - return PyString_Check(obj) ? &obj->ob_type->tp_str : 0; - } - }; + return PyString_Check(obj) ? PyString_AsString(obj) : 0; + } - struct extract_cstring + // Given a target type and a SlotPolicy describing how to perform a + // given conversion, registers from_python converters which use the + // SlotPolicy to extract the type. + template + struct slot_rvalue_from_python { - static char const* execute(PyObject* obj) - { - return PyString_AsString(obj); - } - }; - - // Any object which can be converted to a Python string can also be - // converted to a C++ string, since the latter owns its bytes. - struct convertible_to_string - { - static unaryfunc* execute(PyObject* obj) - { - return obj->ob_type->tp_str ? &obj->ob_type->tp_str : 0; - } - }; - - // Transform a function returning a unaryfunc* into one that returns a void* - template - struct return_void_ptr - { - static void* execute(PyObject* p) { return F::execute(p); } - }; - - template < - class T // The target type - , class Convertible // returns a pointer to a unaryfunc producing an object - , class TExtract // ...from which TExtract extracts T's constructor argument - > - struct tp_scalar_from_python - : from_python_converter - { - private: - typedef return_void_ptr convertible_fn; - public: - tp_scalar_from_python() - : from_python_converter( - &convertible_fn::execute - , convert) - {} - - static T convert(PyObject* obj, from_python_data& data) + slot_rvalue_from_python() { - unaryfunc converter = *(unaryfunc*)data.stage1; - ref converted(converter(obj)); - return TExtract::execute(converted.get()); + registry::insert( + &slot_rvalue_from_python::convertible + , &slot_rvalue_from_python::construct + , undecorated_type_id() + ); } - }; - - // Extract a reference to T using the functions in the source - // object's type slots - template < - class T // The target type - , class Convertible // returns a pointer to a unaryfunc producing an object - , class TExtract // ...from which TExtract extracts T's constructor argument - > - struct tp_cref_from_python - : value_from_python > - { + private: - typedef tp_cref_from_python self; - typedef value_from_python > base; - - public: - tp_cref_from_python() - : base(&return_void_ptr::execute) - {} - - static T const& convert(PyObject* obj, from_python_data& data) + static void* convertible(PyObject* obj) { - unaryfunc converter = *(unaryfunc*)data.stage1; - - void* storage = self::get_storage(data); - - ref converted(converter(obj)); - - T* const p = new (storage) T(TExtract::execute(converted.get())); - - // note that construction is successful. - data.stage1 = p; - - return *p; + unaryfunc* slot = SlotPolicy::get_slot(obj); + return slot && *slot ? slot : 0; + } + + static void construct(PyObject* obj, rvalue_stage1_data* data) + { + // Get the (intermediate) source object + unaryfunc creator = *static_cast(data->convertible); + ref intermediate(creator(obj)); + + // Get the location in which to construct + void* storage = ((rvalue_data*)data)->storage.bytes; + new (storage) T(SlotPolicy::extract(intermediate.get())); + + // record successful construction + data->convertible = storage; } }; - struct convertible_to_int + // A SlotPolicy for extracting integer types from Python objects + struct int_rvalue_from_python { - static unaryfunc* execute(PyObject* obj) + static unaryfunc* get_slot(PyObject* obj) { PyNumberMethods* number_methods = obj->ob_type->tp_as_number; if (number_methods == 0) return 0; // For floating types, return the float conversion slot to avoid - // creating a new object. We'll handle that in - // py_int_or_float_as_long, below + // creating a new object. We'll handle that below if (PyObject_TypeCheck(obj, &PyFloat_Type) && number_methods->nb_float) return &number_methods->nb_float; - return number_methods && number_methods->nb_int - ? &number_methods->nb_int : 0; + return &number_methods->nb_int; } - }; - - struct py_int_or_float_as_long - { - static long execute(PyObject* obj) + + static long extract(PyObject* intermediate) { - if (PyObject_TypeCheck(obj, &PyFloat_Type)) + if (PyObject_TypeCheck(intermediate, &PyFloat_Type)) { - return numeric_cast(PyFloat_AS_DOUBLE(obj)); + return numeric_cast(PyFloat_AS_DOUBLE(intermediate)); } else { - return PyInt_AS_LONG(obj); + return PyInt_AS_LONG(intermediate); } } }; + + // identity_unaryfunc/non_null -- manufacture a unaryfunc "slot" + // which just returns its argument. Used for bool conversions, since + // all Python objects are directly convertible to bool extern "C" PyObject* identity_unaryfunc(PyObject* x) { Py_INCREF(x); return x; } - unaryfunc non_null = identity_unaryfunc; - - struct convertible_to_bool + + // A SlotPolicy for extracting bool from a Python object + struct bool_rvalue_from_python { - static unaryfunc* execute(PyObject* obj) + static unaryfunc* get_slot(PyObject*) { return &non_null; } - }; - - struct py_object_as_bool - { - static bool execute(PyObject* obj) + + static bool extract(PyObject* intermediate) { - return PyObject_IsTrue(obj); + return PyObject_IsTrue(intermediate); } }; - - struct convertible_to_double + // A SlotPolicy for extracting floating types from Python objects. + struct float_rvalue_from_python { - static unaryfunc* execute(PyObject* obj) + static unaryfunc* get_slot(PyObject* obj) { PyNumberMethods* number_methods = obj->ob_type->tp_as_number; if (number_methods == 0) @@ -189,67 +132,63 @@ namespace if (PyObject_TypeCheck(obj, &PyInt_Type) && number_methods->nb_int) return &number_methods->nb_int; - return number_methods && number_methods->nb_float - ? &number_methods->nb_float : 0; + return &number_methods->nb_float; } - }; - - struct py_float_or_int_as_double - { - static double execute(PyObject* obj) + + static double extract(PyObject* intermediate) { - if (PyObject_TypeCheck(obj, &PyInt_Type)) + if (PyObject_TypeCheck(intermediate, &PyInt_Type)) { - return PyInt_AS_LONG(obj); + return PyInt_AS_LONG(intermediate); } else { - return PyFloat_AS_DOUBLE(obj); + return PyFloat_AS_DOUBLE(intermediate); } } }; - template - struct scalar_from_python + // A SlotPolicy for extracting C++ strings from Python objects. + struct string_rvalue_from_python { - tp_cref_from_python cref_converter; - tp_scalar_from_python value_converter; - }; - - template - void register_int_converters(T* = 0) - { - static scalar_from_python x; - } -} + // If the underlying object is "string-able" this will succeed + static unaryfunc* get_slot(PyObject* obj) + { + return &obj->ob_type->tp_str; + }; -#define REGISTER_INT_CONVERTERS(U) register_int_converters() + // Remember that this will be used to construct the result object + static char const* extract(PyObject* intermediate) + { + return PyString_AsString(intermediate); + } + }; +} + +#define REGISTER_INT_CONVERTERS(U) slot_rvalue_from_python() #define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U) void initialize_builtin_converters() { - static scalar_from_python< - bool, convertible_to_bool, py_object_as_bool> bool_from_python; - + // booleans + slot_rvalue_from_python(); + + // integer types REGISTER_INT_CONVERTERS2(char); REGISTER_INT_CONVERTERS2(short); REGISTER_INT_CONVERTERS2(int); REGISTER_INT_CONVERTERS2(long); - static scalar_from_python< - float,convertible_to_double,py_float_or_int_as_double> float_from_python; + // floating types + slot_rvalue_from_python(); + slot_rvalue_from_python(); + slot_rvalue_from_python(); - static scalar_from_python< - double,convertible_to_double,py_float_or_int_as_double> double_from_python; - - static scalar_from_python< - long double,convertible_to_double,py_float_or_int_as_double> long_double_from_python; - - static scalar_from_python< - char const*, convertible_to_cstring, extract_cstring> cstring_from_python; + // Add an lvalue converter for char which gets us char const* + registry::insert(convert_to_cstring,undecorated_type_id()); - static tp_cref_from_python< - std::string, convertible_to_string, extract_cstring> string_from_python; + // Register by-value converters to std::string + slot_rvalue_from_python(); } }}} // namespace boost::python::converter diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 2e844acf..0650fcbb 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -4,23 +4,40 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include -#include +#include +#include +#include namespace boost { namespace python { namespace converter { -from_python_converter_base::from_python_converter_base( - type_id_t type - , from_python_check checker - ) - : body(type) - , m_convertible(checker) - +BOOST_PYTHON_DECL void* find( + PyObject* source + , rvalue_from_python_registration const* chain + , rvalue_stage1_data& data) { - // Insert this in the converter chain. - from_python_converter_base*& head = registry::from_python_chain(type); - m_next = head; - head = this; + for (;chain != 0; chain = chain->next) + { + void* r = chain->convertible(source); + if (r != 0) + { + data.construct = chain->construct; + return data.convertible = r; + } + } + return data.convertible = 0; +} + +BOOST_PYTHON_DECL void* find( + PyObject* const source + , lvalue_from_python_registration const* chain) +{ + for (;chain != 0; chain = chain->next) + { + void* r = chain->convert(source); + if (r != 0) + return r; + } + return 0; } }}} // namespace boost::python::converter diff --git a/src/converter/handle.cpp b/src/converter/handle.cpp deleted file mode 100644 index 1a2b8c31..00000000 --- a/src/converter/handle.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include - -namespace boost { namespace python { namespace converter { - -bool handle::convertible() const -{ - for (handle const* p = this; p != 0; p = p->m_next) - { - if (p->m_body == 0) - return false; - } - return true; -} - -void handle::destroy() -{ - // Recurse down the chain releasing from tail to head - if (m_next != 0) - m_next->destroy(); - - // Our body knows how to destroy us. If we never got a body, - // there's nothing to do. - if (m_body) - m_body->destroy_handle(this); -} - -// void handle::dummy::nonnull() {} - -}}} // namespace boost::python::converter diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index c90d709d..bdfa1c8a 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -4,6 +4,7 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #include +#include #include #include #include @@ -19,20 +20,23 @@ namespace // // The unique to_python converter for the associated C++ type. to_python_value_function m_to_python_converter; - + // The collection of from_python converters for the associated // C++ type. - from_python_converter_base* m_from_python_converters; + lvalue_from_python_registration* m_lvalue_from_python; + rvalue_from_python_registration* m_rvalue_from_python; // The class object associated with this type PyTypeObject* m_class_object; }; - typedef std::map registry_t; + typedef std::map registry_t; registry_t& entries() { static registry_t registry; + +#ifdef BOOST_PYTHON_DYNAMIC_LIB // this conditional should go away eventually. static bool builtin_converters_initialized = false; if (!builtin_converters_initialized) { @@ -42,17 +46,19 @@ namespace // initialize_builtin_converters(); } +#endif return registry; } - entry* find(type_id_t type) + entry* find(undecorated_type_id_t type) { return &entries()[type]; } entry::entry() : m_to_python_converter(0) - , m_from_python_converters(0) + , m_lvalue_from_python(0) + , m_rvalue_from_python(0) , m_class_object(0) { } @@ -78,15 +84,46 @@ namespace registry slot = f; } - from_python_converter_base*& from_python_chain(type_id_t key) + // Insert an lvalue from_python converter + void insert(void* (*convert)(PyObject*), undecorated_type_id_t key) { - return find(key)->m_from_python_converters; + entry* found = find(key); + lvalue_from_python_registration *registration = new lvalue_from_python_registration; + registration->convert = convert; + registration->next = found->m_lvalue_from_python; + found->m_lvalue_from_python = registration; + + insert(convert, 0, key); } - + + // Insert an rvalue from_python converter + void insert(void* (*convertible)(PyObject*) + , constructor_function construct + , undecorated_type_id_t key) + { + entry* found = find(key); + rvalue_from_python_registration *registration = new rvalue_from_python_registration; + registration->convertible = convertible; + registration->construct = construct; + registration->next = found->m_rvalue_from_python; + found->m_rvalue_from_python = registration; + } + PyTypeObject*& class_object(undecorated_type_id_t key) { return find(key)->m_class_object; } + + lvalue_from_python_registration*& lvalue_converters(undecorated_type_id_t key) + { + return find(key)->m_lvalue_from_python; + } + + rvalue_from_python_registration*& rvalue_converters(undecorated_type_id_t key) + { + return find(key)->m_rvalue_from_python; + } + } // namespace registry }}} // namespace boost::python::converter diff --git a/src/converter/unwrap.cpp b/src/converter/unwrap.cpp deleted file mode 100644 index 6a72ab77..00000000 --- a/src/converter/unwrap.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include - -namespace boost { namespace python { namespace converter { - -namespace -{ - struct pyobject_unwrapper : unwrapper_base - { - pyobject_unwrapper(); - void* can_convert(PyObject*) const; - }; - - pyobject_unwrapper static_unwrapper; - std::pair unwrapper_pair(&static_unwrapper,&static_unwrapper); - - pyobject_unwrapper::pyobject_unwrapper() - : unwrapper_base(type_id()) - { - } - - void* pyobject_unwrapper::can_convert(PyObject*) const - { - return non_null; - } -} - -BOOST_PYTHON_DECL std::pair& -unwrap_more_::m_unwrapper = unwrapper_pair; - -}}} // namespace boost::python::converter diff --git a/src/converter/unwrapper.cpp b/src/converter/unwrapper.cpp deleted file mode 100644 index 6279febf..00000000 --- a/src/converter/unwrapper.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#include -#include -#include - -namespace boost { namespace python { namespace converter { - -unwrapper_base::unwrapper_base(type_id_t key) - : body(key) -{ - registry::insert(*this); -} - -unwrapper_base::~unwrapper_base() -{ - if (can_unregister()) - registry::remove(*this); -} - -namespace -{ - int arbitrary; -} - -void* const unwrapper_base::non_null = &arbitrary; - -}}} // namespace boost::python::converter diff --git a/src/converter/wrapper.cpp b/src/converter/wrapper.cpp deleted file mode 100644 index 567ff99d..00000000 --- a/src/converter/wrapper.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include - -namespace boost { namespace python { namespace converter { - -wrapper_base::wrapper_base(type_id_t type) - : body(type) -{ - registry::insert(*this); -} - -wrapper_base::~wrapper_base() -{ - if (can_unregister()) - registry::remove(*this); -} - -namespace -{ - // This doesn't actually get called, but we need something to fill - // in the slot in the wrap class. - struct identity_wrapper_t : wrapper - { - PyObject* convert(PyObject* source) const - { - return source; - } - }; - - identity_wrapper_t identity_wrapper_object; -} - -BOOST_PYTHON_DECL body& identity_wrapper = identity_wrapper_object; - -}}} // namespace boost::python::converter diff --git a/src/object/class.cpp b/src/object/class.cpp index d35a7b5e..8186f9be 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -163,7 +163,7 @@ void instance_holder::install(PyObject* self) throw() } BOOST_PYTHON_DECL void* -find_instance_impl(PyObject* inst, converter::type_id_t type) +find_instance_impl(PyObject* inst, converter::undecorated_type_id_t type) { if (inst->ob_type->ob_type != &class_metatype_object) return 0; diff --git a/test/destroy_test.cpp b/test/destroy_test.cpp new file mode 100644 index 00000000..c6be42fc --- /dev/null +++ b/test/destroy_test.cpp @@ -0,0 +1,81 @@ +#include +#include + +struct bar; + +namespace boost +{ + // lie to the library about bar so we can show that it's destructor is optimized away. + template <> + struct has_trivial_destructor + { + BOOST_STATIC_CONSTANT(bool, value=true); + }; +} + + +int count; +int marks[] = { + -1 + , -1, -1 + , -1, -1, -1, -1 + , -1 +}; +int* kills = marks; + +struct foo +{ + foo() : n(count++) {} + ~foo() + { + *kills++ = n; + } + int n; +}; + +struct bar : foo {}; + +void assert_destructions(int n) +{ + for (int i = 0; i < n; ++i) + assert(marks[i] == i); + assert(marks[n] == -1); +} + +int main() +{ + assert_destructions(0); + typedef int a[2]; + + foo* f1 = new foo; + boost::python::detail::destroy_reference(f1); + assert_destructions(1); + + foo* f2 = new foo[2]; + typedef foo x[2]; + + boost::python::detail::destroy_reference(f2); + assert_destructions(3); + + typedef foo y[2][2]; + x* f3 = new y; + boost::python::detail::destroy_reference(f3); + assert_destructions(7); + + bar* b1 = new bar; + boost::python::detail::destroy_reference(b1); + assert_destructions(7); + + bar* b2 = new bar[2]; + typedef bar xb[2]; + + boost::python::detail::destroy_reference(b2); + assert_destructions(7); + + typedef bar yb[2][2]; + xb* b3 = new yb; + boost::python::detail::destroy_reference(b3); + assert_destructions(7); + + return 0; +} diff --git a/test/indirect_traits_test.cpp b/test/indirect_traits_test.cpp new file mode 100644 index 00000000..a15e7f85 --- /dev/null +++ b/test/indirect_traits_test.cpp @@ -0,0 +1,48 @@ +//#include +#include +#include + +//#define print(expr) printf("%s ==> %s\n", #expr, expr) + +int main() +{ +using namespace boost::python::detail; + + assert(is_reference_to_pointer::value); + assert(is_reference_to_pointer::value); + assert(is_reference_to_pointer::value); + assert(is_reference_to_pointer::value); + + assert(!is_reference_to_pointer::value); + assert(!is_reference_to_pointer::value); + assert(!is_reference_to_pointer::value); + + assert(!is_reference_to_const::value); + assert(is_reference_to_const::value); + assert(!is_reference_to_const::value); + assert(is_reference_to_const::value); + + assert(!is_reference_to_const::value); + assert(!is_reference_to_const::value); + assert(!is_reference_to_const::value); + + assert(is_reference_to_non_const::value); + assert(!is_reference_to_non_const::value); + assert(is_reference_to_non_const::value); + assert(!is_reference_to_non_const::value); + + assert(!is_reference_to_non_const::value); + assert(!is_reference_to_non_const::value); + assert(!is_reference_to_non_const::value); + + assert(!is_reference_to_volatile::value); + assert(!is_reference_to_volatile::value); + assert(is_reference_to_volatile::value); + assert(is_reference_to_volatile::value); + + assert(!is_reference_to_volatile::value); + assert(!is_reference_to_volatile::value); + assert(!is_reference_to_volatile::value); + + return 0; +} diff --git a/test/m1.cpp b/test/m1.cpp index 723b471d..439d58e2 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -9,15 +9,13 @@ #include "complicated.hpp" #include #include +#include #include #include #include #include #include -#include -#include #include -#include #include #include #include @@ -105,7 +103,6 @@ PyObject* new_simple() // description of how the type parameters to wrapper<> and unwrapper<> // are selected. // -using boost::python::converter::from_python_data; using boost::python::to_python_converter; // Wrap a simple by copying it into a Simple @@ -120,16 +117,13 @@ struct simple_to_python } }; -int noddy_to_int(PyObject* p, from_python_data&) +struct int_from_noddy_extractor { - return static_cast(p)->x; -} - -// Extract a mutable reference to an int from a Noddy. -int& noddy_to_int_ref(PyObject* p, from_python_data&) -{ - return static_cast(p)->x; -} + static int& execute(NoddyObject& p) + { + return p.x; + } +}; // // Some C++ functions to expose to Python @@ -205,40 +199,23 @@ D take_d(D const& d) { return d; } BOOST_PYTHON_MODULE_INIT(m1) { - using boost::python::module; - using boost::python::class_; - using boost::python::converter::from_python_converter; - using boost::python::lvalue_from_python; - using boost::python::value_from_python; - using boost::python::type_from_python; - using boost::python::get_member; - using boost::python::copy_const_reference; - using boost::python::return_value_policy; + using namespace boost::python; using boost::mpl::type_list; - // Create the converters; they are self-registering/unregistering. - static simple_to_python c1; + simple_to_python(); - static from_python_converter c2( - &(boost::python::type_from_python<&NoddyType>::convertible), noddy_to_int); - - static from_python_converter c3( - &(boost::python::type_from_python<&NoddyType>::convertible), noddy_to_int_ref); + type_from_python<&NoddyType,int_from_noddy_extractor>(); - static boost::python::lvalue_from_python< + boost::python::type_from_python< &SimpleType - , simple - , SimpleObject #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - , boost::python::get_member + , member_extractor #else , extract_simple_object #endif - > - unwrap_simple; + >(); - static boost::python::lvalue_from_python<&SimpleType, SimpleObject> - unwrap_simple2; + type_from_python<&SimpleType, identity_extractor >(); module m1("m1"); diff --git a/test/pointer_type_id_test.cpp b/test/pointer_type_id_test.cpp new file mode 100644 index 00000000..24035709 --- /dev/null +++ b/test/pointer_type_id_test.cpp @@ -0,0 +1,39 @@ +#include +#include +#include + +int main() +{ + using namespace boost::python::converter; + + undecorated_type_id_t x + = undecorated_type_id(); + + + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + assert(pointer_type_id() == x); + + return 0; +} From 389968468698765dcfb1c9a20a98e3ea78150d98 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Feb 2002 05:28:48 +0000 Subject: [PATCH 0278/1042] inital checkin [SVN r12925] --- test/select_from_python_test.cpp | 148 +++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 test/select_from_python_test.cpp diff --git a/test/select_from_python_test.cpp b/test/select_from_python_test.cpp new file mode 100644 index 00000000..7063767e --- /dev/null +++ b/test/select_from_python_test.cpp @@ -0,0 +1,148 @@ +#include +//#include +//#include +#include +#include + +int result; + +#define ASSERT_SAME(T1,T2) \ + if (!is_same< T1, T2 >::value) { \ + std::cout << "*********************\n"; \ + std::cout << type_id< T1 >() << " != " << type_id< T2 >() << "\n"; \ + std::cout << "*********************\n"; \ + result = 1; \ + } + +int main() +{ + using namespace boost::python::converter; + using namespace boost; + + + ASSERT_SAME( + select_from_python::type, rvalue_from_python + ); + + ASSERT_SAME( + select_from_python::type, rvalue_from_python + ); + + ASSERT_SAME( + select_from_python::type, rvalue_from_python + ); + + ASSERT_SAME( + select_from_python::type, rvalue_from_python + ); + + + + ASSERT_SAME( + select_from_python::type, pointer_from_python + ); + + ASSERT_SAME( + select_from_python::type, pointer_from_python + ); + + ASSERT_SAME( + select_from_python::type, pointer_from_python + ); + + ASSERT_SAME( + select_from_python::type, pointer_from_python + ); + + + + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, rvalue_from_python + ); + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + + + ASSERT_SAME( + select_from_python::type, pointer_const_reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, pointer_const_reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, pointer_const_reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, pointer_const_reference_from_python + ); + + + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + + ASSERT_SAME( + select_from_python::type, reference_from_python + ); + return result; +} From e0147657977f5693a3af72f031ac84b4a3144d39 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Feb 2002 20:18:46 +0000 Subject: [PATCH 0279/1042] More use of ice_xxx for old EDG compilers [SVN r12929] --- include/boost/python/detail/indirect_traits.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index 8c096a2f..f925eaee 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -31,7 +31,8 @@ struct is_reference_to_non_const bool, value = ( ::boost::type_traits::ice_and< ::boost::is_reference::value - , !::boost::python::detail::is_reference_to_const::value + , ::boost::type_traits::ice_not< + ::boost::python::detail::is_reference_to_const::value>::value >::value) ); }; From f6381e7e5e6809062d209b960efe266ed2bd0af5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Feb 2002 21:20:05 +0000 Subject: [PATCH 0280/1042] Added complex support, and support for user-defined conversions of classic instances [SVN r12938] --- .../python/converter/builtin_converters.hpp | 4 + src/converter/builtin_converters.cpp | 97 ++++++++++++++++--- test/test_builtin_converters.cpp | 8 +- test/test_builtin_converters.py | 36 +++++++ 4 files changed, 132 insertions(+), 13 deletions(-) diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index 8293b0a7..7ae7a357 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -8,6 +8,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -58,6 +59,9 @@ BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x ? x : detail::none()) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) namespace converter { diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index 8db20586..2e9bcbec 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -10,8 +10,10 @@ #include #include #include +#include #include #include +#include namespace boost { namespace python { namespace converter { @@ -73,15 +75,18 @@ namespace // For floating types, return the float conversion slot to avoid // creating a new object. We'll handle that below - if (PyObject_TypeCheck(obj, &PyFloat_Type) && number_methods->nb_float) + if (PyFloat_Check(obj)) return &number_methods->nb_float; - + + if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__int__")) + return 0; + return &number_methods->nb_int; } static long extract(PyObject* intermediate) { - if (PyObject_TypeCheck(intermediate, &PyFloat_Type)) + if (PyFloat_Check(intermediate)) { return numeric_cast(PyFloat_AS_DOUBLE(intermediate)); } @@ -93,22 +98,23 @@ namespace }; - // identity_unaryfunc/non_null -- manufacture a unaryfunc "slot" - // which just returns its argument. Used for bool conversions, since - // all Python objects are directly convertible to bool + // identity_unaryfunc/py_object_identity -- manufacture a unaryfunc + // "slot" which just returns its argument. Used for bool + // conversions, since all Python objects are directly convertible to + // bool extern "C" PyObject* identity_unaryfunc(PyObject* x) { Py_INCREF(x); return x; } - unaryfunc non_null = identity_unaryfunc; + unaryfunc py_object_identity = identity_unaryfunc; // A SlotPolicy for extracting bool from a Python object struct bool_rvalue_from_python { static unaryfunc* get_slot(PyObject*) { - return &non_null; + return &py_object_identity; } static bool extract(PyObject* intermediate) @@ -127,17 +133,19 @@ namespace return 0; // For integer types, return the tp_int conversion slot to avoid - // creating a new object. We'll handle that in - // py_float_or_int_as_double, below - if (PyObject_TypeCheck(obj, &PyInt_Type) && number_methods->nb_int) + // creating a new object. We'll handle that below + if (PyInt_Check(obj)) return &number_methods->nb_int; + if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__float__")) + return 0; + return &number_methods->nb_float; } static double extract(PyObject* intermediate) { - if (PyObject_TypeCheck(intermediate, &PyInt_Type)) + if (PyInt_Check(intermediate)) { return PyInt_AS_LONG(intermediate); } @@ -154,6 +162,9 @@ namespace // If the underlying object is "string-able" this will succeed static unaryfunc* get_slot(PyObject* obj) { + if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__str__")) + return 0; + return &obj->ob_type->tp_str; }; @@ -163,6 +174,64 @@ namespace return PyString_AsString(intermediate); } }; + + + // identity_unaryfunc/non_null -- manufacture a unaryfunc "slot" + // which just returns its argument. Used for bool conversions, since + // all Python objects are directly convertible to bool + extern "C" PyObject* to_complex_unaryfunc(PyObject* x) + { + return PyObject_CallMethod(x, "__complex__", const_cast("()")); + } + unaryfunc py_object_to_complex = to_complex_unaryfunc; + + struct complex_rvalue_from_python + { + static unaryfunc* get_slot(PyObject* obj) + { + + if (PyComplex_Check(obj)) + return &py_object_identity; + + PyNumberMethods* number_methods = obj->ob_type->tp_as_number; + + // For integer types, return the tp_int conversion slot to avoid + // creating a new object. We'll handle that below + if (PyInt_Check(obj) && number_methods) + return &number_methods->nb_int; + + if (PyFloat_Check(obj) && number_methods) + return &number_methods->nb_float; + + if (!PyObject_HasAttrString((PyObject*)obj, "__complex__")) + return 0; + + return &py_object_to_complex; + } + + static std::complex extract(PyObject* intermediate) + { + if (PyComplex_Check(intermediate)) + { + return std::complex( + PyComplex_RealAsDouble(intermediate) + , PyComplex_ImagAsDouble(intermediate)); + } + else if (PyInt_Check(intermediate)) + { + return PyInt_AS_LONG(intermediate); + } + else if (PyFloat_Check(intermediate)) + { + return PyFloat_AS_DOUBLE(intermediate); + } + else + { + PyErr_SetString(PyExc_TypeError, "__complex__ method did not return a Complex object"); + throw error_already_set(); + } + } + }; } #define REGISTER_INT_CONVERTERS(U) slot_rvalue_from_python() @@ -184,6 +253,10 @@ void initialize_builtin_converters() slot_rvalue_from_python(); slot_rvalue_from_python(); + slot_rvalue_from_python,complex_rvalue_from_python>(); + slot_rvalue_from_python,complex_rvalue_from_python>(); + slot_rvalue_from_python,complex_rvalue_from_python>(); + // Add an lvalue converter for char which gets us char const* registry::insert(convert_to_cstring,undecorated_type_id()); diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp index f95ebe2b..4c07d9f4 100644 --- a/test/test_builtin_converters.cpp +++ b/test/test_builtin_converters.cpp @@ -5,7 +5,7 @@ // to its suitability for any purpose. #include #include - +#include template struct by_value @@ -41,6 +41,9 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters_ext) .def("rewrap_value_float", by_value::rewrap) .def("rewrap_value_double", by_value::rewrap) .def("rewrap_value_long_double", by_value::rewrap) + .def("rewrap_value_complex_float", by_value >::rewrap) + .def("rewrap_value_complex_double", by_value >::rewrap) + .def("rewrap_value_complex_long_double", by_value >::rewrap) .def("rewrap_value_string", by_value::rewrap) .def("rewrap_value_cstring", by_value::rewrap) @@ -57,6 +60,9 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters_ext) .def("rewrap_const_reference_float", by_const_reference::rewrap) .def("rewrap_const_reference_double", by_const_reference::rewrap) .def("rewrap_const_reference_long_double", by_const_reference::rewrap) + .def("rewrap_const_reference_complex_float", by_const_reference >::rewrap) + .def("rewrap_const_reference_complex_double", by_const_reference >::rewrap) + .def("rewrap_const_reference_complex_long_double", by_const_reference >::rewrap) .def("rewrap_const_reference_string", by_const_reference::rewrap) .def("rewrap_const_reference_cstring", by_const_reference::rewrap) diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index 50b58ce6..3a4722c7 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -30,6 +30,13 @@ >>> rewrap_value_long_double(4.2) - 4.2 0.0 +>>> abs(rewrap_value_complex_float(4+.2j) - (4+.2j)) < .000001 +1 +>>> abs(rewrap_value_complex_double(4+.2j) - (4+.2j)) < .000001 +1 +>>> abs(rewrap_value_complex_long_double(4+.2j) - (4+.2j)) < .000001 +1 + >>> rewrap_value_cstring('hello, world') 'hello, world' >>> rewrap_value_string('yo, wassup?') @@ -57,6 +64,7 @@ 42 >>> rewrap_const_reference_unsigned_long(42) 42 + >>> abs(rewrap_const_reference_float(4.2) - 4.2) < .000001 1 >>> rewrap_const_reference_double(4.2) - 4.2 @@ -64,6 +72,13 @@ >>> rewrap_const_reference_long_double(4.2) - 4.2 0.0 +>>> abs(rewrap_const_reference_complex_float(4+.2j) - (4+.2j)) < .000001 +1 +>>> abs(rewrap_const_reference_complex_double(4+.2j) - (4+.2j)) < .000001 +1 +>>> abs(rewrap_const_reference_complex_long_double(4+.2j) - (4+.2j)) < .000001 +1 + >>> rewrap_const_reference_cstring('hello, world') 'hello, world' >>> rewrap_const_reference_string('yo, wassup?') @@ -83,6 +98,27 @@ Now check implicit conversions between floating/integer types >>> rewrap_value_int(42.0) 42 +Check that classic classes also work + +>>> class FortyTwo: +... def __int__(self): +... return 42 +... def __float__(self): +... return 42.0 +... def __complex__(self): +... return complex(4+.2j) +... def __str__(self): +... return '42' + +>>> rewrap_const_reference_float(FortyTwo()) +42.0 +>>> rewrap_value_int(FortyTwo()) +42 +>>> rewrap_const_reference_string(FortyTwo()) +'42' +>>> abs(rewrap_value_complex_double(FortyTwo()) - (4+.2j)) < .000001 +1 + """ def run(args = None): import sys From a16ff296389a88375cc908186aa679eb13fc403f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 27 Feb 2002 17:29:01 +0000 Subject: [PATCH 0281/1042] Fixed generation [SVN r12957] --- include/boost/python/detail/returning.hpp | 1339 ++++++++++++--------- src/gen_returning.py | 60 +- 2 files changed, 777 insertions(+), 622 deletions(-) diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 599e5d37..d7e98cd8 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -1,5 +1,5 @@ -// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears +// (C) Copyright David Abrahams 2001,2002. Permission to copy, use, modify, sell +// and distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // @@ -23,10 +23,10 @@ template struct returning { template - static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; // find the result converter @@ -34,20 +34,20 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + ) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; // find the result converter @@ -55,22 +55,22 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; // find the result converter @@ -78,24 +78,25 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; // find the result converter @@ -103,26 +104,28 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; // find the result converter @@ -130,28 +133,31 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); + from_python c5(PyTuple_GET_ITEM(args_, 5)); if (!c5.convertible()) return 0; // find the result converter @@ -159,19 +165,23 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4)) + , c5(PyTuple_GET_ITEM(args_, 5))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)() const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; // find the result converter @@ -179,20 +189,20 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + ) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; // find the result converter @@ -200,22 +210,22 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; // find the result converter @@ -223,24 +233,25 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; // find the result converter @@ -248,26 +259,28 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; // find the result converter @@ -275,28 +288,31 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); + from_python c5(PyTuple_GET_ITEM(args_, 5)); if (!c5.convertible()) return 0; // find the result converter @@ -304,19 +320,23 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4)) + , c5(PyTuple_GET_ITEM(args_, 5))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)() volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; // find the result converter @@ -324,20 +344,20 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + ) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; // find the result converter @@ -345,22 +365,22 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; // find the result converter @@ -368,24 +388,25 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; // find the result converter @@ -393,26 +414,28 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; // find the result converter @@ -420,28 +443,31 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); + from_python c5(PyTuple_GET_ITEM(args_, 5)); if (!c5.convertible()) return 0; // find the result converter @@ -449,22 +475,26 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4)) + , c5(PyTuple_GET_ITEM(args_, 5))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } // missing const volatile type traits # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template - static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; // find the result converter @@ -472,20 +502,20 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + ) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)() ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; // find the result converter @@ -493,22 +523,22 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; // find the result converter @@ -516,24 +546,25 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; // find the result converter @@ -541,26 +572,28 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; // find the result converter @@ -568,28 +601,31 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); + from_python c5(PyTuple_GET_ITEM(args_, 5)); if (!c5.convertible()) return 0; // find the result converter @@ -597,176 +633,193 @@ struct returning typename eval::type cr; if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4)) + , c5(PyTuple_GET_ITEM(args_, 5))) ); - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); - - if (!result) return 0; - return policies.postcall(args, result); + return policies.postcall(args_, result); } # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - + template - static PyObject* call(R (*pf)(), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(), PyObject* args_, PyObject*, P const& policies) { // find the result converter typedef typename P::result_converter result_converter; - typename eval::type c0; - if (!c0.convertible()) return 0; + typename eval::type cr; + if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; - PyObject* result = c0( (*pf)() ); - - if (!result) return 0; - return policies.postcall(args, result); + PyObject* result = cr( (*pf)( + ) ); + + return policies.postcall(args_, result); } - template - static PyObject* call(R (*pf)(A0), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; // find the result converter typedef typename P::result_converter result_converter; - typename eval::type c1; - if (!c1.convertible()) return 0; + typename eval::type cr; + if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; - PyObject* result = c1( (*pf)(c0(PyTuple_GET_ITEM(args, 0))) ); - - if (!result) return 0; - return policies.postcall(args, result); + PyObject* result = cr( (*pf)( + c0(PyTuple_GET_ITEM(args_, 0))) ); + + return policies.postcall(args_, result); } template - static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0, A1), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; // find the result converter typedef typename P::result_converter result_converter; - typename eval::type c2; - if (!c2.convertible()) return 0; + typename eval::type cr; + if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; - PyObject* result = c2( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1))) ); - - if (!result) return 0; - return policies.postcall(args, result); + PyObject* result = cr( (*pf)( + c0(PyTuple_GET_ITEM(args_, 0)) + , c1(PyTuple_GET_ITEM(args_, 1))) ); + + return policies.postcall(args_, result); } template - static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; // find the result converter typedef typename P::result_converter result_converter; - typename eval::type c3; - if (!c3.convertible()) return 0; + typename eval::type cr; + if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; - PyObject* result = c3( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))) ); - - if (!result) return 0; - return policies.postcall(args, result); + PyObject* result = cr( (*pf)( + c0(PyTuple_GET_ITEM(args_, 0)) + , c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2))) ); + + return policies.postcall(args_, result); } template - static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; // find the result converter typedef typename P::result_converter result_converter; - typename eval::type c4; - if (!c4.convertible()) return 0; + typename eval::type cr; + if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; - PyObject* result = c4( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))) ); - - if (!result) return 0; - return policies.postcall(args, result); + PyObject* result = cr( (*pf)( + c0(PyTuple_GET_ITEM(args_, 0)) + , c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3))) ); + + return policies.postcall(args_, result); } template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; // find the result converter typedef typename P::result_converter result_converter; - typename eval::type c5; - if (!c5.convertible()) return 0; + typename eval::type cr; + if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; - PyObject* result = c5( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))) ); - - if (!result) return 0; - return policies.postcall(args, result); + PyObject* result = cr( (*pf)( + c0(PyTuple_GET_ITEM(args_, 0)) + , c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4))) ); + + return policies.postcall(args_, result); } template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); + from_python c5(PyTuple_GET_ITEM(args_, 5)); if (!c5.convertible()) return 0; // find the result converter typedef typename P::result_converter result_converter; - typename eval::type c6; - if (!c6.convertible()) return 0; + typename eval::type cr; + if (!cr.convertible()) return 0; - if (!policies.precall(args)) return 0; + if (!policies.precall(args_)) return 0; - PyObject* result = c6( (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))) ); - - if (!result) return 0; - return policies.postcall(args, result); + PyObject* result = cr( (*pf)( + c0(PyTuple_GET_ITEM(args_, 0)) + , c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4)) + , c5(PyTuple_GET_ITEM(args_, 5))) ); + + return policies.postcall(args_, result); } }; @@ -775,560 +828,646 @@ struct returning { typedef void R; template - static PyObject* call(R (A0::*pmf)(), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + ); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); + from_python c5(PyTuple_GET_ITEM(args_, 5)); if (!c5.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4)) + , c5(PyTuple_GET_ITEM(args_, 5))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)() const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)() const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + ); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); + from_python c5(PyTuple_GET_ITEM(args_, 5)); if (!c5.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4)) + , c5(PyTuple_GET_ITEM(args_, 5))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)() volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)() volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + ); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); + from_python c5(PyTuple_GET_ITEM(args_, 5)); if (!c5.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4)) + , c5(PyTuple_GET_ITEM(args_, 5))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } // missing const volatile type traits # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template - static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + ); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); + from_python c5(PyTuple_GET_ITEM(args_, 5)); if (!c5.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4)) + , c5(PyTuple_GET_ITEM(args_, 5))); - if (!policies.precall(args)) return 0; - - ((c0(PyTuple_GET_ITEM(args, 0))).*pmf)(c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - - return policies.postcall(args, detail::none()); + return policies.postcall(args_, detail::none()); } # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - + template - static PyObject* call(R (*pf)(), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(), PyObject* args_, PyObject*, P const& policies) { - (*pf)(); - - return policies.postcall(args, detail::none()); + (*pf)( + ); + + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (*pf)(A0), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; + + if (!policies.precall(args_)) return 0; - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0))); - - return policies.postcall(args, detail::none()); + (*pf)( + c0(PyTuple_GET_ITEM(args_, 0))); + + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (*pf)(A0, A1), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0, A1), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; + + if (!policies.precall(args_)) return 0; - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1))); - - return policies.postcall(args, detail::none()); + (*pf)( + c0(PyTuple_GET_ITEM(args_, 0)) + , c1(PyTuple_GET_ITEM(args_, 1))); + + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; + + if (!policies.precall(args_)) return 0; - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2))); - - return policies.postcall(args, detail::none()); + (*pf)( + c0(PyTuple_GET_ITEM(args_, 0)) + , c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2))); + + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; + + if (!policies.precall(args_)) return 0; - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3))); - - return policies.postcall(args, detail::none()); + (*pf)( + c0(PyTuple_GET_ITEM(args_, 0)) + , c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3))); + + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; + + if (!policies.precall(args_)) return 0; - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4))); - - return policies.postcall(args, detail::none()); + (*pf)( + c0(PyTuple_GET_ITEM(args_, 0)) + , c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4))); + + return policies.postcall(args_, detail::none()); } template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject*, P const& policies) + static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args, 0)); + from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args, 1)); + from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args, 2)); + from_python c2(PyTuple_GET_ITEM(args_, 2)); if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args, 3)); + from_python c3(PyTuple_GET_ITEM(args_, 3)); if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args, 4)); + from_python c4(PyTuple_GET_ITEM(args_, 4)); if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args, 5)); + from_python c5(PyTuple_GET_ITEM(args_, 5)); if (!c5.convertible()) return 0; + + if (!policies.precall(args_)) return 0; - if (!policies.precall(args)) return 0; - - (*pf)(c0(PyTuple_GET_ITEM(args, 0)), c1(PyTuple_GET_ITEM(args, 1)), c2(PyTuple_GET_ITEM(args, 2)), c3(PyTuple_GET_ITEM(args, 3)), c4(PyTuple_GET_ITEM(args, 4)), c5(PyTuple_GET_ITEM(args, 5))); - - return policies.postcall(args, detail::none()); + (*pf)( + c0(PyTuple_GET_ITEM(args_, 0)) + , c1(PyTuple_GET_ITEM(args_, 1)) + , c2(PyTuple_GET_ITEM(args_, 2)) + , c3(PyTuple_GET_ITEM(args_, 3)) + , c4(PyTuple_GET_ITEM(args_, 4)) + , c5(PyTuple_GET_ITEM(args_, 5))); + + return policies.postcall(args_, detail::none()); } }; diff --git a/src/gen_returning.py b/src/gen_returning.py index 80e3342b..8f7c866c 100644 --- a/src/gen_returning.py +++ b/src/gen_returning.py @@ -1,4 +1,4 @@ -# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and +# (C) Copyright David Abrahams 2001,2002. Permission to copy, use, modify, sell and # distribute this software is granted provided this copyright notice appears # in all copies. This software is provided "as is" without express or implied # warranty, and with no claim as to its suitability for any purpose. @@ -8,8 +8,8 @@ from gen_function import * import string -header = '''// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears +header = '''// (C) Copyright David Abrahams 2001,2002. Permission to copy, use, modify, sell +// and distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // @@ -24,11 +24,10 @@ body_sections = ( #ifndef RETURNING_DWA20011201_HPP # define RETURNING_DWA20011201_HPP -//# include # include # include -# include # include +# include namespace boost { namespace python { namespace detail { @@ -62,32 +61,49 @@ struct returning #' -member_function = ''' template - static PyObject* call(R (A0::*pmf)(%(A%+%:, %))%1, PyObject* args, PyObject* /* keywords */ ) +member_function = ''' template + static PyObject* call(R (A0::*pmf)(%(A%+%:, %))%1, PyObject* args_, PyObject*, P const& policies) { // check that each of the arguments is convertible - unwrap c0(PyTuple_GET_ITEM(args, 0)); -%( unwrap_more c%+(PyTuple_GET_ITEM(args, %+), c%n); + from_python c0(PyTuple_GET_ITEM(args_, 0)); + if (!c0.convertible()) return 0; +%( from_python c%+(PyTuple_GET_ITEM(args_, %+)); + if (!c%+.convertible()) return 0; %) %[r%: // find the result converter - wrap_more r(c%n); -%] if (!c0) return 0; - %[r%:return r( %]((*c0).*pmf)(%(*c%+%:, %))%[r%: )%];%[v%: - return detail::none();%] + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + +%] if (!policies.precall(args_)) return 0; + + %[r%:PyObject* result = cr( %]((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( + %(c%+(PyTuple_GET_ITEM(args_, %+))%: + , %))%[r%: )%]; + + return policies.postcall(args_, %[r%:result%]%[v%:detail::none()%]); } ''' -free_function = '''%{ template <%(class A%n%:, %)> -%} static PyObject* call(R (*pf)(%(A%n%:, %)), PyObject*%{ args%}, PyObject* /* keywords */ ) +free_function = ''' template + static PyObject* call(R (*pf)(%(A%n%:, %)), PyObject* args_, PyObject*, P const& policies) {%{ // check that each of the arguments is convertible -%}%( unwrap%{_more%} c%n(PyTuple_GET_ITEM(args, %n)%{, c%-%}); -%)%[r%: - // find the result converter - wrap%{_more%} c%n%{(c%-)%};%]%[not-void-and-0-arg%: - if (!c0) return 0;%] - %[r%:return c%n( %](*pf)(%(*c%n%:, %))%[r%: )%];%[v%: - return detail::none();%] +%}%( from_python c%n(PyTuple_GET_ITEM(args_, %n)); + if (!c%n.convertible()) return 0; +%) +%[r%: // find the result converter + typedef typename P::result_converter result_converter; + typename eval::type cr; + if (!cr.convertible()) return 0; + +%]%[not-void-and-0-arg%: if (!policies.precall(args_)) return 0; + +%] %[r%:PyObject* result = cr( %](*pf)( + %(c%n(PyTuple_GET_ITEM(args_, %n))%: + , %))%[r%: )%]; + + return policies.postcall(args_, %[r%:result%]%[v%:detail::none()%]); } ''' From 8a956bcdf63cfc329732e0bc67609e0149d88f87 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 27 Feb 2002 21:12:52 +0000 Subject: [PATCH 0282/1042] missing typename fix [SVN r12960] --- include/boost/python/converter/from_python.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index 0881a06a..4fe240ce 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -40,7 +40,7 @@ struct pointer_const_reference_from_python bool convertible() const; private: - detail::referent_storage::type m_result; + typename detail::referent_storage::type m_result; static lvalue_from_python_registration*& chain; }; From 0ef39e4440113748831aebd103c5e63f2c86e095 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 27 Feb 2002 21:13:02 +0000 Subject: [PATCH 0283/1042] improvements for EDG [SVN r12961] --- .../python/converter/from_python_data.hpp | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp index 57a3d76e..d88eb90e 100644 --- a/include/boost/python/converter/from_python_data.hpp +++ b/include/boost/python/converter/from_python_data.hpp @@ -19,6 +19,8 @@ # include # include # include +# else +# include # endif namespace boost { namespace python { namespace converter { @@ -105,24 +107,23 @@ namespace detail bool, choose_t2 = ( aligned2 && ( is_same::value - | (align2 < alignment_of::value) + | (align2 < align1) | (sizeof(T2) < sizeof(T1))) )); - typedef mpl::select_type::type type; + typedef typename mpl::select_type::type type; }; }; typedef mpl::type_list< - char,short,int,long,float,double,long double + char,short,int,long, float,double,long double ,void* ,void(*)() ,void (alignment_dummy::*)() , char (alignment_dummy::*) - > + >::type align_types; -#endif // EDG is too slow - +#endif // EDG is too slow template union aligned_storage { @@ -148,10 +149,27 @@ namespace detail typedef typename loop::state align_t; #else + typedef typename remove_cv::type>::type referent; + // The Python source makes the assumption that double has - // maximal alignment anyway - typedef double align_t; - + // maximal alignment, but that fails on some platforms + BOOST_STATIC_CONSTANT( + std::size_t, target_align = alignment_of::value); + + // Here we make some assumptions and leave out some possible + // types worth checking, but this should work most of the time. + typedef typename mpl::select_type< + is_POD::value + , referent + , typename mpl::select_type< + alignment_of::value >= target_align + , long + , typename mpl::select_type< + alignment_of::value >= target_align + , double + , long double>::type + >::type + >::type align_t; #endif BOOST_STATIC_CONSTANT(std::size_t, alignment1 = alignment_of::value); BOOST_STATIC_CONSTANT(std::size_t, alignment2 = referent_alignment::value); From bbc49e1ba3ecc87f644483c480e4f382f522e6e1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 27 Feb 2002 21:13:34 +0000 Subject: [PATCH 0284/1042] go with debug build by default [SVN r12962] --- Jamfile | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Jamfile b/Jamfile index 79dfd9e5..9bf18e2e 100644 --- a/Jamfile +++ b/Jamfile @@ -14,7 +14,13 @@ include python.jam ; BOOST_PYTHON_V2 ; - local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) ; + local gcc-release-properties + = speed -fomit-frame-pointer + on -foptimize-sibling-calls + ; + + local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) $(gcc-release-properties) +; dll bpl : @@ -37,39 +43,39 @@ include python.jam ; # -------- general test ------- extension m1 : test/m1.cpp bpl : - : debug-python + : ; extension m2 : test/m2.cpp bpl : - : debug-python ; + : ; - boost-python-runtest try : test/newtest.py m1 m2 : : debug-python ; + boost-python-runtest try : test/newtest.py m1 m2 : : ; # ----------- builtin converters ----------- extension builtin_converters_ext : test/test_builtin_converters.cpp bpl : - : debug-python + : ; boost-python-runtest test_builtin_converters : test/test_builtin_converters.py builtin_converters_ext : - : debug-python + : ; # ----------- pointer adoption ----------- extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp bpl : - : debug-python + : ; boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py test_pointer_adoption_ext : - : debug-python + : ; } From 493ff9c6850aab69ad9b250fec9f24d007c361ed Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 27 Feb 2002 23:18:08 +0000 Subject: [PATCH 0285/1042] Intel 5 compatibility [SVN r12963] --- include/boost/python/to_python_indirect.hpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index 306b3246..7b77f5ff 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -10,6 +10,7 @@ # include # include # include +# include # include namespace boost { namespace python { @@ -34,8 +35,15 @@ namespace detail template static result_type execute(T* p) { - return new objects::pointer_holder, T>( - std::auto_ptr(p)); + // can't use auto_ptr with Intel 5 for some reason +# if defined(__ICL) && __ICL < 600 + typedef boost::shared_ptr smart_pointer; +# else + typedef std::auto_ptr smart_pointer; +# endif + + return new objects::pointer_holder( + smart_pointer(p)); } }; From ee26e13beab1f3ac9277241fbf6d5e8a70e3a6c5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 28 Feb 2002 00:05:00 +0000 Subject: [PATCH 0286/1042] Added missing PyObject*const& converter [SVN r12966] --- include/boost/python/from_python.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/boost/python/from_python.hpp b/include/boost/python/from_python.hpp index 62b340f1..8c3f94bb 100644 --- a/include/boost/python/from_python.hpp +++ b/include/boost/python/from_python.hpp @@ -27,6 +27,14 @@ struct from_python PyObject* operator()(PyObject* source) const { return source; } }; +template <> +struct from_python +{ + from_python(PyObject*) {} + bool convertible() const { return true; } + PyObject*const& operator()(PyObject*const& source) const { return source; } +}; + // // implementations // From ccb7a8f94feb0713b6b2a19bf29d50b8126b99fd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 28 Feb 2002 00:18:07 +0000 Subject: [PATCH 0287/1042] Make cxx 6.5 bugs happy [SVN r12967] --- src/converter/from_python.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 0650fcbb..57aee355 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -28,7 +28,7 @@ BOOST_PYTHON_DECL void* find( } BOOST_PYTHON_DECL void* find( - PyObject* const source + PyObject* source , lvalue_from_python_registration const* chain) { for (;chain != 0; chain = chain->next) From 412a00249f24e2b0017a88d49559c31ee7cc2a8c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 28 Feb 2002 00:24:06 +0000 Subject: [PATCH 0288/1042] Move module_base to detail, avoiding recompilation dependencies [SVN r12970] --- include/boost/python/detail/module_base.hpp | 44 +++++++++++++++++++++ include/boost/python/module.hpp | 31 +-------------- include/boost/python/object/class.hpp | 1 - src/module.cpp | 7 ++-- src/object/class.cpp | 3 +- 5 files changed, 51 insertions(+), 35 deletions(-) create mode 100644 include/boost/python/detail/module_base.hpp diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp new file mode 100644 index 00000000..e8a00ba6 --- /dev/null +++ b/include/boost/python/detail/module_base.hpp @@ -0,0 +1,44 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MODULE_BASE_DWA2002227_HPP +# define MODULE_BASE_DWA2002227_HPP +# include +# include + +namespace boost { namespace python { namespace detail { + +class BOOST_PYTHON_DECL module_base +{ + public: + // Create a module. REQUIRES: only one module is created per module. + module_base(const char* name); + ~module_base(); + + // Add elements to the module + void setattr(const char* name, PyObject*); + void setattr(const char* name, ref const&); + void add(PyTypeObject* x); // just use the type's name + void add_type(ref); + + // Return a reference to the Python module object being built + inline ref object() const; + + private: + ref m_module; + static PyMethodDef initial_methods[1]; +}; + +// +// inline implementations +// +inline ref module_base::object() const +{ + return m_module; +} + +}}} // namespace boost::python::detail + +#endif // MODULE_BASE_DWA2002227_HPP diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 11b0b6c7..7df183d5 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -8,36 +8,14 @@ # include # include -# include # include # include -# include # include +# include namespace boost { namespace python { -class BOOST_PYTHON_DECL module_base -{ - public: - // Create a module. REQUIRES: only one module is created per module. - module_base(const char* name); - ~module_base(); - - // Add elements to the module - void setattr(const char* name, PyObject*); - void setattr(const char* name, ref const&); - void add(PyTypeObject* x); // just use the type's name - void add_type(ref); - - // Return a reference to the Python module object being built - ref object() const; - - private: - ref m_module; - static PyMethodDef initial_methods[1]; -}; - -class module : public module_base +class module : public detail::module_base { public: module(const char* name) @@ -76,11 +54,6 @@ class module : public module_base // // inline implementations // -inline ref module_base::object() const -{ - return m_module; -} - inline module& module::setattr(const char* name, PyObject* x) { this->module_base::setattr(name, x); diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 04f0e992..0d5210c7 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -6,7 +6,6 @@ #ifndef CLASS_DWA20011214_HPP # define CLASS_DWA20011214_HPP -# include # include # include # include diff --git a/src/module.cpp b/src/module.cpp index dbc81729..0291c9c1 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -6,9 +6,10 @@ // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. -#include +#include +#include -namespace boost { namespace python { +namespace boost { namespace python { namespace detail { module_base::module_base(const char* name) : m_module( @@ -46,4 +47,4 @@ void module_base::add_type(ref x) PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; -}} // namespace boost::python +}}} // namespace boost::python::detail diff --git a/src/object/class.cpp b/src/object/class.cpp index 8186f9be..b9deb98f 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -3,8 +3,7 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include -#include +#include #include #include #include From db9fb22cf445a226c503f139496a8c6bffcb4921 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 28 Feb 2002 00:24:52 +0000 Subject: [PATCH 0289/1042] Tests for NULL == None [SVN r12971] --- test/test_builtin_converters.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index 3a4722c7..50d436e5 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -84,6 +84,17 @@ >>> rewrap_const_reference_string('yo, wassup?') 'yo, wassup?' + +Check that None <==> NULL + +>>> rewrap_const_reference_cstring(None) + +But when converted to a string rvalue, None becomes 'None': + +>>> rewrap_const_reference_string(None) +'None' + + Now check implicit conversions between floating/integer types >>> rewrap_const_reference_float(42) From a2dec7a05dd8f92591e12a7cf0972d3506a44d92 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 28 Feb 2002 00:48:48 +0000 Subject: [PATCH 0290/1042] Make cxx 6.5 bugs happy [SVN r12973] --- include/boost/python/converter/from_python.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index 4fe240ce..f2680ef3 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -130,7 +130,7 @@ inline from_python_base::from_python_base(void* result) } inline from_python_base::from_python_base( - PyObject* const source + PyObject* source , lvalue_from_python_registration const* chain) : m_result(find(source, chain)) { From b28dc5523752d79df1f524f872c9fd9ab12e74f6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 28 Feb 2002 06:08:27 +0000 Subject: [PATCH 0291/1042] suppress warnings with CWPro7 [SVN r12977] --- src/converter/builtin_converters.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index 2e9bcbec..fe6708e6 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -221,15 +221,13 @@ namespace { return PyInt_AS_LONG(intermediate); } - else if (PyFloat_Check(intermediate)) - { - return PyFloat_AS_DOUBLE(intermediate); - } - else + else if (!PyFloat_Check(intermediate)) { PyErr_SetString(PyExc_TypeError, "__complex__ method did not return a Complex object"); throw error_already_set(); } + + return PyFloat_AS_DOUBLE(intermediate); } }; } From 0e597f576875670c699fe33da9191ed74d9e1cc2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 28 Feb 2002 15:38:21 +0000 Subject: [PATCH 0292/1042] Suppress some warnings on older EDGs [SVN r12984] --- include/boost/python/converter/from_python.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index f2680ef3..f9192be2 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -10,6 +10,7 @@ # include # include # include +# include # include # include # include @@ -179,7 +180,9 @@ namespace detail template inline void write_void_ptr_reference(void const volatile* storage, void* ptr, U&(*)()) { - write_void_ptr(storage, ptr, U(0)); + // stripping CV qualification suppresses warnings on older EDGs + typedef typename remove_cv::type u_stripped; + write_void_ptr(storage, ptr, u_stripped(0)); } } From edad2a1ee5cbc379e1862cc92e219a331a731a36 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 1 Mar 2002 20:33:04 +0000 Subject: [PATCH 0293/1042] *** empty log message *** [SVN r12999] --- .../python/converter/from_python_data.hpp | 154 ++++++++---------- include/boost/python/detail/eval.hpp | 2 + 2 files changed, 66 insertions(+), 90 deletions(-) diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp index d88eb90e..fe026172 100644 --- a/include/boost/python/converter/from_python_data.hpp +++ b/include/boost/python/converter/from_python_data.hpp @@ -13,15 +13,12 @@ # include # include # include - -// Keep these for the metaprogram which EDG is choking on. -# if !defined(__EDG__) || (__EDG_VERSION__ > 245) -# include -# include -# include -# else -# include -# endif +# include +# include +//# include +# include +# include +# include namespace boost { namespace python { namespace converter { @@ -75,111 +72,88 @@ namespace detail }; # endif - - struct unknown_alignment - { - void* p; - }; - -// EDG is too slow to handle this metaprogram :( -#if !defined(__EDG__) || (__EDG_VERSION__ > 245) struct alignment_dummy; + typedef void (*function_ptr)(); + typedef int (alignment_dummy::*member_ptr); + typedef int (alignment_dummy::*member_function_ptr)(); - template - struct best_alignment_type +# define BOOST_PYTHON_ALIGNMENT_TYPES BOOST_PP_TUPLE_TO_LIST( \ + 11, ( \ + char, short, int, long, float, double, long double \ + , void*, function_ptr, member_ptr, member_function_ptr)) + +# define BOOST_PYTHON_CHOOSE_LOWER_ALIGNMENT(R,P,I,T) \ + typename mpl::select_type< \ + alignment_of::value <= target, T, char>::type BOOST_PP_CAT(t,I); + +# define BOOST_PYTHON_CHOOSE_LOWER_SIZE(R,P,I,T) \ + typename mpl::select_type< \ + sizeof(T) <= target, T, char>::type BOOST_PP_CAT(t,I); + +# define BOOST_PYTHON_CHOOSE_T(R,P,I,T) T BOOST_PP_CAT(t,I); + + template + union lower_alignment { - template - struct apply - { - BOOST_STATIC_CONSTANT( - std::size_t, align1 = alignment_of::value); - - BOOST_STATIC_CONSTANT( - std::size_t, align2 = alignment_of::value); - - BOOST_STATIC_CONSTANT( - bool, aligned2 = ( - (align2 >= target_alignment) - & (align2 % target_alignment == 0)) - ); - - BOOST_STATIC_CONSTANT( - bool, choose_t2 = ( - aligned2 && ( - is_same::value - | (align2 < align1) - | (sizeof(T2) < sizeof(T1))) - )); - - typedef typename mpl::select_type::type type; - }; + BOOST_PP_LIST_FOR_EACH_I( + BOOST_PYTHON_CHOOSE_LOWER_ALIGNMENT + , ignored, BOOST_PYTHON_ALIGNMENT_TYPES) }; - typedef mpl::type_list< - char,short,int,long, float,double,long double - ,void* - ,void(*)() - ,void (alignment_dummy::*)() - , char (alignment_dummy::*) - >::type - align_types; -#endif // EDG is too slow + template + union lower_size + { + BOOST_PP_LIST_FOR_EACH_I( + BOOST_PYTHON_CHOOSE_LOWER_SIZE + , ignored, BOOST_PYTHON_ALIGNMENT_TYPES) + }; + + union max_align + { + BOOST_PP_LIST_FOR_EACH_I( + BOOST_PYTHON_CHOOSE_T + , ignored, BOOST_PYTHON_ALIGNMENT_TYPES) + }; + template union aligned_storage { Align align; - char bytes[size - // this is just a STATIC_ASSERT. For some reason - // MSVC was barfing on the boost one. - - (is_same::value ? size : 0)]; + char bytes[size]; }; template struct referent_storage { -// EDG is too slow to handle this metaprogram :( -#if !defined(__EDG__) || (__EDG_VERSION__ > 245) - typedef mpl::for_each< - align_types - , unknown_alignment - , best_alignment_type< - referent_alignment::value - > - > loop; - - typedef typename loop::state align_t; -#else typedef typename remove_cv::type>::type referent; - - // The Python source makes the assumption that double has - // maximal alignment, but that fails on some platforms - BOOST_STATIC_CONSTANT( - std::size_t, target_align = alignment_of::value); - // Here we make some assumptions and leave out some possible - // types worth checking, but this should work most of the time. + BOOST_STATIC_CONSTANT(std::size_t, target = referent_alignment::value); + typedef lower_alignment t1; + typedef lower_size::value> t2; + typedef typename mpl::select_type< - is_POD::value - , referent + ::boost::detail::ice_and< + alignment_of::value >= target + , alignment_of::value % target == 0 + >::value + , t1 , typename mpl::select_type< - alignment_of::value >= target_align - , long - , typename mpl::select_type< - alignment_of::value >= target_align - , double - , long double>::type + ::boost::detail::ice_and< + alignment_of::value >= target + , alignment_of::value % target == 0 + >::value + , t2 + , max_align >::type >::type align_t; -#endif - BOOST_STATIC_CONSTANT(std::size_t, alignment1 = alignment_of::value); - BOOST_STATIC_CONSTANT(std::size_t, alignment2 = referent_alignment::value); + + BOOST_STATIC_CONSTANT(std::size_t, found = alignment_of::value); - BOOST_STATIC_ASSERT(alignment1 >= alignment2); - BOOST_STATIC_ASSERT(alignment1 % alignment2 == 0); + BOOST_STATIC_ASSERT(found >= target); + BOOST_STATIC_ASSERT(found % target == 0); typedef aligned_storage::value> type; }; - } template diff --git a/include/boost/python/detail/eval.hpp b/include/boost/python/detail/eval.hpp index 3e799507..8699f701 100644 --- a/include/boost/python/detail/eval.hpp +++ b/include/boost/python/detail/eval.hpp @@ -6,6 +6,8 @@ #ifndef EVAL_DWA2002124_HPP # define EVAL_DWA2002124_HPP +# include + namespace boost { namespace python { namespace detail { template struct undefined; From 71cbe1cf50d6d93d298b6d2744aa06848cb1d036 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 1 Mar 2002 21:24:49 +0000 Subject: [PATCH 0294/1042] quick fixes for KCC [SVN r13000] --- .../python/converter/from_python_data.hpp | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp index fe026172..9b418957 100644 --- a/include/boost/python/converter/from_python_data.hpp +++ b/include/boost/python/converter/from_python_data.hpp @@ -15,7 +15,7 @@ # include # include # include -//# include +# include # include # include # include @@ -129,19 +129,23 @@ namespace detail BOOST_STATIC_CONSTANT(std::size_t, target = referent_alignment::value); typedef lower_alignment t1; + + BOOST_STATIC_CONSTANT(bool, t1_aligned = + (alignment_of::value >= target) + & (alignment_of::value % target == 0)); + typedef lower_size::value> t2; + BOOST_STATIC_CONSTANT(bool, t2_aligned = + (alignment_of::value >= target) + & (alignment_of::value % target == 0)); + + typedef typename mpl::select_type< - ::boost::detail::ice_and< - alignment_of::value >= target - , alignment_of::value % target == 0 - >::value + t1_aligned , t1 , typename mpl::select_type< - ::boost::detail::ice_and< - alignment_of::value >= target - , alignment_of::value % target == 0 - >::value + t2_aligned , t2 , max_align >::type From 9644610e049ae06b52b63e9545ae32b62fc13679 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Mar 2002 01:33:55 +0000 Subject: [PATCH 0295/1042] obsolete [SVN r13004] --- include/boost/python/converter/handle.hpp | 108 ---------------------- 1 file changed, 108 deletions(-) delete mode 100644 include/boost/python/converter/handle.hpp diff --git a/include/boost/python/converter/handle.hpp b/include/boost/python/converter/handle.hpp deleted file mode 100644 index 82e085b0..00000000 --- a/include/boost/python/converter/handle.hpp +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef HANDLE_DWA20011130_HPP -# define HANDLE_DWA20011130_HPP -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -struct BOOST_PYTHON_DECL body; - -// The common base class for unwrap_ and wrap_ handle objects. They -// share a common base so that handles can be linked into a chain -// within a function wrapper which is managed by a single object. -struct BOOST_PYTHON_DECL handle : private boost::noncopyable -{ - public: // member functions - - // All constructors take a body* passed from the derived class. - // - // Constructors taking a handle links this into a chain of - // handles, for more efficient management in function wrappers - handle(); - handle(body* body); - handle(body* body, handle& prev); - - // returns true iff all handles in the chain can convert their - // arguments - bool convertible() const; - - // safe_bool idiom from Peter Dimov: provides handles to/from - // bool without enabling handles to integer types/void*. - private: - struct dummy { inline void nonnull() {} }; - typedef void (dummy::*safe_bool)(); - public: - inline operator safe_bool() const; - inline safe_bool operator!() const; - - protected: // member functions for derived classes - // Get the body we hold - inline body* get_body() const; - - inline void set_body(body*); - inline void set_prev(handle&); - - // Release all bodies in the chain, in reverse order of - // initialization. Only actually called for the head of the chain. - void destroy(); - - private: - // Holds implementation - body* m_body; - - // handle for next argument, if any. - handle* m_next; -}; - -// -// implementations -// -inline handle::handle() - : m_next(0) -{} - -inline handle::handle(body* body, handle& prev) - : m_body(body), m_next(0) -{ - prev.m_next = this; -} - -inline handle::handle(body* body) - : m_body(body), m_next(0) -{ -} - -inline handle::operator handle::safe_bool() const -{ - return convertible() ? &dummy::nonnull : 0; -} - -inline handle::safe_bool handle::operator!() const -{ - return convertible() ? 0 : &dummy::nonnull; -} - -inline body* handle::get_body() const -{ - return m_body; -} - -inline void handle::set_body(body* body) -{ - m_body = body; -} - -inline void handle::set_prev(handle& prev) -{ - prev.m_next = this; -} - -}}} // namespace boost::python::converter - -#endif // HANDLE_DWA20011130_HPP From a437af44f8b6ea4ea8d16e5845d70d9823cfd157 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Mar 2002 01:52:38 +0000 Subject: [PATCH 0296/1042] obsolete [SVN r13005] --- .../python/converter/unwrapper_select.hpp | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 include/boost/python/converter/unwrapper_select.hpp diff --git a/include/boost/python/converter/unwrapper_select.hpp b/include/boost/python/converter/unwrapper_select.hpp deleted file mode 100644 index d60923af..00000000 --- a/include/boost/python/converter/unwrapper_select.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef UNWRAPPER_SELECT_DWA20011229_HPP -# define UNWRAPPER_SELECT_DWA20011229_HPP - -namespace boost { namespace python { namespace converter { - -template struct unwrapper; - -// Select the type returned by unwrapper objects when unwrapping a -// given type. When unwrapping T const&, the unwrapper returns T&, so -// that the same unwrapper object can be used for both conversions (on -// a conforming compiler). -template -struct unwrapper_select -{ - typedef unwrapper type; -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct unwrapper_select -{ - typedef unwrapper type; -}; -# endif - -}}} // namespace boost::python::converter - -#endif // UNWRAPPER_SELECT_DWA20011229_HPP From 1257b32464f60490c366bc26802a27f922c6ba32 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Mar 2002 02:29:06 +0000 Subject: [PATCH 0297/1042] added missing 'inline' [SVN r13006] --- include/boost/python/from_python.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/from_python.hpp b/include/boost/python/from_python.hpp index 8c3f94bb..726928ac 100644 --- a/include/boost/python/from_python.hpp +++ b/include/boost/python/from_python.hpp @@ -39,7 +39,7 @@ struct from_python // implementations // template -from_python::from_python(PyObject* source) +inline from_python::from_python(PyObject* source) : base(source) { } From 087f09e9a6dd68bfd5af5e6591824a6074fb24f3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 2 Mar 2002 02:52:36 +0000 Subject: [PATCH 0298/1042] flotsam removal [SVN r13007] --- include/boost/python/with_custodian_and_ward.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/boost/python/with_custodian_and_ward.hpp b/include/boost/python/with_custodian_and_ward.hpp index 4ae975af..517d690f 100644 --- a/include/boost/python/with_custodian_and_ward.hpp +++ b/include/boost/python/with_custodian_and_ward.hpp @@ -11,8 +11,6 @@ namespace boost { namespace python { -enum custodial_timing { pre_call, post_call }; - template struct with_custodian_and_ward : Base { From bd9df7e6199c7e0ad5b0b32f27c13a611d7b568c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 3 Mar 2002 20:46:06 +0000 Subject: [PATCH 0299/1042] Apply patch due to Craig Rodriguez [SVN r13049] --- include/boost/python/detail/init_function.hpp | 110 +++++++++--------- src/gen_init_function.py | 2 +- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/include/boost/python/detail/init_function.hpp b/include/boost/python/detail/init_function.hpp index ed34f9be..3c6f2380 100644 --- a/include/boost/python/detail/init_function.hpp +++ b/include/boost/python/detail/init_function.hpp @@ -175,106 +175,106 @@ struct init_function template static init* create(signature1) { return new init1::const_reference>; + typename detail::parameter_traits::const_reference>; } template static init* create(signature2) { return new init2::const_reference, - detail::parameter_traits::const_reference>; + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference>; } template static init* create(signature3) { return new init3::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference>; } template static init* create(signature4) { return new init4::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference>; } template static init* create(signature5) { return new init5::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference>; } template static init* create(signature6) { return new init6::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference>; } template static init* create(signature7) { return new init7::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference>; } template static init* create(signature8) { return new init8::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference>; } template static init* create(signature9) { return new init9::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference>; } template static init* create(signature10) { return new init10::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference, - detail::parameter_traits::const_reference>; + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference, + typename detail::parameter_traits::const_reference>; } }; diff --git a/src/gen_init_function.py b/src/gen_init_function.py index ff294dbb..94e8041a 100644 --- a/src/gen_init_function.py +++ b/src/gen_init_function.py @@ -169,7 +169,7 @@ struct init_function template <%(class A%n%:, %)> %} static init* create(signature%x%{<%(A%n%:, %)>%}) { return new init%x::const_reference%)>; + typename detail::parameter_traits::const_reference%)>; } """, args)+"""}; From 97825fb2c7b2d77c2c0611eb609eb2a77b8ac315 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 6 Mar 2002 01:33:46 +0000 Subject: [PATCH 0300/1042] Kill some Intel5 warnings [SVN r13108] --- include/boost/python/detail/config.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index c488cb64..efd1500b 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -33,10 +33,15 @@ # define BOOST_MSVC6_OR_EARLIER 1 # endif -# pragma warning (disable : 4786) +# pragma warning (disable : 4786) + +# elif defined(__ICL) && __ICL < 600 // Intel C++ 5 + +# pragma warning(disable: 985) // identifier was truncated in debug information # endif + // Work around the broken library implementation/strict ansi checking on some // EDG-based compilers (e.g. alpha), which incorrectly warn that the result of // offsetof() is not an integer constant expression. From e79a66851c02c061be6678d3a7118907d7305596 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 8 Mar 2002 14:56:39 +0000 Subject: [PATCH 0301/1042] Beginning of callback implementation [SVN r13135] --- Jamfile | 104 +++--------------- .../python/converter/builtin_converters.hpp | 24 +++- .../converter/callback_to_python_base.hpp | 45 ++++++++ .../python/converter/find_from_python.hpp | 7 +- .../boost/python/converter/from_python.hpp | 42 +------ .../python/converter/from_python_data.hpp | 37 ++++++- .../converter/lvalue_from_python_chain.hpp | 67 +++++++++++ include/boost/python/converter/registry.hpp | 8 +- .../python/converter/to_python_function.hpp | 44 +++++--- .../converter/to_python_function_type.hpp | 30 +++++ include/boost/python/to_python_converter.hpp | 2 +- include/boost/python/to_python_value.hpp | 16 +-- src/converter/builtin_converters.cpp | 2 +- src/converter/from_python.cpp | 12 +- src/converter/registry.cpp | 8 +- src/object/function.cpp | 30 ++++- test/Jamfile | 75 +++++++++++++ test/test_builtin_converters.cpp | 4 +- test/test_builtin_converters.py | 2 +- 19 files changed, 381 insertions(+), 178 deletions(-) create mode 100644 include/boost/python/converter/callback_to_python_base.hpp create mode 100644 include/boost/python/converter/lvalue_from_python_chain.hpp create mode 100644 include/boost/python/converter/to_python_function_type.hpp create mode 100644 test/Jamfile diff --git a/Jamfile b/Jamfile index 9bf18e2e..4a1af66f 100644 --- a/Jamfile +++ b/Jamfile @@ -4,93 +4,21 @@ subproject libs/python ; SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; - -{ - local BOOST_PYTHON_V2_PROPERTIES - = $(PYTHON_PROPERTIES) - <*>"-inline deferred" - <*>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers - BOOST_PYTHON_DYNAMIC_LIB - BOOST_PYTHON_V2 - ; - - local gcc-release-properties - = speed -fomit-frame-pointer - on -foptimize-sibling-calls - ; - - local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) $(gcc-release-properties) -; - - dll bpl - : - src/converter/from_python.cpp - src/converter/registry.cpp - src/converter/type_id.cpp - src/object/class.cpp - src/object/function.cpp - src/object/inheritance.cpp - src/object/life_support.cpp - src/errors.cpp - src/module.cpp - src/objects.cpp - src/converter/builtin_converters.cpp - : - $(BOOST_PYTHON_V2_PROPERTIES) - BOOST_PYTHON_SOURCE - ; - - # -------- general test ------- - extension m1 : test/m1.cpp bpl - : - : - ; - - extension m2 : test/m2.cpp bpl - : - : ; - - boost-python-runtest try : test/newtest.py m1 m2 : : ; - - # ----------- builtin converters ----------- - - extension builtin_converters_ext : test/test_builtin_converters.cpp bpl - : - : - ; - - boost-python-runtest test_builtin_converters : test/test_builtin_converters.py - builtin_converters_ext - : - : - ; - - # ----------- pointer adoption ----------- - - extension test_pointer_adoption_ext : test/test_pointer_adoption.cpp bpl - : - : - ; - - boost-python-runtest test_pointer_adoption : test/test_pointer_adoption.py - test_pointer_adoption_ext - : - : - ; - -} - -unit-test indirect_traits_test - : test/indirect_traits_test.cpp : $(BOOST_ROOT) ; -unit-test destroy_test - : test/destroy_test.cpp : $(BOOST_ROOT) ; -unit-test pointer_type_id_test - : test/pointer_type_id_test.cpp : $(BOOST_ROOT) ; - -unit-test select_from_python_test - : test/select_from_python_test.cpp +dll bpl + : + src/converter/from_python.cpp + src/converter/registry.cpp src/converter/type_id.cpp - src/converter/registry.cpp # MWerks needs this for some reason - : $(PYTHON_PROPERTIES) + src/object/class.cpp + src/object/function.cpp + src/object/inheritance.cpp + src/object/life_support.cpp + src/errors.cpp + src/module.cpp + src/objects.cpp + src/converter/builtin_converters.cpp + src/converter/callback.cpp + : + $(BOOST_PYTHON_V2_PROPERTIES) + BOOST_PYTHON_SOURCE ; - diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index 7ae7a357..4db0eb9c 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -7,6 +7,7 @@ # define BUILTIN_CONVERTERS_DWA2002124_HPP # include # include +# include # include # include @@ -23,6 +24,11 @@ namespace detail }; } +namespace converter +{ + template struct callback_to_python; +} + # define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ template <> struct to_python_value \ : detail::builtin_to_python \ @@ -39,7 +45,19 @@ namespace detail { \ return (expr); \ } \ - }; + }; \ + namespace converter \ + { \ + template <> struct callback_to_python< T > \ + { \ + callback_to_python(T const& x) \ + : m_held(expr) {} \ + PyObject* get() const \ + { return m_held.get(); } \ + private: \ + ref m_held; \ + }; \ + } # define BOOST_PYTHON_TO_INT(T) \ @@ -53,12 +71,12 @@ BOOST_PYTHON_TO_INT(int) BOOST_PYTHON_TO_INT(long) # undef BOOST_TO_PYTHON_INT -BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, x ? PyString_FromString(x) : detail::none()) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, x ? PyString_FromString(x) : boost::python::detail::none()) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, x ? x : detail::none()) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, (x ? x : boost::python::detail::none())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) diff --git a/include/boost/python/converter/callback_to_python_base.hpp b/include/boost/python/converter/callback_to_python_base.hpp new file mode 100644 index 00000000..c878850e --- /dev/null +++ b/include/boost/python/converter/callback_to_python_base.hpp @@ -0,0 +1,45 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CALLBACK_TO_PYTHON_BASE_DWA200237_HPP +# define CALLBACK_TO_PYTHON_BASE_DWA200237_HPP +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +namespace detail +{ + struct callback_to_python_holder + { + callback_to_python_holder(PyObject* obj); + inline PyObject* get() const; + private: + ref m_held; + }; + + struct BOOST_PYTHON_DECL callback_to_python_base : callback_to_python_holder + { + callback_to_python_base(void const volatile* source, to_python_function_t); + }; + + // + // implmentation + // + inline callback_to_python_holder::callback_to_python_holder(PyObject* obj) + : m_held(obj) + { + } + + inline PyObject* callback_to_python_holder::get() const + { + return m_held.get(); + } +} + +}}} // namespace boost::python::converter + +#endif // CALLBACK_TO_PYTHON_BASE_DWA200237_HPP diff --git a/include/boost/python/converter/find_from_python.hpp b/include/boost/python/converter/find_from_python.hpp index 863c44a6..e7f7ca81 100644 --- a/include/boost/python/converter/find_from_python.hpp +++ b/include/boost/python/converter/find_from_python.hpp @@ -8,17 +8,18 @@ # include # include +# include namespace boost { namespace python { namespace converter { struct lvalue_from_python_registration; struct rvalue_from_python_registration; -struct rvalue_stage1_data; BOOST_PYTHON_DECL void* find( PyObject* source, lvalue_from_python_registration const*); -BOOST_PYTHON_DECL void* find( - PyObject* source, rvalue_from_python_registration const*, rvalue_stage1_data&); + +BOOST_PYTHON_DECL rvalue_stage1_data find( + PyObject* source, rvalue_from_python_registration const*); }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index f9192be2..5fe8901a 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -8,13 +8,14 @@ # include # include -# include # include # include # include # include # include # include +# include +# include namespace boost { namespace python { namespace converter { @@ -42,8 +43,6 @@ struct pointer_const_reference_from_python private: typename detail::referent_storage::type m_result; - - static lvalue_from_python_registration*& chain; }; // Used when T == U* @@ -52,8 +51,6 @@ struct pointer_from_python : from_python_base { pointer_from_python(PyObject*); T operator()(PyObject*) const; - - static lvalue_from_python_registration*& chain; }; // Used when T == U& and (T != V const& or T == W volatile&) @@ -62,8 +59,6 @@ struct reference_from_python : from_python_base { reference_from_python(PyObject*); T operator()(PyObject*) const; - - static lvalue_from_python_registration*& chain; }; // ------- rvalue converters --------- @@ -79,14 +74,12 @@ class rvalue_from_python public: rvalue_from_python(PyObject*); - ~rvalue_from_python(); bool convertible() const; result_type operator()(PyObject*); private: rvalue_data m_data; - static rvalue_from_python_registration*& chain; }; template @@ -191,7 +184,7 @@ inline pointer_const_reference_from_python::pointer_const_reference_from_pyth { detail::write_void_ptr_reference( m_result.bytes - , p == Py_None ? p : find(p, chain) + , p == Py_None ? p : find(p, lvalue_from_python_chain::value) , (T(*)())0); } @@ -208,15 +201,11 @@ inline T pointer_const_reference_from_python::operator()(PyObject* p) const : detail::void_ptr_to_reference(m_result.bytes, (T(*)())0); } -template -lvalue_from_python_registration*& pointer_const_reference_from_python::chain - = registry::lvalue_converters(pointer_type_id()); - // -------- template inline pointer_from_python::pointer_from_python(PyObject* p) - : from_python_base(p == Py_None ? p : find(p, chain)) + : from_python_base(p == Py_None ? p : find(p, lvalue_from_python_chain::value)) { } @@ -226,15 +215,11 @@ inline T pointer_from_python::operator()(PyObject* p) const return (p == Py_None) ? 0 : T(result()); } -template -lvalue_from_python_registration*& pointer_from_python::chain - = registry::lvalue_converters(pointer_type_id()); - // -------- template inline reference_from_python::reference_from_python(PyObject* p) - : from_python_base(find(p,chain)) + : from_python_base(find(p,lvalue_from_python_chain::value)) { } @@ -244,23 +229,12 @@ inline T reference_from_python::operator()(PyObject*) const return detail::void_ptr_to_reference(result(), (T(*)())0); } -template -lvalue_from_python_registration*& reference_from_python::chain - = registry::lvalue_converters(undecorated_type_id()); - // ------- template inline rvalue_from_python::rvalue_from_python(PyObject* obj) + : m_data(find(obj, rvalue_from_python_chain::value)) { - find(obj, chain, m_data.stage1); -} - -template -inline rvalue_from_python::~rvalue_from_python() -{ - if (m_data.stage1.convertible == m_data.storage.bytes) - python::detail::destroy_reference(m_data.storage.bytes); } template @@ -279,10 +253,6 @@ rvalue_from_python::operator()(PyObject* p) return detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0); } -template -rvalue_from_python_registration*& rvalue_from_python::chain - = registry::rvalue_converters(undecorated_type_id()); - }}} // namespace boost::python::converter #endif // FROM_PYTHON_DWA2002127_HPP diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp index 9b418957..9fa9410a 100644 --- a/include/boost/python/converter/from_python_data.hpp +++ b/include/boost/python/converter/from_python_data.hpp @@ -16,6 +16,7 @@ # include # include # include +# include # include # include # include @@ -161,7 +162,7 @@ namespace detail } template -struct rvalue_data +struct rvalue_base_data { rvalue_stage1_data stage1; @@ -170,6 +171,40 @@ struct rvalue_data >::type storage; }; +template +struct rvalue_data : rvalue_base_data +{ + rvalue_data(rvalue_stage1_data const&); + rvalue_data(void*); + ~rvalue_data(); +}; + +// +// Implementataions +// +template +inline rvalue_data::rvalue_data(rvalue_stage1_data const& stage1) +{ + this->stage1 = stage1; +} + +template +inline rvalue_data::rvalue_data(void* convertible) +{ + this->stage1.convertible = convertible; +} + +template +inline rvalue_data::~rvalue_data() +{ + if (this->stage1.convertible == this->storage.bytes) + python::detail::destroy_reference< + add_reference< + add_cv::type + >::type + >(storage.bytes); +} + }}} // namespace boost::python::converter #endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP diff --git a/include/boost/python/converter/lvalue_from_python_chain.hpp b/include/boost/python/converter/lvalue_from_python_chain.hpp new file mode 100644 index 00000000..f1417460 --- /dev/null +++ b/include/boost/python/converter/lvalue_from_python_chain.hpp @@ -0,0 +1,67 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP +# define LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP + +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +// Given T == U*cv&, T == U*, or T == U&, lvalue_from_python_chain +// declares a "templated global reference" to the lvalue from_python +// converter chain for U +namespace detail +{ + template + struct ptr_or_ptr_ref_lvalue_from_python_chain + { + static lvalue_from_python_registration*const& value; + }; + + template + lvalue_from_python_registration*const& + ptr_or_ptr_ref_lvalue_from_python_chain::value + = registry::lvalue_converters(pointer_type_id()); + + template + struct ref_lvalue_from_python_chain + { + static lvalue_from_python_registration*const& value; + }; + + template + lvalue_from_python_registration*const& + ref_lvalue_from_python_chain::value + = registry::lvalue_converters(undecorated_type_id()); + + template + struct select_lvalue_from_python_chain + { + BOOST_STATIC_CONSTANT( + bool, ptr = boost::python::detail::is_reference_to_pointer::value + || is_pointer::value); + + typedef typename add_reference::type>::type normalized; + + typedef typename mpl::select_type< + ptr + , ptr_or_ptr_ref_lvalue_from_python_chain + , ref_lvalue_from_python_chain + >::type type; + }; +} + +template +struct lvalue_from_python_chain + : detail::select_lvalue_from_python_chain::type +{ +}; + +}}} // namespace boost::python::converter + +#endif // LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index a511a1a4..1c8dba24 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -8,7 +8,7 @@ # include # include # include -# include +# include # include namespace boost { namespace python { namespace converter { @@ -22,10 +22,10 @@ namespace registry BOOST_PYTHON_DECL lvalue_from_python_registration*& lvalue_converters(undecorated_type_id_t); BOOST_PYTHON_DECL rvalue_from_python_registration*& rvalue_converters(undecorated_type_id_t); - BOOST_PYTHON_DECL to_python_value_function const& - to_python_function(undecorated_type_id_t); + BOOST_PYTHON_DECL to_python_function_t const& + get_to_python_function(undecorated_type_id_t); - BOOST_PYTHON_DECL void insert(to_python_value_function, undecorated_type_id_t); + BOOST_PYTHON_DECL void insert(to_python_function_t, undecorated_type_id_t); // Insert an lvalue from_python converter BOOST_PYTHON_DECL void insert(void* (*convert)(PyObject*), undecorated_type_id_t); diff --git a/include/boost/python/converter/to_python_function.hpp b/include/boost/python/converter/to_python_function.hpp index a438ce0c..ff3891e2 100644 --- a/include/boost/python/converter/to_python_function.hpp +++ b/include/boost/python/converter/to_python_function.hpp @@ -8,23 +8,41 @@ # include # include +# include +# include +# include +# include namespace boost { namespace python { namespace converter { -// The type of stored function pointers which actually do conversion -// by-value. The void* points to the object to be converted, and -// type-safety is preserved through runtime registration. -typedef PyObject* (*to_python_value_function)(void const*); - -// Given a typesafe to_python conversion function, produces a -// to_python_value_function which can be registered in the usual way. -template -struct as_to_python_value_function +// to_python_function -- +// +// essentially a "templated global reference" which holds the +// converter for converting a type to Python by-value. We "normalize" +// T by adding "const volatile&" so that fewer global variables and +// associated static initializations are generated. +namespace detail +{ + template + struct to_python_function_base + { + static to_python_function_t const& value; + }; + + template + to_python_function_t const& + to_python_function_base::value + = converter::registry::get_to_python_function(undecorated_type_id()); +} + +template +struct to_python_function + : detail::to_python_function_base< + typename add_reference< + typename add_cv::type + >::type + > { - static PyObject* convert(void const* x) - { - return ToPython::convert(*(T const*)x); - } }; }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/to_python_function_type.hpp b/include/boost/python/converter/to_python_function_type.hpp new file mode 100644 index 00000000..197654e5 --- /dev/null +++ b/include/boost/python/converter/to_python_function_type.hpp @@ -0,0 +1,30 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP +# define TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP +# include + +namespace boost { namespace python { namespace converter { + +// The type of stored function pointers which actually do conversion +// by-value. The void* points to the object to be converted, and +// type-safety is preserved through runtime registration. +typedef PyObject* (*to_python_function_t)(void const*); + +// Given a typesafe to_python conversion function, produces a +// to_python_function_t which can be registered in the usual way. +template +struct as_to_python_function +{ + static PyObject* convert(void const* x) + { + return ToPython::convert(*(T const*)x); + } +}; + +}}} // namespace boost::python::converter + +#endif // TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP diff --git a/include/boost/python/to_python_converter.hpp b/include/boost/python/to_python_converter.hpp index 7e46c505..47473419 100644 --- a/include/boost/python/to_python_converter.hpp +++ b/include/boost/python/to_python_converter.hpp @@ -25,7 +25,7 @@ struct to_python_converter template to_python_converter::to_python_converter() { - typedef converter::as_to_python_value_function< + typedef converter::as_to_python_function< T, Conversion > normalized; diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp index ecff5808..ffb68ada 100644 --- a/include/boost/python/to_python_value.hpp +++ b/include/boost/python/to_python_value.hpp @@ -23,25 +23,14 @@ struct to_python_value static bool convertible(); PyObject* operator()(argument_type) const; - - private: - // Note that this is a pointer to a function pointer - static converter::to_python_value_function const* fconvert; }; -template -converter::to_python_value_function const* -to_python_value::fconvert - = &converter::registry::to_python_function(converter::undecorated_type_id()); - - template bool to_python_value::convertible() { // if this assert fires, our static variable hasn't been set up yet. - assert(fconvert != 0); - return *fconvert != 0; + return converter::to_python_function::value != 0; } template @@ -49,8 +38,7 @@ PyObject* to_python_value::operator()(argument_type x) const { // This might be further optimized on platforms which dynamically // link without specific imports/exports - converter::to_python_value_function f = *fconvert; - return f(&x); + return converter::to_python_function::value(&x); } }} // namespace boost::python diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index fe6708e6..87d0d7b4 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -56,7 +56,7 @@ namespace ref intermediate(creator(obj)); // Get the location in which to construct - void* storage = ((rvalue_data*)data)->storage.bytes; + void* storage = ((rvalue_base_data*)data)->storage.bytes; new (storage) T(SlotPolicy::extract(intermediate.get())); // record successful construction diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 57aee355..8a68cc44 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -10,21 +10,23 @@ namespace boost { namespace python { namespace converter { -BOOST_PYTHON_DECL void* find( +BOOST_PYTHON_DECL rvalue_stage1_data find( PyObject* source - , rvalue_from_python_registration const* chain - , rvalue_stage1_data& data) + , rvalue_from_python_registration const* chain) { + rvalue_stage1_data data; + data.convertible = 0; for (;chain != 0; chain = chain->next) { void* r = chain->convertible(source); if (r != 0) { + data.convertible = r; data.construct = chain->construct; - return data.convertible = r; + break; } } - return data.convertible = 0; + return data; } BOOST_PYTHON_DECL void* find( diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index bdfa1c8a..2d104b01 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -19,7 +19,7 @@ namespace // entry(); // The unique to_python converter for the associated C++ type. - to_python_value_function m_to_python_converter; + to_python_function_t m_to_python_converter; // The collection of from_python converters for the associated // C++ type. @@ -66,15 +66,15 @@ namespace // namespace registry { - to_python_value_function const& to_python_function( + to_python_function_t const& get_to_python_function( undecorated_type_id_t key) { return find(key)->m_to_python_converter; } - void insert(to_python_value_function f, undecorated_type_id_t source_t) + void insert(to_python_function_t f, undecorated_type_id_t source_t) { - to_python_value_function& slot = find(source_t)->m_to_python_converter; + to_python_function_t& slot = find(source_t)->m_to_python_converter; assert(slot == 0); // we have a problem otherwise if (slot != 0) { diff --git a/src/object/function.cpp b/src/object/function.cpp index a30e9f15..a9f0c94d 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -112,6 +112,30 @@ void function::add_to_namespace( throw error_already_set(); } +namespace +{ + struct bind_return + { + bind_return(PyObject*& result, function const* f, PyObject* args, PyObject* keywords) + : m_result(result) + , m_f(f) + , m_args(args) + , m_keywords(keywords) + {} + + void operator()() const + { + m_result = m_f->call(m_args, m_keywords); + } + + private: + PyObject*& m_result; + function const* m_f; + PyObject* m_args; + PyObject* m_keywords; + }; +} + extern "C" { // Stolen from Python's funcobject.c @@ -130,9 +154,11 @@ extern "C" } static PyObject * - function_call(PyObject *func, PyObject *arg, PyObject *kw) + function_call(PyObject *func, PyObject *args, PyObject *kw) { - return static_cast(func)->call(arg, kw); + PyObject* result = 0; + handle_exception(bind_return(result, static_cast(func), args, kw)); + return result; } } diff --git a/test/Jamfile b/test/Jamfile new file mode 100644 index 00000000..767b07e6 --- /dev/null +++ b/test/Jamfile @@ -0,0 +1,75 @@ +subproject libs/python/test ; + +# bring in the rules for python +SEARCH on python.jam = $(BOOST_BUILD_PATH) ; +include python.jam ; + +local PYTHON_V1_PROPERTIES = $(PYTHON_PROPERTIES) ; +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) + { + if $(f:S) = .py + { + if $(py) + { + EXIT too many python drivers specified: "$(py)" "$(f)" ; + } + py = $(f) ; + } + } + + name ?= $(py:S=) ; + + for local f in $(files) + { + if $(f:S) != .py + { + local m = $(f:S=) ; + + if $(m) = $(py:S=) + { + m = $(name) ; + + if $(m) = $(py:S=) + { + m = $(m)_ext ; + } + } + extension $(m) : $(f) ../bpl ; + modules += $(m) ; + } + } + + boost-python-runtest $(name) : $(py) $(modules) ; +} + +bpl-test try : newtest.py m1.cpp m2.cpp ; +bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ; +bpl-test test_pointer_adoption ; +bpl-test callbacks ; + +# --- unit tests of library components --- +unit-test indirect_traits_test + : indirect_traits_test.cpp : $(BOOST_ROOT) ; +unit-test destroy_test + : destroy_test.cpp : $(BOOST_ROOT) ; +unit-test pointer_type_id_test + : pointer_type_id_test.cpp : $(BOOST_ROOT) ; + +unit-test select_from_python_test + : select_from_python_test.cpp + ../src/converter/type_id.cpp + # ../src/converter/registry.cpp # MWerks needs this for some reason + + : $(BOOST_ROOT) BOOST_PYTHON_STATIC_LIB + $(PYTHON_V1_PROPERTIES) + ; + diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp index 4c07d9f4..939f9dc4 100644 --- a/test/test_builtin_converters.cpp +++ b/test/test_builtin_converters.cpp @@ -25,9 +25,9 @@ struct by_const_reference } }; -BOOST_PYTHON_MODULE_INIT(builtin_converters_ext) +BOOST_PYTHON_MODULE_INIT(builtin_converters) { - boost::python::module("builtin_converters_ext") + boost::python::module("builtin_converters") .def("rewrap_value_bool", by_value::rewrap) .def("rewrap_value_signed_char", by_value::rewrap) diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index 50d436e5..3958c15a 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -1,5 +1,5 @@ """ ->>> from builtin_converters_ext import * +>>> from builtin_converters import * >>> rewrap_value_bool(None) 0 >>> rewrap_value_bool(0) From 532833ff705f4446aeeda0029a2bd5de56c9ed23 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 8 Mar 2002 15:29:39 +0000 Subject: [PATCH 0302/1042] initial checkin [SVN r13136] --- src/converter/callback.cpp | 69 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/converter/callback.cpp diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp new file mode 100644 index 00000000..b3158500 --- /dev/null +++ b/src/converter/callback.cpp @@ -0,0 +1,69 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include + +namespace boost { namespace python { namespace converter { + +namespace detail +{ + + namespace + { + inline PyObject* convert(void const volatile* source, to_python_function_t converter) + { + if (converter == 0) + { + PyErr_SetString( + PyExc_TypeError + , const_cast("no to_python (by-value) converter found for type")); + throw error_already_set(); + } + return converter(const_cast(source)); + } + } + + callback_to_python_base::callback_to_python_base( + void const volatile* source, to_python_function_t converter) + : callback_to_python_holder(convert(source, converter)) + { + } + + BOOST_PYTHON_DECL void throw_if_not_registered(rvalue_stage1_data const& data) + { + if (!data.convertible) + { + PyErr_SetString( + PyExc_TypeError + , const_cast("no from_python (by-value) converters found for type")); + throw error_already_set(); + } + } + + BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_stage1_data& data, void* storage) + { + ref holder(src); + + data = find(src, static_cast(data.convertible)); + + if (!data.convertible) + { + PyErr_SetString( + PyExc_TypeError + , const_cast("no registered from_python (by-value) converter was able to convert type")); + throw error_already_set(); + } + if (data.construct != 0) + data.construct(src, &data); + + return data.convertible; + } +} + +}}} // namespace boost::python::converter From a25021d215d3801f5c671ccdaa299d4f18bac161 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 8 Mar 2002 15:32:32 +0000 Subject: [PATCH 0303/1042] Initial checkin [SVN r13137] --- .../converter/rvalue_from_python_chain.hpp | 39 ++++++++++ test/callbacks.cpp | 71 +++++++++++++++++++ test/callbacks.py | 43 +++++++++++ 3 files changed, 153 insertions(+) create mode 100644 include/boost/python/converter/rvalue_from_python_chain.hpp create mode 100644 test/callbacks.cpp create mode 100644 test/callbacks.py diff --git a/include/boost/python/converter/rvalue_from_python_chain.hpp b/include/boost/python/converter/rvalue_from_python_chain.hpp new file mode 100644 index 00000000..c57ef564 --- /dev/null +++ b/include/boost/python/converter/rvalue_from_python_chain.hpp @@ -0,0 +1,39 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef RVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP +# define RVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +namespace detail +{ + template + struct rvalue_from_python_chain_impl + { + static rvalue_from_python_registration*const& value; + }; + + template + rvalue_from_python_registration*const& rvalue_from_python_chain_impl::value + = registry::rvalue_converters(undecorated_type_id()); +} + +template +struct rvalue_from_python_chain + : detail::rvalue_from_python_chain_impl< + typename add_reference< + typename add_cv::type + >::type + > +{ +}; + +}}} // namespace boost::python::converter + +#endif // RVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP diff --git a/test/callbacks.cpp b/test/callbacks.cpp new file mode 100644 index 00000000..9991e41f --- /dev/null +++ b/test/callbacks.cpp @@ -0,0 +1,71 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include + +using namespace boost::python; + +int apply_int_int(PyObject* f, int x) +{ + return returning::call(f, x); +} + +void apply_void_int(PyObject* f, int x) +{ + returning::call(f, x); +} + +struct X +{ + explicit X(int x) : x(x), magic(7654321) { ++counter; } + X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } + ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } + + void set(int x) { assert(magic == 7654321); this->x = x; } + int value() const { assert(magic == 7654321); return x; } + static int count() { return counter; } + private: + void operator=(X const&); + private: + int x; + long magic; + static int counter; +}; + +X apply_X_X(PyObject* f, X x) +{ + return returning::call(f, x); +} + +void apply_void_X_ref(PyObject* f, X x) +{ + returning::call(f, boost::ref(x)); +} + +int X::counter; + +BOOST_PYTHON_MODULE_INIT(callbacks_ext) +{ + boost::python::module("callbacks_ext") + .def("apply_int_int", apply_int_int) + .def("apply_void_int", apply_void_int) + .def("apply_X_X", apply_X_X) + .def("apply_void_X_ref", apply_void_X_ref) + .add( + class_("X") + .def_init(args()) + .def_init(args()) + .def("value", &X::value) + .def("set", &X::set) + ) + .def("x_count", &X::count) + ; +} + + + diff --git a/test/callbacks.py b/test/callbacks.py new file mode 100644 index 00000000..16c5be94 --- /dev/null +++ b/test/callbacks.py @@ -0,0 +1,43 @@ +''' +>>> from callbacks_ext import * + +>>> def double(x): +... return x + x +... +>>> apply_int_int(double, 42) +84 +>>> apply_void_int(double, 42) + +>>> def identity(x): +... return x + +>>> x = apply_X_X(identity, X(42)) +>>> x.value() +42 +>>> x_count() +1 +>>> del x +>>> x_count() +0 + +>>> def increment(x): +... x.set(x.value() + 1) +... +>>> x = X(42) +>>> apply_void_X_ref(increment, x) +>>> x.value() +43 +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 305469472619b2f22dae6c43a9fdb0e40c661ba7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 8 Mar 2002 16:05:17 +0000 Subject: [PATCH 0304/1042] conformance fix [SVN r13138] --- include/boost/python/converter/from_python_data.hpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp index 9fa9410a..dd0a0282 100644 --- a/include/boost/python/converter/from_python_data.hpp +++ b/include/boost/python/converter/from_python_data.hpp @@ -197,12 +197,10 @@ inline rvalue_data::rvalue_data(void* convertible) template inline rvalue_data::~rvalue_data() { + typedef typename add_reference::type>::type ref_type; + if (this->stage1.convertible == this->storage.bytes) - python::detail::destroy_reference< - add_reference< - add_cv::type - >::type - >(storage.bytes); + python::detail::destroy_reference(this->storage.bytes); } }}} // namespace boost::python::converter From 7e76c855356009ceb5d589a9fe8bcb382169d498 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 8 Mar 2002 16:13:32 +0000 Subject: [PATCH 0305/1042] initial checkin [SVN r13139] --- include/boost/python/converter/callback.hpp | 113 ++++++++++++++ include/boost/python/returning.hpp | 159 ++++++++++++++++++++ 2 files changed, 272 insertions(+) create mode 100644 include/boost/python/converter/callback.hpp create mode 100644 include/boost/python/returning.hpp diff --git a/include/boost/python/converter/callback.hpp b/include/boost/python/converter/callback.hpp new file mode 100644 index 00000000..3e1e462e --- /dev/null +++ b/include/boost/python/converter/callback.hpp @@ -0,0 +1,113 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CALLBACK_DWA2002228_HPP +# define CALLBACK_DWA2002228_HPP + +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +namespace detail +{ + template + struct pointer_callback_from_python + { + pointer_callback_from_python(); + T operator()(PyObject*) const; + }; + + template + struct reference_callback_from_python + { + reference_callback_from_python(); + T operator()(PyObject*) const; + }; + + template + struct rvalue_callback_from_python + { + rvalue_callback_from_python(); + T const& operator()(PyObject*); + private: + rvalue_data m_data; + }; + + template + struct select_callback_from_python + { + BOOST_STATIC_CONSTANT( + bool, ptr = is_pointer::value); + + BOOST_STATIC_CONSTANT( + bool, ref = is_reference::value); + + typedef typename mpl::select_type< + ptr + , pointer_callback_from_python + , typename mpl::select_type< + ref + , reference_callback_from_python + , rvalue_callback_from_python + >::type + >::type type; + }; + + + template + struct reference_callback_to_python + { + + }; +} + +template +struct callback_from_python + : detail::select_callback_from_python::type +{ +}; + +template +struct callback_to_python : detail::callback_to_python_base +{ + public: // member functions + // Throw an exception if the conversion can't succeed + callback_to_python(T const&); +}; + +// +// Implementations +// +namespace detail +{ + template + rvalue_callback_from_python::rvalue_callback_from_python() + : m_data(rvalue_from_python_chain::value) + { + throw_if_not_registered(m_data.stage1); + } + + template + T const& rvalue_callback_from_python::operator()(PyObject* obj) + { + return *(T*)convert_rvalue(obj, m_data.stage1, m_data.storage.bytes); + } +} + +template +callback_to_python::callback_to_python(T const& x) + : callback_to_python_base(&x, to_python_function::value) +{ +} + +}}} // namespace boost::python::converter + +#endif // CALLBACK_DWA2002228_HPP diff --git a/include/boost/python/returning.hpp b/include/boost/python/returning.hpp new file mode 100644 index 00000000..c34f97f6 --- /dev/null +++ b/include/boost/python/returning.hpp @@ -0,0 +1,159 @@ +// (C) Copyright David Abrahams 2001,2002. Permission to copy, use, modify, sell +// and distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// This work was funded in part by Lawrence Berkeley National Labs +// +// This file generated for 5-argument member functions and 6-argument free +// functions by gen_returning.py + +#ifndef RETURNING_DWA20020228_HPP +# define RETURNING_DWA20020228_HPP + +# include +# include +# include +# include + +namespace boost { namespace python { + +// Calling C++ from Python +template +struct returning +{ + static R call(char const* name, PyObject* self) + { + converter::callback_from_python cr; + return cr(PyEval_CallMethod( + self + , const_cast(name) + , const_cast("()") + )); + } + + static R call(PyObject* self) + { + converter::callback_from_python cr; + return cr(PyEval_CallFunction(self, const_cast("()") + )); + } + + template + static R call_method(PyObject* self, const char* name, A1 const& a1) + { + converter::callback_from_python cr; + return cr(PyEval_CallMethod( + self + , const_cast(name) + , const_cast("(O)") + , converter::callback_to_python(a1).get() + )); + } + + template + static R call(PyObject* self, A1 const& a1) + { + converter::callback_from_python cr; + return cr(PyEval_CallFunction( + self + , const_cast("(O)") + , converter::callback_to_python(a1).get() + )); + } + + template + static R call_method(PyObject* self, const char* name, A1 const& a1, A2 const& a2) + { + converter::callback_from_python cr; + return cr(PyEval_CallMethod( + self + , const_cast(name) + , const_cast("(O)") + , converter::callback_to_python(a1).get() + , converter::callback_to_python(a2).get() + )); + } + + template + static R call(PyObject* self, A1 const& a1, A2 const& a2) + { + converter::callback_from_python cr; + return cr(PyEval_CallFunction( + self + , const_cast("(O)") + , converter::callback_to_python(a1).get() + , converter::callback_to_python(a2).get() + )); + } + +}; + +template <> +struct returning +{ + typedef void R; + static R call(char const* name, PyObject* self) + { + ref x(PyEval_CallMethod( + self + , const_cast(name) + , const_cast("()") + )); + } + + static R call(PyObject* self) + { + ref x(PyEval_CallFunction(self, const_cast("()") + )); + } + + template + static R call_method(PyObject* self, const char* name, A1 const& a1) + { + ref x(PyEval_CallMethod( + self + , const_cast(name) + , const_cast("(O)") + , converter::callback_to_python(a1).get() + )); + } + + template + static R call(PyObject* self, A1 const& a1) + { + ref x(PyEval_CallFunction( + self + , const_cast("(O)") + , converter::callback_to_python(a1).get() + )); + } + + template + static R call_method(PyObject* self, const char* name, A1 const& a1, A2 const& a2) + { + ref x(PyEval_CallMethod( + self + , const_cast(name) + , const_cast("(O)") + , converter::callback_to_python(a1).get() + , converter::callback_to_python(a2).get() + )); + } + + template + static R call(PyObject* self, A1 const& a1, A2 const& a2) + { + ref x(PyEval_CallFunction( + self + , const_cast("(O)") + , converter::callback_to_python(a1).get() + , converter::callback_to_python(a2).get() + )); + } +}; + +}} // namespace boost::python + +#endif // RETURNING_DWA20020228_HPP + From a16d9f91eea41c8cb1dbe1b2a77aa1d84bd6454a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 8 Mar 2002 16:14:26 +0000 Subject: [PATCH 0306/1042] Initial checkin [SVN r13140] --- .../converter/callback_from_python_base.hpp | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 include/boost/python/converter/callback_from_python_base.hpp diff --git a/include/boost/python/converter/callback_from_python_base.hpp b/include/boost/python/converter/callback_from_python_base.hpp new file mode 100644 index 00000000..0eeccb0e --- /dev/null +++ b/include/boost/python/converter/callback_from_python_base.hpp @@ -0,0 +1,20 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP +# define CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP + +namespace boost { namespace python { namespace converter { + +namespace detail +{ + // Throw an exception + BOOST_PYTHON_DECL void throw_if_not_registered(rvalue_stage1_data const&); + BOOST_PYTHON_DECL void* convert_rvalue(PyObject*, rvalue_stage1_data& data, void* storage); +} + +}}} // namespace boost::python::converter + +#endif // CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP From 7c009e2443e210fa9fffc53d080c68a6d14dd63d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 9 Mar 2002 20:51:43 +0000 Subject: [PATCH 0307/1042] Added static assertion to be sure it's not used on values [SVN r13146] --- include/boost/python/to_python_indirect.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index 7b77f5ff..fbbfc6f7 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -72,6 +72,7 @@ namespace detail template inline bool to_python_indirect::convertible() { + BOOST_STATIC_ASSERT(is_pointer::value || is_reference::value); return type() != 0; } From 0301d4462b8c9a90a7b157c9cfe2da336e94373b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 9 Mar 2002 21:01:36 +0000 Subject: [PATCH 0308/1042] Added reference, deep and shallow pointer to_python conversions [SVN r13147] --- include/boost/python/converter/callback.hpp | 121 ++++++++++++++++++-- 1 file changed, 112 insertions(+), 9 deletions(-) diff --git a/include/boost/python/converter/callback.hpp b/include/boost/python/converter/callback.hpp index 3e1e462e..756466e3 100644 --- a/include/boost/python/converter/callback.hpp +++ b/include/boost/python/converter/callback.hpp @@ -8,11 +8,15 @@ # include # include +# include # include # include # include # include # include +# include +# include +# include namespace boost { namespace python { namespace converter { @@ -63,9 +67,64 @@ namespace detail template - struct reference_callback_to_python + struct reference_callback_to_python : callback_to_python_holder { + reference_callback_to_python(T& x); + private: + static PyObject* get_object(T& x); + }; + + template + struct value_callback_to_python : callback_to_python_base + { + // Throw an exception if the conversion can't succeed + value_callback_to_python(T const&); + }; + + template + struct pointer_deep_callback_to_python : callback_to_python_base + { + // Throw an exception if the conversion can't succeed + pointer_deep_callback_to_python(Ptr); + }; + + template + struct pointer_shallow_callback_to_python : callback_to_python_holder + { + // Throw an exception if the conversion can't succeed + pointer_shallow_callback_to_python(Ptr); + private: + static PyObject* get_object(Ptr p); + }; + + template + struct select_callback_to_python + { + BOOST_STATIC_CONSTANT( + bool, ptr = is_pointer::value); + BOOST_STATIC_CONSTANT( + bool, ref_wrapper = is_reference_wrapper::value); + + BOOST_STATIC_CONSTANT( + bool, ptr_wrapper = is_pointer_wrapper::value); + + typedef typename unwrap_reference::type unwrapped_referent; + typedef typename unwrap_pointer::type unwrapped_ptr; + + typedef typename mpl::select_type< + ptr + , pointer_deep_callback_to_python + , typename mpl::select_type< + ptr_wrapper + , pointer_shallow_callback_to_python + , typename mpl::select_type< + ref_wrapper + , reference_callback_to_python + , value_callback_to_python + >::type + >::type + >::type type; }; } @@ -76,11 +135,13 @@ struct callback_from_python }; template -struct callback_to_python : detail::callback_to_python_base +struct callback_to_python + : detail::select_callback_to_python::type { + typedef typename detail::select_callback_to_python::type base; public: // member functions // Throw an exception if the conversion can't succeed - callback_to_python(T const&); + callback_to_python(T const& x); }; // @@ -89,24 +150,66 @@ struct callback_to_python : detail::callback_to_python_base namespace detail { template - rvalue_callback_from_python::rvalue_callback_from_python() + inline rvalue_callback_from_python::rvalue_callback_from_python() : m_data(rvalue_from_python_chain::value) { throw_if_not_registered(m_data.stage1); } template - T const& rvalue_callback_from_python::operator()(PyObject* obj) + inline T const& rvalue_callback_from_python::operator()(PyObject* obj) { return *(T*)convert_rvalue(obj, m_data.stage1, m_data.storage.bytes); } + + BOOST_PYTHON_DECL void throw_no_class_registered(); + + template + inline value_callback_to_python::value_callback_to_python(T const& x) + : callback_to_python_base(&x, to_python_function::value) + { + } + + template + inline pointer_deep_callback_to_python::pointer_deep_callback_to_python(Ptr x) + : callback_to_python_base(x, pointee_to_python_function::value) + { + } + + template + inline PyObject* reference_callback_to_python::get_object(T& x) + { + to_python_indirect convert; + if (!convert.convertible()) + throw_no_class_registered(); + return convert(x); + } + + template + inline reference_callback_to_python::reference_callback_to_python(T& x) + : callback_to_python_holder(get_object(x)) + { + } + + template + inline pointer_shallow_callback_to_python::pointer_shallow_callback_to_python(Ptr x) + : callback_to_python_holder(get_object(x)) + {} + + template + inline PyObject* pointer_shallow_callback_to_python::get_object(Ptr x) + { + to_python_indirect convert; + if (!convert.convertible()) + throw_no_class_registered(); + return x ? convert(x) : python::detail::none(); + } } template -callback_to_python::callback_to_python(T const& x) - : callback_to_python_base(&x, to_python_function::value) -{ -} +inline callback_to_python::callback_to_python(T const& x) + : base(x) +{} }}} // namespace boost::python::converter From 69d7011baf1ed100df3bc5585278c27c00f8d1c5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 9 Mar 2002 21:02:18 +0000 Subject: [PATCH 0309/1042] Killed bogus #include [SVN r13148] --- include/boost/python/converter/from_python.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index 5fe8901a..03bfcb26 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -10,7 +10,6 @@ # include # include # include -# include # include # include # include From 74fe5bc4dd45dcb852a2d4c2487f799e522a3aea Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 9 Mar 2002 21:05:18 +0000 Subject: [PATCH 0310/1042] Killed bogus #include msvc6 workaround [SVN r13149] --- include/boost/python/converter/from_python_data.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp index dd0a0282..1ce8bd7a 100644 --- a/include/boost/python/converter/from_python_data.hpp +++ b/include/boost/python/converter/from_python_data.hpp @@ -15,7 +15,6 @@ # include # include # include -# include # include # include # include @@ -177,6 +176,8 @@ struct rvalue_data : rvalue_base_data rvalue_data(rvalue_stage1_data const&); rvalue_data(void*); ~rvalue_data(); + private: + typedef typename add_reference::type>::type ref_type; }; // @@ -197,8 +198,6 @@ inline rvalue_data::rvalue_data(void* convertible) template inline rvalue_data::~rvalue_data() { - typedef typename add_reference::type>::type ref_type; - if (this->stage1.convertible == this->storage.bytes) python::detail::destroy_reference(this->storage.bytes); } From 22f66123541e90f825519712ed7c13a25e9312ad Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 9 Mar 2002 21:08:04 +0000 Subject: [PATCH 0311/1042] Killed ambiguity-causing overload [SVN r13150] --- include/boost/python/detail/unwind_type.hpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/boost/python/detail/unwind_type.hpp b/include/boost/python/detail/unwind_type.hpp index e8ccd0c8..72ebef71 100644 --- a/include/boost/python/detail/unwind_type.hpp +++ b/include/boost/python/detail/unwind_type.hpp @@ -68,13 +68,6 @@ struct unwind_helper } }; -template -inline typename Generator::result_type -unwind_type(U& p, Generator* = 0) -{ - return unwind_helper::value>::execute(p, (Generator*)0); -} - template inline typename Generator::result_type unwind_type(U const& p, Generator* = 0) From f271726cd8687370551587e95a92a6b977d136d9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 9 Mar 2002 21:13:09 +0000 Subject: [PATCH 0312/1042] Added reference, deep and shallow pointer to_python conversions [SVN r13152] --- .../converter/pointee_to_python_function.hpp | 51 +++++++++++++++++++ src/converter/callback.cpp | 14 ++++- test/callbacks.cpp | 26 ++++++++-- test/callbacks.py | 39 ++++++++++++++ 4 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 include/boost/python/converter/pointee_to_python_function.hpp diff --git a/include/boost/python/converter/pointee_to_python_function.hpp b/include/boost/python/converter/pointee_to_python_function.hpp new file mode 100644 index 00000000..0f1ae99e --- /dev/null +++ b/include/boost/python/converter/pointee_to_python_function.hpp @@ -0,0 +1,51 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP +# define POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP + +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +// pointee_to_python_function -- +// +// essentially a "templated global reference" which holds the +// converter for converting a type to Python by-value. We "normalize" +// T by adding "const volatile&" so that fewer global variables and +// associated static initializations are generated. +namespace detail +{ + template + struct pointee_to_python_function_base + { + static to_python_function_t const& value; + }; + + template + to_python_function_t const& + pointee_to_python_function_base::value + = converter::registry::get_to_python_function(pointer_type_id()); +} + +template +struct pointee_to_python_function + : detail::pointee_to_python_function_base< + typename add_reference< + typename add_cv::type + >::type + > +{ +}; + +}}} // namespace boost::python::converter + +#endif // POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index b3158500..a248f1ad 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace boost { namespace python { namespace converter { @@ -25,7 +26,10 @@ namespace detail , const_cast("no to_python (by-value) converter found for type")); throw error_already_set(); } - return converter(const_cast(source)); + + return source == 0 + ? python::detail::none() + : converter(const_cast(source)); } } @@ -45,6 +49,14 @@ namespace detail throw error_already_set(); } } + + BOOST_PYTHON_DECL void throw_no_class_registered() + { + PyErr_SetString( + PyExc_TypeError + , const_cast("class not registered for to_python type")); + throw error_already_set(); + } BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_stage1_data& data, void* storage) { diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 9991e41f..2bf285b5 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using namespace boost::python; @@ -42,9 +43,24 @@ X apply_X_X(PyObject* f, X x) return returning::call(f, x); } -void apply_void_X_ref(PyObject* f, X x) +void apply_void_X_ref(PyObject* f, X& x) { - returning::call(f, boost::ref(x)); + returning::call(f, boost::ref(x)); +} + +void apply_void_X_cref(PyObject* f, X const& x) +{ + returning::call(f, boost::cref(x)); +} + +void apply_void_X_ptr(PyObject* f, X* x) +{ + returning::call(f, ptr(x)); +} + +void apply_void_X_deep_ptr(PyObject* f, X* x) +{ + returning::call(f, x); } int X::counter; @@ -56,6 +72,9 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) .def("apply_void_int", apply_void_int) .def("apply_X_X", apply_X_X) .def("apply_void_X_ref", apply_void_X_ref) + .def("apply_void_X_cref", apply_void_X_cref) + .def("apply_void_X_ptr", apply_void_X_ptr) + .def("apply_void_X_deep_ptr", apply_void_X_deep_ptr) .add( class_("X") .def_init(args()) @@ -67,5 +86,4 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) ; } - - +#include "module_tail.cpp" diff --git a/test/callbacks.py b/test/callbacks.py index 16c5be94..810aad53 100644 --- a/test/callbacks.py +++ b/test/callbacks.py @@ -27,6 +27,45 @@ >>> apply_void_X_ref(increment, x) >>> x.value() 43 + +>>> apply_void_X_cref(increment, x) +>>> x.value() # const-ness is not respected, sorry! +44 + +>>> last_x = 1 +>>> def decrement(x): +... global last_x +... last_x = x +... if x is not None: +... x.set(x.value() - 1) + +>>> apply_void_X_ptr(decrement, x) +>>> x.value() +43 +>>> last_x.value() +43 +>>> increment(last_x) +>>> x.value() +44 +>>> last_x.value() +44 + +>>> apply_void_X_ptr(decrement, None) +>>> assert last_x is None +>>> x.value() +44 + +>>> last_x = 1 +>>> apply_void_X_deep_ptr(decrement, None) +>>> assert last_x is None +>>> x.value() +44 + +>>> apply_void_X_deep_ptr(decrement, x) +>>> x.value() +44 +>>> last_x.value() +43 ''' def run(args = None): From 5da8206915a4d4fabc0659f88c8b1a620eef85d7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 9 Mar 2002 21:13:26 +0000 Subject: [PATCH 0313/1042] initial checkin [SVN r13153] --- include/boost/python/ptr.hpp | 127 +++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 include/boost/python/ptr.hpp diff --git a/include/boost/python/ptr.hpp b/include/boost/python/ptr.hpp new file mode 100644 index 00000000..4e0f067e --- /dev/null +++ b/include/boost/python/ptr.hpp @@ -0,0 +1,127 @@ +#ifndef BOOST_PTR_HPP_INCLUDED +# define BOOST_PTR_HPP_INCLUDED +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// +// Based on boost/ref.hpp, thus: +// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) +// Copyright (C) 2001 Peter Dimov + +# if _MSC_VER+0 >= 1020 +# pragma once +# endif + +# include + +namespace boost { namespace python { + +template class pointer_wrapper +{ + public: + typedef Ptr type; + + explicit pointer_wrapper(Ptr x): p_(x) {} + operator Ptr() const { return p_; } + Ptr get() const { return p_; } + private: + Ptr p_; +}; + +template +inline pointer_wrapper ptr(T t) +{ + return pointer_wrapper(t); +} + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +class is_pointer_wrapper +{ + public: + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +class is_pointer_wrapper > +{ + public: + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template +class unwrap_pointer +{ + public: + typedef T type; +}; + +template +class unwrap_pointer > +{ + public: + typedef T type; +}; +# else // no partial specialization + +}} // namespace boost::python + +#include + +namespace boost { namespace python { + +namespace detail +{ + typedef char (&yes_pointer_wrapper_t)[1]; + typedef char (&no_pointer_wrapper_t)[2]; + + no_pointer_wrapper_t is_pointer_wrapper_test(...); + + template + yes_pointer_wrapper_t is_pointer_wrapper_test(type< pointer_wrapper >); + + template + struct pointer_unwrapper + { + template + struct apply + { + typedef T type; + }; + }; + + template<> + struct pointer_unwrapper + { + template + struct apply + { + typedef typename T::type type; + }; + }; +} + +template +class is_pointer_wrapper +{ + public: + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof(detail::is_pointer_wrapper_test(type())) + == sizeof(detail::yes_pointer_wrapper_t))); +}; + +template +class unwrap_pointer + : public detail::pointer_unwrapper< + is_pointer_wrapper::value + >::template apply +{}; + +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +}} // namespace boost::python + +#endif // #ifndef BOOST_PTR_HPP_INCLUDED From 74078552df235f7adf34d8f397387d072bd2608b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 9 Mar 2002 23:59:04 +0000 Subject: [PATCH 0314/1042] Improved error messages Added support for pointer/reference returns [SVN r13154] --- src/converter/callback.cpp | 43 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index a248f1ad..68ea32f1 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -45,11 +45,50 @@ namespace detail { PyErr_SetString( PyExc_TypeError - , const_cast("no from_python (by-value) converters found for type")); + , const_cast("no from_python rvalue or lvalue converters found for type")); throw error_already_set(); } } + BOOST_PYTHON_DECL void throw_if_not_registered(lvalue_from_python_registration*const& x) + { + if (!x) + { + PyErr_SetString( + PyExc_TypeError + , const_cast("no from_python lvalue converters found for type")); + throw error_already_set(); + } + } + + BOOST_PYTHON_DECL void* callback_convert_reference( + PyObject* source + , lvalue_from_python_registration*const& converters) + { + ref holder(source); + void* result = find(source, converters); + if (!result) + { + PyErr_SetString( + PyExc_TypeError + , const_cast("no registered from_python lvalue converter was able to convert object")); + throw error_already_set(); + } + return result; + } + + BOOST_PYTHON_DECL void* callback_convert_pointer( + PyObject* source + , lvalue_from_python_registration*const& converters) + { + if (source == Py_None) + { + Py_DECREF(source); + return 0; + } + return callback_convert_reference(source, converters); + } + BOOST_PYTHON_DECL void throw_no_class_registered() { PyErr_SetString( @@ -68,7 +107,7 @@ namespace detail { PyErr_SetString( PyExc_TypeError - , const_cast("no registered from_python (by-value) converter was able to convert type")); + , const_cast("no registered from_python lvalue or rvalue converter was able to convert object")); throw error_already_set(); } if (data.construct != 0) From ae1c1b3a47e7a76d572ce13e8aa473d5c8ff9e06 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Mar 2002 06:25:09 +0000 Subject: [PATCH 0315/1042] Improved None <==> NULL correspondence [SVN r13155] --- include/boost/python/to_python_indirect.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index fbbfc6f7..a636ff66 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -67,6 +67,22 @@ namespace detail return python::objects::class_object::reference; } }; + + // null_pointer_to_none -- return none() for null pointers and 0 for all other types/values + // + // Uses simulated partial ordering + template + inline PyObject* null_pointer_to_none(T&, int) + { + return 0; + } + + // overload for pointers + template + inline PyObject* null_pointer_to_none(T* x, long) + { + return x == 0 ? python::detail::none() : 0; + } } template @@ -79,6 +95,10 @@ inline bool to_python_indirect::convertible() template inline PyObject* to_python_indirect::operator()(T x) const { + PyObject* const null_result = detail::null_pointer_to_none(x, 1L); + if (null_result != 0) + return null_result; + PyObject* raw_result = type()->tp_alloc(type(), 0); if (raw_result == 0) From 7eb42dc36b02149979fac59a28a3477b758cae51 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Mar 2002 06:26:11 +0000 Subject: [PATCH 0316/1042] factored out void_ptr manipulations [SVN r13156] --- include/boost/python/type_from_python.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/python/type_from_python.hpp b/include/boost/python/type_from_python.hpp index 16b8da81..d5b9faed 100644 --- a/include/boost/python/type_from_python.hpp +++ b/include/boost/python/type_from_python.hpp @@ -7,6 +7,7 @@ # define TYPE_FROM_PYTHON_DWA2002130_HPP # include +# include namespace boost { namespace python { @@ -31,7 +32,7 @@ namespace detail { typedef typename boost::add_reference::type param; return &Extractor::execute( - boost::python::converter::detail::void_ptr_to_reference( + boost::python::detail::void_ptr_to_reference( op, (param(*)())0 ) ); } From 688c64ce2118e2231a93adbfe75a8c8cf81a644f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Mar 2002 06:29:05 +0000 Subject: [PATCH 0317/1042] char conversions Handle dangling references [SVN r13157] --- .../python/converter/builtin_converters.hpp | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index 4db0eb9c..c0d2ba09 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -27,9 +27,13 @@ namespace detail namespace converter { template struct callback_to_python; + BOOST_PYTHON_DECL PyObject* do_call_to_python(char); + BOOST_PYTHON_DECL PyObject* do_call_to_python(char const*); + BOOST_PYTHON_DECL PyObject* do_call_to_python(PyObject*); + BOOST_PYTHON_DECL PyObject* do_callback_to_python(PyObject*); } -# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ +# define BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(T, expr) \ template <> struct to_python_value \ : detail::builtin_to_python \ { \ @@ -45,7 +49,9 @@ namespace converter { \ return (expr); \ } \ - }; \ + }; + +# define BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(T, expr) \ namespace converter \ { \ template <> struct callback_to_python< T > \ @@ -57,8 +63,11 @@ namespace converter private: \ ref m_held; \ }; \ - } + } +# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ + BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(T,expr) \ + BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(T,expr) # define BOOST_PYTHON_TO_INT(T) \ BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \ @@ -71,12 +80,14 @@ BOOST_PYTHON_TO_INT(int) BOOST_PYTHON_TO_INT(long) # undef BOOST_TO_PYTHON_INT -BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, x ? PyString_FromString(x) : boost::python::detail::none()) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_call_to_python(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_call_to_python(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(PyObject*, (x ? x : boost::python::detail::none())) +BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(PyObject*, converter::do_call_to_python(x)) +BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(PyObject*, converter::do_callback_to_python(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) From 3447aaa8c67c3a648f2af72473bd2ac7c7f542df Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Mar 2002 06:32:07 +0000 Subject: [PATCH 0318/1042] Pointer/reference from_python callback conversions [SVN r13158] --- include/boost/python/converter/callback.hpp | 26 +++++++++++++++++++ .../converter/callback_from_python_base.hpp | 5 ++++ 2 files changed, 31 insertions(+) diff --git a/include/boost/python/converter/callback.hpp b/include/boost/python/converter/callback.hpp index 756466e3..a8fceb53 100644 --- a/include/boost/python/converter/callback.hpp +++ b/include/boost/python/converter/callback.hpp @@ -164,6 +164,32 @@ namespace detail BOOST_PYTHON_DECL void throw_no_class_registered(); + template + inline reference_callback_from_python::reference_callback_from_python() + { + detail::throw_if_not_registered(lvalue_from_python_chain::value); + } + + template + inline T reference_callback_from_python::operator()(PyObject* obj) const + { + return python::detail::void_ptr_to_reference( + callback_convert_reference(obj, lvalue_from_python_chain::value) + , (T(*)())0); + } + + template + inline pointer_callback_from_python::pointer_callback_from_python() + { + detail::throw_if_not_registered(lvalue_from_python_chain::value); + } + + template + inline T pointer_callback_from_python::operator()(PyObject* obj) const + { + return T(callback_convert_pointer(obj, lvalue_from_python_chain::value)); + } + template inline value_callback_to_python::value_callback_to_python(T const& x) : callback_to_python_base(&x, to_python_function::value) diff --git a/include/boost/python/converter/callback_from_python_base.hpp b/include/boost/python/converter/callback_from_python_base.hpp index 0eeccb0e..117ba145 100644 --- a/include/boost/python/converter/callback_from_python_base.hpp +++ b/include/boost/python/converter/callback_from_python_base.hpp @@ -10,9 +10,14 @@ namespace boost { namespace python { namespace converter { namespace detail { + // Throw an exception BOOST_PYTHON_DECL void throw_if_not_registered(rvalue_stage1_data const&); BOOST_PYTHON_DECL void* convert_rvalue(PyObject*, rvalue_stage1_data& data, void* storage); + + BOOST_PYTHON_DECL void throw_if_not_registered(lvalue_from_python_registration*const&); + BOOST_PYTHON_DECL void* callback_convert_reference(PyObject*, lvalue_from_python_registration*const&); + BOOST_PYTHON_DECL void* callback_convert_pointer(PyObject*, lvalue_from_python_registration*const&); } }}} // namespace boost::python::converter From 948cde1a312e2a777d5fcf2fd1c24f2cfd9cf6fd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Mar 2002 06:33:13 +0000 Subject: [PATCH 0319/1042] factored out void_ptr manipulations [SVN r13159] --- .../boost/python/converter/from_python.hpp | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index 03bfcb26..1c6a8b3c 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -15,6 +15,7 @@ # include # include # include +# include namespace boost { namespace python { namespace converter { @@ -143,12 +144,6 @@ inline void*const& from_python_base::result() const namespace detail { - template - inline U& void_ptr_to_reference(void const volatile* p, U&(*)()) - { - return *(U*)p; - } - template struct null_ptr_owner { @@ -161,27 +156,12 @@ namespace detail { return null_ptr_owner::value; } - - template - inline void write_void_ptr(void const volatile* storage, void* ptr, T*) - { - *(T**)storage = (T*)ptr; - } - - // writes U(ptr) into the storage - template - inline void write_void_ptr_reference(void const volatile* storage, void* ptr, U&(*)()) - { - // stripping CV qualification suppresses warnings on older EDGs - typedef typename remove_cv::type u_stripped; - write_void_ptr(storage, ptr, u_stripped(0)); - } } template inline pointer_const_reference_from_python::pointer_const_reference_from_python(PyObject* p) { - detail::write_void_ptr_reference( + python::detail::write_void_ptr_reference( m_result.bytes , p == Py_None ? p : find(p, lvalue_from_python_chain::value) , (T(*)())0); @@ -190,14 +170,14 @@ inline pointer_const_reference_from_python::pointer_const_reference_from_pyth template inline bool pointer_const_reference_from_python::convertible() const { - return detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0; + return python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0; } template inline T pointer_const_reference_from_python::operator()(PyObject* p) const { return (p == Py_None) ? detail::null_ptr_reference((T(*)())0) - : detail::void_ptr_to_reference(m_result.bytes, (T(*)())0); + : python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0); } // -------- @@ -225,7 +205,7 @@ inline reference_from_python::reference_from_python(PyObject* p) template inline T reference_from_python::operator()(PyObject*) const { - return detail::void_ptr_to_reference(result(), (T(*)())0); + return python::detail::void_ptr_to_reference(result(), (T(*)())0); } // ------- @@ -249,7 +229,7 @@ rvalue_from_python::operator()(PyObject* p) if (m_data.stage1.construct != 0) m_data.stage1.construct(p, &m_data.stage1); - return detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0); + return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0); } }}} // namespace boost::python::converter From e589d7f1e1a791b2a554b7a6097140f9c4ee89b8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Mar 2002 06:35:59 +0000 Subject: [PATCH 0320/1042] adjustments for use with callbacks [SVN r13161] --- .../python/converter/lvalue_from_python_chain.hpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/include/boost/python/converter/lvalue_from_python_chain.hpp b/include/boost/python/converter/lvalue_from_python_chain.hpp index f1417460..2a86bcfa 100644 --- a/include/boost/python/converter/lvalue_from_python_chain.hpp +++ b/include/boost/python/converter/lvalue_from_python_chain.hpp @@ -14,7 +14,9 @@ namespace boost { namespace python { namespace converter { // Given T == U*cv&, T == U*, or T == U&, lvalue_from_python_chain // declares a "templated global reference" to the lvalue from_python -// converter chain for U +// converter chain for U. The optional bool second argument callback, +// when true, removes special treatment for T == U*cv& so that the +// converter for U* is found. namespace detail { template @@ -39,12 +41,13 @@ namespace detail ref_lvalue_from_python_chain::value = registry::lvalue_converters(undecorated_type_id()); - template + template struct select_lvalue_from_python_chain { BOOST_STATIC_CONSTANT( - bool, ptr = boost::python::detail::is_reference_to_pointer::value - || is_pointer::value); + bool, ptr + = !callback && boost::python::detail::is_reference_to_pointer::value + || is_pointer::value); typedef typename add_reference::type>::type normalized; @@ -56,9 +59,9 @@ namespace detail }; } -template +template struct lvalue_from_python_chain - : detail::select_lvalue_from_python_chain::type + : detail::select_lvalue_from_python_chain::type { }; From a56f66e721476e199d917fb1d23d58a795dabddd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Mar 2002 06:37:58 +0000 Subject: [PATCH 0321/1042] Factor to_python guts [SVN r13162] --- src/converter/builtin_converters.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index 87d0d7b4..0ded9c78 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -232,6 +232,30 @@ namespace }; } +BOOST_PYTHON_DECL PyObject* do_call_to_python(char x) +{ + return PyString_FromStringAndSize(&x, 1); +} + +BOOST_PYTHON_DECL PyObject* do_call_to_python(char const* x) +{ + return x ? PyString_FromString(x) : boost::python::detail::none(); +} + +BOOST_PYTHON_DECL PyObject* do_call_to_python(PyObject* x) +{ + return x ? x : boost::python::detail::none(); +} + +BOOST_PYTHON_DECL PyObject* do_callback_to_python(PyObject* x) +{ + if (x == 0) + return boost::python::detail::none(); + + Py_INCREF(x); + return x; +} + #define REGISTER_INT_CONVERTERS(U) slot_rvalue_from_python() #define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U) From be6016a97200d651198a187d1321f16475b907fa Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Mar 2002 06:38:50 +0000 Subject: [PATCH 0322/1042] Prevent dangling reference returns [SVN r13163] --- src/converter/callback.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index 68ea32f1..0ff0c29a 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -66,6 +66,13 @@ namespace detail , lvalue_from_python_registration*const& converters) { ref holder(source); + if (source->ob_refcnt <= 2) + { + PyErr_SetString( + PyExc_ReferenceError + , const_cast("Attempt to return dangling internal reference")); + throw error_already_set(); + } void* result = find(source, converters); if (!result) { From c170b1b83ee11ebc77b54ee2fef01cf98b15e257 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Mar 2002 06:41:04 +0000 Subject: [PATCH 0323/1042] char conversions Handle dangling references [SVN r13164] --- test/callbacks.cpp | 38 ++++++++++++++++++++++++++++++++++++++ test/callbacks.py | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 2bf285b5..6d1b8fba 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -8,6 +8,8 @@ #include #include #include +#include +#include using namespace boost::python; @@ -48,6 +50,16 @@ void apply_void_X_ref(PyObject* f, X& x) returning::call(f, boost::ref(x)); } +X& apply_X_ref_pyobject(PyObject* f, PyObject* obj) +{ + return returning::call(f, obj); +} + +X* apply_X_ptr_pyobject(PyObject* f, PyObject* obj) +{ + return returning::call(f, obj); +} + void apply_void_X_cref(PyObject* f, X const& x) { returning::call(f, boost::cref(x)); @@ -63,6 +75,21 @@ void apply_void_X_deep_ptr(PyObject* f, X* x) returning::call(f, x); } +char const* apply_cstring_cstring(PyObject* f, char const* s) +{ + return returning ::call(f, s); +} + +char const* apply_cstring_pyobject(PyObject* f, PyObject* s) +{ + return returning ::call(f, s); +} + +char apply_char_char(PyObject* f, char c) +{ + return returning ::call(f, c); +} + int X::counter; BOOST_PYTHON_MODULE_INIT(callbacks_ext) @@ -75,6 +102,17 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) .def("apply_void_X_cref", apply_void_X_cref) .def("apply_void_X_ptr", apply_void_X_ptr) .def("apply_void_X_deep_ptr", apply_void_X_deep_ptr) + + .def("apply_X_ptr_pyobject", apply_X_ptr_pyobject + , return_value_policy()) + + .def("apply_X_ref_pyobject", apply_X_ref_pyobject + , return_value_policy()) + + .def("apply_cstring_cstring", apply_cstring_cstring) + .def("apply_cstring_pyobject", apply_cstring_pyobject) + .def("apply_char_char", apply_char_char) + .add( class_("X") .def_init(args()) diff --git a/test/callbacks.py b/test/callbacks.py index 810aad53..71ad3fb7 100644 --- a/test/callbacks.py +++ b/test/callbacks.py @@ -66,6 +66,46 @@ 44 >>> last_x.value() 43 + +>>> y = apply_X_ref_pyobject(identity, x) +>>> assert y.value() == x.value() +>>> increment(x) +>>> assert y.value() == x.value() + +>>> y = apply_X_ptr_pyobject(identity, x) +>>> assert y.value() == x.value() +>>> increment(x) +>>> assert y.value() == x.value() + +>>> y = apply_X_ptr_pyobject(identity, None) +>>> y + +>>> def new_x(ignored): +... return X(666) +... +>>> try: apply_X_ref_pyobject(new_x, 1) +... except ReferenceError: pass +... else: print 'no error' + +>>> try: apply_X_ptr_pyobject(new_x, 1) +... except ReferenceError: pass +... else: print 'no error' + +>>> try: apply_cstring_cstring(identity, 'hello') +... except ReferenceError: pass +... else: print 'no error' + +>>> apply_char_char(identity, 'x') +'x' + +>>> apply_cstring_pyobject(identity, 'hello') +'hello' + +>>> apply_cstring_pyobject(identity, None) + + +>>> apply_char_char(identity, 'x') +'x' ''' def run(args = None): From 2fa0910547a92a6a1cf0cb7cb11e5b4f6242e3c8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 10 Mar 2002 06:41:40 +0000 Subject: [PATCH 0324/1042] initial checkin [SVN r13165] --- include/boost/python/detail/void_ptr.hpp | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 include/boost/python/detail/void_ptr.hpp diff --git a/include/boost/python/detail/void_ptr.hpp b/include/boost/python/detail/void_ptr.hpp new file mode 100644 index 00000000..676a5cac --- /dev/null +++ b/include/boost/python/detail/void_ptr.hpp @@ -0,0 +1,34 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef VOID_PTR_DWA200239_HPP +# define VOID_PTR_DWA200239_HPP + +namespace boost { namespace python { namespace detail { + +template +inline U& void_ptr_to_reference(void const volatile* p, U&(*)()) +{ + return *(U*)p; +} + +template +inline void write_void_ptr(void const volatile* storage, void* ptr, T*) +{ + *(T**)storage = (T*)ptr; +} + +// writes U(ptr) into the storage +template +inline void write_void_ptr_reference(void const volatile* storage, void* ptr, U&(*)()) +{ + // stripping CV qualification suppresses warnings on older EDGs + typedef typename remove_cv::type u_stripped; + write_void_ptr(storage, ptr, u_stripped(0)); +} + +}}} // namespace boost::python::detail + +#endif // VOID_PTR_DWA200239_HPP From bccd85467654e28d29be4427ea94277d52f0f02b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 11 Mar 2002 18:43:02 +0000 Subject: [PATCH 0325/1042] Initial work for virtual function support [SVN r13175] --- include/boost/python/class.hpp | 7 +- include/boost/python/class_fwd.hpp | 8 +- include/boost/python/object/class.hpp | 19 -- include/boost/python/object/make_holder.hpp | 14 +- .../boost/python/object/pointer_holder.hpp | 182 +++++++++++++++++- include/boost/python/object/value_holder.hpp | 158 ++++++++++++++- .../boost/python/object/value_holder_fwd.hpp | 17 ++ src/object/class.cpp | 4 +- 8 files changed, 360 insertions(+), 49 deletions(-) create mode 100644 include/boost/python/object/value_holder_fwd.hpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 8dede0e3..7f31df88 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -9,6 +9,7 @@ # include # include # include +# include # include # include # include @@ -32,12 +33,6 @@ namespace // put some convenience classes into the unnamed namespace for the use namespace boost { namespace python { -// Forward declarations -namespace objects -{ - struct value_holder_generator; -} - namespace detail { // This is an mpl BinaryMetaFunction object with a runtime behavior, diff --git a/include/boost/python/class_fwd.hpp b/include/boost/python/class_fwd.hpp index 6faf7aae..bef2e250 100644 --- a/include/boost/python/class_fwd.hpp +++ b/include/boost/python/class_fwd.hpp @@ -5,6 +5,7 @@ // to its suitability for any purpose. #ifndef CLASS_FWD_DWA200222_HPP # define CLASS_FWD_DWA200222_HPP +# include namespace boost { namespace python { @@ -13,15 +14,10 @@ namespace detail struct empty_list; } -namespace objects -{ - struct value_holder_generator; -} - template < class T // class being wrapped , class Bases = detail::empty_list - , class HolderGenerator = objects::value_holder_generator + , class HolderGenerator = objects::value_holder_generator<> > class class_; diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 0d5210c7..d453967c 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -11,7 +11,6 @@ # include # include # include -# include # include namespace boost { namespace python { @@ -55,24 +54,6 @@ struct BOOST_PYTHON_DECL instance_holder : private noncopyable virtual void* holds(converter::undecorated_type_id_t) = 0; void install(PyObject* inst) throw(); - - struct iterator_policies : default_iterator_policies - { - template - void increment(Iterator& p) - { - p.base() = p.base()->next(); - } - }; - - typedef iterator_adaptor< - instance_holder* - , iterator_policies - , value_type_is - , reference_is - , pointer_is - , iterator_category_is > iterator; - private: instance_holder* m_next; }; diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 825e02b0..1ba6f932 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -22,7 +22,7 @@ struct make_holder<0> template struct apply { - typedef typename detail::eval::type holder; + typedef typename python::detail::eval::type holder; static void execute( PyObject* p) { @@ -38,7 +38,7 @@ struct make_holder<1> template struct apply { - typedef typename detail::eval::type holder; + typedef typename python::detail::eval::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; @@ -57,7 +57,7 @@ struct make_holder<2> template struct apply { - typedef typename detail::eval::type holder; + typedef typename python::detail::eval::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -77,7 +77,7 @@ struct make_holder<3> template struct apply { - typedef typename detail::eval::type holder; + typedef typename python::detail::eval::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -99,7 +99,7 @@ struct make_holder<4> template struct apply { - typedef typename detail::eval::type holder; + typedef typename python::detail::eval::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -123,7 +123,7 @@ struct make_holder<5> template struct apply { - typedef typename detail::eval::type holder; + typedef typename python::detail::eval::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -149,7 +149,7 @@ struct make_holder<6> template struct apply { - typedef typename detail::eval::type holder; + typedef typename python::detail::eval::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index c307f019..2722ae85 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -12,6 +12,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -145,7 +146,137 @@ struct pointer_holder : instance_holder Pointer m_p; }; -}}} +template +struct pointer_holder_back_reference : instance_holder +{ + pointer_holder_back_reference(Pointer); + + // Forward construction to the held object + pointer_holder_back_reference(PyObject* p) + : m_p(new Value(p)) {} + + + template + pointer_holder_back_reference(PyObject* p, A1 a1) + : m_p(new Value(p + , (typename unwrap_reference::type&)(a1) + )) + {} + + template + pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2) + : m_p(new Value(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + )) + {} + + template + pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3) + : m_p(new Value(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + )) + {} + + template + pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4) + : m_p(new Value(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + )) + {} + + template + pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) + : m_p(new Value(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + )) {} + + template + pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) + : m_p(new Value(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + )) {} + + template + pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) + : m_p(new Value(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + )) + {} + + template + pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) + : m_p(new Value(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) + )) + {} + + template + pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) + : m_p(new Value(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) + , (typename unwrap_reference::type&)(a9) + )) + {} + + template + pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) + : m_p(new Value(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) + , (typename unwrap_reference::type&)(a9) + , (typename unwrap_reference::type&)(a10) + )) + {} + + private: // required holder implementation + void* holds(converter::undecorated_type_id_t); + + private: // data members + Pointer m_p; +}; + +}}} // namespace boost::python::objects // back to namespace boost for this forward declaration namespace boost @@ -164,19 +295,54 @@ struct shared_ptr_generator }; }; +struct no_back_reference; + +// Workaround lack of partial specialization +namespace detail +{ + template + struct pointer_holder_back_reference_generator + { + template + struct apply + { + typedef typename boost::python::detail::eval< + PointerGenerator,BackReferenceType + >::type pointer; + + typedef pointer_holder_back_reference type; + }; + }; + + template + struct plain_pointer_holder_generator + { + template + struct apply + { + typedef typename boost::python::detail::eval< + PointerGenerator,Held + >::type pointer; + + typedef pointer_holder type; + }; + }; +} + // A generator metafunction which can be passed to make_holder // PointerGenerator should be another generator metafunction which // makes the appropriate (smart) pointer type to hold the argument to // pointer_holder_generator. -template +template struct pointer_holder_generator + : mpl::select_type< + is_same::value + , detail::plain_pointer_holder_generator< + PointerGenerator> + , detail::pointer_holder_back_reference_generator< + BackReferenceType,PointerGenerator> + >::type { - template - struct apply - { - typedef typename detail::eval::type pointer; - typedef pointer_holder type; - }; }; template diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 6533bc39..62222a23 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -6,6 +6,7 @@ #ifndef VALUE_HOLDER_DWA20011215_HPP # define VALUE_HOLDER_DWA20011215_HPP +# include # include # include # include @@ -140,8 +141,136 @@ struct value_holder : instance_holder Held m_held; }; +template +struct value_holder_back_reference : instance_holder +{ + // Forward construction to the held object + value_holder_back_reference(PyObject* p) + : m_held() {} + + template + value_holder_back_reference(PyObject* p, A1 a1) + : m_held(p + , (typename unwrap_reference::type&)(a1) + ) + {} + + template + value_holder_back_reference(PyObject* p, A1 a1, A2 a2) + : m_held(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + ) + {} + + template + value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3) + : m_held(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + ) + {} + + template + value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4) + : m_held(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + ) + {} + + template + value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) + : m_held(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + ) {} + + template + value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) + : m_held(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + ) {} + + template + value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) + : m_held(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + ) + {} + + template + value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) + : m_held(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) + ) + {} + + template + value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) + : m_held(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) + , (typename unwrap_reference::type&)(a9) + ) + {} + + template + value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) + : m_held(p + , (typename unwrap_reference::type&)(a1) + , (typename unwrap_reference::type&)(a2) + , (typename unwrap_reference::type&)(a3) + , (typename unwrap_reference::type&)(a4) + , (typename unwrap_reference::type&)(a5) + , (typename unwrap_reference::type&)(a6) + , (typename unwrap_reference::type&)(a7) + , (typename unwrap_reference::type&)(a8) + , (typename unwrap_reference::type&)(a9) + , (typename unwrap_reference::type&)(a10) + ) + {} + + private: // required holder implementation + void* holds(converter::undecorated_type_id_t); + + private: // data members + BackReferenceType m_held; +}; + // A generator metafunction which can be passed to make_holder -struct value_holder_generator +template <> +struct value_holder_generator { template struct apply @@ -150,6 +279,16 @@ struct value_holder_generator }; }; +template +struct value_holder_generator +{ + template + struct apply + { + typedef value_holder_back_reference type; + }; +}; + template void* value_holder::holds(converter::undecorated_type_id_t dst_t) { @@ -158,6 +297,23 @@ void* value_holder::holds(converter::undecorated_type_id_t dst_t) : find_static_type(&m_held, src_t, dst_t); } +template +void* value_holder_back_reference::holds( + converter::undecorated_type_id_t dst_t) +{ + converter::undecorated_type_id_t src_t = converter::undecorated_type_id(); + if (src_t == dst_t) + { + Held* x = &m_held; + return x; + } + + src_t = converter::undecorated_type_id(); + return src_t == dst_t + ? &m_held + : find_static_type(&m_held, src_t, dst_t); +} + }}} // namespace boost::python::objects #endif // VALUE_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/object/value_holder_fwd.hpp b/include/boost/python/object/value_holder_fwd.hpp new file mode 100644 index 00000000..6cb2a0f5 --- /dev/null +++ b/include/boost/python/object/value_holder_fwd.hpp @@ -0,0 +1,17 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef VALUE_HOLDER_FWD_DWA2002311_HPP +# define VALUE_HOLDER_FWD_DWA2002311_HPP + +namespace boost { namespace python { namespace objects { + +struct no_back_reference; + +template struct value_holder_generator; + +}}} // namespace boost::python::object + +#endif // VALUE_HOLDER_FWD_DWA2002311_HPP diff --git a/src/object/class.cpp b/src/object/class.cpp index b9deb98f..dc3a42af 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -169,9 +169,9 @@ find_instance_impl(PyObject* inst, converter::undecorated_type_id_t type) instance* self = reinterpret_cast(inst); - for (instance_holder::iterator match(self->objects), end(0); match != end; ++match) + for (instance_holder* match = self->objects; match != 0; match = match->next()) { - void* const found = (*match).holds(type); + void* const found = match->holds(type); if (found) return found; } From 23769371bc8bd2baa16c6fb5ef14f37ad18cb05d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 11 Mar 2002 18:57:45 +0000 Subject: [PATCH 0326/1042] Elimination of boost/python/detail/eval.hpp; using mpl::apply instead [SVN r13176] --- include/boost/python/detail/caller.hpp | 1 - include/boost/python/detail/eval.hpp | 40 ------------ include/boost/python/detail/returning.hpp | 63 ++++++++++--------- include/boost/python/object/make_holder.hpp | 16 ++--- .../boost/python/object/pointer_holder.hpp | 6 +- 5 files changed, 43 insertions(+), 83 deletions(-) delete mode 100644 include/boost/python/detail/eval.hpp diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index d0b01b6e..68da40e6 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -7,7 +7,6 @@ # define CALLER_DWA20011214_HPP # include -# include # include # include # include diff --git a/include/boost/python/detail/eval.hpp b/include/boost/python/detail/eval.hpp deleted file mode 100644 index 8699f701..00000000 --- a/include/boost/python/detail/eval.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef EVAL_DWA2002124_HPP -# define EVAL_DWA2002124_HPP - -# include - -namespace boost { namespace python { namespace detail { - -template struct undefined; -template -struct eval -{ -# if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 - // based on the (non-conforming) MSVC trick from MPL - template - struct unarymetafunction_vc : UnaryMetaFunction {}; - - // illegal C++ which causes VC to admit that unarymetafunction_vc - // can have a nested template: - template<> - struct unarymetafunction_vc - { - template struct apply; - }; - - typedef typename unarymetafunction_vc< - ::boost::mpl::detail::msvc_never_true::value - >::template apply::type type; -# else - typedef typename UnaryMetaFunction::template apply::type type; -# endif -}; - -}}} // namespace boost::python::detail - -#endif // EVAL_DWA2002124_HPP diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index d7e98cd8..2c5d8c4f 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -15,6 +15,7 @@ # include # include # include +# include namespace boost { namespace python { namespace detail { @@ -31,7 +32,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -52,7 +53,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -75,7 +76,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -101,7 +102,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -130,7 +131,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -162,7 +163,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -186,7 +187,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -207,7 +208,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -230,7 +231,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -256,7 +257,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -285,7 +286,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -317,7 +318,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -341,7 +342,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -362,7 +363,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -385,7 +386,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -411,7 +412,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -440,7 +441,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -472,7 +473,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -499,7 +500,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -520,7 +521,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -543,7 +544,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -569,7 +570,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -598,7 +599,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -630,7 +631,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -652,7 +653,7 @@ struct returning { // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -671,7 +672,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -692,7 +693,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -716,7 +717,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -743,7 +744,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -773,7 +774,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; @@ -806,7 +807,7 @@ struct returning // find the result converter typedef typename P::result_converter result_converter; - typename eval::type cr; + typename mpl::apply1::type cr; if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 1ba6f932..871ed059 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -10,7 +10,7 @@ # include # include # include -# include +# include namespace boost { namespace python { namespace objects { @@ -22,7 +22,7 @@ struct make_holder<0> template struct apply { - typedef typename python::detail::eval::type holder; + typedef typename mpl::apply1::type holder; static void execute( PyObject* p) { @@ -38,7 +38,7 @@ struct make_holder<1> template struct apply { - typedef typename python::detail::eval::type holder; + typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; @@ -57,7 +57,7 @@ struct make_holder<2> template struct apply { - typedef typename python::detail::eval::type holder; + typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -77,7 +77,7 @@ struct make_holder<3> template struct apply { - typedef typename python::detail::eval::type holder; + typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -99,7 +99,7 @@ struct make_holder<4> template struct apply { - typedef typename python::detail::eval::type holder; + typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -123,7 +123,7 @@ struct make_holder<5> template struct apply { - typedef typename python::detail::eval::type holder; + typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -149,7 +149,7 @@ struct make_holder<6> template struct apply { - typedef typename python::detail::eval::type holder; + typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 2722ae85..57cb6b47 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -9,10 +9,10 @@ # include # include # include -# include # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -306,7 +306,7 @@ namespace detail template struct apply { - typedef typename boost::python::detail::eval< + typedef typename mpl::apply1< PointerGenerator,BackReferenceType >::type pointer; @@ -320,7 +320,7 @@ namespace detail template struct apply { - typedef typename boost::python::detail::eval< + typedef typename mpl::apply1< PointerGenerator,Held >::type pointer; From 0bdf3542e451e1e4d5725cfb7b616956b27c53cd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 12 Mar 2002 20:43:42 +0000 Subject: [PATCH 0327/1042] factored out find_instance [SVN r13181] --- include/boost/python/object/class.hpp | 14 -------------- include/boost/python/object/class_converters.hpp | 5 ++--- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index d453967c..468240c0 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -65,20 +65,6 @@ struct instance instance_holder* objects; }; -// Given an undecorated type_id, find the instance data which -// corresponds to it, or return 0 in case no such type is held. -BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::undecorated_type_id_t); - -// This produces a function with the right signature for use in from_python conversions -template -struct instance_finder -{ - static inline void* execute(PyObject* p) - { - return find_instance_impl(p, converter::undecorated_type_id()); - } -}; - BOOST_PYTHON_DECL ref class_metatype(); BOOST_PYTHON_DECL ref class_type(); diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index 540565bf..5c2a35ae 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -10,6 +10,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -89,9 +90,7 @@ template class_converters::class_converters(ref const& type_object) : m_wrapper(type_object) { - converter::registry::insert( - &instance_finder::execute - , converter::undecorated_type_id()); + (void)instance_finder::registration; // register all up/downcasts here register_dynamic_id(); From 3caa91cc36bc04cf1bbe0726a6d8b2fdf20949d9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 12 Mar 2002 21:07:26 +0000 Subject: [PATCH 0328/1042] More fixes [SVN r13182] --- include/boost/python/class.hpp | 15 +++- include/boost/python/object/find_instance.hpp | 37 +++++++++ .../boost/python/object/pointer_holder.hpp | 76 ++++++++++++++----- include/boost/python/object/value_holder.hpp | 55 +++++++++++--- test/Jamfile | 1 + 5 files changed, 150 insertions(+), 34 deletions(-) create mode 100644 include/boost/python/object/find_instance.hpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 7f31df88..0a9c5d87 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -12,6 +12,7 @@ # include # include # include +# include # include # include # include @@ -103,14 +104,24 @@ class class_ : private objects::class_base // Use function::add_to_namespace to achieve overloading if // appropriate. objects::function::add_to_namespace( - this->object(), name, ref(detail::wrap_function(f))); + this->object(), name, + ref(detail::wrap_function( + // This bit of nastiness casts F to a member function of T if possible. + detail::member_function_cast::stage1(f).stage2((T*)0).stage3(f) + ))); return *this; } template self& def(char const* name, Fn fn, CallPolicy policy) { - this->def(name, boost::python::make_function(fn, policy)); + this->def(name + , boost::python::make_function( + // 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) + , policy) + ); + return *this; } diff --git a/include/boost/python/object/find_instance.hpp b/include/boost/python/object/find_instance.hpp new file mode 100644 index 00000000..c60a82f7 --- /dev/null +++ b/include/boost/python/object/find_instance.hpp @@ -0,0 +1,37 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FIND_INSTANCE_DWA2002312_HPP +# define FIND_INSTANCE_DWA2002312_HPP + +namespace boost { namespace python { namespace objects { + +// Given an undecorated type_id, find the instance data which +// corresponds to it, or return 0 in case no such type is held. +BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, converter::undecorated_type_id_t); + +// This produces a function with the right signature for use in from_python conversions +template +struct instance_finder +{ + instance_finder() + { + converter::registry::insert(&execute, converter::undecorated_type_id()); + } + + static instance_finder const registration; + private: + static inline void* execute(PyObject* p) + { + return find_instance_impl(p, converter::undecorated_type_id()); + } +}; + +template +instance_finder const instance_finder::registration; + +}}} // namespace boost::python::objects + +#endif // FIND_INSTANCE_DWA2002312_HPP diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 57cb6b47..84700299 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -9,6 +9,7 @@ # include # include # include +# include # include # include # include @@ -153,67 +154,88 @@ struct pointer_holder_back_reference : instance_holder // Forward construction to the held object pointer_holder_back_reference(PyObject* p) - : m_p(new Value(p)) {} + : m_p(new BackReferenceType(p)) { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) , (typename unwrap_reference::type&)(a5) - )) {} + )) { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) , (typename unwrap_reference::type&)(a5) , (typename unwrap_reference::type&)(a6) - )) {} + )) { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -222,11 +244,14 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a6) , (typename unwrap_reference::type&)(a7) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -236,11 +261,14 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a7) , (typename unwrap_reference::type&)(a8) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -251,11 +279,14 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a8) , (typename unwrap_reference::type&)(a9) )) - {} + { + (void)instance_finder::registration; + } + template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) - : m_p(new Value(p + : m_p(new BackReferenceType(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -267,7 +298,10 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a9) , (typename unwrap_reference::type&)(a10) )) - {} + { + (void)instance_finder::registration; + } + private: // required holder implementation void* holds(converter::undecorated_type_id_t); diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 62222a23..c0a5c580 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -10,6 +10,7 @@ # include # include # include +# include # include namespace boost { namespace python { namespace objects { @@ -146,14 +147,20 @@ struct value_holder_back_reference : instance_holder { // Forward construction to the held object value_holder_back_reference(PyObject* p) - : m_held() {} + : m_held() { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1) : m_held(p , (typename unwrap_reference::type&)(a1) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2) @@ -161,7 +168,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3) @@ -170,7 +180,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4) @@ -180,7 +193,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) @@ -190,7 +206,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) , (typename unwrap_reference::type&)(a5) - ) {} + ) { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) @@ -201,7 +220,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a4) , (typename unwrap_reference::type&)(a5) , (typename unwrap_reference::type&)(a6) - ) {} + ) { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) @@ -214,7 +236,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a6) , (typename unwrap_reference::type&)(a7) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) @@ -228,7 +253,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a7) , (typename unwrap_reference::type&)(a8) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) @@ -243,7 +271,10 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a8) , (typename unwrap_reference::type&)(a9) ) - {} + { + (void)instance_finder::registration; + } + template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) @@ -259,7 +290,9 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a9) , (typename unwrap_reference::type&)(a10) ) - {} + { + (void)instance_finder::registration; + } private: // required holder implementation void* holds(converter::undecorated_type_id_t); diff --git a/test/Jamfile b/test/Jamfile index 767b07e6..1f5de1e9 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -55,6 +55,7 @@ bpl-test try : newtest.py m1.cpp m2.cpp ; bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ; bpl-test test_pointer_adoption ; bpl-test callbacks ; +bpl-test virtual_functions ; # --- unit tests of library components --- unit-test indirect_traits_test From c18d8fa9677dfde9501bd01f2dabd4827705973c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 12 Mar 2002 21:14:03 +0000 Subject: [PATCH 0329/1042] added first virtual function tests [SVN r13183] --- test/virtual_functions.cpp | 118 +++++++++++++++++++++++++++++++++++++ test/virtual_functions.py | 100 +++++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+) create mode 100644 test/virtual_functions.cpp create mode 100644 test/virtual_functions.py diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp new file mode 100644 index 00000000..ab05fe3c --- /dev/null +++ b/test/virtual_functions.cpp @@ -0,0 +1,118 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include + +using namespace boost::python; + +struct X +{ + explicit X(int x) : x(x), magic(7654321) { ++counter; } + X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } + virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } + + void set(int x) { assert(magic == 7654321); this->x = x; } + int value() const { assert(magic == 7654321); return x; } + static int count() { return counter; } + private: + void operator=(X const&); + private: + int x; + long magic; + static int counter; +}; + +struct Y : X +{ + Y(int x) : X(x) {}; +}; + +struct abstract : X +{ + abstract(int x) : X(x) {}; + int call_f(Y const& y) { return f(y); } + virtual int f(Y const& y) = 0; +}; + +struct concrete : X +{ + concrete(int x) : X(x) {}; + int call_f(Y const& y) { return f(y); } + virtual int f(Y const& y) { set(y.value()); return y.value(); } +}; + +struct abstract_callback : abstract +{ + abstract_callback(PyObject* p, int x) + : abstract(x), self(p) + {} + + int f(Y const& y) + { + return returning::call_method(self, "f", boost::ref(y)); + } + + PyObject* self; +}; + +struct concrete_callback : concrete +{ + concrete_callback(PyObject* p, int x) + : concrete(x), self(p) + {} + + int f(Y const& y) + { + return returning::call_method(self, "f", boost::ref(y)); + } + + int f_impl(Y const& y) + { + return this->concrete::f(y); + } + + PyObject* self; +}; + +int X::counter; + +BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) +{ + module("virtual_functions_ext") + .add( + class_, objects::value_holder_generator >("concrete") + .def_init(args()) + .def("value", &concrete::value) + .def("set", &concrete::set) + .def("call_f", &concrete::call_f) + .def("f", &concrete_callback::f_impl)) + +#if 0 + .add( + class_ + , objects::pointer_holder_generator< + boost::python::objects::shared_ptr_generator + , abstract_callback> + >("abstract") + + .def_init(args()) + .def("value", &abstract::value) + .def("call_f", &abstract::call_f) + .def("set", &abstract::set)) +#endif + + .add( + class_("Y") + .def_init(args()) + .def("value", &Y::value) + .def("set", &Y::set) + ) + ; +} + +#include "module_tail.cpp" diff --git a/test/virtual_functions.py b/test/virtual_functions.py new file mode 100644 index 00000000..8ea992c5 --- /dev/null +++ b/test/virtual_functions.py @@ -0,0 +1,100 @@ +''' +>>> from virtual_functions_ext import * + +>>> class C1(concrete): +... def f(self, y): +... return concrete.f(self, Y(-y.value())) + +>>> class C2(concrete): +... pass + +<<<>>> class A1(abstract): +<<<... def f(self, y): +<<<... return abstract.f(self, Y(-y.value())) +<<< +<<<>>> class A2(abstract): +<<<... pass +<<< + +>>> y1 = Y(16) +>>> y2 = Y(17) + + + +# +# Test abstract with f overridden +# +<<<>>> a1 = A1(42) +<<<>>> a1.value() +<<<42 +<<< +<<<# Call f indirectly from C++ +<<<>>> a1.call_f(y1) +<<<-16 +<<< +<<<# Call f directly from Python +<<<>>> a1.f(y2) +<<<-17 +<<< +<<<# +<<<# Test abstract with f not overridden +<<<# +<<<>>> a2 = A2(42) +<<<>>> A2.value() +<<<42 +<<< +<<<# Call f indirectly from C++ +<<<>>> c1.call_f(y1) +<<<16 +<<< +<<<# Call f directly from Python +<<<>>> c1.f(y2) +<<<17 +<<< +############# Concrete Tests ############ + +# +# Test concrete with f overridden +# +>>> c1 = C1(42) +>>> c1.value() +42 + +# Call f indirectly from C++ +>>> c1.call_f(y1) +-16 + +# Call f directly from Python +>>> c1.f(y2) +-17 + +# +# Test concrete with f not overridden +# +>>> c2 = C2(42) +>>> c2.value() +42 + +# Call f indirectly from C++ +>>> c2.call_f(y1) +16 + +# Call f directly from Python +>>> c2.f(y2) +17 + + +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 81a07899ae2451bcb7cd2cc677e76444990f2f9b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 12 Mar 2002 21:15:28 +0000 Subject: [PATCH 0330/1042] initial checkin [SVN r13184] --- .../python/detail/member_function_cast.hpp | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 include/boost/python/detail/member_function_cast.hpp diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp new file mode 100644 index 00000000..3d965021 --- /dev/null +++ b/include/boost/python/detail/member_function_cast.hpp @@ -0,0 +1,231 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MEMBER_FUNCTION_CAST_DWA2002311_HPP +# define MEMBER_FUNCTION_CAST_DWA2002311_HPP +# include +# include + +namespace boost { namespace python { namespace detail { + +template +struct cast_helper +{ + struct yes_helper + { + static FT stage3(FT x) { return x; } + }; + + struct no_helper + { + template + static T stage3(T x) { return x; } + }; + + static yes_helper stage2(S*) { return yes_helper(); } + static no_helper stage2(void*) { return no_helper(); } +}; + +struct non_member_function_cast_impl +{ + template + static non_member_function_cast_impl stage1(T) { return non_member_function_cast_impl(); } + + template + static non_member_function_cast_impl stage2(T) { return non_member_function_cast_impl(); } + + template + T stage3(T x) { return x; } +}; + +template +struct member_function_cast_impl +{ + template + static cast_helper stage1(R (S::*)()) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0)) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1)) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2)) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3)) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4)) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4,A5)) + { + return cast_helper(); + } + +# if 1 + template + static cast_helper stage1(R (S::*)()const) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0)const) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1)const) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2)const) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3)const) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4)const) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4,A5)const) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)()volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0)volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1)volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2)volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3)volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4)volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4,A5)volatile) + { + return cast_helper(); + } + +// # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + static cast_helper stage1(R (S::*)()const volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0)const volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1)const volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2)const volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3)const volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4)const volatile) + { + return cast_helper(); + } + + template + static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4,A5)const volatile) + { + return cast_helper(); + } +# endif +}; + + +template +struct member_function_cast + : mpl::select_type< + is_member_function_pointer::value + , member_function_cast_impl + , non_member_function_cast_impl + >::type +{ +}; + +}}} // namespace boost::python::detail + +#endif // MEMBER_FUNCTION_CAST_DWA2002311_HPP From 6528bd0e4fa0f22368e08ef2b4152056e8504ef4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 14 Mar 2002 18:43:36 +0000 Subject: [PATCH 0331/1042] Fixes for VC7 [SVN r13194] --- src/object/inheritance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object/inheritance.cpp b/src/object/inheritance.cpp index 7efc980c..5b95e478 100644 --- a/src/object/inheritance.cpp +++ b/src/object/inheritance.cpp @@ -109,7 +109,7 @@ namespace make_iterator_property_map( to_target , get(vertex_index, reverse_topology) -# ifdef BOOST_MSVC_STD_ITERATOR +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION , *to_target # endif ) From fbbc1981cabf54cdb37b15c15b119365b009d578 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Mar 2002 00:25:26 +0000 Subject: [PATCH 0332/1042] Bug fix (thanks, VC7!) [SVN r13200] --- include/boost/python/detail/member_function_cast.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp index 3d965021..52718390 100644 --- a/include/boost/python/detail/member_function_cast.hpp +++ b/include/boost/python/detail/member_function_cast.hpp @@ -56,13 +56,13 @@ struct member_function_cast_impl } template - static cast_helper stage1(R (S::*)(A0,A1)) + static cast_helper stage1(R (S::*)(A0,A1)) { return cast_helper(); } template - static cast_helper stage1(R (S::*)(A0,A1,A2)) + static cast_helper stage1(R (S::*)(A0,A1,A2)) { return cast_helper(); } From aa705b07f3f7812a6ebc2a2b3eae92a57758d4ea Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Mar 2002 00:25:43 +0000 Subject: [PATCH 0333/1042] VC7 workaround [SVN r13201] --- include/boost/python/object/make_holder.hpp | 58 +++++++++++++-------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 871ed059..5268bde4 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -14,6 +14,22 @@ namespace boost { namespace python { namespace objects { +namespace detail +{ + // Use of this workaround as opposed to straightforward mpl::at + // needed for vc7, for some reason. + template + struct at + { + private: + typedef typename mpl::at_algorithm_traits< + typename mpl::sequence_traits::sequence_category + >::template algorithm::type base; + public: + typedef typename base::type type; + }; +} + template struct make_holder; template <> @@ -39,7 +55,7 @@ struct make_holder<1> struct apply { typedef typename mpl::apply1::type holder; - typedef typename mpl::at<0,ArgList>::type t0; + typedef typename detail::at<0,ArgList>::type t0; typedef typename forward::type f0; static void execute( @@ -58,9 +74,9 @@ struct make_holder<2> struct apply { typedef typename mpl::apply1::type holder; - typedef typename mpl::at<0,ArgList>::type t0; + typedef typename detail::at<0,ArgList>::type t0; typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; + typedef typename detail::at<1,ArgList>::type t1; typedef typename forward::type f1; static void execute( @@ -78,11 +94,11 @@ struct make_holder<3> struct apply { typedef typename mpl::apply1::type holder; - typedef typename mpl::at<0,ArgList>::type t0; + typedef typename detail::at<0,ArgList>::type t0; typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; + typedef typename detail::at<1,ArgList>::type t1; typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; + typedef typename detail::at<2,ArgList>::type t2; typedef typename forward::type f2; static void execute( @@ -100,13 +116,13 @@ struct make_holder<4> struct apply { typedef typename mpl::apply1::type holder; - typedef typename mpl::at<0,ArgList>::type t0; + typedef typename detail::at<0,ArgList>::type t0; typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; + typedef typename detail::at<1,ArgList>::type t1; typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; + typedef typename detail::at<2,ArgList>::type t2; typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; + typedef typename detail::at<3,ArgList>::type t3; typedef typename forward::type f3; static void execute( @@ -124,15 +140,15 @@ struct make_holder<5> struct apply { typedef typename mpl::apply1::type holder; - typedef typename mpl::at<0,ArgList>::type t0; + typedef typename detail::at<0,ArgList>::type t0; typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; + typedef typename detail::at<1,ArgList>::type t1; typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; + typedef typename detail::at<2,ArgList>::type t2; typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; + typedef typename detail::at<3,ArgList>::type t3; typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; + typedef typename detail::at<4,ArgList>::type t4; typedef typename forward::type f4; static void execute( @@ -150,17 +166,17 @@ struct make_holder<6> struct apply { typedef typename mpl::apply1::type holder; - typedef typename mpl::at<0,ArgList>::type t0; + typedef typename detail::at<0,ArgList>::type t0; typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; + typedef typename detail::at<1,ArgList>::type t1; typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; + typedef typename detail::at<2,ArgList>::type t2; typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; + typedef typename detail::at<3,ArgList>::type t3; typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; + typedef typename detail::at<4,ArgList>::type t4; typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; + typedef typename detail::at<5,ArgList>::type t5; typedef typename forward::type f5; static void execute( From a2071feeb11685a4aed5a67c042edb70fbe6b174 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Mar 2002 12:47:04 +0000 Subject: [PATCH 0334/1042] Roll back vc7 workarounds; Aleksey has folded them into the MPL code [SVN r13207] --- include/boost/python/object/make_holder.hpp | 58 ++++++++------------- 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 5268bde4..871ed059 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -14,22 +14,6 @@ namespace boost { namespace python { namespace objects { -namespace detail -{ - // Use of this workaround as opposed to straightforward mpl::at - // needed for vc7, for some reason. - template - struct at - { - private: - typedef typename mpl::at_algorithm_traits< - typename mpl::sequence_traits::sequence_category - >::template algorithm::type base; - public: - typedef typename base::type type; - }; -} - template struct make_holder; template <> @@ -55,7 +39,7 @@ struct make_holder<1> struct apply { typedef typename mpl::apply1::type holder; - typedef typename detail::at<0,ArgList>::type t0; + typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; static void execute( @@ -74,9 +58,9 @@ struct make_holder<2> struct apply { typedef typename mpl::apply1::type holder; - typedef typename detail::at<0,ArgList>::type t0; + typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; - typedef typename detail::at<1,ArgList>::type t1; + typedef typename mpl::at<1,ArgList>::type t1; typedef typename forward::type f1; static void execute( @@ -94,11 +78,11 @@ struct make_holder<3> struct apply { typedef typename mpl::apply1::type holder; - typedef typename detail::at<0,ArgList>::type t0; + typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; - typedef typename detail::at<1,ArgList>::type t1; + typedef typename mpl::at<1,ArgList>::type t1; typedef typename forward::type f1; - typedef typename detail::at<2,ArgList>::type t2; + typedef typename mpl::at<2,ArgList>::type t2; typedef typename forward::type f2; static void execute( @@ -116,13 +100,13 @@ struct make_holder<4> struct apply { typedef typename mpl::apply1::type holder; - typedef typename detail::at<0,ArgList>::type t0; + typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; - typedef typename detail::at<1,ArgList>::type t1; + typedef typename mpl::at<1,ArgList>::type t1; typedef typename forward::type f1; - typedef typename detail::at<2,ArgList>::type t2; + typedef typename mpl::at<2,ArgList>::type t2; typedef typename forward::type f2; - typedef typename detail::at<3,ArgList>::type t3; + typedef typename mpl::at<3,ArgList>::type t3; typedef typename forward::type f3; static void execute( @@ -140,15 +124,15 @@ struct make_holder<5> struct apply { typedef typename mpl::apply1::type holder; - typedef typename detail::at<0,ArgList>::type t0; + typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; - typedef typename detail::at<1,ArgList>::type t1; + typedef typename mpl::at<1,ArgList>::type t1; typedef typename forward::type f1; - typedef typename detail::at<2,ArgList>::type t2; + typedef typename mpl::at<2,ArgList>::type t2; typedef typename forward::type f2; - typedef typename detail::at<3,ArgList>::type t3; + typedef typename mpl::at<3,ArgList>::type t3; typedef typename forward::type f3; - typedef typename detail::at<4,ArgList>::type t4; + typedef typename mpl::at<4,ArgList>::type t4; typedef typename forward::type f4; static void execute( @@ -166,17 +150,17 @@ struct make_holder<6> struct apply { typedef typename mpl::apply1::type holder; - typedef typename detail::at<0,ArgList>::type t0; + typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; - typedef typename detail::at<1,ArgList>::type t1; + typedef typename mpl::at<1,ArgList>::type t1; typedef typename forward::type f1; - typedef typename detail::at<2,ArgList>::type t2; + typedef typename mpl::at<2,ArgList>::type t2; typedef typename forward::type f2; - typedef typename detail::at<3,ArgList>::type t3; + typedef typename mpl::at<3,ArgList>::type t3; typedef typename forward::type f3; - typedef typename detail::at<4,ArgList>::type t4; + typedef typename mpl::at<4,ArgList>::type t4; typedef typename forward::type f4; - typedef typename detail::at<5,ArgList>::type t5; + typedef typename mpl::at<5,ArgList>::type t5; typedef typename forward::type f5; static void execute( From a8d6f40794fee484ec07f1d13c2514a687889779 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Mar 2002 14:16:31 +0000 Subject: [PATCH 0335/1042] *** empty log message *** [SVN r13210] --- .../python/detail/member_function_cast.hpp | 14 ++++- include/boost/python/detail/wrap_function.hpp | 5 ++ src/object/inheritance.cpp | 2 +- test/Jamfile | 7 ++- test/member_function_cast.cpp | 55 +++++++++++++++++++ test/module_tail.cpp | 3 + 6 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 test/member_function_cast.cpp diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp index 52718390..6e3f18c4 100644 --- a/include/boost/python/detail/member_function_cast.hpp +++ b/include/boost/python/detail/member_function_cast.hpp @@ -43,6 +43,13 @@ struct non_member_function_cast_impl template struct member_function_cast_impl { +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + template + static non_member_function_cast_impl stage1(U) + { + return non_member_function_cast_impl(); + } +# endif template static cast_helper stage1(R (S::*)()) { @@ -85,7 +92,6 @@ struct member_function_cast_impl return cast_helper(); } -# if 1 template static cast_helper stage1(R (S::*)()const) { @@ -170,7 +176,6 @@ struct member_function_cast_impl return cast_helper(); } -// # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template static cast_helper stage1(R (S::*)()const volatile) { @@ -212,17 +217,20 @@ struct member_function_cast_impl { return cast_helper(); } -# endif }; template struct member_function_cast +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + : member_function_cast_impl +# else : mpl::select_type< is_member_function_pointer::value , member_function_cast_impl , non_member_function_cast_impl >::type +# endif { }; diff --git a/include/boost/python/detail/wrap_function.hpp b/include/boost/python/detail/wrap_function.hpp index 0424183d..682b3e89 100644 --- a/include/boost/python/detail/wrap_function.hpp +++ b/include/boost/python/detail/wrap_function.hpp @@ -45,9 +45,14 @@ template PyObject* wrap_function(F f) { return wrap_function_select< +# if 1 + type_traits::ice_not< + is_pointer::value +# else type_traits::ice_or< is_function::value , is_member_function_pointer::value +# endif >::value >::execute(f); } diff --git a/src/object/inheritance.cpp b/src/object/inheritance.cpp index 5b95e478..91a37f02 100644 --- a/src/object/inheritance.cpp +++ b/src/object/inheritance.cpp @@ -109,7 +109,7 @@ namespace make_iterator_property_map( to_target , get(vertex_index, reverse_topology) -# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# ifdef BOOST_NO_STD_ITERATOR_TRAITS , *to_target # endif ) diff --git a/test/Jamfile b/test/Jamfile index 1f5de1e9..a01efdde 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -59,11 +59,14 @@ bpl-test virtual_functions ; # --- unit tests of library components --- unit-test indirect_traits_test - : indirect_traits_test.cpp : $(BOOST_ROOT) ; + : indirect_traits_test.cpp : $(BOOST_ROOT) ; unit-test destroy_test : destroy_test.cpp : $(BOOST_ROOT) ; unit-test pointer_type_id_test - : pointer_type_id_test.cpp : $(BOOST_ROOT) ; + : pointer_type_id_test.cpp : $(BOOST_ROOT) ; + +unit-test member_function_cast + : member_function_cast.cpp : $(BOOST_ROOT) ; unit-test select_from_python_test : select_from_python_test.cpp diff --git a/test/member_function_cast.cpp b/test/member_function_cast.cpp new file mode 100644 index 00000000..986d87b5 --- /dev/null +++ b/test/member_function_cast.cpp @@ -0,0 +1,55 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include + +using namespace boost; + +template +void assert_same(S, type* = 0) +{ + BOOST_STATIC_ASSERT((is_same::value)); +} + +template +void assert_mf_cast(F f, type* = 0, type* = 0) +{ + assert_same( + python::detail::member_function_cast::stage1(f).stage2((Target*)0).stage3(f) + ); +} + +struct X +{ + int f() const { return 0; } + void g(char*) {} +}; + +struct Y : X +{ + +}; + +struct Z : Y +{ + int f() const { return 0; } + void g(char*) {} +}; + +int main() +{ + assert_mf_cast(&X::f); + assert_mf_cast(&X::g); + + assert_mf_cast(&Z::f); + assert_mf_cast(&Z::g); + + assert_mf_cast(3); + assert_mf_cast(X()); + return 0; +}; diff --git a/test/module_tail.cpp b/test/module_tail.cpp index 6849bf83..763e7dff 100644 --- a/test/module_tail.cpp +++ b/test/module_tail.cpp @@ -16,10 +16,13 @@ extern "C" BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved ); # ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4297) extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) { throw; } +# pragma warning(pop) # endif BOOL WINAPI DllMain( From 08ac2877261938a38136c4f1edd087e560e63a0b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Mar 2002 07:04:28 +0000 Subject: [PATCH 0336/1042] warning suppression for vc7 [SVN r13229] --- test/comprehensive.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 6c7cc4d3..d4617181 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -1225,6 +1225,9 @@ extern "C" BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvRese # ifdef BOOST_MSVC extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) +# if BOOST_MSVC > 1200 + throw(...) +# endif { throw; } From 3b8dc924c3c0aae4b066c9254685b3bd4cb1c81c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Mar 2002 07:06:09 +0000 Subject: [PATCH 0337/1042] Removed defunct workarounds [SVN r13230] --- src/conversions.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/conversions.cpp b/src/conversions.cpp index e6b6161a..e180af67 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -19,9 +19,7 @@ #include #include #include -#ifndef BOOST_NO_LIMITS -# include -#endif +#include BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE @@ -53,19 +51,11 @@ T integer_from_python(PyObject* p, boost::python::type) { const long long_result = from_python(p, boost::python::type()); -#ifndef BOOST_NO_LIMITS try { return boost::numeric_cast(long_result); } catch(const boost::bad_numeric_cast&) -#else - if (static_cast(long_result) == long_result) - { - return static_cast(long_result); - } - else -#endif { char buffer[256]; const char message[] = "%ld out of range for %s"; @@ -73,7 +63,7 @@ T integer_from_python(PyObject* p, boost::python::type) PyErr_SetString(PyExc_ValueError, buffer); throw boost::python::argument_error(); } -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 +#if defined(__MWERKS__) && __MWERKS__ <= 0x2407 return 0; // Not smart enough to know that the catch clause always rethrows #endif } @@ -83,16 +73,11 @@ PyObject* integer_to_python(T value) { long value_as_long; -#ifndef BOOST_NO_LIMITS try { value_as_long = boost::numeric_cast(value); } catch(const boost::bad_numeric_cast&) -#else - value_as_long = static_cast(value); - if (value_as_long != value) -#endif { const char message[] = "value out of range for Python int"; PyErr_SetString(PyExc_ValueError, message); From d72128107ee45312b23c18bb32b0b59ad3dcc7ab Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Mar 2002 07:16:06 +0000 Subject: [PATCH 0338/1042] no comment [SVN r13231] --- include/boost/python/conversions.hpp | 7 +++---- include/boost/python/detail/init_function.hpp | 6 ++++++ src/extension_class.cpp | 3 +-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/boost/python/conversions.hpp b/include/boost/python/conversions.hpp index 24ac5614..f328981e 100644 --- a/include/boost/python/conversions.hpp +++ b/include/boost/python/conversions.hpp @@ -157,16 +157,15 @@ BOOST_PYTHON_DECL PyObject* to_python(unsigned char); BOOST_PYTHON_DECL unsigned char from_python(PyObject*, boost::python::type); unsigned char from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type); +BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type); + # ifndef BOOST_MSVC6_OR_EARLIER PyObject* to_python(float); -float from_python(PyObject*, boost::python::type); PyObject* to_python(double); -double from_python(PyObject*, boost::python::type); # else BOOST_PYTHON_DECL PyObject* to_python(float); -BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type); BOOST_PYTHON_DECL PyObject* to_python(double); -BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type); # endif float from_python(PyObject*, boost::python::type); diff --git a/include/boost/python/detail/init_function.hpp b/include/boost/python/detail/init_function.hpp index 3c6f2380..048c90dd 100644 --- a/include/boost/python/detail/init_function.hpp +++ b/include/boost/python/detail/init_function.hpp @@ -168,6 +168,9 @@ template struct init_function { +# ifdef BOOST_MSVC6_OR_EARLIER +# define typename +# endif static init* create(signature0) { return new init0; } @@ -276,6 +279,9 @@ struct init_function typename detail::parameter_traits::const_reference, typename detail::parameter_traits::const_reference>; } +#ifdef BOOST_MSVC6_OR_EARLIER +# undef typename +#endif }; class BOOST_PYTHON_DECL init : public function diff --git a/src/extension_class.cpp b/src/extension_class.cpp index cc784ca6..98505347 100644 --- a/src/extension_class.cpp +++ b/src/extension_class.cpp @@ -11,7 +11,6 @@ #define BOOST_PYTHON_SOURCE -#include #include #include #include @@ -178,7 +177,7 @@ extension_instance::~extension_instance() } } -meta_class* extension_meta_class() +BOOST_PYTHON_DECL meta_class* extension_meta_class() { static meta_class result; return &result; From 0ce8ab7bcec74ee7f0ed19079e511445dfe18099 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Mar 2002 14:52:30 +0000 Subject: [PATCH 0339/1042] Full virtual function and abstract base support; new class interface. [SVN r13253] --- include/boost/python/class.hpp | 190 +++++++++++------- include/boost/python/class_fwd.hpp | 7 +- .../boost/python/detail/arg_tuple_size.hpp | 2 +- include/boost/python/detail/msvc_typeinfo.hpp | 31 +-- include/boost/python/make_function.hpp | 6 +- .../boost/python/object/class_converters.hpp | 25 +-- include/boost/python/object/class_wrapper.hpp | 11 +- include/boost/python/object/find_instance.hpp | 3 + include/boost/python/object/make_holder.hpp | 36 ++-- .../boost/python/object/pointer_holder.hpp | 142 +++++-------- include/boost/python/object/select_holder.hpp | 70 +++++++ include/boost/python/object/value_holder.hpp | 23 +-- test/Jamfile | 15 ++ test/m1.cpp | 13 +- test/select_holder.cpp | 77 +++++++ test/virtual_functions.cpp | 14 +- test/virtual_functions.py | 70 +++---- 17 files changed, 430 insertions(+), 305 deletions(-) create mode 100644 include/boost/python/object/select_holder.hpp create mode 100644 test/select_holder.cpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 0a9c5d87..cff0adf9 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -7,55 +7,50 @@ # define CLASS_DWA200216_HPP # include +# include +# include # include # include -# include # include # include # include -# include # include +# include +# include # include # include -# include - -namespace // put some convenience classes into the unnamed namespace for the user -{ - // A type list for specifying bases - template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename B, ::boost::mpl::null_argument) > - struct bases : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(B) >::type - {}; - - // A type list for specifying arguments - template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename A, ::boost::mpl::null_argument) > - struct args : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(A) >::type - {}; -} +# include +# include +# include +# include namespace boost { namespace python { namespace detail { - // This is an mpl BinaryMetaFunction object with a runtime behavior, - // which is to write the id of the type which is passed as its 2nd - // compile-time argument into the iterator pointed to by its runtime - // argument - struct write_type_id - { - // The first argument is Ignored because mpl::for_each is still - // currently an accumulate (reduce) implementation. - template struct apply - { - // also an artifact of accumulate-based for_each - typedef void type; + struct write_type_id; + + template + struct select_held_type; + + template + struct has_noncopyable; - // Here's the runtime behavior - static void execute(converter::undecorated_type_id_t** p) - { - *(*p)++ = converter::undecorated_type_id(); - } - }; - }; + // Register a to_python converter for a class T, depending on the + // type of the first (tag) argument. The 2nd argument is a pointer + // to the type of holder that must be created. The 3rd argument is a + // reference to the Python type object to be created. + template + static inline void register_copy_constructor(mpl::bool_t const&, Holder*, ref const& obj, T* = 0) + { + objects::class_wrapper x(obj); + } + + // Tag dispatched to have no effect. + template + static inline void register_copy_constructor(mpl::bool_t const&, Holder*, ref const&, T* = 0) + { + } } // @@ -64,27 +59,24 @@ namespace detail // This is the primary mechanism through which users will expose // C++ classes to Python. The three template arguments are: // -// T - The class being exposed to Python -// -// Bases - An MPL sequence of base classes -// -// HolderGenerator - -// An optional type generator for the "holder" which -// maintains the C++ object inside the Python instance. The -// default just holds the object "by-value", but other -// holders can be substituted which will hold the C++ object -// by smart pointer, for example. -// template < class T // class being wrapped - , class Bases - , class HolderGenerator + , class X1 // = detail::not_specified + , class X2 // = detail::not_specified + , class X3 // = detail::not_specified > class class_ : private objects::class_base { - typedef class_ self; + 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; + public: - // Automatically derive the class name - only works on some // compilers because type_info::name is sometimes mangled (gcc) class_(); @@ -130,7 +122,12 @@ class class_ : private objects::class_base template self& def_init(Args const&) { - def("__init__", make_constructor()); + def("__init__", + make_constructor( + // Using runtime type selection works around a CWPro7 bug. + objects::select_holder((held_type*)0).get() + ) + ); return *this; } @@ -147,6 +144,12 @@ class class_ : private objects::class_base private: // types 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 @@ -159,50 +162,97 @@ class class_ : private objects::class_base // Write the rest of the elements into succeeding positions. class_id* p = ids + 1; - mpl::for_each::execute(&p); + mpl::for_each::execute(&p); } BOOST_STATIC_CONSTANT( - std::size_t, size = mpl::size::value + 1); + std::size_t, size = mpl::size::value + 1); class_id ids[size]; }; - - private: // helper functions - void initialize_converters(); }; // // implementations // -template -inline class_::class_() +template +inline class_::class_() : class_base(typeid(T).name(), id_vector::size, id_vector().ids) { - // Bring the class converters into existence. This static object - // will survive until the shared library this module lives in is - // unloaded (that doesn't happen until Python terminates). - static objects::class_converters converters(object()); + // register converters + objects::register_class_from_python(); + + detail::register_copy_constructor( + mpl::bool_t() + , objects::select_holder((held_type*)0).get() + , this->object()); } -template -inline class_::class_(char const* name) +template +inline class_::class_(char const* name) : class_base(name, id_vector::size, id_vector().ids) { - // Bring the class converters into existence. This static object - // will survive until the shared library this module lives in is - // unloaded (that doesn't happen until Python terminates). - static objects::class_converters converters(object()); + // register converters + objects::register_class_from_python(); + + detail::register_copy_constructor( + mpl::bool_t() + , objects::select_holder((held_type*)0).get() + , this->object()); } -template -inline ref class_::object() const +template +inline ref class_::object() const { typedef objects::class_base base; return this->base::object(); } +namespace detail +{ + // This is an mpl BinaryMetaFunction object with a runtime behavior, + // which is to write the id of the type which is passed as its 2nd + // compile-time argument into the iterator pointed to by its runtime + // argument + struct write_type_id + { + // The first argument is Ignored because mpl::for_each is still + // currently an accumulate (reduce) implementation. + template struct apply + { + // also an artifact of accumulate-based for_each + typedef void type; + + // Here's the runtime behavior + static void execute(converter::undecorated_type_id_t** p) + { + *(*p)++ = converter::undecorated_type_id(); + } + }; + }; + + + template + struct has_noncopyable + : type_traits::ice_or< + is_same::value + , is_same::value + , is_same::value> + {}; + + + template + struct select_held_type + : mpl::select_type< + !(specifies_bases::value | is_same::value) + , T + , Prev + > + { + }; +} + }} // namespace boost::python #endif // CLASS_DWA200216_HPP diff --git a/include/boost/python/class_fwd.hpp b/include/boost/python/class_fwd.hpp index bef2e250..1ef941aa 100644 --- a/include/boost/python/class_fwd.hpp +++ b/include/boost/python/class_fwd.hpp @@ -5,7 +5,7 @@ // to its suitability for any purpose. #ifndef CLASS_FWD_DWA200222_HPP # define CLASS_FWD_DWA200222_HPP -# include +# include namespace boost { namespace python { @@ -16,8 +16,9 @@ namespace detail template < class T // class being wrapped - , class Bases = detail::empty_list - , class HolderGenerator = objects::value_holder_generator<> + , class X1 = detail::not_specified + , class X2 = detail::not_specified + , class X3 = detail::not_specified > class class_; diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index 04bca0af..fa38a4a9 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -103,7 +103,7 @@ struct arg_tuple_size // Metrowerks thinks this creates ambiguities -# if !defined(__MWERKS__) || __MWERKS__ > 0x2406 +# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 template struct arg_tuple_size diff --git a/include/boost/python/detail/msvc_typeinfo.hpp b/include/boost/python/detail/msvc_typeinfo.hpp index 2473023a..3da411f0 100644 --- a/include/boost/python/detail/msvc_typeinfo.hpp +++ b/include/boost/python/detail/msvc_typeinfo.hpp @@ -8,7 +8,8 @@ #include #include - +#include +#include // // Fix for MSVC's broken typeid() implementation which doesn't strip // decoration. This fix doesn't handle cv-qualified array types. It @@ -62,35 +63,35 @@ inline typeinfo typeid_nonref(boost::type* = 0) } template -inline typeinfo typeid_ref(boost::type*, ...) -{ - return typeid_nonref(); -} - -template -inline typeinfo typeid_ref(boost::type*, T& (*)()) +inline typeinfo typeid_ref(T&(*)()) { return typeid_nonref(); } template -inline typeinfo typeid_array(bool_t, boost::type* = 0) +inline typeinfo array_ref_typeid(bool_t, bool_t, boost::type* = 0) { - typedef T (*x)(); - return typeid_ref((boost::type*)0, x(0)); + return typeid_ref((T&(*)())0); } template -inline typeinfo typeid_array(bool_t, boost::type* = 0) +inline typeinfo array_ref_typeid(bool_t, bool_t, boost::type* = 0) { - return typeid_nonref(); + return typeid_ref((T(*)())0); +} + +template +inline typeinfo array_ref_typeid(bool_t, bool_t, boost::type* = 0) +{ + return typeid_ref((T&(*)())0); } template inline typeinfo msvc_typeid(boost::type* = 0) { - typedef bool_t::value> tag; - return typeid_array(tag(), (boost::type*)0); + typedef bool_t::value> array_tag; + typedef bool_t::value> ref_tag; + return array_ref_typeid(array_tag(), ref_tag(), (boost::type*)0); } }}} // namespace boost::python::detail diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index 2943d96c..6e7f1661 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -35,8 +35,8 @@ objects::function* make_function(F f, Policies const& policies) , detail::arg_tuple_size::value); } -template -objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0) +template +objects::function* make_constructor(Holder* = 0, ArgList* = 0) { enum { nargs = mpl::size::value }; @@ -44,7 +44,7 @@ objects::function* make_constructor(T* = 0, ArgList* = 0, Generator* = 0) objects::py_function( ::boost::bind(detail::caller(), objects::make_holder - ::template apply::execute + ::template apply::execute , _1, _2, default_call_policies())) , nargs + 1); } diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index 5c2a35ae..8f2786f3 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -11,27 +11,10 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { -// Instantiating this class brings into existence all converters -// associated with a class Bases is expected to be an mpl sequence of -// base types. -template -struct class_converters -{ - public: // member functions - // Constructor takes the python class object associated with T - class_converters(ref const& python_class); - - private: // data members - class_wrapper m_wrapper; -}; - -// -// Implementation details -// - ////////////////////////////////////////////////////////////////////// // // register_base_of - @@ -86,9 +69,11 @@ struct register_base_of }; }; + +// Brings into existence all converters associated with a class Bases +// is expected to be an mpl sequence of base types. template -class_converters::class_converters(ref const& type_object) - : m_wrapper(type_object) +inline void register_class_from_python(Derived* = 0, Bases* = 0) { (void)instance_finder::registration; diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index f8702205..577d1012 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -6,15 +6,14 @@ #ifndef CLASS_WRAPPER_DWA20011221_HPP # define CLASS_WRAPPER_DWA20011221_HPP -# include # include # include namespace boost { namespace python { namespace objects { -template +template struct class_wrapper - : to_python_converter > + : to_python_converter > { class_wrapper(ref const& type_) : m_class_object_keeper(type_) @@ -39,7 +38,7 @@ struct class_wrapper // Build a value_holder to contain the object using the copy // constructor - value_holder* p = new value_holder(raw_result, cref(x)); + Holder* p = new Holder(raw_result, cref(x)); // Install it in the instance p->install(raw_result); @@ -53,8 +52,8 @@ struct class_wrapper static PyTypeObject* m_class_object; }; -template -PyTypeObject* class_wrapper::m_class_object; +template +PyTypeObject* class_wrapper::m_class_object; }}} // namespace boost::python::objects diff --git a/include/boost/python/object/find_instance.hpp b/include/boost/python/object/find_instance.hpp index c60a82f7..3db670fc 100644 --- a/include/boost/python/object/find_instance.hpp +++ b/include/boost/python/object/find_instance.hpp @@ -6,6 +6,9 @@ #ifndef FIND_INSTANCE_DWA2002312_HPP # define FIND_INSTANCE_DWA2002312_HPP +# include +# include + namespace boost { namespace python { namespace objects { // Given an undecorated type_id, find the instance data which diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 871ed059..59043317 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -10,7 +10,6 @@ # include # include # include -# include namespace boost { namespace python { namespace objects { @@ -19,14 +18,13 @@ template struct make_holder; template <> struct make_holder<0> { - template + template struct apply { - typedef typename mpl::apply1::type holder; static void execute( PyObject* p) { - (new holder(p))->install(p); + (new Holder(p))->install(p); } }; }; @@ -35,10 +33,9 @@ struct make_holder<0> template <> struct make_holder<1> { - template + template struct apply { - typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; @@ -46,7 +43,7 @@ struct make_holder<1> PyObject* p , t0 a0) { - (new holder(p, f0(a0)))->install(p); + (new Holder(p, f0(a0)))->install(p); } }; }; @@ -54,10 +51,9 @@ struct make_holder<1> template <> struct make_holder<2> { - template + template struct apply { - typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -66,7 +62,7 @@ struct make_holder<2> static void execute( PyObject* p, t0 a0, t1 a1) { - (new holder(p, f0(a0), f1(a1)))->install(p); + (new Holder(p, f0(a0), f1(a1)))->install(p); } }; }; @@ -74,10 +70,9 @@ struct make_holder<2> template <> struct make_holder<3> { - template + template struct apply { - typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -88,7 +83,7 @@ struct make_holder<3> static void execute( PyObject* p, t0 a0, t1 a1, t2 a2) { - (new holder(p, f0(a0), f1(a1), f2(a2)))->install(p); + (new Holder(p, f0(a0), f1(a1), f2(a2)))->install(p); } }; }; @@ -96,10 +91,9 @@ struct make_holder<3> template <> struct make_holder<4> { - template + template struct apply { - typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -112,7 +106,7 @@ struct make_holder<4> static void execute( PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3) { - (new holder(p, f0(a0), f1(a1), f2(a2), f3(a3)))->install(p); + (new Holder(p, f0(a0), f1(a1), f2(a2), f3(a3)))->install(p); } }; }; @@ -120,10 +114,9 @@ struct make_holder<4> template <> struct make_holder<5> { - template + template struct apply { - typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -138,7 +131,7 @@ struct make_holder<5> static void execute( PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3, t4 a4) { - (new holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4)))->install(p); + (new Holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4)))->install(p); } }; }; @@ -146,10 +139,9 @@ struct make_holder<5> template <> struct make_holder<6> { - template + template struct apply { - typedef typename mpl::apply1::type holder; typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; @@ -166,7 +158,7 @@ struct make_holder<6> static void execute( PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) { - (new holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4), f5(a5)))->install(p); + (new Holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4), f5(a5)))->install(p); } }; }; diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 84700299..8bce39bd 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -14,6 +14,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -147,81 +148,83 @@ struct pointer_holder : instance_holder Pointer m_p; }; -template +template struct pointer_holder_back_reference : instance_holder { + private: + typedef typename python::detail::pointee::type held_type; + public: + pointer_holder_back_reference(Pointer); // Forward construction to the held object pointer_holder_back_reference(PyObject* p) - : m_p(new BackReferenceType(p)) { - (void)instance_finder::registration; + : m_p(new held_type(p)) { + (void)instance_finder::registration; } - - template pointer_holder_back_reference(PyObject* p, A1 a1) - : m_p(new BackReferenceType(p + : m_p(new held_type(p , (typename unwrap_reference::type&)(a1) )) { - (void)instance_finder::registration; + (void)instance_finder::registration; } template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2) - : m_p(new BackReferenceType(p + : m_p(new held_type(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) )) { - (void)instance_finder::registration; + (void)instance_finder::registration; } template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3) - : m_p(new BackReferenceType(p + : m_p(new held_type(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) )) { - (void)instance_finder::registration; + (void)instance_finder::registration; } template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4) - : m_p(new BackReferenceType(p + : m_p(new held_type(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) )) { - (void)instance_finder::registration; + (void)instance_finder::registration; } template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - : m_p(new BackReferenceType(p + : m_p(new held_type(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) , (typename unwrap_reference::type&)(a4) , (typename unwrap_reference::type&)(a5) )) { - (void)instance_finder::registration; + (void)instance_finder::registration; } template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - : m_p(new BackReferenceType(p + : m_p(new held_type(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -229,13 +232,13 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a5) , (typename unwrap_reference::type&)(a6) )) { - (void)instance_finder::registration; + (void)instance_finder::registration; } template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) - : m_p(new BackReferenceType(p + : m_p(new held_type(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -245,13 +248,13 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a7) )) { - (void)instance_finder::registration; + (void)instance_finder::registration; } template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) - : m_p(new BackReferenceType(p + : m_p(new held_type(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -262,13 +265,13 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a8) )) { - (void)instance_finder::registration; + (void)instance_finder::registration; } template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) - : m_p(new BackReferenceType(p + : m_p(new held_type(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -280,13 +283,13 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a9) )) { - (void)instance_finder::registration; + (void)instance_finder::registration; } template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) - : m_p(new BackReferenceType(p + : m_p(new held_type(p , (typename unwrap_reference::type&)(a1) , (typename unwrap_reference::type&)(a2) , (typename unwrap_reference::type&)(a3) @@ -299,7 +302,7 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a10) )) { - (void)instance_finder::registration; + (void)instance_finder::registration; } @@ -310,81 +313,18 @@ struct pointer_holder_back_reference : instance_holder Pointer m_p; }; -}}} // namespace boost::python::objects - -// back to namespace boost for this forward declaration -namespace boost -{ - template class shared_ptr; -} - -namespace boost { namespace python { namespace objects { - -struct shared_ptr_generator -{ - template - struct apply - { - typedef boost::shared_ptr type; - }; -}; - -struct no_back_reference; - -// Workaround lack of partial specialization -namespace detail -{ - template - struct pointer_holder_back_reference_generator - { - template - struct apply - { - typedef typename mpl::apply1< - PointerGenerator,BackReferenceType - >::type pointer; - - typedef pointer_holder_back_reference type; - }; - }; - - template - struct plain_pointer_holder_generator - { - template - struct apply - { - typedef typename mpl::apply1< - PointerGenerator,Held - >::type pointer; - - typedef pointer_holder type; - }; - }; -} - -// A generator metafunction which can be passed to make_holder -// PointerGenerator should be another generator metafunction which -// makes the appropriate (smart) pointer type to hold the argument to -// pointer_holder_generator. -template -struct pointer_holder_generator - : mpl::select_type< - is_same::value - , detail::plain_pointer_holder_generator< - PointerGenerator> - , detail::pointer_holder_back_reference_generator< - BackReferenceType,PointerGenerator> - >::type -{ -}; - template pointer_holder::pointer_holder(Pointer p) : m_p(p) { } +template +pointer_holder_back_reference::pointer_holder_back_reference(Pointer p) + : m_p(p) +{ +} + template void* pointer_holder::holds(converter::undecorated_type_id_t dst_t) { @@ -396,6 +336,20 @@ void* pointer_holder::holds(converter::undecorated_type_id_t dst : find_dynamic_type(&*this->m_p, src_t, dst_t); } +template +void* pointer_holder_back_reference::holds(converter::undecorated_type_id_t dst_t) +{ + if (dst_t == converter::undecorated_type_id()) + return &this->m_p; + + if (dst_t == converter::undecorated_type_id()) + return &*this->m_p; + + converter::type_id_t src_t = converter::undecorated_type_id(); + Value* p = &*this->m_p; + return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t); +} + }}} // namespace boost::python::objects #endif // POINTER_HOLDER_DWA20011215_HPP diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp new file mode 100644 index 00000000..39d50c0a --- /dev/null +++ b/include/boost/python/object/select_holder.hpp @@ -0,0 +1,70 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef SELECT_HOLDER_DWA2002322_HPP +# define SELECT_HOLDER_DWA2002322_HPP + +# include +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace objects { + +namespace detail +{ + template + struct select_value_holder + { + typedef typename mpl::select_type< + (!is_same::value) | has_back_reference::value + , value_holder_back_reference + , value_holder + >::type holder; + + static holder* get() { return 0; } + }; + + template + struct select_pointer_holder + { + typedef typename python::detail::pointee::type pointee; + + typedef typename mpl::select_type< + (!is_same::value) | has_back_reference::value + , pointer_holder_back_reference + , pointer_holder + >::type holder; + + static holder* get() { return 0; } + }; +} + +template +inline detail::select_value_holder select_holder(python::detail::not_specified*, T* = 0, NotSpecified* = 0) +{ + return detail::select_value_holder(); +} + +template +inline detail::select_value_holder select_holder(T*, Held* = 0) +{ + return detail::select_value_holder(); +} + + +template +detail::select_pointer_holder select_holder(void*, Ptr* = 0, T* = 0) +{ + return detail::select_pointer_holder(); +} + +}}} // namespace boost::python::objects + +#endif // SELECT_HOLDER_DWA2002322_HPP diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index c0a5c580..4154a7e8 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -142,7 +142,7 @@ struct value_holder : instance_holder Held m_held; }; -template +template struct value_holder_back_reference : instance_holder { // Forward construction to the held object @@ -301,27 +301,6 @@ struct value_holder_back_reference : instance_holder BackReferenceType m_held; }; -// A generator metafunction which can be passed to make_holder -template <> -struct value_holder_generator -{ - template - struct apply - { - typedef value_holder type; - }; -}; - -template -struct value_holder_generator -{ - template - struct apply - { - typedef value_holder_back_reference type; - }; -}; - template void* value_holder::holds(converter::undecorated_type_id_t dst_t) { diff --git a/test/Jamfile b/test/Jamfile index a01efdde..6db104fb 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -68,6 +68,20 @@ unit-test pointer_type_id_test unit-test member_function_cast : member_function_cast.cpp : $(BOOST_ROOT) ; +unit-test bases + : bases.cpp : $(BOOST_ROOT) ; + +unit-test if_else + : if_else.cpp : $(BOOST_ROOT) ; + +unit-test pointee + : pointee.cpp : $(BOOST_ROOT) ; + +unit-test select_holder + : select_holder.cpp + : $(BOOST_ROOT) BOOST_PYTHON_STATIC_LIB $(PYTHON_PROPERTIES) +; + unit-test select_from_python_test : select_from_python_test.cpp ../src/converter/type_id.cpp @@ -77,3 +91,4 @@ unit-test select_from_python_test $(PYTHON_V1_PROPERTIES) ; + diff --git a/test/m1.cpp b/test/m1.cpp index 439d58e2..cbaaf8db 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -201,6 +201,7 @@ BOOST_PYTHON_MODULE_INIT(m1) { using namespace boost::python; using boost::mpl::type_list; + using boost::shared_ptr; simple_to_python(); @@ -219,10 +220,6 @@ BOOST_PYTHON_MODULE_INIT(m1) module m1("m1"); - typedef boost::python::objects::pointer_holder_generator< - boost::python::objects::shared_ptr_generator - > use_shared_ptr; - m1 // Insert the metaclass for all extension classes .setattr("xclass", boost::python::objects::class_metatype()) @@ -251,7 +248,7 @@ BOOST_PYTHON_MODULE_INIT(m1) .def("take_d", take_d) .add( - class_, use_shared_ptr>("A") + class_ >("A") .def_init() .def("name", &A::name) ) @@ -262,13 +259,13 @@ BOOST_PYTHON_MODULE_INIT(m1) // or "C" below if we make them part of the same chain m1 .add( - class_, use_shared_ptr>("B") + class_, shared_ptr >("B") .def_init() .def("name", &B::name) ) .add( - class_, use_shared_ptr>("C") + class_, shared_ptr >("C") .def_init() .def("name", &C::name) ) @@ -276,7 +273,7 @@ BOOST_PYTHON_MODULE_INIT(m1) m1 .add( - class_, use_shared_ptr>("D") + class_, bases >("D") .def_init() .def("name", &D::name) ) diff --git a/test/select_holder.cpp b/test/select_holder.cpp new file mode 100644 index 00000000..cb8fd640 --- /dev/null +++ b/test/select_holder.cpp @@ -0,0 +1,77 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include +#include + +#define BOOST_INCLUDE_MAIN +#include + +struct BR {}; + +struct Base {}; +struct Derived : Base {}; + +namespace boost { namespace python +{ + // specialization + template <> + struct has_back_reference
    + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; +}} // namespace boost::python + +template +void assert_same(U* = 0, T* = 0) +{ + BOOST_TEST((boost::is_same::value)); + BOOST_STATIC_ASSERT((boost::is_same::value)); + +} + +template +void assert_holder(T* = 0, Held* = 0, Holder* = 0) +{ + assert_same(boost::python::objects::select_holder((Held*)0).get()); +} + +int test_main(int, char * []) +{ + using namespace boost::python::detail; + using namespace boost::python::objects; + + assert_holder >(); + + assert_holder >(); + assert_holder >(); + assert_holder >(); + + assert_holder >(); + + assert_holder + ,pointer_holder,Base> >(); + + assert_holder + ,pointer_holder_back_reference,Base> >(); + + assert_holder + ,pointer_holder_back_reference,BR> > (); + + return 0; +} + +#if defined(__GNUC__) && __GNUC__ <= 3 +// This definition is needed for MinGW 2.95.2 for some reason +namespace boost { namespace python +{ + bool handle_exception_impl(boost::function0) { return false; } +}} +#endif diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp index ab05fe3c..586048d5 100644 --- a/test/virtual_functions.cpp +++ b/test/virtual_functions.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using namespace boost::python; @@ -66,6 +67,10 @@ struct concrete_callback : concrete : concrete(x), self(p) {} + concrete_callback(PyObject* p, concrete const& x) + : concrete(x), self(p) + {} + int f(Y const& y) { return returning::call_method(self, "f", boost::ref(y)); @@ -85,26 +90,21 @@ BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) { module("virtual_functions_ext") .add( - class_, objects::value_holder_generator >("concrete") + class_("concrete") .def_init(args()) .def("value", &concrete::value) .def("set", &concrete::set) .def("call_f", &concrete::call_f) .def("f", &concrete_callback::f_impl)) -#if 0 .add( - class_ - , objects::pointer_holder_generator< - boost::python::objects::shared_ptr_generator - , abstract_callback> + class_ >("abstract") .def_init(args()) .def("value", &abstract::value) .def("call_f", &abstract::call_f) .def("set", &abstract::set)) -#endif .add( class_("Y") diff --git a/test/virtual_functions.py b/test/virtual_functions.py index 8ea992c5..9b074b1a 100644 --- a/test/virtual_functions.py +++ b/test/virtual_functions.py @@ -8,13 +8,13 @@ >>> class C2(concrete): ... pass -<<<>>> class A1(abstract): -<<<... def f(self, y): -<<<... return abstract.f(self, Y(-y.value())) -<<< -<<<>>> class A2(abstract): -<<<... pass -<<< +>>> class A1(abstract): +... def f(self, y): +... return y.value() * 2 + +>>> class A2(abstract): +... pass + >>> y1 = Y(16) >>> y2 = Y(17) @@ -24,33 +24,35 @@ # # Test abstract with f overridden # -<<<>>> a1 = A1(42) -<<<>>> a1.value() -<<<42 -<<< -<<<# Call f indirectly from C++ -<<<>>> a1.call_f(y1) -<<<-16 -<<< -<<<# Call f directly from Python -<<<>>> a1.f(y2) -<<<-17 -<<< -<<<# -<<<# Test abstract with f not overridden -<<<# -<<<>>> a2 = A2(42) -<<<>>> A2.value() -<<<42 -<<< -<<<# Call f indirectly from C++ -<<<>>> c1.call_f(y1) -<<<16 -<<< -<<<# Call f directly from Python -<<<>>> c1.f(y2) -<<<17 -<<< +>>> a1 = A1(42) +>>> a1.value() +42 + +# Call f indirectly from C++ +>>> a1.call_f(y1) +32 + +# Call f directly from Python +>>> a1.f(y2) +34 + +# +# Test abstract with f not overridden +# +>>> a2 = A2(42) +>>> a2.value() +42 + +# Call f indirectly from C++ +>>> try: a2.call_f(y1) +... except AttributeError: pass +... else: print 'no exception' + +# Call f directly from Python +>>> try: a2.call_f(y2) +... except AttributeError: pass +... else: print 'no exception' + ############# Concrete Tests ############ # From 453fbbed1bf3ece47d97e3b2fd903b5e0bb186e5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Mar 2002 15:05:58 +0000 Subject: [PATCH 0340/1042] initial checkin [SVN r13255] --- include/boost/python/detail/not_specified.hpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 include/boost/python/detail/not_specified.hpp diff --git a/include/boost/python/detail/not_specified.hpp b/include/boost/python/detail/not_specified.hpp new file mode 100644 index 00000000..ce1b280d --- /dev/null +++ b/include/boost/python/detail/not_specified.hpp @@ -0,0 +1,15 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef NOT_SPECIFIED_DWA2002321_HPP +# define NOT_SPECIFIED_DWA2002321_HPP + +namespace boost { namespace python { namespace detail { + + struct not_specified {}; + +}}} // namespace boost::python::detail + +#endif // NOT_SPECIFIED_DWA2002321_HPP From 9d3d50c654f7a976cbcd9d2ad9543271a8ae6b79 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Mar 2002 15:19:56 +0000 Subject: [PATCH 0341/1042] initial checkin [SVN r13256] --- include/boost/python/args.hpp | 19 ++++ include/boost/python/bases.hpp | 58 ++++++++++ include/boost/python/detail/if_else.hpp | 117 ++++++++++++++++++++ include/boost/python/detail/pointee.hpp | 36 ++++++ include/boost/python/has_back_reference.hpp | 22 ++++ test/bases.cpp | 63 +++++++++++ test/if_else.cpp | 61 ++++++++++ test/pointee.cpp | 35 ++++++ 8 files changed, 411 insertions(+) create mode 100644 include/boost/python/args.hpp create mode 100644 include/boost/python/bases.hpp create mode 100644 include/boost/python/detail/if_else.hpp create mode 100644 include/boost/python/detail/pointee.hpp create mode 100644 include/boost/python/has_back_reference.hpp create mode 100644 test/bases.cpp create mode 100644 test/if_else.cpp create mode 100644 test/pointee.cpp diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp new file mode 100644 index 00000000..b584506b --- /dev/null +++ b/include/boost/python/args.hpp @@ -0,0 +1,19 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ARGS_DWA2002323_HPP +# define ARGS_DWA2002323_HPP +# include + +namespace boost { namespace python { + +// A type list for specifying arguments +template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename A, ::boost::mpl::null_argument) > +struct args : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(A) >::type +{}; + +}} // namespace boost::python + +#endif // ARGS_DWA2002323_HPP diff --git a/include/boost/python/bases.hpp b/include/boost/python/bases.hpp new file mode 100644 index 00000000..468c6744 --- /dev/null +++ b/include/boost/python/bases.hpp @@ -0,0 +1,58 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BASES_DWA2002321_HPP +# define BASES_DWA2002321_HPP +# include +# include +# include +# include + +namespace boost { namespace python { + // A type list for specifying bases + template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename B, ::boost::mpl::null_argument) > + struct bases : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(B) >::type + {}; + + namespace detail + { +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template struct specifies_bases + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; + template < BOOST_MPL_LIST_PARAMETERS(class B) > + struct specifies_bases< bases< BOOST_MPL_LIST_PARAMETERS(B) > > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; +# else + template < BOOST_MPL_LIST_PARAMETERS(class B) > + static char is_bases_helper(bases< BOOST_MPL_LIST_PARAMETERS(B) > const&); + + static char (& is_bases_helper(...) )[256]; + + template struct specifies_bases + { + private: + static typename add_reference::type make(); + BOOST_STATIC_CONSTANT(bool, non_ref = !is_reference::value); + public: + BOOST_STATIC_CONSTANT(bool, value = non_ref & (sizeof(is_bases_helper(make())) == 1)); + }; +# endif + template > + struct select_bases + : mpl::select_type< + specifies_bases::value + , T + , Prev + > + { + }; + } +}} // namespace boost::python + +#endif // BASES_DWA2002321_HPP diff --git a/include/boost/python/detail/if_else.hpp b/include/boost/python/detail/if_else.hpp new file mode 100644 index 00000000..6668617c --- /dev/null +++ b/include/boost/python/detail/if_else.hpp @@ -0,0 +1,117 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef IF_ELSE_DWA2002322_HPP +# define IF_ELSE_DWA2002322_HPP +# include + +namespace boost { namespace python { namespace detail { + +template struct elif_selected; + +template +struct if_selected +{ + template + struct elif : elif_selected + { + }; + + template + struct else_ + { + typedef T type; + }; +}; + +# if defined(BOOST_MSVC) && (BOOST_MSVC == 1300) +namespace msvc70_aux { + +template< bool > struct inherit_from +{ + template< typename T > struct result + { + typedef T type; + }; +}; + +template<> struct inherit_from +{ + template< typename T > struct result + { + struct type {}; + }; +}; + +template< typename T > +struct never_true +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +} // namespace msvc70_aux + +#endif // # if defined(BOOST_MSVC) && (BOOST_MSVC == 1300) + +template +struct elif_selected +{ +# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407) + template class then; +# elif defined(BOOST_MSVC) && (BOOST_MSVC == 1300) + template + struct then : msvc70_aux::inherit_from< msvc70_aux::never_true::value > + ::template result< if_selected >::type + { + }; +# else + template + struct then : if_selected + { + }; +# endif +}; + +# if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__MWERKS__) && __MWERKS__ <= 0x2407) +template +template +class elif_selected::then : public if_selected +{ +}; +# endif + +template struct if_ +{ + template + struct then : if_selected + { + }; +}; + +struct if_unselected +{ + template struct elif : if_ + { + }; + + template + struct else_ + { + typedef U type; + }; +}; + +template <> +struct if_ +{ + template + struct then : if_unselected + { + }; +}; + +}}} // namespace boost::python::detail + +#endif // IF_ELSE_DWA2002322_HPP diff --git a/include/boost/python/detail/pointee.hpp b/include/boost/python/detail/pointee.hpp new file mode 100644 index 00000000..2af1535f --- /dev/null +++ b/include/boost/python/detail/pointee.hpp @@ -0,0 +1,36 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef POINTEE_DWA2002323_HPP +# define POINTEE_DWA2002323_HPP + +# include + +namespace boost { namespace python { namespace detail { + +template +struct pointee_impl +{ + template struct apply : remove_pointer {}; +}; + +template <> +struct pointee_impl +{ + template struct apply + { + typedef typename T::element_type type; + }; +}; + +template +struct pointee + : pointee_impl::value>::template apply +{ +}; + +}}} // namespace boost::python::detail + +#endif // POINTEE_DWA2002323_HPP diff --git a/include/boost/python/has_back_reference.hpp b/include/boost/python/has_back_reference.hpp new file mode 100644 index 00000000..95a3ae9a --- /dev/null +++ b/include/boost/python/has_back_reference.hpp @@ -0,0 +1,22 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef HAS_BACK_REFERENCE_DWA2002323_HPP +# define HAS_BACK_REFERENCE_DWA2002323_HPP + +namespace boost { namespace python { + +// traits class which users can specialize to indicate that a class +// contains a back-reference to its owning PyObject* +template +struct has_back_reference +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + + +}} // namespace boost::python + +#endif // HAS_BACK_REFERENCE_DWA2002323_HPP diff --git a/test/bases.cpp b/test/bases.cpp new file mode 100644 index 00000000..e4f91990 --- /dev/null +++ b/test/bases.cpp @@ -0,0 +1,63 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include + +struct A; +struct B; + +template +struct choose_bases + : boost::python::detail::select_bases< + X + , typename boost::python::detail::select_bases< + Y + , typename boost::python::detail::select_bases::type + >::type> +{ + +}; + +int main() +{ + BOOST_STATIC_ASSERT((boost::python::detail::specifies_bases< + boost::python::bases >::value)); + + BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< + boost::python::bases& >::value)); + + BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< + void* >::value)); + + BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< + int >::value)); + + BOOST_STATIC_ASSERT((!boost::python::detail::specifies_bases< + int[5] >::value)); + + typedef boost::python::detail::select_bases< + int + , boost::python::detail::select_bases::type > collected1; + + BOOST_STATIC_ASSERT((boost::is_same >::value)); + BOOST_STATIC_ASSERT((boost::is_same::type,boost::python::bases<> >::value)); + + typedef boost::python::detail::select_bases< + int + , boost::python::detail::select_bases< + boost::python::bases + , boost::python::detail::select_bases< + A + >::type + >::type + > collected2; + + BOOST_STATIC_ASSERT((boost::is_same >::value)); + BOOST_STATIC_ASSERT((boost::is_same,long>::type,boost::python::bases >::value)); + + return 0; +} diff --git a/test/if_else.cpp b/test/if_else.cpp new file mode 100644 index 00000000..d8bd34ca --- /dev/null +++ b/test/if_else.cpp @@ -0,0 +1,61 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include + + typedef char c1; + typedef char c2[2]; + typedef char c3[3]; + typedef char c4[4]; + +template +struct choose +{ +#if 1 + typedef typename boost::python::detail::if_< + (sizeof(c1) == size) + >::template then< + c1 + >::template elif< + (sizeof(c2) == size) + >::template then< + c2 + >::template elif< + (sizeof(c3) == size) + >::template then< + c3 + >::template elif< + (sizeof(c4) == size) + >::template then< + c4 + >::template else_::type type; +#else + typedef typename boost::python::detail::if_< + (sizeof(c1) == size) + , c1 + >::template elif< + (sizeof(c2) == size) + , c2 + >::template elif< + (sizeof(c3) == size) + , c3 + >::template elif< + (sizeof(c4) == size) + , c4 + >::template else_::type type; +#endif +}; + +int main() +{ + BOOST_STATIC_ASSERT((boost::is_same::type,c1>::value)); + BOOST_STATIC_ASSERT((boost::is_same::type,c2>::value)); + BOOST_STATIC_ASSERT((boost::is_same::type,c3>::value)); + BOOST_STATIC_ASSERT((boost::is_same::type,c4>::value)); + BOOST_STATIC_ASSERT((boost::is_same::type,void*>::value)); + return 0; +} diff --git a/test/pointee.cpp b/test/pointee.cpp new file mode 100644 index 00000000..7935e897 --- /dev/null +++ b/test/pointee.cpp @@ -0,0 +1,35 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include + +struct A; + +int main() +{ + BOOST_STATIC_ASSERT( + (boost::is_same< + boost::python::detail::pointee >::type + , char** + >::value)); + + BOOST_STATIC_ASSERT( + (boost::is_same< + boost::python::detail::pointee >::type + , A>::value)); + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + BOOST_STATIC_ASSERT( + (boost::is_same< + boost::python::detail::pointee::type + , char + >::value)); +#endif + return 0; +} From 516f30a307f5b4785e1a45cd619339d55a487035 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Mar 2002 15:51:50 +0000 Subject: [PATCH 0342/1042] fixes for older KCCs [SVN r13258] --- include/boost/python/class.hpp | 9 ++++++--- include/boost/python/object/select_holder.hpp | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index cff0adf9..166ced73 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -245,9 +245,12 @@ namespace detail template struct select_held_type : mpl::select_type< - !(specifies_bases::value | is_same::value) - , T - , Prev + type_traits::ice_or< + type_traits::ice_not::value>::value + , is_same::value + >::value + , T + , Prev > { }; diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index 39d50c0a..72446358 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -22,8 +22,10 @@ namespace detail template struct select_value_holder { + BOOST_STATIC_CONSTANT(bool, selector = (!is_same::value) | has_back_reference::value); + typedef typename mpl::select_type< - (!is_same::value) | has_back_reference::value + selector , value_holder_back_reference , value_holder >::type holder; @@ -35,9 +37,10 @@ namespace detail struct select_pointer_holder { typedef typename python::detail::pointee::type pointee; + BOOST_STATIC_CONSTANT(bool, selector = (!is_same::value) | has_back_reference::value); typedef typename mpl::select_type< - (!is_same::value) | has_back_reference::value + selector , pointer_holder_back_reference , pointer_holder >::type holder; From 2666c7312fec46924a4b995c8f81a3a6d633d795 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Mar 2002 16:48:10 +0000 Subject: [PATCH 0343/1042] bug fix [SVN r13260] --- include/boost/python/class.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 166ced73..48fb4532 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -246,11 +246,11 @@ namespace detail struct select_held_type : mpl::select_type< type_traits::ice_or< - type_traits::ice_not::value>::value + specifies_bases::value , is_same::value >::value - , T , Prev + , T > { }; From 4ad579d4ad26844b96632087bb96262e24fadcf3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Mar 2002 17:09:01 +0000 Subject: [PATCH 0344/1042] extend minGW workaround to all compilers [SVN r13261] --- test/select_holder.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/select_holder.cpp b/test/select_holder.cpp index cb8fd640..0d186e5a 100644 --- a/test/select_holder.cpp +++ b/test/select_holder.cpp @@ -68,10 +68,8 @@ int test_main(int, char * []) return 0; } -#if defined(__GNUC__) && __GNUC__ <= 3 -// This definition is needed for MinGW 2.95.2 for some reason +// This definition is needed for MinGW 2.95.2 and KCC on OSF for some reason namespace boost { namespace python { bool handle_exception_impl(boost::function0) { return false; } }} -#endif From a3a633242f7085e32532984339cc1f826a3abadf Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Mar 2002 17:13:00 +0000 Subject: [PATCH 0345/1042] Added missing declspec [SVN r13262] --- test/select_holder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/select_holder.cpp b/test/select_holder.cpp index 0d186e5a..869ac92a 100644 --- a/test/select_holder.cpp +++ b/test/select_holder.cpp @@ -71,5 +71,5 @@ int test_main(int, char * []) // This definition is needed for MinGW 2.95.2 and KCC on OSF for some reason namespace boost { namespace python { - bool handle_exception_impl(boost::function0) { return false; } + bool BOOST_PYTHON_DECL handle_exception_impl(boost::function0) { return false; } }} From 6004a35e23142ac5a4cd6d266de57d30f7de3cab Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Mar 2002 17:22:32 +0000 Subject: [PATCH 0346/1042] bug fix [SVN r13263] --- test/select_holder.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/select_holder.cpp b/test/select_holder.cpp index 869ac92a..f6b22baa 100644 --- a/test/select_holder.cpp +++ b/test/select_holder.cpp @@ -68,8 +68,11 @@ int test_main(int, char * []) return 0; } -// This definition is needed for MinGW 2.95.2 and KCC on OSF for some reason +#if !defined(_WIN32) || defined(__GNUC__) +// This definition is needed for MinGW 2.95.2 and KCC on OSF for some +// reason, but will break other Win32 compilers. namespace boost { namespace python { - bool BOOST_PYTHON_DECL handle_exception_impl(boost::function0) { return false; } + bool handle_exception_impl(boost::function0) { return false; } }} +#endif From 8d88a92fe49a23a2d5b3b9230f62dd5ff2fd3d71 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Mar 2002 21:31:21 +0000 Subject: [PATCH 0347/1042] instantiation hacks for tru64cxx6.5 [SVN r13265] --- include/boost/python/class.hpp | 1 + .../boost/python/object/class_converters.hpp | 6 ++++- .../boost/python/object/pointer_holder.hpp | 22 +++++++++---------- include/boost/python/object/value_holder.hpp | 22 +++++++++---------- test/member_function_cast.cpp | 2 +- 5 files changed, 29 insertions(+), 24 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 48fb4532..f040a789 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -169,6 +169,7 @@ class class_ : private objects::class_base std::size_t, size = mpl::size::value + 1); class_id ids[size]; }; + friend struct id_vector; }; diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index 8f2786f3..86fcd64b 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -75,7 +75,11 @@ struct register_base_of template inline void register_class_from_python(Derived* = 0, Bases* = 0) { - (void)instance_finder::registration; + // cause the static registration to be instantiated. Can't just + // cast it to void on all compilers; some will skip its + // initialization. + void const* ignored = &instance_finder::registration; + (void)ignored; // register all up/downcasts here register_dynamic_id(); diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 8bce39bd..4ec46377 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -160,7 +160,7 @@ struct pointer_holder_back_reference : instance_holder // Forward construction to the held object pointer_holder_back_reference(PyObject* p) : m_p(new held_type(p)) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } template @@ -169,7 +169,7 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a1) )) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -180,7 +180,7 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a2) )) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -192,7 +192,7 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a3) )) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -205,7 +205,7 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a4) )) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -218,7 +218,7 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a4) , (typename unwrap_reference::type&)(a5) )) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -232,7 +232,7 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a5) , (typename unwrap_reference::type&)(a6) )) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -248,7 +248,7 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a7) )) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -265,7 +265,7 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a8) )) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -283,7 +283,7 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a9) )) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -302,7 +302,7 @@ struct pointer_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a10) )) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 4154a7e8..e6d7f454 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -148,7 +148,7 @@ struct value_holder_back_reference : instance_holder // Forward construction to the held object value_holder_back_reference(PyObject* p) : m_held() { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -158,7 +158,7 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a1) ) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -169,7 +169,7 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a2) ) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -181,7 +181,7 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a3) ) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -194,7 +194,7 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a4) ) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -207,7 +207,7 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a4) , (typename unwrap_reference::type&)(a5) ) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -221,7 +221,7 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a5) , (typename unwrap_reference::type&)(a6) ) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -237,7 +237,7 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a7) ) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -254,7 +254,7 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a8) ) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -272,7 +272,7 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a9) ) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } @@ -291,7 +291,7 @@ struct value_holder_back_reference : instance_holder , (typename unwrap_reference::type&)(a10) ) { - (void)instance_finder::registration; + void const* x = &instance_finder::registration; (void)x; } private: // required holder implementation diff --git a/test/member_function_cast.cpp b/test/member_function_cast.cpp index 986d87b5..a754fd36 100644 --- a/test/member_function_cast.cpp +++ b/test/member_function_cast.cpp @@ -52,4 +52,4 @@ int main() assert_mf_cast(3); assert_mf_cast(X()); return 0; -}; +} From 11bd4c32231261d82fc561e76cd879663db6cbab Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Mar 2002 23:55:08 +0000 Subject: [PATCH 0348/1042] Test for has_back_reference<> specialization [SVN r13272] --- test/Jamfile | 1 + test/back_reference.cpp | 99 +++++++++++++++++++++++++++++++++++++++++ test/back_reference.py | 26 +++++++++++ 3 files changed, 126 insertions(+) create mode 100644 test/back_reference.cpp create mode 100644 test/back_reference.py diff --git a/test/Jamfile b/test/Jamfile index 6db104fb..9809c5db 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -56,6 +56,7 @@ bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters bpl-test test_pointer_adoption ; bpl-test callbacks ; bpl-test virtual_functions ; +bpl-test back_reference ; # --- unit tests of library components --- unit-test indirect_traits_test diff --git a/test/back_reference.cpp b/test/back_reference.cpp new file mode 100644 index 00000000..e1338eaa --- /dev/null +++ b/test/back_reference.cpp @@ -0,0 +1,99 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// This test shows that a class can be wrapped "as itself" but also +// acquire a back-reference iff has_back_reference<> is appropriately +// specialized. +using namespace boost::python; + +struct X +{ + explicit X(int x) : x(x), magic(7654321) { ++counter; } + X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } + virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } + + void set(int x) { assert(magic == 7654321); this->x = x; } + int value() const { assert(magic == 7654321); return x; } + static int count() { return counter; } + private: + void operator=(X const&); + private: + int x; + long magic; + static int counter; +}; + +int X::counter; + +struct Y : X +{ + Y(PyObject* self, int x) : X(x) {}; + Y(PyObject* self, Y const& rhs) : X(rhs), self(self) {}; + private: + Y(Y const&); + PyObject* self; +}; + +struct Z : X +{ + Z(PyObject* self, int x) : X(x) {}; + Z(PyObject* self, Z const& rhs) : X(rhs), self(self) {}; + private: + Z(Z const&); + PyObject* self; +}; + +Y const& copy_Y(Y const& y) { return y; } +Z const& copy_Z(Z const& z) { return z; } + +namespace boost { namespace python +{ + template <> + struct has_back_reference + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template <> + struct has_back_reference + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; +}} + + +BOOST_PYTHON_MODULE_INIT(back_reference_ext) +{ + module("back_reference_ext") + .def("copy_Y", copy_Y, return_value_policy()) + .def("copy_Z", copy_Z, return_value_policy()) + .def("x_instances", &X::count) + .add( + class_("Y") + .def_init(args()) + .def("value", &Y::value) + .def("set", &Y::set) + ) + + .add( + class_ >("Z") + .def_init(args()) + .def("value", &Z::value) + .def("set", &Z::set) + ) + ; +} + +#include "module_tail.cpp" diff --git a/test/back_reference.py b/test/back_reference.py new file mode 100644 index 00000000..552deec8 --- /dev/null +++ b/test/back_reference.py @@ -0,0 +1,26 @@ +''' +>>> from back_reference_ext import * +>>> y = Y(3) +>>> z = Z(4) +>>> x_instances() +2 +>>> y2 = copy_Y(y) +>>> x_instances() +3 +>>> z2 = copy_Z(z) +>>> x_instances() +4 +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From ac34e0e1086709b5f070bf45fc4f0a7c30772b9e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 26 Mar 2002 06:38:41 +0000 Subject: [PATCH 0349/1042] implicit conversions [SVN r13277] --- .../python/converter/find_from_python.hpp | 3 ++ include/boost/python/converter/implicit.hpp | 50 +++++++++++++++++++ include/boost/python/implicit.hpp | 28 +++++++++++ include/boost/python/type_from_python.hpp | 2 +- src/converter/from_python.cpp | 12 +++++ test/Jamfile | 1 + test/implicit.cpp | 37 ++++++++++++++ test/implicit.py | 20 ++++++++ test/test_class.hpp | 31 ++++++++++++ 9 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 include/boost/python/converter/implicit.hpp create mode 100644 include/boost/python/implicit.hpp create mode 100644 test/implicit.cpp create mode 100644 test/implicit.py create mode 100644 test/test_class.hpp diff --git a/include/boost/python/converter/find_from_python.hpp b/include/boost/python/converter/find_from_python.hpp index e7f7ca81..709c5de0 100644 --- a/include/boost/python/converter/find_from_python.hpp +++ b/include/boost/python/converter/find_from_python.hpp @@ -21,6 +21,9 @@ BOOST_PYTHON_DECL void* find( BOOST_PYTHON_DECL rvalue_stage1_data find( PyObject* source, rvalue_from_python_registration const*); +BOOST_PYTHON_DECL rvalue_from_python_registration const* find_chain( + PyObject* source, rvalue_from_python_registration const*); + }}} // namespace boost::python::converter #endif // FIND_FROM_PYTHON_DWA2002223_HPP diff --git a/include/boost/python/converter/implicit.hpp b/include/boost/python/converter/implicit.hpp new file mode 100644 index 00000000..95372810 --- /dev/null +++ b/include/boost/python/converter/implicit.hpp @@ -0,0 +1,50 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef IMPLICIT_DWA2002326_HPP +# define IMPLICIT_DWA2002326_HPP +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +template +struct implicit +{ + static void* convertible(PyObject* obj) + { + // Find a converter registration which can produce a Source + // instance from obj + return const_cast( + find_chain(obj, rvalue_from_python_chain::value)); + } + + static void construct(PyObject* obj, rvalue_stage1_data* data) + { + // This is the registration we got from the convertible step + rvalue_from_python_registration const* registration + = static_cast(data->convertible); + + // Call the convertible function again + rvalue_data intermediate_data(registration->convertible(obj)); + + // Use the result to construct the source type if the first + // converter was an rvalue converter. + if (registration->construct != 0) + registration->construct(obj, &intermediate_data.stage1); + + void* storage = ((rvalue_base_data*)data)->storage.bytes; + new (storage) Target(*(Source*)intermediate_data.storage.bytes); + + // record successful construction + data->convertible = storage; + + } +}; + +}}} // namespace boost::python::converter + +#endif // IMPLICIT_DWA2002326_HPP diff --git a/include/boost/python/implicit.hpp b/include/boost/python/implicit.hpp new file mode 100644 index 00000000..b13898e8 --- /dev/null +++ b/include/boost/python/implicit.hpp @@ -0,0 +1,28 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef IMPLICIT_DWA2002325_HPP +# define IMPLICIT_DWA2002325_HPP +# include +# include +# include +# include + +namespace boost { namespace python { + +template +void implicitly_convertible(boost::type* = 0, boost::type* = 0) +{ + typedef converter::implicit functions; + + converter::registry::insert( + &functions::convertible + , &functions::construct + , converter::undecorated_type_id()); +} + +}} // namespace boost::python + +#endif // IMPLICIT_DWA2002325_HPP diff --git a/include/boost/python/type_from_python.hpp b/include/boost/python/type_from_python.hpp index d5b9faed..38d2ceea 100644 --- a/include/boost/python/type_from_python.hpp +++ b/include/boost/python/type_from_python.hpp @@ -22,7 +22,7 @@ namespace detail } // A function generator whose static execute() function is an lvalue - // from_python converter using the given Extractor. U is exepcted to + // from_python converter using the given Extractor. U is expected to // be the actual type of the PyObject instance from which the result // is being extracted. template diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 8a68cc44..f821201a 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -29,6 +29,18 @@ BOOST_PYTHON_DECL rvalue_stage1_data find( return data; } +BOOST_PYTHON_DECL rvalue_from_python_registration const* find_chain( + PyObject* source + , rvalue_from_python_registration const* chain) +{ + for (;chain != 0; chain = chain->next) + { + if (chain->convertible(source)) + break; + } + return chain; +} + BOOST_PYTHON_DECL void* find( PyObject* source , lvalue_from_python_registration const* chain) diff --git a/test/Jamfile b/test/Jamfile index 9809c5db..52253f2a 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -57,6 +57,7 @@ bpl-test test_pointer_adoption ; bpl-test callbacks ; bpl-test virtual_functions ; bpl-test back_reference ; +bpl-test implicit ; # --- unit tests of library components --- unit-test indirect_traits_test diff --git a/test/implicit.cpp b/test/implicit.cpp new file mode 100644 index 00000000..17cbe7f7 --- /dev/null +++ b/test/implicit.cpp @@ -0,0 +1,37 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include "test_class.hpp" + +// This test shows that a class can be wrapped "as itself" but also +// acquire a back-reference iff has_back_reference<> is appropriately +// specialized. +using namespace boost::python; + +typedef test_class<> X; + +int x_value(X const& x) +{ + return x.value(); +} + +BOOST_PYTHON_MODULE_INIT(implicit_ext) +{ + implicitly_convertible(); + module("implicit_ext") + .def("x_value", x_value) + .add( + class_("X") + .def_init(args()) + .def("value", &X::value) + .def("set", &X::set) + ) + ; +} + +#include "module_tail.cpp" diff --git a/test/implicit.py b/test/implicit.py new file mode 100644 index 00000000..322467c0 --- /dev/null +++ b/test/implicit.py @@ -0,0 +1,20 @@ +''' +>>> from implicit_ext import * +>>> x_value(X(42)) +42 +>>> x_value(42) +42 +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) diff --git a/test/test_class.hpp b/test/test_class.hpp new file mode 100644 index 00000000..920a6b1f --- /dev/null +++ b/test/test_class.hpp @@ -0,0 +1,31 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TEST_CLASS_DWA2002326_HPP +# define TEST_CLASS_DWA2002326_HPP +# include + +template +struct test_class +{ + explicit test_class(int x) : x(x), magic(7654321 + n) { ++counter; } + test_class(test_class const& rhs) : x(rhs.x), magic(7654321 + n) { ++counter; } + virtual ~test_class() { assert(magic == 7654321 + n); magic = 6666666; x = 9999; --counter; } + + void set(int x) { assert(magic == 7654321 + n); this->x = x; } + int value() const { assert(magic == 7654321 + n); return x; } + static int count() { return counter; } + private: + void operator=(test_class const&); + private: + int x; + long magic; + static int counter; +}; + +template +int test_class::counter; + +#endif // TEST_CLASS_DWA2002326_HPP From 576269dae9600dd68fe6554bdbeca17938c8dd3c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 26 Mar 2002 17:16:33 +0000 Subject: [PATCH 0350/1042] more implicit conversion work [SVN r13282] --- include/boost/python/converter/implicit.hpp | 2 +- include/boost/python/converter/registry.hpp | 8 +++++ include/boost/python/implicit.hpp | 2 +- src/converter/from_python.cpp | 33 ++++++++++++++++++--- src/converter/registry.cpp | 16 ++++++++++ test/implicit.cpp | 11 +++++++ test/implicit.py | 6 ++++ test/test_class.hpp | 1 + 8 files changed, 73 insertions(+), 6 deletions(-) diff --git a/include/boost/python/converter/implicit.hpp b/include/boost/python/converter/implicit.hpp index 95372810..23c2ece5 100644 --- a/include/boost/python/converter/implicit.hpp +++ b/include/boost/python/converter/implicit.hpp @@ -37,7 +37,7 @@ struct implicit registration->construct(obj, &intermediate_data.stage1); void* storage = ((rvalue_base_data*)data)->storage.bytes; - new (storage) Target(*(Source*)intermediate_data.storage.bytes); + new (storage) Target(*static_cast(intermediate_data.stage1.convertible)); // record successful construction data->convertible = storage; diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index 1c8dba24..72676605 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -37,6 +37,14 @@ namespace registry , undecorated_type_id_t ); + // Insert an rvalue from_python converter at the tail of the + // chain. Used for implicit conversions + BOOST_PYTHON_DECL void push_back( + void* (*convertible)(PyObject*) + , constructor_function + , undecorated_type_id_t + ); + BOOST_PYTHON_DECL PyTypeObject*& class_object(undecorated_type_id_t key); } diff --git a/include/boost/python/implicit.hpp b/include/boost/python/implicit.hpp index b13898e8..f7146e40 100644 --- a/include/boost/python/implicit.hpp +++ b/include/boost/python/implicit.hpp @@ -17,7 +17,7 @@ void implicitly_convertible(boost::type* = 0, boost::type* = 0) { typedef converter::implicit functions; - converter::registry::insert( + converter::registry::push_back( &functions::convertible , &functions::construct , converter::undecorated_type_id()); diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index f821201a..805902a5 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include namespace boost { namespace python { namespace converter { @@ -29,15 +31,38 @@ BOOST_PYTHON_DECL rvalue_stage1_data find( return data; } +namespace +{ + // Prevent looping in implicit conversions. This could/should be + // much more efficient, but will work for now. + typedef std::vector visited_t; + static visited_t visited; +} + BOOST_PYTHON_DECL rvalue_from_python_registration const* find_chain( PyObject* source , rvalue_from_python_registration const* chain) -{ - for (;chain != 0; chain = chain->next) +{ + visited_t::iterator p = std::lower_bound(visited.begin(), visited.end(), chain); + if (p != visited.end() && *p == chain) + return 0; + + visited.insert(p, chain); + try { - if (chain->convertible(source)) - break; + for (;chain != 0; chain = chain->next) + { + if (chain->convertible(source)) + break; + } } + catch(...) + { + visited.erase(p); + throw; + } + p = std::lower_bound(visited.begin(), visited.end(), chain); + visited.erase(p); return chain; } diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index 2d104b01..822812e3 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -109,6 +109,22 @@ namespace registry found->m_rvalue_from_python = registration; } + // Insert an rvalue from_python converter + void push_back(void* (*convertible)(PyObject*) + , constructor_function construct + , undecorated_type_id_t key) + { + rvalue_from_python_registration** found = &find(key)->m_rvalue_from_python; + while (*found != 0) + found = &(*found)->next; + + rvalue_from_python_registration *registration = new rvalue_from_python_registration; + registration->convertible = convertible; + registration->construct = construct; + registration->next = 0; + *found = registration; + } + PyTypeObject*& class_object(undecorated_type_id_t key) { return find(key)->m_class_object; diff --git a/test/implicit.cpp b/test/implicit.cpp index 17cbe7f7..2b017fb4 100644 --- a/test/implicit.cpp +++ b/test/implicit.cpp @@ -14,24 +14,35 @@ using namespace boost::python; typedef test_class<> X; +typedef test_class<1> Y; int x_value(X const& x) { return x.value(); } +X make_x(int n) { return X(n); } + BOOST_PYTHON_MODULE_INIT(implicit_ext) { implicitly_convertible(); module("implicit_ext") .def("x_value", x_value) + .def("make_x", make_x) .add( class_("X") .def_init(args()) .def("value", &X::value) .def("set", &X::set) ) + .add( + class_("Y") + .def_init(args()) + .def("value", &Y::value) + .def("set", &Y::set) + ) ; + implicitly_convertible(); } #include "module_tail.cpp" diff --git a/test/implicit.py b/test/implicit.py index 322467c0..e0d8c067 100644 --- a/test/implicit.py +++ b/test/implicit.py @@ -4,6 +4,12 @@ 42 >>> x_value(42) 42 +>>> x = make_x(X(42)) +>>> x.value() +42 +>>> try: make_x('fool') +... except TypeError: pass +... else: print 'no error' ''' def run(args = None): diff --git a/test/test_class.hpp b/test/test_class.hpp index 920a6b1f..414cd084 100644 --- a/test/test_class.hpp +++ b/test/test_class.hpp @@ -16,6 +16,7 @@ struct test_class void set(int x) { assert(magic == 7654321 + n); this->x = x; } int value() const { assert(magic == 7654321 + n); return x; } + operator int() const { return x; } static int count() { return counter; } private: void operator=(test_class const&); From 2a6060e42595f408f916981b4db0c4484d97e21c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 26 Mar 2002 17:41:06 +0000 Subject: [PATCH 0351/1042] Cleanup [SVN r13283] --- test/implicit.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test/implicit.cpp b/test/implicit.cpp index 2b017fb4..50479158 100644 --- a/test/implicit.cpp +++ b/test/implicit.cpp @@ -8,13 +8,9 @@ #include #include "test_class.hpp" -// This test shows that a class can be wrapped "as itself" but also -// acquire a back-reference iff has_back_reference<> is appropriately -// specialized. using namespace boost::python; typedef test_class<> X; -typedef test_class<1> Y; int x_value(X const& x) { @@ -35,12 +31,6 @@ BOOST_PYTHON_MODULE_INIT(implicit_ext) .def("value", &X::value) .def("set", &X::set) ) - .add( - class_("Y") - .def_init(args()) - .def("value", &Y::value) - .def("set", &Y::set) - ) ; implicitly_convertible(); } From 383a51dde809d8b76463ec0694573ce39ec6742a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 30 Mar 2002 01:21:10 +0000 Subject: [PATCH 0352/1042] removed flotsam [SVN r13307] --- include/boost/python/converter/from_python_data.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp index 1ce8bd7a..ec57f479 100644 --- a/include/boost/python/converter/from_python_data.hpp +++ b/include/boost/python/converter/from_python_data.hpp @@ -125,8 +125,6 @@ namespace detail template struct referent_storage { - typedef typename remove_cv::type>::type referent; - BOOST_STATIC_CONSTANT(std::size_t, target = referent_alignment::value); typedef lower_alignment t1; From 4a81d366bb880db31a1d4b64e4f3acfd0827896f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 30 Mar 2002 01:22:18 +0000 Subject: [PATCH 0353/1042] Stop exporting the TypeObject [SVN r13308] --- include/boost/python/object/function.hpp | 2 -- src/object/function.cpp | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index 2a05a946..d750ad80 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -40,8 +40,6 @@ struct BOOST_PYTHON_DECL function : PyObject function* m_overloads; }; -extern BOOST_PYTHON_DECL PyTypeObject function_type; - // // implementations // diff --git a/src/object/function.cpp b/src/object/function.cpp index a9f0c94d..b251618d 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -11,6 +11,7 @@ namespace boost { namespace python { namespace objects { +extern PyTypeObject function_type; function::function(py_function implementation, unsigned min_args, unsigned max_args) : m_fn(implementation) From 7ffc983edd4bf6530967914ddafdbe403d1e1ecd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 30 Mar 2002 01:23:28 +0000 Subject: [PATCH 0354/1042] support for data members [SVN r13309] --- include/boost/python/class.hpp | 33 ++++++++++----- .../boost/python/copy_mutable_reference.hpp | 41 +++++++++++++++++++ test/Jamfile | 1 + test/data_members.py | 29 +++++++++++++ test/test_class.hpp | 7 ++-- 5 files changed, 98 insertions(+), 13 deletions(-) create mode 100644 include/boost/python/copy_mutable_reference.hpp create mode 100644 test/data_members.py diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index f040a789..ad1561ba 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -22,6 +22,7 @@ # include # include # include +# include # include namespace boost { namespace python { @@ -65,7 +66,7 @@ template < , class X2 // = detail::not_specified , class X3 // = detail::not_specified > -class class_ : private objects::class_base +class class_ : public objects::class_base { typedef class_ self; BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable::value)); @@ -138,8 +139,28 @@ class class_ : private objects::class_base return *this; } + // + // Data member access + // + template + self& def_readonly(char const* name, D T::*pm) + { + ref fget(make_getter(pm)); + this->add_property(name, fget); + return *this; + } + + template + self& def_readwrite(char const* name, D T::*pm) + { + ref fget(make_getter(pm)); + ref fset(make_setter(pm)); + this->add_property(name, fget, fset); + return *this; + } + // return the underlying object - ref object() const; +// ref object() const; private: // types typedef objects::class_id class_id; @@ -202,14 +223,6 @@ inline class_::class_(char const* name) , this->object()); } -template -inline ref class_::object() const -{ - typedef objects::class_base base; - - return this->base::object(); -} - namespace detail { // This is an mpl BinaryMetaFunction object with a runtime behavior, diff --git a/include/boost/python/copy_mutable_reference.hpp b/include/boost/python/copy_mutable_reference.hpp new file mode 100644 index 00000000..f7594ccd --- /dev/null +++ b/include/boost/python/copy_mutable_reference.hpp @@ -0,0 +1,41 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef COPY_MUTABLE_REFERENCE_DWA2002131_HPP +# define COPY_MUTABLE_REFERENCE_DWA2002131_HPP +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + template + struct copy_mutable_reference_expects_a_reference_to_non_const_return_type +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} +# endif + ; +} + +template struct to_python_value; + +struct copy_mutable_reference +{ + template + struct apply + { + typedef typename mpl::select_type< + detail::is_reference_to_non_const::value + , to_python_value + , detail::copy_mutable_reference_expects_a_reference_to_non_const_return_type + >::type type; + }; +}; + +}} // namespace boost::python + +#endif // COPY_MUTABLE_REFERENCE_DWA2002131_HPP diff --git a/test/Jamfile b/test/Jamfile index 52253f2a..39514d5d 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -58,6 +58,7 @@ bpl-test callbacks ; bpl-test virtual_functions ; bpl-test back_reference ; bpl-test implicit ; +bpl-test data_members ; # --- unit tests of library components --- unit-test indirect_traits_test diff --git a/test/data_members.py b/test/data_members.py new file mode 100644 index 00000000..33de59d0 --- /dev/null +++ b/test/data_members.py @@ -0,0 +1,29 @@ +''' +>>> from data_members_ext import * +>>> x = X(42) +>>> x.x +42 +>>> try: x.x = 77 +>>> except AttributeError: pass +>>> else: print 'no error' + +>>> y = Y(69) +>>> y.x +69 +>>> y.x = 77 +>>> y.x +77 +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) diff --git a/test/test_class.hpp b/test/test_class.hpp index 414cd084..18164102 100644 --- a/test/test_class.hpp +++ b/test/test_class.hpp @@ -18,12 +18,13 @@ struct test_class int value() const { assert(magic == 7654321 + n); return x; } operator int() const { return x; } static int count() { return counter; } - private: - void operator=(test_class const&); - private: + int x; long magic; static int counter; + + private: + void operator=(test_class const&); }; template From bc552d326cb7b81dd6b75a847d23302ddf0fc7f6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 30 Mar 2002 01:29:31 +0000 Subject: [PATCH 0355/1042] initial checkin [SVN r13310] --- include/boost/python/data_members.hpp | 111 ++++++++++++++++++++++++++ test/data_members.cpp | 36 +++++++++ 2 files changed, 147 insertions(+) create mode 100644 include/boost/python/data_members.hpp create mode 100644 test/data_members.cpp diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp new file mode 100644 index 00000000..000560e3 --- /dev/null +++ b/include/boost/python/data_members.hpp @@ -0,0 +1,111 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef DATA_MEMBERS_DWA2002328_HPP +# define DATA_MEMBERS_DWA2002328_HPP + +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + template + struct member + { + static PyObject* get(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies) + { + from_python c0(PyTuple_GET_ITEM(args_, 0)); + if (!c0.convertible()) return 0; + + // find the result converter + typedef typename Policies::result_converter result_converter; + typedef typename boost::add_reference::type source; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + PyObject* result = cr( (c0(PyTuple_GET_ITEM(args_, 0)))->*pm ); + + return policies.postcall(args_, result); + } + + static PyObject* set(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies) + { + // check that each of the arguments is convertible + from_python c0(PyTuple_GET_ITEM(args_, 0)); + if (!c0.convertible()) return 0; + + typedef typename add_const::type target1; + typedef typename add_reference::type target; + from_python c1(PyTuple_GET_ITEM(args_, 1)); + + if (!c1.convertible()) return 0; + + if (!policies.precall(args_)) return 0; + + (c0(PyTuple_GET_ITEM(args_, 0)))->*pm = c1(PyTuple_GET_ITEM(args_, 1)); + + return policies.postcall(args_, detail::none()); + } + }; +} + +template +objects::function* make_getter(D C::*pm) +{ + typedef return_value_policy default_policy; + return new objects::function( + objects::py_function( + ::boost::bind( + &detail::member::get, pm, _1, _2 + , default_policy())) + , 1); +} + +template +objects::function* make_getter(D C::*pm, Policies const& policies) +{ + return new objects::function( + objects::py_function( + ::boost::bind( + &detail::member::get, pm, _1, _2 + , policies)) + , 1); +} + +template +objects::function* make_setter(D C::*pm) +{ + return new objects::function( + objects::py_function( + ::boost::bind( + &detail::member::set, pm, _1, _2 + , default_call_policies())) + , 1); +} + +template +objects::function* make_setter(D C::*pm, Policies const& policies) +{ + return new objects::function( + objects::py_function( + ::boost::bind( + &detail::member::set, pm, _1, _2 + , policies)) + , 1); +} + + +}} // namespace boost::python + +#endif // DATA_MEMBERS_DWA2002328_HPP diff --git a/test/data_members.cpp b/test/data_members.cpp new file mode 100644 index 00000000..4657fe6d --- /dev/null +++ b/test/data_members.cpp @@ -0,0 +1,36 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include "test_class.hpp" + +using namespace boost::python; + +typedef test_class<> X; + +typedef test_class<1> Y; + +BOOST_PYTHON_MODULE_INIT(data_members_ext) +{ + module("data_members_ext") + .add( + class_("X") + .def_init(args()) + .def("value", &X::value) + .def("set", &X::set) + .def_readonly("x", &X::x) + ) + .add( + class_("Y") + .def_init(args()) + .def("value", &Y::value) + .def("set", &Y::set) + .def_readwrite("x", &Y::x) + ) + ; +} + +#include "module_tail.cpp" From 900e035412cf00cc3e7ec56a711d0688c1fd50e6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 30 Mar 2002 01:43:26 +0000 Subject: [PATCH 0356/1042] data member support [SVN r13311] --- include/boost/python/object/class.hpp | 2 ++ src/object/class.cpp | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 468240c0..5ca8c41e 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -37,6 +37,8 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable // Retrieve the underlying object ref object() const { return m_object; } + void add_property(char const* name, ref const& fget); + void add_property(char const* name, ref const& fget, ref const& fset); private: ref m_object; }; diff --git a/src/object/class.cpp b/src/object/class.cpp index dc3a42af..648af6d0 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -250,4 +250,24 @@ class_base::class_base( r.set(types[0], m_object); } +extern "C" +{ + // This declaration needed due to broken Python 2.2 headers + extern DL_IMPORT(PyTypeObject) PyProperty_Type; +} + +void class_base::add_property(char const* name, ref const& fget) +{ + ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "sO", fget.get())); + if (PyObject_SetAttrString(object().get(), const_cast(name), property.get()) < 0) + throw error_already_set(); +} + +void class_base::add_property(char const* name, ref const& fget, ref const& fset) +{ + ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "sOO", fget.get(), fset.get())); + if (PyObject_SetAttrString(object().get(), const_cast(name), property.get()) < 0) + throw error_already_set(); +} + }}} // namespace boost::python::objects From 27d335ebe116d623517e7650f8f03f4930c76c87 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 30 Mar 2002 02:21:00 +0000 Subject: [PATCH 0357/1042] Fixes to last checkin [SVN r13312] --- include/boost/python/data_members.hpp | 4 ++-- src/object/class.cpp | 4 ++-- test/data_members.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp index 000560e3..fec774ae 100644 --- a/include/boost/python/data_members.hpp +++ b/include/boost/python/data_members.hpp @@ -91,7 +91,7 @@ objects::function* make_setter(D C::*pm) ::boost::bind( &detail::member::set, pm, _1, _2 , default_call_policies())) - , 1); + , 2); } template @@ -102,7 +102,7 @@ objects::function* make_setter(D C::*pm, Policies const& policies) ::boost::bind( &detail::member::set, pm, _1, _2 , policies)) - , 1); + , 2); } diff --git a/src/object/class.cpp b/src/object/class.cpp index 648af6d0..9341da7d 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -258,14 +258,14 @@ extern "C" void class_base::add_property(char const* name, ref const& fget) { - ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "sO", fget.get())); + ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.get())); if (PyObject_SetAttrString(object().get(), const_cast(name), property.get()) < 0) throw error_already_set(); } void class_base::add_property(char const* name, ref const& fget, ref const& fset) { - ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "sOO", fget.get(), fset.get())); + ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.get(), fset.get())); if (PyObject_SetAttrString(object().get(), const_cast(name), property.get()) < 0) throw error_already_set(); } diff --git a/test/data_members.py b/test/data_members.py index 33de59d0..598d1373 100644 --- a/test/data_members.py +++ b/test/data_members.py @@ -4,8 +4,8 @@ >>> x.x 42 >>> try: x.x = 77 ->>> except AttributeError: pass ->>> else: print 'no error' +... except AttributeError: pass +... else: print 'no error' >>> y = Y(69) >>> y.x From 68dbb130846e75487be49bd9430d2449269420b1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 30 Mar 2002 13:47:36 +0000 Subject: [PATCH 0358/1042] initial checkin [SVN r13316] --- doc/v2/callbacks.txt | 88 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 doc/v2/callbacks.txt diff --git a/doc/v2/callbacks.txt b/doc/v2/callbacks.txt new file mode 100644 index 00000000..a58ca0ea --- /dev/null +++ b/doc/v2/callbacks.txt @@ -0,0 +1,88 @@ +Here's the plan: + +I aim to provide an interface similar to that of Boost.Python v1's +callback<>::call(...) for dealing with callbacks. The interface will +look like: + + returning::call("method_name", self_object, a1, a2...); + +or + + returning::call(callable_object, a1, a2...); + +ARGUMENT HANDLING + +There is an issue concerning how to make Python objects from the +arguments a1...aN. A new Python object must be created; should the C++ +object be copied into that Python object, or should the Python object +simply hold a reference/pointer to the C++ object? In general, the +latter approach is unsafe, since the called function may store a +reference to the Python object somewhere. If the Python object is used +after the C++ object is destroyed, we'll crash Python. + +I plan to make the copying behavior the default, and to allow a +non-copying behavior if the user writes boost::ref(a1) instead of a1 +directly. At least this way, the user doesn't get dangerous behavior "by +accident". It's also worth noting that the non-copying ("by-reference") +behavior is in general only available for class types, and will fail at +runtime with a Python exception if used otherwise** + +However, pointer types present a problem: My first thought is to refuse +to compile if any aN has pointer type: after all, a user can always pass +*aN to pass "by-value" or ref(*aN) to indicate a pass-by-reference +behavior. However, this creates a problem for the expected NULL pointer +=> None conversion: it's illegal to dereference a null pointer value. + +We could use another construct, say "ptr(aN)", to deal with null +pointers, but then what does it mean? We know what it does when aN is +NULL, but it might either have by-value or by-reference behavior when aN +is non-null. + +The compromise I've settled on is this: + +1. The default behavior is pass-by-value. If you pass a non-null + pointer, the pointee is copied into a new Python object; otherwise + the corresponding Python argument will be None. + +2. if you want by-reference behavior, use ptr(aN) if aN is a pointer + and ref(aN) otherwise. If a null pointer is passed to ptr(aN), the + corresponding Python argument will be None. + +RESULT HANDLING + +As for results, we have a similar problem: if ResultType is allowed to +be a pointer or reference type, the lifetime of the object it refers to +is probably being managed by a Python object. When that Python object is +destroyed, our pointer dangles. The problem is particularly bad when the +ResultType is char const* - the corresponding Python String object is +typically uniquely-referenced, meaning that the pointer dangles as soon +as returning::call() returns. + +Boost.Python v1 deals with this issue by refusing to compile any uses of +callback::call(), but IMO this goes both too far and not +far enough. It goes too far because there are cases where the owning +String object survives beyond the call (just for instance when it's the +name of a Python class), and it goes not far enough because we might +just as well have the same problem with any returned pointer or +reference. + +I propose to address this in Boost.Python v2 by + + 1. lifting the compile-time restriction on const + char* callback returns + + 2. detecting the case when the reference count on the + result Python object is 1 and throwing an exception + inside of returning::call() when U is a pointer or + reference type. + +I think this is acceptably safe because users have to explicitly specify +a pointer/reference for U in returning, and they will be protected +against dangles at runtime, at least long enough to get out of the +returning::call() invocation. + +-Dave + +**It would be possible to make it fail at compile-time for non-class +types such as int and char, but I'm not sure it's a good idea to impose +this restriction yet. From 7d7eac50303aa2da26ef061922713f0fb77c24bd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 1 Apr 2002 21:47:16 +0000 Subject: [PATCH 0359/1042] Don't build any Python stuff if no Python installation found [SVN r13342] --- build/Jamfile | 8 ++++++++ build/__init__.py | 14 ++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 build/__init__.py diff --git a/build/Jamfile b/build/Jamfile index c9f6fa75..94348c4a 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -61,6 +61,13 @@ subproject libs/python/build ; SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; +# This nasty hack works with versions of Python 1.5.2 -> 2.2 to avoid +# building any Python stuff if there's no installation. +SEARCH on __init__.py = $(PYTHON_LIB_PATH)/test $(SUBDIR) ; +include __init__.py ; +if ! $(gNO_PYTHON_INSTALL) +{ + local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_DYNAMIC_LIB ; ####################### @@ -154,3 +161,4 @@ boost-python-multi-example-runtest ivect2 : ivect dvect ; boost-python-multi-example-runtest noncopyable : noncopyable_import noncopyable_export ; +} \ No newline at end of file diff --git a/build/__init__.py b/build/__init__.py new file mode 100644 index 00000000..94f3b100 --- /dev/null +++ b/build/__init__.py @@ -0,0 +1,14 @@ +# Dummy file actually to be included by Jam when the python headers +# can't be found + +if ! $(gNO_PYTHON_INSTALL) +{ + ECHO Couldn't find Python $(PYTHON_VERSION) installation in $(PYTHON_ROOT) ; + ECHO skipping Boost.Python library build ; + ECHO You can configure the location of your python installation, by setting: ; + ECHO PYTHON_ROOT - currently \"$(PYTHON_ROOT)\" ; + ECHO PYTHON_VERSION - currently \"$(PYTHON_VERSION)\" ; + ECHO PYTHON_INCLUDES - configured from PYTHON_ROOT, currently \"$(PYTHON_INCLUDES)\" ; + ECHO PYTHON_LIB_PATH - configured from PYTHON_ROOT, currently \"$(PYTHON_LIB_PATH)\" ; +} +gNO_PYTHON_INSTALL ?= true ; From ed184acb4016a82e33a115b347e19182ac3721f6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 2 Apr 2002 05:48:46 +0000 Subject: [PATCH 0360/1042] initial checkin [SVN r13344] --- doc/v2/Mar2002.html | 234 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 doc/v2/Mar2002.html diff --git a/doc/v2/Mar2002.html b/doc/v2/Mar2002.html new file mode 100644 index 00000000..e8898edb --- /dev/null +++ b/doc/v2/Mar2002.html @@ -0,0 +1,234 @@ + + + + +Boost.Python - March 2002 Progress Report + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    March 2002 Progress Report

    +
    +
    +

    Contents

    +
    +
    Accomplishments
    +
    +
    Calling Python from C++
    +
    Virtual Functions
    +
    Abstract Classes
    +
    C++ Implicit Conversions
    +
    C++ Data Members
    +
    Miscellaneous
    +
    + +
    The Near future
    + +
    Notes
    + +
    + +

    Accomplishments

    + +March was mostly devoted to the reimplementation of features from +Boost.Python v1, and some new features. Re-examination of the features +from Boost.Python v1 allowed me to make significant improvements. + +

    Calling Python from C++

    + +The ability to call Python from C++ is crucial for virtual function +support. Implementing this feature well for V2 proved to be more +interesting than I expected. You can review most of the relevant +design decisions +here. + +

    +One point which isn't emphasized in that document is that there +are subtle differences in the way from_python conversions +work when used for C++ function arguments and Python function return +values. In particular, while T const& arguments may +invoke rvalue converters, a reference-to-const return value requires +an lvalue converter, since a temporary conversion result would leave +the returned reference dangling. + +

    I'm not particularly pleased with the current callback interface, +since it usually results in constructs like: +

    +return returning<X&>::call(f, obj);
    +
    +However, I think the following may be possible and I plan to investigate: +
    +return apply<X&>(f, obj);
    +
    +I'm open to suggestion for better names (and syntaxes)! + +

    Virtual Functions

    + +Once Python callbacks were implemented, it was just a short step to +implementing virtual functions. Python extension class exposing a C++ +class whose virtual functions are overridable in Python must actually +hold a C++ instance of a class derived from the one exposed to +Python. Needing some way for users to specify that class, I added an +optional template argument to value_holder_generator and +pointer_holder_generator<> to specify the class +actually held. This move began to put pressure on the +class_<> interface, since the need for the user to +produce complicated instantations of +class_<> was increased: + +
    +class<Foo, bases<>, value_holder_generator<Foo_callback> >("Foo")
    +.def("hello", &Foo::hello)
    +...
    +
    + +

    Abstract Classes

    + +Normally when a C++ class is exposed to Python, the library registers +a conversion function which allows users to wrap functions returning +values of that type. Naturally, these return values are temporaries, +so the conversion function must make a copy in some +dynamically-allocated storage (a "holder") which is managed +by the corresponding Python object. + +

    Unfortunately, in the case of abstract classes (and other types +without a publicly-accessible copy constructor), instantiating this +conversion function causes a compilation error. In order to support +non-copyable classes, there had to be some way to prevent the library +from trying to instantiate the conversion function. The only practical +approach I could think of was to add an additional template parameter +to the class_<> interface. When the number of +template parameters with useful defaults begins to grow, it is often +hard to choose an order which allows users to take advantage of the +defaults. + +

    + +This was the straw that broke the +class_<> interface's back and caused the redesign +whose outcome is detailed here. +The approach allows the user to supply the optional parameters in an +arbitrary order. It was inspired by the use of named +template parameters in the Boost Iterator Adaptor +Library, though in this case it is possible to deduce the meaning +of the template parameters entirely from their type properties, +resulting in a simpler interface. Although the move from a +policy-based design to what resembles a configuration DSL usually +implies a loss of flexibility, in this case I think any costs are far +outweighed by the advantages. + +

    Note: working around the limitations of the various compilers I'm +supporting was non-trivial, and resulted in a few messy implementation +details. It might be a good idea to switch to a more-straightforward +approach once Metrowerks CodeWarrior Pro8 is released. + +

    C++ Implicit Conversions

    + +Support for C++ implicit conversion involves creating +from_python converters for a type U which in +turn use from_python converters registered for a type +T where there exists a implicit conversion from +T to U. The current implementation is +subject to two inefficiencies: +
      + +
    1. Because an rvalue from_python converter produces two +pieces of data (a function and a void*) from its +convertible() function, we end up calling the function +for T twice: once when the converter is looked up in the +registry, and again when the conversion is actually performed. + +
    2. A vector is used to mark the "visited" converters, preventing +infinite recursion as T to +U and U to T converters +continually search through one-another. + +
    + +I consider the former to be a minor issue. The second may or may not +prove to be computationally significant, but I believe that +architecturally, it points toward a need for more sophisticated +overload resolution. It may be that we want CLOS-style multimethod +dispatching along with C++ style rules that prevent more than one +implicit conversion per argument. + +

    C++ Data Members

    + +To supply the ability to directly access data members, I was able to +hijack the new Python property +type. I had hoped that I would also be able to re-use the work of make_function to create callable python +objects from C++ functions which access a data member of a given +class. C++ facilities for specifying data member pointer non-type +template arguments require the user to explicitly specify the type of +the data member and this under-utilized feature is also not +well-implemented on all compilers, so passing the member pointer as a +runtime value is the only practical approach. The upshot is that any +such entity would actually have to be a function object, and I +haven't implemented automatic wrapping of C++ callable function +objects yet, so there is less re-use in the implementation than I'd +like. I hope to implement callable object wrapping and refactor this +code one day. I also hope to implement static data member support, +for which Python's property will not be an appropriate descriptor. + +

    Miscellaneous

    +
      +
    • Moved args<> and bases<> from unnamed namespace to boost::python in their own header files. +
    • Convert NULL pointers returned from wrapped C++ functions to None. +
    • Improved some compile-time error checks. +
    • Eliminated boost/python/detail/eval.hpp in favor of +more-general boost/mpl/apply.hpp. +
    • General code cleanup and refactoring. +
    • Works with Microsoft Visual C++ 7.0 +
    • Warning suppression for many compilers +
    • Elegant interface design for exporting enum types. +
    +
    + +

    The Near Future

    + +Before April 15th I plan to +
      +
    1. Document all implemented features +
    2. Implement a CallPolicy interface for constructors of wrapped +classes +
    3. Implement conversions for char types. +
    4. Implement automated code generation for all headers containing +families of overloaded functions to handle arbitrary arity. +
    + +I also hope to implement a mechanism for generating conversions +between arbitrary Python sequences and C++ containers, if time permits +(and others haven't already done it)! + +

    Notes

    + +The older version of KCC used by Kull is generating lots of warnings +about a construct I use to instantiate static members of various class +templates. I'm thinking of moving to an idiom which uses a function +template to suppress it, but worry about bloating the size of debug +builds. Since KCC users may be moving to GCC, I'm not sure that it's +worth doing anything about it. + +

    Revised + + 1 April, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + From 0b965d1ee40c8823713176dbc027716ee7535465 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 2 Apr 2002 07:52:07 +0000 Subject: [PATCH 0361/1042] fixed link [SVN r13345] --- doc/v2/Mar2002.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/v2/Mar2002.html b/doc/v2/Mar2002.html index e8898edb..5b7a3a58 100644 --- a/doc/v2/Mar2002.html +++ b/doc/v2/Mar2002.html @@ -48,8 +48,7 @@ The ability to call Python from C++ is crucial for virtual function support. Implementing this feature well for V2 proved to be more interesting than I expected. You can review most of the relevant design decisions -here. +here.

    One point which isn't emphasized in that document is that there From 6835c344eb191a77fdb7a83fbd24e754072d5cce Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 2 Apr 2002 21:08:55 +0000 Subject: [PATCH 0362/1042] Simplified fix [SVN r13347] --- include/boost/python/detail/wrap_function.hpp | 35 ++++--------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/include/boost/python/detail/wrap_function.hpp b/include/boost/python/detail/wrap_function.hpp index 682b3e89..0dcccd70 100644 --- a/include/boost/python/detail/wrap_function.hpp +++ b/include/boost/python/detail/wrap_function.hpp @@ -9,6 +9,8 @@ # include # include # include +# include +# include # include namespace boost { namespace python { namespace detail { @@ -21,39 +23,16 @@ namespace boost { namespace python { namespace detail { // function pointer or function type, should produce a callable Python // object. -template -struct wrap_function_select -{ - template - static objects::function* execute(F f) - { - return make_function(f); - } -}; +template +inline PyObject* wrap_function_aux(F f, PyObject*) { return f; } -template<> -struct wrap_function_select -{ - template - static F execute(F f) - { - return f; - } -}; +template +inline PyObject* wrap_function_aux(F f, ...) { return make_function(f); } template PyObject* wrap_function(F f) { - return wrap_function_select< -# if 1 - type_traits::ice_not< - is_pointer::value -# else - type_traits::ice_or< - is_function::value - , is_member_function_pointer::value -# endif - >::value >::execute(f); + return wrap_function_aux(f, f); } }}} // namespace boost::python::detail From aed7e14d4bc0ba4d722f41c98e8fe5d227e774ab Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 2 Apr 2002 21:11:57 +0000 Subject: [PATCH 0363/1042] Add test for regular functions added as member functions [SVN r13348] --- test/m1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/m1.cpp b/test/m1.cpp index cbaaf8db..61c2848b 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -172,7 +172,7 @@ struct A struct B : A { B() : x(1) {} - char const* name() { return "B"; } + static char const* name(B*) { return "B"; } int x; }; From 81124780d0d2a6d7bf7e24cbdc5395c240e659db Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 2 Apr 2002 22:19:22 +0000 Subject: [PATCH 0364/1042] Support for constructor policies [SVN r13350] --- include/boost/python/class.hpp | 13 +++ .../boost/python/detail/indirect_traits.hpp | 82 +++++++++++++++++++ include/boost/python/make_function.hpp | 14 ++++ test/indirect_traits_test.cpp | 8 ++ test/test_pointer_adoption.cpp | 2 + test/test_pointer_adoption.py | 22 +++++ 6 files changed, 141 insertions(+) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index ad1561ba..8e921780 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -132,6 +132,19 @@ class class_ : public objects::class_base return *this; } + template + self& def_init(Args const&, CallPolicy policy) + { + def("__init__", + make_constructor( + policy + // Using runtime type selection works around a CWPro7 bug. + , objects::select_holder((held_type*)0).get() + ) + ); + return *this; + } + // Define the default constructor. self& def_init() { diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index f925eaee..a3e67dd3 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -7,6 +7,7 @@ # define INDIRECT_TRAITS_DWA2002131_HPP # include # include +# include # include namespace boost { namespace python { namespace detail { @@ -24,6 +25,68 @@ struct is_reference_to_const BOOST_STATIC_CONSTANT(bool, value = true); }; +# if 0 // Corresponding code doesn't work on MSVC yet +template +struct is_reference_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_reference_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_reference_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_reference_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_reference_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; +# endif + +template +struct is_pointer_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_pointer_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_pointer_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_pointer_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + +template +struct is_pointer_to_function +{ + BOOST_STATIC_CONSTANT(bool, value = is_function::value); +}; + template struct is_reference_to_non_const { @@ -114,6 +177,25 @@ struct is_pointer_help >::type type; }; +# if 0 // doesn't seem to work yet +template +struct is_reference_to_function +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(::boost::detail::is_function_tester(t)) == sizeof(::boost::type_traits::yes_type)); +# endif + +template +struct is_pointer_to_function +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(::boost::detail::is_function_tester(t)) == sizeof(::boost::type_traits::yes_type)); +}; + template typename is_const_help::type reference_to_const_helper(V&); outer_no_type diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index 6e7f1661..5ce5ec7d 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -49,6 +49,20 @@ objects::function* make_constructor(Holder* = 0, ArgList* = 0) , nargs + 1); } +template +objects::function* make_constructor(Policies const& policies, Holder* = 0, ArgList* = 0) +{ + enum { nargs = mpl::size::value }; + + return new objects::function( + objects::py_function( + ::boost::bind(detail::caller(), + objects::make_holder + ::template apply::execute + , _1, _2, policies)) + , nargs + 1); +} + }} // namespace boost::python #endif // MAKE_FUNCTION_DWA20011221_HPP diff --git a/test/indirect_traits_test.cpp b/test/indirect_traits_test.cpp index a15e7f85..338e4d6a 100644 --- a/test/indirect_traits_test.cpp +++ b/test/indirect_traits_test.cpp @@ -8,6 +8,14 @@ int main() { using namespace boost::python::detail; +#if 0 // not yet supported + assert(is_reference_to_function::value); + assert(!is_reference_to_function::value); +#endif + + assert(!is_pointer_to_function::value); + assert(is_pointer_to_function::value); + assert(is_reference_to_pointer::value); assert(is_reference_to_pointer::value); assert(is_reference_to_pointer::value); diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index 87b3eaab..33cd4dc2 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -60,6 +60,7 @@ struct A struct B { B() : x(0) {} + B(A* x_) : x(x_) {} inner const* adopt(A* x) { this->x = x; return &x->get_inner(); } @@ -101,6 +102,7 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) .add( class_("B") .def_init() + .def_init(args(), with_custodian_and_ward_postcall<1,2>()) .def("adopt", &B::adopt // Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self") diff --git a/test/test_pointer_adoption.py b/test/test_pointer_adoption.py index 075a640b..d28dea5c 100644 --- a/test/test_pointer_adoption.py +++ b/test/test_pointer_adoption.py @@ -48,6 +48,28 @@ >>> del b >>> num_a_instances() 0 + +Test call policies for constructors here + +>>> a = create('second a') +>>> num_a_instances() +1 +>>> b = B(a) +>>> num_a_instances() +1 +>>> a.content() +'second a' + +>>> del a +>>> num_a_instances() +1 +>>> b.a_content() +'second a' + +>>> del b +>>> num_a_instances() +0 + """ def run(args = None): import sys From 17eb4a266011e2c55a6d150b740ae7abdb9521e3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 3 Apr 2002 17:33:34 +0000 Subject: [PATCH 0365/1042] Bug fix thanks to "Peter Bienstman" for finding it. [SVN r13361] --- include/boost/python/detail/member_function_cast.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp index 6e3f18c4..5ac2caa3 100644 --- a/include/boost/python/detail/member_function_cast.hpp +++ b/include/boost/python/detail/member_function_cast.hpp @@ -65,13 +65,13 @@ struct member_function_cast_impl template static cast_helper stage1(R (S::*)(A0,A1)) { - return cast_helper(); + return cast_helper(); } template static cast_helper stage1(R (S::*)(A0,A1,A2)) { - return cast_helper(); + return cast_helper(); } template @@ -86,6 +86,7 @@ struct member_function_cast_impl return cast_helper(); } + template static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4,A5)) { From 5a6bc4404a9d813cfbd830a1e637940a59c827f6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 4 Apr 2002 15:53:12 +0000 Subject: [PATCH 0366/1042] Peter Bienstman's regression tests and associated fixes. [SVN r13366] --- .../python/converter/from_python_data.hpp | 78 +------------------ test/Jamfile | 2 + test/bienstman1.cpp | 41 ++++++++++ test/bienstman1.py | 15 ++++ test/bienstman2.cpp | 29 +++++++ test/bienstman2.py | 15 ++++ 6 files changed, 103 insertions(+), 77 deletions(-) create mode 100644 test/bienstman1.cpp create mode 100644 test/bienstman1.py create mode 100644 test/bienstman2.cpp create mode 100644 test/bienstman2.py diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp index ec57f479..b0d8a49f 100644 --- a/include/boost/python/converter/from_python_data.hpp +++ b/include/boost/python/converter/from_python_data.hpp @@ -9,7 +9,6 @@ # include # include # include -# include # include # include # include @@ -24,18 +23,10 @@ namespace boost { namespace python { namespace converter { namespace detail { - template struct referent_alignment; template struct referent_size; # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct referent_alignment - { - BOOST_STATIC_CONSTANT( - std::size_t, value = alignment_of::value); - }; - template struct referent_size { @@ -45,26 +36,6 @@ namespace detail # else - template - struct alignment_chars - { - BOOST_STATIC_CONSTANT( - std::size_T, n = alignment_of::value); - char elements[n + 1]; - }; - - template struct referent_alignment - { - template - static alignment_chars helper(U&); - - static T t; - - BOOST_STATIC_CONSTANT( - std::size_t, value = sizeof(helper(t).elements) - 1); - }; - - template struct referent_size { static T f(); @@ -82,24 +53,12 @@ namespace detail char, short, int, long, float, double, long double \ , void*, function_ptr, member_ptr, member_function_ptr)) -# define BOOST_PYTHON_CHOOSE_LOWER_ALIGNMENT(R,P,I,T) \ - typename mpl::select_type< \ - alignment_of::value <= target, T, char>::type BOOST_PP_CAT(t,I); - # define BOOST_PYTHON_CHOOSE_LOWER_SIZE(R,P,I,T) \ typename mpl::select_type< \ sizeof(T) <= target, T, char>::type BOOST_PP_CAT(t,I); # define BOOST_PYTHON_CHOOSE_T(R,P,I,T) T BOOST_PP_CAT(t,I); - template - union lower_alignment - { - BOOST_PP_LIST_FOR_EACH_I( - BOOST_PYTHON_CHOOSE_LOWER_ALIGNMENT - , ignored, BOOST_PYTHON_ALIGNMENT_TYPES) - }; - template union lower_size { @@ -108,13 +67,6 @@ namespace detail , ignored, BOOST_PYTHON_ALIGNMENT_TYPES) }; - union max_align - { - BOOST_PP_LIST_FOR_EACH_I( - BOOST_PYTHON_CHOOSE_T - , ignored, BOOST_PYTHON_ALIGNMENT_TYPES) - }; - template union aligned_storage { @@ -125,35 +77,7 @@ namespace detail template struct referent_storage { - BOOST_STATIC_CONSTANT(std::size_t, target = referent_alignment::value); - typedef lower_alignment t1; - - BOOST_STATIC_CONSTANT(bool, t1_aligned = - (alignment_of::value >= target) - & (alignment_of::value % target == 0)); - - typedef lower_size::value> t2; - - BOOST_STATIC_CONSTANT(bool, t2_aligned = - (alignment_of::value >= target) - & (alignment_of::value % target == 0)); - - - typedef typename mpl::select_type< - t1_aligned - , t1 - , typename mpl::select_type< - t2_aligned - , t2 - , max_align - >::type - >::type align_t; - - BOOST_STATIC_CONSTANT(std::size_t, found = alignment_of::value); - - BOOST_STATIC_ASSERT(found >= target); - BOOST_STATIC_ASSERT(found % target == 0); - + typedef lower_size::value> align_t; typedef aligned_storage::value> type; }; } diff --git a/test/Jamfile b/test/Jamfile index 39514d5d..a9cd3fa0 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -51,6 +51,8 @@ rule bpl-test ( name ? : files * ) boost-python-runtest $(name) : $(py) $(modules) ; } +bpl-test bienstman1 ; +bpl-test bienstman2 ; bpl-test try : newtest.py m1.cpp m2.cpp ; bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ; bpl-test test_pointer_adoption ; diff --git a/test/bienstman1.cpp b/test/bienstman1.cpp new file mode 100644 index 00000000..ab184b22 --- /dev/null +++ b/test/bienstman1.cpp @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +struct A {}; + +struct V +{ + + virtual void f() = 0; + + const A* inside() {return &a;} + + A a; +}; + +const A* outside(const V& v) {return &v.a;} + +BOOST_PYTHON_MODULE_INIT(bienstman1_ext) +{ + using namespace boost::python; + using boost::shared_ptr; + using boost::python::return_value_policy; + using boost::python::reference_existing_object; + + module m("bienstman1_ext"); + + m + .add(class_ >("A")) + + .add( + class_("V") + .def("inside", &V::inside, + return_value_policy()) + .def("outside", outside, + return_value_policy()) + ) + ; +} + diff --git a/test/bienstman1.py b/test/bienstman1.py new file mode 100644 index 00000000..5d75388c --- /dev/null +++ b/test/bienstman1.py @@ -0,0 +1,15 @@ +''' +>>> import bienstman1_ext +''' +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) diff --git a/test/bienstman2.cpp b/test/bienstman2.cpp new file mode 100644 index 00000000..ecb2158b --- /dev/null +++ b/test/bienstman2.cpp @@ -0,0 +1,29 @@ +#include +#include + +struct C {}; + +struct D {}; + +struct E +{ + const D fe (const C&) {return D();} + const D fe2(const C&, const C&) {return D();} +}; + +BOOST_PYTHON_MODULE_INIT(m) +{ + using namespace boost::python; + + module m("m"); + + m + .add(class_("C")) + .add(class_("D")) + .add( + class_("E") + .def("fe", &E::fe) // this compiles. + .def("fe2", &E::fe2) // this doesn't. + ) + ; +} diff --git a/test/bienstman2.py b/test/bienstman2.py new file mode 100644 index 00000000..364f5504 --- /dev/null +++ b/test/bienstman2.py @@ -0,0 +1,15 @@ +''' +>>> import bienstman1_ext.py +''' +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 8de3571aa835743548b57bf7ef397dac283cdcc5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 4 Apr 2002 17:27:24 +0000 Subject: [PATCH 0367/1042] initial checkin [SVN r13368] --- doc/v2/feb2002.html | 367 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 doc/v2/feb2002.html diff --git a/doc/v2/feb2002.html b/doc/v2/feb2002.html new file mode 100644 index 00000000..423244ba --- /dev/null +++ b/doc/v2/feb2002.html @@ -0,0 +1,367 @@ + + + + + Boost.Python - February 2002 Progress Report + + + + +
    +

    C++ Boost

    + +
    +

    Boost.Python

    + +

    February 2002 Progress Report

    +
    +


    + +

    Contents

    + +
    +
    Python10 Conference Report + +
    Boost.Python v2 Progress + +
    +
    +
    Documentation + +
    Overhaul of + to_python/from_python + conversion mechanism + +
    Miscellaneous +
    +
    + +

    Python10 Conference Report

    + I spent the first week of February at the Python10 conference + in Alexandria, VA. I'm including this experience report + for two reasons: firstly, it documents where my time was + used. Secondly, a public presence for Boost.Python and + interaction between the Python and C++ communities is + important to the future of Boost.Python, which in turn is + important to the Kull Project. + +

    Andy Koenig, of all people, was the keynote speaker of + this year's opening plenary session. He presented his + "impressions of a polyglot outsider", which + studiously avoided any mention of C++ until the end of his + talk, when he was asked about standardization. I was + surprised to learn that the C++ community at large wanted a + few more years before beginning but when ANSI accepted + HP's request for a standard, the process was forced to + start: it was a matter of participating or having + standardization proceed without one's input. Andy managed + to highlight very effectively the balance of strengths in + Python, one of the most important being its support for + extension via libraries. In many ways that makes Python a + good analogue for C++ in the interpreted world + +

    There were several kind mentions of the Boost.Python + library from people who found it indispensable. I was + particularly happy that Karl MacMillan, Michael Droettboom, + and Ichiro Fujinaga from Johns Hopkins is using it to do OCR + on a vast library of music notation, since in a previous life + I was an author of music notation software. These guys are + also drawing on Ullrich Koethe's VIGRA library for image + manipulation (Ullrich has been a major contributor to + Boost.Python). They also have a system for writing the + Boost.Python wrapper code in C++ comments, which allows them + to keep all of the code in one place. I've asked them to + send me some information on that. + +

    The development of Swig has been gaining momentum again + (the basic description at + www.boost.org/libs/python/doc/comparisons.html still + applies). The talk given about it by David Beazly was very + well-attended, and they appear to have quite a few users. + Swig's strengths (coverage of many langauages) and + weaknesses (incomplete C++ language support) haven't + changed, although the C++ support seems to have improved + considerably - they now claim to have a complete model of the + C++ type system. It seems to be mostly geared at wrapping + what Walter Landry calls "C-Tran": C++ code which + traffics in built-in types with little use of abstraction. + I'm not knocking that, either: I'm sure a lot of that + code exists, so it's a valuable service. One feature Swig + has which I'd like to steal is the ability to unwrap a + single Python argument into multiple C++ arguments, for + example, by converting a Python string into a pointer and + length. When his talk was over, David approached me about a + possible joint workshop on language binding, which sounds + like a fun idea to me. + +

    I spent some considerable time talking with Steven Knight, + the leader of the Scons build tool effort. We had a lot to + share with one another, and I gained a much better + appreciation for many of the Scons design decisions. Scons + seems to be concentrating on being the ultimate build system + substrate, and Steve seemed to think that we were on the + right track with our high-level design. We both hope that the + Boost.Build V2 high-level architecture can eventually be + ported to run on top of Scons. + +

    They also have a highly-refined and successful development + procedure which I'd like to emulate for Boost.Build V2. + Among many other things they do, their source-control system + automatically ensures that when you check in a new test, it + is automatically run on the currently checked-in state of the + code, and is expected to fail -- a relatively obvious good + idea which I've never heard before. + +

    Guido Van Rossum's "State of the Python + Union" address was full of questions for the community + about what should be done next, but the one idea Guido seemed + to stress was that core language stability and continuing + library development would be a good idea (sound familiar?) I + mentioned the Boost model as a counterpoint to the idea of + something like CPAN (the massive Perl library archives), and + it seemed to generate some significant interest. I've + offered to work with anyone from the Python community who + wants to set up something like Boost. + +

    There was some discussion of "string + interpolation" (variable substitution in strings), and + Guido mentioned that he had some thoughts about the + strengths/weaknesses of Python's formatting interface. It + might be useful for those working on formatting for boost to + contact him and find out what he has to say. + +

    Ka-Ping Yee demoed a Mailman discussion thread weaver. + This tool weaves the various messages in a discussion thread + into a single document so you can follow the entire + conversation. Since we're looking very seriously at + moving Boost to Mailman, this could be a really useful thing + for us to have. If we do this, we'll move the yahoogroups + discussions into the mailman archive so old discussions can + be easily accessed in the same fashion. + +

    And, just because it's cool, though perhaps not + relevant: http://homepages.ulb.ac.be/~arigo/psyco/ is a + promising effort to accelerate the execution of Python code + to speeds approaching those of compiled languages. It + reminded me a lot of Todd Veldhuizen's research into + moving parts of C++ template compilation to runtime, only + coming from the opposite end of things. + +

    Boost.Python v2 Progress

    + Here's what actually got accomplished. + +

    Documentation

    + +

    My first priority upon returning from Python10 was to get + some documentation in place. After wasting an unfortunate + amount of time looking at automatic documentation tools which + don't quite work, I settled down to use Bill Kempf's + HTML templates designed to be a boost standard. While they + are working well, it is highly labor-intensive. + +

    I decided to begin with the high-level reference material, + as opposed to tutorial, narrative, or nitty-gritty details of + the framework. It seemed more important to have a precise + description of the way the commonly-used components work than + to have examples in HTML (since we already have some test + modules), and since the low-level details are much + less-frequently needed by users it made sense for me to + simply respond to support requests for the time being. + +

    After completing approximately 60% of the high-level docs + (currently checked in to libs/python/doc/v2), I found myself + ready to start documenting the mechanisms for creating + to-/from-python converters. This caused a dilemma: I had + realized during the previous week that a much simpler, + more-efficient, and easier-to-use implementation was + possible, but I hadn't planned on implementing it right + away, since what was already in place worked adequately. I + had also received my first query on the C++-sig about how to + write such a converter + +

    Given the labor-intensive nature of documentation writing, + I decided it would be a bad idea to document the conversion + mechanism if I was just going to rewrite it. Often the best + impetus for simplifying a design is the realization that + understandably documenting its current state would be too + difficult, and this was no exception. + +

    Overhaul of + to_python/from_python conversion + mechanism

    + +

    There were two basic realizations involved here: + +

      +
    1. to_python conversion could be a one-step + process, once an appropriate conversion function is found. + This allows elimination of the separate indirect + convertibility check + +
    2. There are basically two categories of from_python + conversions: those which lvalues stored within or held by + the Python object (essentially extractions), like what + happens when an instance of a C++ class exposed with class_ + is used as the target of a wrapped member function), and + those in which a new rvalue gets created, as when a Python + Float is converted to a C++ + complex<double> or a Python tuple is + converted to a C++ std::vector<>. From + the client side, there are two corresponding categories of + conversion: those which demand an lvalue conversion and + those which can accept an lvalue or an rvalue conversion. +
    + The latter realization allowed the following collapse, which + considerably simplified things: + +
    + + + + + + + + + + + + + + + + + +
    Target Type + + Eligible Converters + +
    T + + T rvalue or lvalue + +
    T const + +
    T volatile + +
    T const volatile + +
    T const& + +
    T const* + + T lvalue + +
    T volatile* + +
    T const volatile* + +
    T& + +
    T volatile& + +
    T const volatile& + +
    T* const& + +
    T const* const& + +
    T volatile*const& + +
    T const volatile*const& +
    +
    + This job included the following additional enhancements: + +
      +
    • Elimination of virtual functions, which cause object + code bloat + +
    • Registration of a single converter function for all + lvalue conversions, two for all rvalue conversions + +
    • Killed lots of unneeded code + +
    • Increased opacity of registry interface + +
    • Eliminated all need for decorated runtime type + identifiers + +
    • Updated test modules to reflect new interface + +
    • Eliminated the need for users to worry about converter + lifetime issues Additional Builtin Conversion Enhancements + +
    • Support for complex<float>, + complex<double>, and complex<long double> + conversions + +
    • Support for bool conversions + +
    • NULL pointers representable by None in Python + +
    • Support for conversion of Python classic classes to + numeric types +
    + +

    Miscellaneous

    + These don't fit easily under a large heading: + +
      +
    • Support CallPolicies for class member functions + +
    • from_python_data.hpp: revamped type alignment + metaprogram so that it's fast enough for KCC + +
    • classfwd.hpp header forward-declares class_<T> + +
    • indirect_traits.hpp: + +
    • added is_pointer_to_reference + +
    • fixed bugs + +
    • Reduced recompilation dependencies + +
    • msvc_typeinfo works around broken MS/Intel typeid() + implementation + +
    • Many fixes and improvements to the type_traits library + in order to work around compiler bugs and suppress warnings + +
    • Eliminated the need for explicit acquisition of + converter registrations + +
    • Expanded constructor support to 6 arguments + +
    • Implemented generalized pointer lifetime support + +
    • Updated code generation for returning.hpp + +
    • Tracked down and fixed cycle GC bugs + +
    • Added comprehensive unit tests for destroy_reference, + pointer_type_id, select_from_python, complex<T>, + bool, and classic class instance conversions +
    + +

    Revised + + 4 April, 2002 + + + +

    © Copyright Dave Abrahams + 2002. All Rights Reserved. + From b601ba55d030d0016ea0c8269566c38b1c7dbb2a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 4 Apr 2002 21:18:00 +0000 Subject: [PATCH 0368/1042] Yet another bug reported by Peter Bienstman is now fixed. [SVN r13370] --- include/boost/python/object/forward.hpp | 93 +++++++- .../boost/python/object/pointer_holder.hpp | 222 +++++++++--------- include/boost/python/object/value_holder.hpp | 222 +++++++++--------- test/Jamfile | 1 + test/bienstman1.py | 3 +- test/bienstman2.py | 2 +- test/bienstman3.cpp | 33 +++ test/bienstman3.py | 15 ++ 8 files changed, 356 insertions(+), 235 deletions(-) create mode 100644 test/bienstman3.cpp create mode 100644 test/bienstman3.py diff --git a/include/boost/python/object/forward.hpp b/include/boost/python/object/forward.hpp index 149b7330..acae1173 100644 --- a/include/boost/python/object/forward.hpp +++ b/include/boost/python/object/forward.hpp @@ -10,28 +10,99 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { +template +struct reference_to_value +{ + typedef typename add_reference::type>::type reference; + + reference_to_value(reference x) : m_value(x) {} + operator reference() const { return m_value; } + private: + reference m_value; +}; + // A little metaprogram which selects the type to pass through an // intermediate forwarding function when the destination argument type // is T. template struct forward -{ - BOOST_STATIC_CONSTANT( - bool, by_value = (is_scalar::value | is_reference::value) - ); - - typedef typename mpl::select_type< - by_value + : mpl::select_type< + is_scalar::value , T - , reference_wrapper< - typename add_const::type - > - >::type type; + , reference_to_value > +{ }; +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +class unforward +{ + public: + typedef typename unwrap_reference::type& type; +}; + +template +class unforward > +{ + public: + typedef T type; +}; +# else // no partial specialization + +namespace detail +{ + typedef char (&yes_reference_to_value_t)[1]; + typedef char (&no_reference_to_value_t)[2]; + + no_reference_to_value_t is_reference_to_value_test(...); + + template + yes_reference_to_value_t is_reference_to_value_test(type< reference_to_value >); + + template + struct unforwarder + { + template + struct apply + { + typedef typename unwrap_reference::type& type; + }; + }; + + template<> + struct unforwarder + { + template + struct apply + { + typedef typename T::reference type; + }; + }; + + template + class is_reference_to_value + { + public: + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof(is_reference_to_value_test(type())) + == sizeof(yes_reference_to_value_t))); + }; +} + +template +class unforward + : public detail::unforwarder< + detail::is_reference_to_value::value + >::template apply +{}; + +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + }}} // namespace boost::python::objects #endif // FORWARD_DWA20011215_HPP diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 4ec46377..3a8e2cec 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -10,7 +10,7 @@ # include # include # include -# include +# include # include # include # include @@ -31,113 +31,113 @@ struct pointer_holder : instance_holder template pointer_holder(PyObject*, A1 a1) : m_p(new Value( - (typename unwrap_reference::type&)(a1) + (typename unforward::type)(a1) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2) : m_p(new Value( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3) : m_p(new Value( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : m_p(new Value( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : m_p(new Value( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : m_p(new Value( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : m_p(new Value( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : m_p(new Value( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : m_p(new Value( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) - , (typename unwrap_reference::type&)(a9) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) + , (typename unforward::type)(a9) )) {} template pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : m_p(new Value( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) - , (typename unwrap_reference::type&)(a9) - , (typename unwrap_reference::type&)(a10) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) + , (typename unforward::type)(a9) + , (typename unforward::type)(a10) )) {} @@ -166,7 +166,7 @@ struct pointer_holder_back_reference : instance_holder template pointer_holder_back_reference(PyObject* p, A1 a1) : m_p(new held_type(p - , (typename unwrap_reference::type&)(a1) + , (typename unforward::type)(a1) )) { void const* x = &instance_finder::registration; (void)x; @@ -176,8 +176,8 @@ struct pointer_holder_back_reference : instance_holder template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2) : m_p(new held_type(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) )) { void const* x = &instance_finder::registration; (void)x; @@ -187,9 +187,9 @@ struct pointer_holder_back_reference : instance_holder template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3) : m_p(new held_type(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) )) { void const* x = &instance_finder::registration; (void)x; @@ -199,10 +199,10 @@ struct pointer_holder_back_reference : instance_holder template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4) : m_p(new held_type(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) )) { void const* x = &instance_finder::registration; (void)x; @@ -212,11 +212,11 @@ struct pointer_holder_back_reference : instance_holder template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : m_p(new held_type(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) )) { void const* x = &instance_finder::registration; (void)x; } @@ -225,12 +225,12 @@ struct pointer_holder_back_reference : instance_holder template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : m_p(new held_type(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) )) { void const* x = &instance_finder::registration; (void)x; } @@ -239,13 +239,13 @@ struct pointer_holder_back_reference : instance_holder template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : m_p(new held_type(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) )) { void const* x = &instance_finder::registration; (void)x; @@ -255,14 +255,14 @@ struct pointer_holder_back_reference : instance_holder template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : m_p(new held_type(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) )) { void const* x = &instance_finder::registration; (void)x; @@ -272,15 +272,15 @@ struct pointer_holder_back_reference : instance_holder template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : m_p(new held_type(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) - , (typename unwrap_reference::type&)(a9) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) + , (typename unforward::type)(a9) )) { void const* x = &instance_finder::registration; (void)x; @@ -290,16 +290,16 @@ struct pointer_holder_back_reference : instance_holder template pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : m_p(new held_type(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) - , (typename unwrap_reference::type&)(a9) - , (typename unwrap_reference::type&)(a10) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) + , (typename unforward::type)(a9) + , (typename unforward::type)(a10) )) { void const* x = &instance_finder::registration; (void)x; diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index e6d7f454..d98d1d10 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -11,7 +11,7 @@ # include # include # include -# include +# include namespace boost { namespace python { namespace objects { @@ -25,113 +25,113 @@ struct value_holder : instance_holder template value_holder(PyObject*, A1 a1) : m_held( - (typename unwrap_reference::type&)(a1) + (typename unforward::type)(a1) ) {} template value_holder(PyObject*, A1 a1, A2 a2) : m_held( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3) : m_held( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : m_held( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : m_held( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : m_held( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : m_held( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : m_held( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : m_held( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) - , (typename unwrap_reference::type&)(a9) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) + , (typename unforward::type)(a9) ) {} template value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : m_held( - (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) - , (typename unwrap_reference::type&)(a9) - , (typename unwrap_reference::type&)(a10) + (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) + , (typename unforward::type)(a9) + , (typename unforward::type)(a10) ) {} @@ -155,7 +155,7 @@ struct value_holder_back_reference : instance_holder template value_holder_back_reference(PyObject* p, A1 a1) : m_held(p - , (typename unwrap_reference::type&)(a1) + , (typename unforward::type)(a1) ) { void const* x = &instance_finder::registration; (void)x; @@ -165,8 +165,8 @@ struct value_holder_back_reference : instance_holder template value_holder_back_reference(PyObject* p, A1 a1, A2 a2) : m_held(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) ) { void const* x = &instance_finder::registration; (void)x; @@ -176,9 +176,9 @@ struct value_holder_back_reference : instance_holder template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3) : m_held(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) ) { void const* x = &instance_finder::registration; (void)x; @@ -188,10 +188,10 @@ struct value_holder_back_reference : instance_holder template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4) : m_held(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) ) { void const* x = &instance_finder::registration; (void)x; @@ -201,11 +201,11 @@ struct value_holder_back_reference : instance_holder template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : m_held(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) ) { void const* x = &instance_finder::registration; (void)x; } @@ -214,12 +214,12 @@ struct value_holder_back_reference : instance_holder template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : m_held(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) ) { void const* x = &instance_finder::registration; (void)x; } @@ -228,13 +228,13 @@ struct value_holder_back_reference : instance_holder template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : m_held(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) ) { void const* x = &instance_finder::registration; (void)x; @@ -244,14 +244,14 @@ struct value_holder_back_reference : instance_holder template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : m_held(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) ) { void const* x = &instance_finder::registration; (void)x; @@ -261,15 +261,15 @@ struct value_holder_back_reference : instance_holder template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : m_held(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) - , (typename unwrap_reference::type&)(a9) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) + , (typename unforward::type)(a9) ) { void const* x = &instance_finder::registration; (void)x; @@ -279,16 +279,16 @@ struct value_holder_back_reference : instance_holder template value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : m_held(p - , (typename unwrap_reference::type&)(a1) - , (typename unwrap_reference::type&)(a2) - , (typename unwrap_reference::type&)(a3) - , (typename unwrap_reference::type&)(a4) - , (typename unwrap_reference::type&)(a5) - , (typename unwrap_reference::type&)(a6) - , (typename unwrap_reference::type&)(a7) - , (typename unwrap_reference::type&)(a8) - , (typename unwrap_reference::type&)(a9) - , (typename unwrap_reference::type&)(a10) + , (typename unforward::type)(a1) + , (typename unforward::type)(a2) + , (typename unforward::type)(a3) + , (typename unforward::type)(a4) + , (typename unforward::type)(a5) + , (typename unforward::type)(a6) + , (typename unforward::type)(a7) + , (typename unforward::type)(a8) + , (typename unforward::type)(a9) + , (typename unforward::type)(a10) ) { void const* x = &instance_finder::registration; (void)x; diff --git a/test/Jamfile b/test/Jamfile index a9cd3fa0..0d494b70 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -53,6 +53,7 @@ rule bpl-test ( name ? : files * ) bpl-test bienstman1 ; bpl-test bienstman2 ; +bpl-test bienstman3 ; bpl-test try : newtest.py m1.cpp m2.cpp ; bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ; bpl-test test_pointer_adoption ; diff --git a/test/bienstman1.py b/test/bienstman1.py index 5d75388c..b98862ca 100644 --- a/test/bienstman1.py +++ b/test/bienstman1.py @@ -1,5 +1,6 @@ ''' ->>> import bienstman1_ext +>>> from bienstman1_ext import * +>>> # from Numeric import * ''' def run(args = None): import sys diff --git a/test/bienstman2.py b/test/bienstman2.py index 364f5504..45ee4134 100644 --- a/test/bienstman2.py +++ b/test/bienstman2.py @@ -1,5 +1,5 @@ ''' ->>> import bienstman1_ext.py +>>> import bienstman2_ext ''' def run(args = None): import sys diff --git a/test/bienstman3.cpp b/test/bienstman3.cpp new file mode 100644 index 00000000..60ddc385 --- /dev/null +++ b/test/bienstman3.cpp @@ -0,0 +1,33 @@ +#include +#include +#include + +struct V +{ + virtual void f() = 0; +}; + +struct B +{ + B(const V&) {} +}; + +BOOST_PYTHON_MODULE_INIT(bienstman3_ext) +{ + using namespace boost::python; + using boost::mpl::type_list; + + module m("bienstman3_ext"); + + m + + .add( + class_("V") + ) + + .add( + class_("B") + .def_init(type_list()) + ) + ; +} diff --git a/test/bienstman3.py b/test/bienstman3.py new file mode 100644 index 00000000..8a14c8ff --- /dev/null +++ b/test/bienstman3.py @@ -0,0 +1,15 @@ +''' +>>> from bienstman3_ext import * +''' +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 022c8502c0d68d040a8982905906fcb6e367403a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 4 Apr 2002 22:52:48 +0000 Subject: [PATCH 0369/1042] Add a Numeric interaction test [SVN r13371] --- test/bienstman1.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/bienstman1.py b/test/bienstman1.py index b98862ca..d5ec22b5 100644 --- a/test/bienstman1.py +++ b/test/bienstman1.py @@ -1,6 +1,8 @@ ''' +# Try to reproduce a Numeric interaction bug if Numeric is installed. >>> from bienstman1_ext import * ->>> # from Numeric import * +>>> try: from Numeric import * +... except: pass ''' def run(args = None): import sys From 4bb5ee4b17ef9cd1cf32aec3ae3d58a5a8bcd5e8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 5 Apr 2002 04:11:04 +0000 Subject: [PATCH 0370/1042] Fixes for GC interoperability [SVN r13373] --- src/object/class.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index 9341da7d..487dc01c 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -23,6 +23,18 @@ instance_holder::~instance_holder() { } +// This is copied from typeobject.c in the Python sources. Even though +// class_metatype_object doesn't set Py_TPFLAGS_HAVE_GC, that bit gets +// filled in by the base class initialization process in +// PyType_Ready(). However, tp_is_gc is *not* copied from the base +// type, making it assume that classes are GC-able even if (like +// class_type_object) they're statically allocated. +static int +type_is_gc(PyTypeObject *python_type) +{ + return python_type->tp_flags & Py_TPFLAGS_HEAPTYPE; +} + PyTypeObject class_metatype_object = { PyObject_HEAD_INIT(0)//&PyType_Type) 0, @@ -63,8 +75,9 @@ PyTypeObject class_metatype_object = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - 0, - // PyType_GenericNew /* tp_new */ + 0, // filled in with type_new /* tp_new */ + 0, // filled in with __PyObject_GC_Del /* tp_free */ + (inquiry)type_is_gc, /* tp_is_gc */ }; // Get the metatype object for all extension classes. From 9137b38fb958f86f97ba75a27e92e911fd1ab5d2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 5 Apr 2002 05:11:10 +0000 Subject: [PATCH 0371/1042] module name bug fix [SVN r13374] --- test/bienstman2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/bienstman2.cpp b/test/bienstman2.cpp index ecb2158b..b2ef1957 100644 --- a/test/bienstman2.cpp +++ b/test/bienstman2.cpp @@ -11,11 +11,11 @@ struct E const D fe2(const C&, const C&) {return D();} }; -BOOST_PYTHON_MODULE_INIT(m) +BOOST_PYTHON_MODULE_INIT(bienstman2_ext) { using namespace boost::python; - module m("m"); + module m("bienstman2_ext"); m .add(class_("C")) From 79f8f3eb141ea1dd844b18cf85bd037125384cdc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Apr 2002 14:48:23 +0000 Subject: [PATCH 0372/1042] Another way to break the lib from Peter Bienstman [SVN r13410] --- test/Jamfile | 1 + test/bienstman4.cpp | 38 ++++++++++++++++++++++++++++++++++++++ test/bienstman4.py | 18 ++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 test/bienstman4.cpp create mode 100644 test/bienstman4.py diff --git a/test/Jamfile b/test/Jamfile index 0d494b70..cc0d3ca8 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -54,6 +54,7 @@ rule bpl-test ( name ? : files * ) bpl-test bienstman1 ; bpl-test bienstman2 ; bpl-test bienstman3 ; +bpl-test bienstman4 ; bpl-test try : newtest.py m1.cpp m2.cpp ; bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ; bpl-test test_pointer_adoption ; diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp new file mode 100644 index 00000000..76a1c209 --- /dev/null +++ b/test/bienstman4.cpp @@ -0,0 +1,38 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include + +struct T1 {}; + +struct Term {Term(T1 const&) {} }; + +struct Expression {void add(Term const&) {} }; + +BOOST_PYTHON_MODULE_INIT(bienstman4_ext) +{ + using namespace boost::python; + using boost::mpl::type_list; + + implicitly_convertible(); + + module("bienstman4_ext") + .add(class_("Expression") + .def("add", &Expression::add)) + .add(class_("T1")) + .add(class_("Term") + .def_init(type_list())) + ; + + + T1 t1; + Expression e; + e.add(t1); +} + diff --git a/test/bienstman4.py b/test/bienstman4.py new file mode 100644 index 00000000..2fede1fc --- /dev/null +++ b/test/bienstman4.py @@ -0,0 +1,18 @@ +''' +>>> from bienstman4_ext import * +>>> t1 = T1() +>>> e = Expression() +>>> e.add(t1) +''' +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From af939fad66be1cdc403833637c93419309c5d57f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Apr 2002 14:51:02 +0000 Subject: [PATCH 0373/1042] MSVC workaround [SVN r13411] --- test/bienstman4.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp index 76a1c209..4df93e0e 100644 --- a/test/bienstman4.cpp +++ b/test/bienstman4.cpp @@ -9,9 +9,9 @@ #include #include -struct T1 {}; +struct Type1 {}; -struct Term {Term(T1 const&) {} }; +struct Term {Term(Type1 const&) {} }; struct Expression {void add(Term const&) {} }; @@ -20,18 +20,18 @@ BOOST_PYTHON_MODULE_INIT(bienstman4_ext) using namespace boost::python; using boost::mpl::type_list; - implicitly_convertible(); + implicitly_convertible(); module("bienstman4_ext") .add(class_("Expression") .def("add", &Expression::add)) - .add(class_("T1")) + .add(class_("T1")) .add(class_("Term") - .def_init(type_list())) + .def_init(type_list())) ; - T1 t1; + Type1 t1; Expression e; e.add(t1); } From 3944786c13e8c6135b7893859cf3db6d5736815b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Apr 2002 15:54:59 +0000 Subject: [PATCH 0374/1042] Fixes [SVN r13412] --- test/bienstman4.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp index 4df93e0e..29e971d8 100644 --- a/test/bienstman4.cpp +++ b/test/bienstman4.cpp @@ -24,8 +24,10 @@ BOOST_PYTHON_MODULE_INIT(bienstman4_ext) module("bienstman4_ext") .add(class_("Expression") + .def_init() .def("add", &Expression::add)) - .add(class_("T1")) + .add(class_("T1") + .def_init()) .add(class_("Term") .def_init(type_list())) ; From 81777a29d5f6f2a3986d983108b7623a50554296 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 10 Apr 2002 05:43:55 +0000 Subject: [PATCH 0375/1042] Fixed Jamfile for running all tests Updated MWERKS warning suppression Rationalized template export [SVN r13421] --- build/Jamfile | 2 +- include/boost/python/classes.hpp | 5 +- include/boost/python/detail/config.hpp | 72 ++++--------------- .../boost/python/detail/extension_class.hpp | 6 +- src/extension_class.cpp | 6 +- test/comprehensive.cpp | 2 +- 6 files changed, 20 insertions(+), 73 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index 94348c4a..00bb22dd 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -121,7 +121,7 @@ rule boost-python-example-runtest ( name ) : ../example/$(name).cpp ; boost-python-runtest $(name) - : ../example/test_$(name).py $(name) ; + : ../example/test_$(name).py $(name) boost_python ; } diff --git a/include/boost/python/classes.hpp b/include/boost/python/classes.hpp index 2725ed7b..114bb16a 100644 --- a/include/boost/python/classes.hpp +++ b/include/boost/python/classes.hpp @@ -145,8 +145,7 @@ namespace detail { // A type which acts a lot like a built-in Python class. T is the obj type, // so class_t is a very simple "class-alike". template -class BOOST_PYTHON_DECL_TEMPLATE class_t - : public boost::python::detail::class_base +class class_t : public boost::python::detail::class_base { public: class_t(meta_class* meta_class_obj, string name, tuple bases, const dictionary& name_space); @@ -227,7 +226,7 @@ class BOOST_PYTHON_DECL_TEMPLATE class_t // The type of a class_t object. template -class BOOST_PYTHON_DECL_TEMPLATE meta_class +class meta_class : public boost::python::detail::reprable< boost::python::detail::callable< boost::python::detail::getattrable< diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index efd1500b..c0cb41e2 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -81,30 +81,12 @@ # define BOOST_PYTHON_STATIC_LINK #endif -#if defined(__MWERKS__) \ +#if defined(__MWERKS__) \ || (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \ || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) # define BOOST_PYTHON_NO_TEMPLATE_EXPORT #endif -#if defined(__GNUC__) -# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern -# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD extern -#endif - -// Handle default cases -#ifndef BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD -# ifdef _WIN32 -# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD extern -# else -# define BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD -# endif -#endif - -#ifndef BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD -# define BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD -#endif - #if defined(BOOST_PYTHON_DYNAMIC_LIB) && defined(_WIN32) # if defined(BOOST_PYTHON_SOURCE) # define BOOST_PYTHON_DECL __declspec(dllexport) @@ -112,54 +94,26 @@ # else # define BOOST_PYTHON_DECL __declspec(dllimport) # endif + +// MinGW, at least, has some problems exporting template instantiations +# if defined(__GNUC__) && __GNUC__ < 3 +# define BOOST_PYTHON_NO_TEMPLATE_EXPORT +# endif + #endif #ifndef BOOST_PYTHON_DECL # define BOOST_PYTHON_DECL #endif -#ifndef BOOST_PYTHON_DECL_TEMPLATE -# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT -# define BOOST_PYTHON_DECL_TEMPLATE BOOST_PYTHON_DECL -# else -# define BOOST_PYTHON_DECL_TEMPLATE -# endif -#endif +#ifndef BOOST_PYTHON_EXPORT +# define BOOST_PYTHON_EXPORT extern +#endif -#if defined(BOOST_PYTHON_SOURCE) -# define BOOST_PYTHON_EXPORT BOOST_PYTHON_EXPORT_TEMPLATE_KEYWORD +#if !defined(BOOST_PYTHON_NO_TEMPLATE_EXPORT) +# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL instantiation #else -# define BOOST_PYTHON_EXPORT BOOST_PYTHON_IMPORT_TEMPLATE_KEYWORD -#endif - -# ifndef BOOST_PYTHON_EXPORT_TEMPLATE -# define BOOST_PYTHON_EXPORT_TEMPLATE BOOST_PYTHON_EXPORT template -# endif - -# define BOOST_PYTHON_EXPORT_TEMPLATE_CLASS BOOST_PYTHON_EXPORT template class BOOST_PYTHON_DECL - -// Borland C++ Fix/error check: -#if defined(__BORLANDC__) -# if (__BORLANDC__ == 0x550) || (__BORLANDC__ == 0x551) - // problems with std::basic_string and dll RTL: -# if defined(_RTLDLL) && defined(_RWSTD_COMPILE_INSTANTIATE) -# ifdef BOOST_PYTHON_BUILD_DLL -# error _RWSTD_COMPILE_INSTANTIATE must not be defined when building regex++ as a DLL -# else -# pragma warn defining _RWSTD_COMPILE_INSTANTIATE when linking to the DLL version of the RTL may produce memory corruption problems in std::basic_string, as a result of separate versions of basic_string's static data in the RTL and you're exe/dll: be warned!! -# endif -# endif -# ifndef _RTLDLL - // this is harmless for a static link: -# define _RWSTD_COMPILE_INSTANTIATE -# endif -# endif - // - // VCL support: - // if we're building a console app then there can't be any VCL (can there?) -# if !defined(__CONSOLE__) && !defined(_NO_VCL) -# define BOOST_PYTHON_USE_VCL -# endif +# define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) struct ThIsTyPeNeVeRuSeD #endif #if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index dd6741d2..d3016744 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -70,10 +70,8 @@ namespace detail } // namespace detail -# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT -BOOST_PYTHON_EXPORT_TEMPLATE_CLASS class_t; -BOOST_PYTHON_EXPORT_TEMPLATE_CLASS meta_class; -# endif +BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(class_t); +BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(meta_class); namespace detail { diff --git a/src/extension_class.cpp b/src/extension_class.cpp index 98505347..334875b9 100644 --- a/src/extension_class.cpp +++ b/src/extension_class.cpp @@ -10,6 +10,7 @@ // 04 Mar 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) #define BOOST_PYTHON_SOURCE +#define BOOST_PYTHON_EXPORT #include #include @@ -681,9 +682,4 @@ PyNumberMethods operator_dispatcher::number_methods = } // namespace detail -# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT -template class BOOST_PYTHON_DECL meta_class; -template class BOOST_PYTHON_DECL class_t; -# endif - }} // namespace boost::python diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index d4617181..31a89fb1 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -167,7 +167,7 @@ int IntPairPythonClass::getattr(const IntPair& p, const std::string& s) PyErr_SetString(PyExc_AttributeError, s.c_str()); throw boost::python::error_already_set(); } -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 +#if defined(__MWERKS__) && __MWERKS__ <= 0x2407 return 0; #endif } From f17876969da7bde7e4f928e02561c056b7083c19 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 10 Apr 2002 06:07:51 +0000 Subject: [PATCH 0376/1042] Removed Ralf's workaround for my bug [SVN r13422] --- include/boost/python/detail/config.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index c0cb41e2..8b8bea42 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -81,9 +81,7 @@ # define BOOST_PYTHON_STATIC_LINK #endif -#if defined(__MWERKS__) \ - || (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \ - || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) +#if defined(__MWERKS__) # define BOOST_PYTHON_NO_TEMPLATE_EXPORT #endif From 10ffaec73051b1d5c7a8dd6de9e66b38d7b9c54e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 10 Apr 2002 09:39:27 +0000 Subject: [PATCH 0377/1042] Start using preprocessor [SVN r13426] --- .../boost/python/detail/arg_tuple_size.hpp | 323 +++--------------- .../python/preprocessed/arg_tuple_size.hpp | 276 +++++++++++++++ 2 files changed, 314 insertions(+), 285 deletions(-) create mode 100644 include/boost/python/preprocessed/arg_tuple_size.hpp diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index fa38a4a9..2d1982dc 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -11,7 +11,12 @@ #ifndef ARG_TUPLE_SIZE_DWA20011201_HPP # define ARG_TUPLE_SIZE_DWA20011201_HPP +# include +# include +# include # include +# include +# include namespace boost { namespace python { namespace detail { @@ -20,203 +25,29 @@ namespace boost { namespace python { namespace detail { // (member) function of the given type. template struct arg_tuple_size; -# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__BORLANDC__) +// Include the pre-expanded version of the code +# if BOOST_PYTHON_DEBUGGABLE_ARITY +# include +# endif -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 0); +# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +// Specializations for function pointers +# define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \ +template \ +struct arg_tuple_size \ +{ \ + BOOST_STATIC_CONSTANT(std::size_t, value = args); \ }; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 1); +// Specializations for member function pointers +# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF1(args, cv) \ +template \ +struct arg_tuple_size \ +{ \ + BOOST_STATIC_CONSTANT(std::size_t, value = args); \ }; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 2); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 3); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 4); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 5); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 6); -}; - - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 1); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 2); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 3); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 4); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 5); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 6); -}; - - -// Metrowerks thinks this creates ambiguities -# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 1); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 2); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 3); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 4); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 5); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 6); -}; - - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 1); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 2); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 3); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 4); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 5); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 6); -}; - - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 1); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 2); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 3); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 4); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 5); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = 6); -}; - - -# endif // __MWERKS__ # else // We will use the "sizeof() trick" to work around the lack of @@ -230,103 +61,25 @@ struct arg_tuple_size // their return value is used to discriminate between various free // and member function pointers at compile-time. -template -char_array<0> arg_tuple_size_helper(R (*)()); +# define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \ +template \ +char_array arg_tuple_size_helper(BOOST_PYTHON_PF(args)); -template -char_array<1> arg_tuple_size_helper(R (*)(A1)); +# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF1(args, cv) \ +template \ +char_array arg_tuple_size_helper(BOOST_PYTHON_PMF(args,cv)); + +# endif -template -char_array<2> arg_tuple_size_helper(R (*)(A1, A2)); - -template -char_array<3> arg_tuple_size_helper(R (*)(A1, A2, A3)); - -template -char_array<4> arg_tuple_size_helper(R (*)(A1, A2, A3, A4)); - -template -char_array<5> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5)); - -template -char_array<6> arg_tuple_size_helper(R (*)(A1, A2, A3, A4, A5, A6)); - -template -char_array<1> arg_tuple_size_helper(R (A0::*)()); - -template -char_array<2> arg_tuple_size_helper(R (A0::*)(A1)); - -template -char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2)); - -template -char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3)); - -template -char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4)); - -template -char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5)); - - -template -char_array<1> arg_tuple_size_helper(R (A0::*)() const); - -template -char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const); - -template -char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const); - -template -char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const); - -template -char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const); - -template -char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const); - - -template -char_array<1> arg_tuple_size_helper(R (A0::*)() volatile); - -template -char_array<2> arg_tuple_size_helper(R (A0::*)(A1) volatile); - -template -char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) volatile); - -template -char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) volatile); - -template -char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) volatile); - -template -char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) volatile); - - -template -char_array<1> arg_tuple_size_helper(R (A0::*)() const volatile); - -template -char_array<2> arg_tuple_size_helper(R (A0::*)(A1) const volatile); - -template -char_array<3> arg_tuple_size_helper(R (A0::*)(A1, A2) const volatile); - -template -char_array<4> arg_tuple_size_helper(R (A0::*)(A1, A2, A3) const volatile); - -template -char_array<5> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4) const volatile); - -template -char_array<6> arg_tuple_size_helper(R (A0::*)(A1, A2, A3, A4, A5) const volatile); +BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_ARG_TUPLE_SIZE_PF, nil) + +# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF(index, ignored, cv) \ + BOOST_PYTHON_REPEAT_MF_ARITY_2ND(BOOST_PYTHON_ARG_TUPLE_SIZE_PMF1,cv) +// Generate a series for each cv-qualification +BOOST_PP_LIST_FOR_EACH(BOOST_PYTHON_ARG_TUPLE_SIZE_PMF,nil,BOOST_PYTHON_MEMBER_FUNCTION_CV) +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(__BORLANDC__) template struct arg_tuple_size { diff --git a/include/boost/python/preprocessed/arg_tuple_size.hpp b/include/boost/python/preprocessed/arg_tuple_size.hpp new file mode 100644 index 00000000..b22590ae --- /dev/null +++ b/include/boost/python/preprocessed/arg_tuple_size.hpp @@ -0,0 +1,276 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ARG_TUPLE_SIZE_DWA2002410_HPP +# define ARG_TUPLE_SIZE_DWA2002410_HPP + +# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=0); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=1); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=2); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=3); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=4); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=5); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=6); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=7); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=8); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=9); +}; + + + templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=1); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=2); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=3); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=4); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=5); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=6); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=7); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=8); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=9); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=10); +}; +// Metrowerks thinks this creates ambiguities +# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=1); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=2); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=3); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=4); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=5); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=6); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=7); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=8); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=9); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=10); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=1); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=2); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=3); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=4); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=5); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=6); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=7); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=8); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=9); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=10); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=1); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=2); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=3); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=4); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=5); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=6); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=7); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=8); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=9); +}; +templatestruct arg_tuple_size{ +BOOST_STATIC_CONSTANT(std::size_t,value=10); +}; +# endif + +# else + +template +char_array<0>arg_tuple_size_helper(R(*)()); +template +char_array<1>arg_tuple_size_helper(R(*)(A0)); +template +char_array<2>arg_tuple_size_helper(R(*)(A0,A1)); +template +char_array<3>arg_tuple_size_helper(R(*)(A0,A1,A2)); +template +char_array<4>arg_tuple_size_helper(R(*)(A0,A1,A2,A3)); +template +char_array<5>arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4)); +template +char_array<6>arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5)); +template +char_array<7>arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6)); +template +char_array<8>arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7)); +template +char_array<9>arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8)); + +template +char_array<1>arg_tuple_size_helper(R(A0::*)()); +template +char_array<2>arg_tuple_size_helper(R(A0::*)(A1)); +template +char_array<3>arg_tuple_size_helper(R(A0::*)(A1,A2)); +template +char_array<4>arg_tuple_size_helper(R(A0::*)(A1,A2,A3)); +template +char_array<5>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)); +template +char_array<6>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)); +template +char_array<7>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)); +template +char_array<8>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)); +template +char_array<9>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)); +template +char_array<10>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)); + +template +char_array<1>arg_tuple_size_helper(R(A0::*)()const); +template +char_array<2>arg_tuple_size_helper(R(A0::*)(A1)const); +template +char_array<3>arg_tuple_size_helper(R(A0::*)(A1,A2)const); +template +char_array<4>arg_tuple_size_helper(R(A0::*)(A1,A2,A3)const); +template +char_array<5>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)const); +template +char_array<6>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)const); +template +char_array<7>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)const); +template +char_array<8>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const); +template +char_array<9>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const); +template +char_array<10>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const); + +template +char_array<1>arg_tuple_size_helper(R(A0::*)()volatile); +template +char_array<2>arg_tuple_size_helper(R(A0::*)(A1)volatile); +template +char_array<3>arg_tuple_size_helper(R(A0::*)(A1,A2)volatile); +template +char_array<4>arg_tuple_size_helper(R(A0::*)(A1,A2,A3)volatile); +template +char_array<5>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)volatile); +template +char_array<6>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)volatile); +template +char_array<7>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)volatile); +template +char_array<8>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)volatile); +template +char_array<9>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile); +template +char_array<10>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile); + +template +char_array<1>arg_tuple_size_helper(R(A0::*)()const volatile); +template +char_array<2>arg_tuple_size_helper(R(A0::*)(A1)const volatile); +template +char_array<3>arg_tuple_size_helper(R(A0::*)(A1,A2)const volatile); +template +char_array<4>arg_tuple_size_helper(R(A0::*)(A1,A2,A3)const volatile); +template +char_array<5>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)const volatile); +template +char_array<6>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)const volatile); +template +char_array<7>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)const volatile); +template +char_array<8>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const volatile); +template +char_array<9>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile); +template +char_array<10>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile); + +# endif + +#endif // ARG_TUPLE_SIZE_DWA2002410_HPP From 558170582a5a6d7b7bd63e09a635bc10c31b06bb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 10 Apr 2002 09:41:52 +0000 Subject: [PATCH 0378/1042] Start using preprocessor library [SVN r13427] --- include/boost/python/detail/preprocessor.hpp | 73 ++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 include/boost/python/detail/preprocessor.hpp diff --git a/include/boost/python/detail/preprocessor.hpp b/include/boost/python/detail/preprocessor.hpp new file mode 100644 index 00000000..58df4f40 --- /dev/null +++ b/include/boost/python/detail/preprocessor.hpp @@ -0,0 +1,73 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef PREPROCESSOR_DWA200247_HPP +# define PREPROCESSOR_DWA200247_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +# define BOOST_PYTHON_CONST() const +# define BOOST_PYTHON_VOLATILE() volatile +# define BOOST_PYTHON_CONST_VOLATILE() const volatile + +# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 +# define BOOST_PYTHON_MEMBER_FUNCTION_CV \ + BOOST_PP_TUPLE_TO_LIST(4, (BOOST_PP_EMPTY \ + , BOOST_PYTHON_CONST \ + , BOOST_PYTHON_VOLATILE \ + , BOOST_PYTHON_CONST_VOLATILE)) +# else +# define BOOST_PYTHON_MEMBER_FUNCTION_CV \ + BOOST_PP_TUPLE_TO_LIST(1, (BOOST_PP_EMPTY)) +# endif + +#ifndef BOOST_PYTHON_DEBUGGABLE_ARITY +# define BOOST_PYTHON_DEBUGGABLE_ARITY 10 +#endif + +#ifndef BOOST_PYTHON_MAX_ARITY +# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245 +// Generate at least two more arguments just to test the syntax +# define BOOST_PYTHON_MAX_ARITY 12 +# else +// Current EDG compilers have a really slow preprocessor which makes +// it important not to generate new functions with it unless +// absolutely neccessary +# define BOOST_PYTHON_MAX_ARITY BOOST_PYTHON_DEBUGGABLE_ARITY +# endif +#endif + +#ifdef BOOST_PYTHON_GENERATE_CODE +# undef BOOST_STATIC_CONSTANT +# define BOOST_PYTHON_ARITY_START 0 +# define BOOST_PYTHON_ARITY_FINISH BOOST_PYTHON_DEBUGGABLE_ARITY +# define BOOST_PYTHON_MF_ARITY_START 1 +# define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY) +#else +# define BOOST_PYTHON_ARITY_START BOOST_PYTHON_DEBUGGABLE_ARITY +# define BOOST_PYTHON_ARITY_FINISH BOOST_PYTHON_MAX_ARITY +# define BOOST_PYTHON_MF_ARITY_START BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY) +# define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY) +#endif + +# define BOOST_PYTHON_PF(Count) R(*)(BOOST_MPL_TEMPLATE_PARAMETERS(0,Count,A)) +# define BOOST_PYTHON_PMF(Count, cv) R(A0::*)(BOOST_MPL_TEMPLATE_PARAMETERS(1,Count,A))cv() + +# define BOOST_PYTHON_REPEAT_ARITY_2ND(function,data) \ + BOOST_PP_REPEAT_FROM_TO_2ND(BOOST_PYTHON_ARITY_START, BOOST_PYTHON_ARITY_FINISH, function, data) + +# define BOOST_PYTHON_REPEAT_MF_ARITY_2ND(function,data) \ + BOOST_PP_REPEAT_FROM_TO_2ND(BOOST_PYTHON_MF_ARITY_START, BOOST_PYTHON_MF_ARITY_FINISH, function, data) + + +}}} // namespace boost::python::detail + +#endif // PREPROCESSOR_DWA200247_HPP From eab0a73f53988caebac38d7fc0c16cc0ef503662 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 10 Apr 2002 17:30:34 +0000 Subject: [PATCH 0379/1042] Use preprocessor lib for caller.hpp [SVN r13435] --- .../boost/python/detail/arg_tuple_size.hpp | 40 ++- include/boost/python/detail/caller.hpp | 214 +++----------- include/boost/python/detail/preprocessor.hpp | 51 +++- include/boost/python/preprocessed/caller.hpp | 261 ++++++++++++++++++ 4 files changed, 350 insertions(+), 216 deletions(-) create mode 100644 include/boost/python/preprocessed/caller.hpp diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index 2d1982dc..69558337 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -12,11 +12,10 @@ # define ARG_TUPLE_SIZE_DWA20011201_HPP # include +# include # include # include -# include # include -# include namespace boost { namespace python { namespace detail { @@ -26,26 +25,26 @@ namespace boost { namespace python { namespace detail { template struct arg_tuple_size; // Include the pre-expanded version of the code -# if BOOST_PYTHON_DEBUGGABLE_ARITY +# ifndef BOOST_PYTHON_GENERATE_CODE # include # endif # if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) // Specializations for function pointers -# define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \ -template \ -struct arg_tuple_size \ -{ \ - BOOST_STATIC_CONSTANT(std::size_t, value = args); \ +# define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \ +template \ +struct arg_tuple_size \ +{ \ + BOOST_STATIC_CONSTANT(std::size_t, value = args); \ }; // Specializations for member function pointers -# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF1(args, cv) \ -template \ -struct arg_tuple_size \ -{ \ - BOOST_STATIC_CONSTANT(std::size_t, value = args); \ +# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF(args, cv) \ +template \ +struct arg_tuple_size \ +{ \ + BOOST_STATIC_CONSTANT(std::size_t, value = args); \ }; # else @@ -61,11 +60,11 @@ struct arg_tuple_size \ // their return value is used to discriminate between various free // and member function pointers at compile-time. -# define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \ -template \ +# define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \ +template \ char_array arg_tuple_size_helper(BOOST_PYTHON_PF(args)); -# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF1(args, cv) \ +# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF(args, cv) \ template \ char_array arg_tuple_size_helper(BOOST_PYTHON_PMF(args,cv)); @@ -73,12 +72,9 @@ char_array arg_tuple_size_helper(BOOST_PYTHON_PMF(args,cv)); BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_ARG_TUPLE_SIZE_PF, nil) -# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF(index, ignored, cv) \ - BOOST_PYTHON_REPEAT_MF_ARITY_2ND(BOOST_PYTHON_ARG_TUPLE_SIZE_PMF1,cv) - -// Generate a series for each cv-qualification -BOOST_PP_LIST_FOR_EACH(BOOST_PYTHON_ARG_TUPLE_SIZE_PMF,nil,BOOST_PYTHON_MEMBER_FUNCTION_CV) - +// Generate a series for each cv-qualification +BOOST_PYTHON_REPEAT_MF_CV_2ND(BOOST_PYTHON_ARG_TUPLE_SIZE_PMF) + # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(__BORLANDC__) template struct arg_tuple_size diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index 68da40e6..feaa9397 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -11,6 +11,9 @@ # include # include # include +# include +# include +# include namespace boost { namespace python { @@ -23,192 +26,41 @@ struct caller { typedef PyObject* result_type; - template - PyObject* operator()(R (*f)(), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif - template - PyObject* operator()(R (*f)(A0), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } +# define BOOST_PYTHON_CALLER_PF(args_, ignored) \ +template < \ + class P \ + , class R \ + BOOST_PP_COMMA_IF(args_) BOOST_MPL_TEMPLATE_PARAMETERS(0, args_, class A) \ + > \ +PyObject* operator()( \ + BOOST_PYTHON_NAMED_PF(f,args_) \ + , PyObject* args, PyObject* keywords \ + , P const& policies \ + ) const \ +{ \ + return returning::call(f, args, keywords, policies); \ +} - template - PyObject* operator()(R (*f)(A0, A1), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (*f)(A0, A1, A2), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (*f)(A0, A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (*f)(A0, A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (*f)(A0, A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } +BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CALLER_PF, nil) // Member functions - template - PyObject* operator()(R (A0::*f)(), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } +# define BOOST_PYTHON_CALLER_PMF(args_, cv) \ +template \ +PyObject* operator()( \ + BOOST_PYTHON_NAMED_PMF(f,args_,cv) \ + , PyObject* args, PyObject* keywords \ + , P const& policies \ + ) const \ +{ \ + return returning::call(f, args, keywords, policies); \ +} - template - PyObject* operator()(R (A0::*f)(A1), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)() const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1) const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2) const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3) const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)() volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1) volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2) volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3) volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)() const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1) const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2) const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3) const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4) const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } - - template - PyObject* operator()(R (A0::*f)(A1, A2, A3, A4, A5) const volatile, PyObject* args, PyObject* keywords, P const& policies) const - { - return returning::call(f, args, keywords, policies); - } +BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_CALLER_PMF) + }; }}} // namespace boost::python::detail diff --git a/include/boost/python/detail/preprocessor.hpp b/include/boost/python/detail/preprocessor.hpp index 58df4f40..2773140e 100644 --- a/include/boost/python/detail/preprocessor.hpp +++ b/include/boost/python/detail/preprocessor.hpp @@ -8,9 +8,11 @@ # include # include +# include # include # include # include +# include namespace boost { namespace python { namespace detail { @@ -18,15 +20,16 @@ namespace boost { namespace python { namespace detail { # define BOOST_PYTHON_VOLATILE() volatile # define BOOST_PYTHON_CONST_VOLATILE() const volatile -# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 -# define BOOST_PYTHON_MEMBER_FUNCTION_CV \ - BOOST_PP_TUPLE_TO_LIST(4, (BOOST_PP_EMPTY \ - , BOOST_PYTHON_CONST \ - , BOOST_PYTHON_VOLATILE \ +# define BOOST_PYTHON_ALL_CV \ + BOOST_PP_TUPLE_TO_LIST(4, (BOOST_PP_EMPTY \ + , BOOST_PYTHON_CONST \ + , BOOST_PYTHON_VOLATILE \ , BOOST_PYTHON_CONST_VOLATILE)) + +# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 +# define BOOST_PYTHON_MEMBER_FUNCTION_CV BOOST_PYTHON_ALL_CV # else -# define BOOST_PYTHON_MEMBER_FUNCTION_CV \ - BOOST_PP_TUPLE_TO_LIST(1, (BOOST_PP_EMPTY)) +# define BOOST_PYTHON_MEMBER_FUNCTION_CV BOOST_PP_TUPLE_TO_LIST(1, (BOOST_PP_EMPTY)) # endif #ifndef BOOST_PYTHON_DEBUGGABLE_ARITY @@ -58,14 +61,36 @@ namespace boost { namespace python { namespace detail { # define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY) #endif -# define BOOST_PYTHON_PF(Count) R(*)(BOOST_MPL_TEMPLATE_PARAMETERS(0,Count,A)) -# define BOOST_PYTHON_PMF(Count, cv) R(A0::*)(BOOST_MPL_TEMPLATE_PARAMETERS(1,Count,A))cv() +# define BOOST_PYTHON_NAMED_PF(f,Count) \ + R(*f)(BOOST_MPL_TEMPLATE_PARAMETERS(0,Count,A)) -# define BOOST_PYTHON_REPEAT_ARITY_2ND(function,data) \ - BOOST_PP_REPEAT_FROM_TO_2ND(BOOST_PYTHON_ARITY_START, BOOST_PYTHON_ARITY_FINISH, function, data) +# define BOOST_PYTHON_NAMED_PMF(f, Count, cv) \ + R(A0::*f)(BOOST_MPL_TEMPLATE_PARAMETERS(1,Count,A))cv() -# define BOOST_PYTHON_REPEAT_MF_ARITY_2ND(function,data) \ - BOOST_PP_REPEAT_FROM_TO_2ND(BOOST_PYTHON_MF_ARITY_START, BOOST_PYTHON_MF_ARITY_FINISH, function, data) +# define BOOST_PYTHON_PF(Count) \ + R(*)(BOOST_MPL_TEMPLATE_PARAMETERS(0,Count,A)) + +# define BOOST_PYTHON_PMF(Count, cv) \ + R(A0::*)(BOOST_MPL_TEMPLATE_PARAMETERS(1,Count,A))cv() + +# define BOOST_PYTHON_REPEAT_ARITY_2ND(function,data) \ + BOOST_PP_REPEAT_FROM_TO_2ND( \ + BOOST_PYTHON_ARITY_START, BOOST_PYTHON_ARITY_FINISH \ + , function, data) + +# define BOOST_PYTHON_REPEAT_MF_ARITY_2ND(function,data) \ + BOOST_PP_REPEAT_FROM_TO_2ND( \ + BOOST_PYTHON_MF_ARITY_START, BOOST_PYTHON_MF_ARITY_FINISH \ + , function, data) + +# define BOOST_PYTHON_REPEAT_PMF_CV(index, function, cv) \ + BOOST_PYTHON_REPEAT_MF_ARITY_2ND(function,cv) + +# define BOOST_PYTHON_REPEAT_MF_CV_2ND(function) \ + BOOST_PP_LIST_FOR_EACH(BOOST_PYTHON_REPEAT_PMF_CV,function,BOOST_PYTHON_MEMBER_FUNCTION_CV) + +# define BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(function) \ + BOOST_PP_LIST_FOR_EACH(BOOST_PYTHON_REPEAT_PMF_CV,function,BOOST_PYTHON_ALL_CV) }}} // namespace boost::python::detail diff --git a/include/boost/python/preprocessed/caller.hpp b/include/boost/python/preprocessed/caller.hpp new file mode 100644 index 00000000..aa466ad7 --- /dev/null +++ b/include/boost/python/preprocessed/caller.hpp @@ -0,0 +1,261 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CALLER_DWA2002410_HPP +# define CALLER_DWA2002410_HPP + +template +PyObject*operator()(R(*f)(),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(*f)(A0),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(*f)(A0,A1),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2,A3),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} + +template +PyObject*operator()(R(A0::*f)(),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)()const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)()volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)()const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,policies); +} + +#endif // CALLER_DWA2002410_HPP From 377fbed517dce77b2cee09f19b26a8e5edb89b2f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 10 Apr 2002 19:33:06 +0000 Subject: [PATCH 0380/1042] Start using preprocessor library [SVN r13436] --- .../python/detail/member_function_cast.hpp | 189 ++----------- include/boost/python/detail/preprocessor.hpp | 13 +- .../preprocessed/member_Function_cast.hpp | 250 ++++++++++++++++++ 3 files changed, 274 insertions(+), 178 deletions(-) create mode 100644 include/boost/python/preprocessed/member_Function_cast.hpp diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp index 5ac2caa3..18af9700 100644 --- a/include/boost/python/detail/member_function_cast.hpp +++ b/include/boost/python/detail/member_function_cast.hpp @@ -7,6 +7,10 @@ # define MEMBER_FUNCTION_CAST_DWA2002311_HPP # include # include +# include +# include +# include +# include namespace boost { namespace python { namespace detail { @@ -49,175 +53,26 @@ struct member_function_cast_impl { return non_member_function_cast_impl(); } -# endif - template - static cast_helper stage1(R (S::*)()) - { - return cast_helper(); - } +# endif + +// Member functions +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif - template - static cast_helper stage1(R (S::*)(A0)) - { - return cast_helper(); - } +# define BOOST_PYTHON_MEMBER_FUNCTION_CAST_STAGE1(args, cv) \ +template < \ + class S \ + , class R \ + BOOST_PP_COMMA_IF(BOOST_PP_DEC(args)) BOOST_MPL_TEMPLATE_PARAMETERS(1, args, class A) \ + > \ +static cast_helper \ +stage1(BOOST_PYTHON_FN(S::*,1,args)cv()) \ +{ \ + return cast_helper(); \ +} - template - static cast_helper stage1(R (S::*)(A0,A1)) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2)) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3)) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4)) - { - return cast_helper(); - } - - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4,A5)) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)()const) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0)const) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1)const) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2)const) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3)const) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4)const) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4,A5)const) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)()volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0)volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1)volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2)volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3)volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4)volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4,A5)volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)()const volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0)const volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1)const volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2)const volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3)const volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4)const volatile) - { - return cast_helper(); - } - - template - static cast_helper stage1(R (S::*)(A0,A1,A2,A3,A4,A5)const volatile) - { - return cast_helper(); - } +BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_MEMBER_FUNCTION_CAST_STAGE1); }; diff --git a/include/boost/python/detail/preprocessor.hpp b/include/boost/python/detail/preprocessor.hpp index 2773140e..23278436 100644 --- a/include/boost/python/detail/preprocessor.hpp +++ b/include/boost/python/detail/preprocessor.hpp @@ -61,17 +61,8 @@ namespace boost { namespace python { namespace detail { # define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY) #endif -# define BOOST_PYTHON_NAMED_PF(f,Count) \ - R(*f)(BOOST_MPL_TEMPLATE_PARAMETERS(0,Count,A)) - -# define BOOST_PYTHON_NAMED_PMF(f, Count, cv) \ - R(A0::*f)(BOOST_MPL_TEMPLATE_PARAMETERS(1,Count,A))cv() - -# define BOOST_PYTHON_PF(Count) \ - R(*)(BOOST_MPL_TEMPLATE_PARAMETERS(0,Count,A)) - -# define BOOST_PYTHON_PMF(Count, cv) \ - R(A0::*)(BOOST_MPL_TEMPLATE_PARAMETERS(1,Count,A))cv() +# define BOOST_PYTHON_FN(inner,start,count) \ + R(inner)(BOOST_MPL_TEMPLATE_PARAMETERS(start,count,A)) # define BOOST_PYTHON_REPEAT_ARITY_2ND(function,data) \ BOOST_PP_REPEAT_FROM_TO_2ND( \ diff --git a/include/boost/python/preprocessed/member_Function_cast.hpp b/include/boost/python/preprocessed/member_Function_cast.hpp new file mode 100644 index 00000000..691b16f5 --- /dev/null +++ b/include/boost/python/preprocessed/member_Function_cast.hpp @@ -0,0 +1,250 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MEMBER_FUNCTION_CAST_DWA2002410_HPP +# define MEMBER_FUNCTION_CAST_DWA2002410_HPP + +template +static cast_helper +stage1(R(S::*)()) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)()const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)()volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)()const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile) +{ + return cast_helper(); +} + +#endif // MEMBER_FUNCTION_CAST_DWA2002410_HPP From 5dab2802b3a241136ce6db34a8bb89954c643e19 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 10 Apr 2002 19:33:52 +0000 Subject: [PATCH 0381/1042] changed the formula for function description with the PP lib [SVN r13437] --- include/boost/python/detail/arg_tuple_size.hpp | 8 ++++---- include/boost/python/detail/caller.hpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index 69558337..e958c1c0 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -34,7 +34,7 @@ template struct arg_tuple_size; // Specializations for function pointers # define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \ template \ -struct arg_tuple_size \ +struct arg_tuple_size \ { \ BOOST_STATIC_CONSTANT(std::size_t, value = args); \ }; @@ -42,7 +42,7 @@ struct arg_tuple_size // Specializations for member function pointers # define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF(args, cv) \ template \ -struct arg_tuple_size \ +struct arg_tuple_size \ { \ BOOST_STATIC_CONSTANT(std::size_t, value = args); \ }; @@ -62,11 +62,11 @@ struct arg_tuple_size \ # define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \ template \ -char_array arg_tuple_size_helper(BOOST_PYTHON_PF(args)); +char_array arg_tuple_size_helper(BOOST_PYTHON_FN(*,0,args)); # define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF(args, cv) \ template \ -char_array arg_tuple_size_helper(BOOST_PYTHON_PMF(args,cv)); +char_array arg_tuple_size_helper(BOOST_PYTHON_FN(A0::*,1,args)cv()); # endif diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index feaa9397..4a779e19 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -37,7 +37,7 @@ template < BOOST_PP_COMMA_IF(args_) BOOST_MPL_TEMPLATE_PARAMETERS(0, args_, class A) \ > \ PyObject* operator()( \ - BOOST_PYTHON_NAMED_PF(f,args_) \ + BOOST_PYTHON_FN(*f,0,args_) \ , PyObject* args, PyObject* keywords \ , P const& policies \ ) const \ @@ -51,7 +51,7 @@ BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CALLER_PF, nil) # define BOOST_PYTHON_CALLER_PMF(args_, cv) \ template \ PyObject* operator()( \ - BOOST_PYTHON_NAMED_PMF(f,args_,cv) \ + BOOST_PYTHON_FN(A0::*f,1,args_)cv() \ , PyObject* args, PyObject* keywords \ , P const& policies \ ) const \ From b704d42fe41e041942ee270fac8dae1293411b7e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 10 Apr 2002 20:56:35 +0000 Subject: [PATCH 0382/1042] Restore workaround for Compaq cxx and SGI CC (it is a generic EDG problem). [SVN r13438] --- include/boost/python/detail/config.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 8b8bea42..c0cb41e2 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -81,7 +81,9 @@ # define BOOST_PYTHON_STATIC_LINK #endif -#if defined(__MWERKS__) +#if defined(__MWERKS__) \ + || (defined(__DECCXX_VER) && __DECCXX_VER <= 60590002) \ + || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) # define BOOST_PYTHON_NO_TEMPLATE_EXPORT #endif From 4018b284e320a6005cac49fc20cad4d3e02a6489 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 11 Apr 2002 04:17:29 +0000 Subject: [PATCH 0383/1042] returning takes policies by-pointer for GCC 2.95.3 :( [SVN r13441] --- include/boost/python/preprocessed/caller.hpp | 100 +++++++++---------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/include/boost/python/preprocessed/caller.hpp b/include/boost/python/preprocessed/caller.hpp index aa466ad7..3a28a9bc 100644 --- a/include/boost/python/preprocessed/caller.hpp +++ b/include/boost/python/preprocessed/caller.hpp @@ -9,253 +9,253 @@ template PyObject*operator()(R(*f)(),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(*f)(A0),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(*f)(A0,A1),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(*f)(A0,A1,A2),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(*f)(A0,A1,A2,A3),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(*f)(A0,A1,A2,A3,A4),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)()const,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1)const,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2)const,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3)const,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)const,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)const,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)const,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)()volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1)volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2)volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3)volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)()const volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } template PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { - return returning::call(f,args,keywords,policies); + return returning::call(f,args,keywords,&policies); } #endif // CALLER_DWA2002410_HPP From 8a3e78629481340df0c144cda9b1f3e81f2f133f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 11 Apr 2002 04:18:52 +0000 Subject: [PATCH 0384/1042] Use preprocessor for detail/returning.hpp [SVN r13442] --- include/boost/python/detail/returning.hpp | 1553 ++--------------- .../preprocessed/returning_non_void.hpp | 991 +++++++++++ .../python/preprocessed/returning_void.hpp | 842 +++++++++ 3 files changed, 1956 insertions(+), 1430 deletions(-) create mode 100644 include/boost/python/preprocessed/returning_non_void.hpp create mode 100644 include/boost/python/preprocessed/returning_void.hpp diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 2c5d8c4f..8ffc2286 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -17,1462 +17,155 @@ # include # include +# include +# include +# include +# include +# include +# include +# include + namespace boost { namespace python { namespace detail { + // Calling C++ from Python template struct returning { - template - static PyObject* call(R (A0::*pmf)(), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; + +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; +# define BOOST_PYTHON_ARG_CONVERTIBLE(index,ignored) \ + from_python \ + BOOST_PP_CAT(c,index)(PyTuple_GET_ITEM(args_, index)); \ + if (!BOOST_PP_CAT(c,index).convertible()) return 0; - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - ) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; +# define BOOST_PYTHON_GET_ARG(index,ignored) \ + BOOST_PP_CAT(c,index)(PyTuple_GET_ITEM(args_, index)) - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args_, 5)); - if (!c5.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4)) - , c5(PyTuple_GET_ITEM(args_, 5))) ); - - return policies.postcall(args_, result); +# define BOOST_PYTHON_RETURNING_NON_VOID_MF(args,cv) \ + template \ + static PyObject* call( \ + BOOST_PYTHON_FN(A0::*pmf,1,args) cv() \ + , PyObject* args_, PyObject* \ + , P const* policies) \ + { \ + /* check that each of the arguments is convertible */ \ + /* self argument is special */ \ + from_python c0(PyTuple_GET_ITEM(args_, 0)); \ + if (!c0.convertible()) return 0; \ + \ + /* Unroll a loop for the rest of them */ \ + BOOST_PP_REPEAT_FROM_TO(1,args,BOOST_PYTHON_ARG_CONVERTIBLE,nil) \ + \ + /* find the result converter */ \ + typedef typename P::result_converter result_converter; \ + typename mpl::apply1::type cr; \ + if (!cr.convertible()) return 0; \ + \ + if (!policies->precall(args_)) return 0; \ + \ + PyObject* result = cr( \ + ((BOOST_PYTHON_GET_ARG(0,nil))->*pmf)( \ + BOOST_PP_ENUM_SHIFTED(args,BOOST_PYTHON_GET_ARG,nil)) \ + ); \ + \ + return policies->postcall(args_, result); \ } - template - static PyObject* call(R (A0::*pmf)() const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - ) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args_, 5)); - if (!c5.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4)) - , c5(PyTuple_GET_ITEM(args_, 5))) ); - - return policies.postcall(args_, result); +// Generate a series for each cv-qualification +BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_RETURNING_NON_VOID_MF) + +# define BOOST_PYTHON_RETURNING_NON_VOID_FN(args,ignored) \ + template \ + static PyObject* call( \ + BOOST_PYTHON_FN(*pf,0,args) \ + , PyObject* args_ \ + , PyObject* \ + , P const* policies) \ + { \ + /* check that each of the arguments is convertible */ \ + BOOST_PP_REPEAT(args,BOOST_PYTHON_ARG_CONVERTIBLE,nil) \ + \ + /* find the result converter */ \ + typedef typename P::result_converter result_converter; \ + typename mpl::apply1::type cr; \ + if (!cr.convertible()) return 0; \ + \ + if (!policies->precall(args_)) return 0; \ + \ + PyObject* result = cr( \ + (*pf)(BOOST_PP_ENUM(args,BOOST_PYTHON_GET_ARG,nil)) \ + ); \ + \ + return policies->postcall(args_, result); \ } - template - static PyObject* call(R (A0::*pmf)() volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - ) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args_, 5)); - if (!c5.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4)) - , c5(PyTuple_GET_ITEM(args_, 5))) ); - - return policies.postcall(args_, result); - } - - -// missing const volatile type traits -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - ) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args_, 5)); - if (!c5.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4)) - , c5(PyTuple_GET_ITEM(args_, 5))) ); - - return policies.postcall(args_, result); - } - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - template - static PyObject* call(R (*pf)(), PyObject* args_, PyObject*, P const& policies) - { - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( (*pf)( - ) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (*pf)(A0), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( (*pf)( - c0(PyTuple_GET_ITEM(args_, 0))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (*pf)(A0, A1), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( (*pf)( - c0(PyTuple_GET_ITEM(args_, 0)) - , c1(PyTuple_GET_ITEM(args_, 1))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( (*pf)( - c0(PyTuple_GET_ITEM(args_, 0)) - , c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( (*pf)( - c0(PyTuple_GET_ITEM(args_, 0)) - , c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( (*pf)( - c0(PyTuple_GET_ITEM(args_, 0)) - , c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4))) ); - - return policies.postcall(args_, result); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args_, 5)); - if (!c5.convertible()) return 0; - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - PyObject* result = cr( (*pf)( - c0(PyTuple_GET_ITEM(args_, 0)) - , c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4)) - , c5(PyTuple_GET_ITEM(args_, 5))) ); - - return policies.postcall(args_, result); - } +BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_RETURNING_NON_VOID_FN, nil) }; template <> struct returning { typedef void R; - template - static PyObject* call(R (A0::*pmf)(), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - if (!policies.precall(args_)) return 0; +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - ); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; +#define BOOST_PYTHON_RETURNING_VOID_MF(args,cv) \ +template \ +static PyObject*call( \ + BOOST_PYTHON_FN(A0::*pmf,1,args) cv() \ + , PyObject*args_ \ + , PyObject* \ + , P const* policies) \ +{ \ + /* check that each of the arguments is convertible */ \ + /* self argument is special */ \ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); \ + if (!c0.convertible()) return 0; \ + \ + /* Unroll a loop for the rest of them */ \ + BOOST_PP_REPEAT_FROM_TO(1,args,BOOST_PYTHON_ARG_CONVERTIBLE,nil) \ + \ + if (!policies->precall(args_)) return 0; \ + \ + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( \ + BOOST_PP_ENUM_SHIFTED(args,BOOST_PYTHON_GET_ARG,nil) \ + ); \ + \ + return policies->postcall(args_,detail::none()); \ +} - if (!policies.precall(args_)) return 0; +//Generate a series for each cv-qualification +BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_RETURNING_VOID_MF) + +#define BOOST_PYTHON_RETURNING_VOID_FN(args,ignored) \ +template \ +static PyObject*call( \ + BOOST_PYTHON_FN(*pf,0,args) \ + , PyObject*args_ \ + , PyObject* \ + , P const* policies) \ +{ \ + /*check that each of the arguments is convertible*/ \ + BOOST_PP_REPEAT(args,BOOST_PYTHON_ARG_CONVERTIBLE,nil) \ + \ + BOOST_PP_EXPR_IF(args,if (!policies->precall(args_)) return 0;) \ + \ + (*pf)(BOOST_PP_ENUM(args,BOOST_PYTHON_GET_ARG,nil)); \ + \ + return policies->postcall(args_,detail::none()); \ +} - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; +BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_RETURNING_VOID_FN,nil) - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args_, 5)); - if (!c5.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4)) - , c5(PyTuple_GET_ITEM(args_, 5))); - - return policies.postcall(args_, detail::none()); - } - - template - static PyObject* call(R (A0::*pmf)() const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - ); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1) const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args_, 5)); - if (!c5.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4)) - , c5(PyTuple_GET_ITEM(args_, 5))); - - return policies.postcall(args_, detail::none()); - } - - template - static PyObject* call(R (A0::*pmf)() volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - ); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1) volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args_, 5)); - if (!c5.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4)) - , c5(PyTuple_GET_ITEM(args_, 5))); - - return policies.postcall(args_, detail::none()); - } - - -// missing const volatile type traits -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - static PyObject* call(R (A0::*pmf)() const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - ); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1) const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2) const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3) const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4) const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (A0::*pmf)(A1, A2, A3, A4, A5) const volatile, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args_, 5)); - if (!c5.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - ((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4)) - , c5(PyTuple_GET_ITEM(args_, 5))); - - return policies.postcall(args_, detail::none()); - } - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - template - static PyObject* call(R (*pf)(), PyObject* args_, PyObject*, P const& policies) - { - (*pf)( - ); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (*pf)(A0), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - (*pf)( - c0(PyTuple_GET_ITEM(args_, 0))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (*pf)(A0, A1), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - (*pf)( - c0(PyTuple_GET_ITEM(args_, 0)) - , c1(PyTuple_GET_ITEM(args_, 1))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (*pf)(A0, A1, A2), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - (*pf)( - c0(PyTuple_GET_ITEM(args_, 0)) - , c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - (*pf)( - c0(PyTuple_GET_ITEM(args_, 0)) - , c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - (*pf)( - c0(PyTuple_GET_ITEM(args_, 0)) - , c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4))); - - return policies.postcall(args_, detail::none()); - } - template - static PyObject* call(R (*pf)(A0, A1, A2, A3, A4, A5), PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; - from_python c1(PyTuple_GET_ITEM(args_, 1)); - if (!c1.convertible()) return 0; - from_python c2(PyTuple_GET_ITEM(args_, 2)); - if (!c2.convertible()) return 0; - from_python c3(PyTuple_GET_ITEM(args_, 3)); - if (!c3.convertible()) return 0; - from_python c4(PyTuple_GET_ITEM(args_, 4)); - if (!c4.convertible()) return 0; - from_python c5(PyTuple_GET_ITEM(args_, 5)); - if (!c5.convertible()) return 0; - - if (!policies.precall(args_)) return 0; - - (*pf)( - c0(PyTuple_GET_ITEM(args_, 0)) - , c1(PyTuple_GET_ITEM(args_, 1)) - , c2(PyTuple_GET_ITEM(args_, 2)) - , c3(PyTuple_GET_ITEM(args_, 3)) - , c4(PyTuple_GET_ITEM(args_, 4)) - , c5(PyTuple_GET_ITEM(args_, 5))); - - return policies.postcall(args_, detail::none()); - } }; }}} // namespace boost::python::detail -#endif // RETURNING_DWA20011201_HPP +#endif//RETURNING_DWA20011201_HPP diff --git a/include/boost/python/preprocessed/returning_non_void.hpp b/include/boost/python/preprocessed/returning_non_void.hpp new file mode 100644 index 00000000..4b39bebc --- /dev/null +++ b/include/boost/python/preprocessed/returning_non_void.hpp @@ -0,0 +1,991 @@ +//Copyright David Abrahams 2002.Permission to copy,use, +//modify,sell and distribute this software is granted provided this +//copyright notice appears in all copies.This software is provided +//"as is" without express or implied warranty,and with no claim as +//to its suitability for any purpose. +#ifndef RETURNING_NON_VOID_DWA2002410_HPP +#define RETURNING_NON_VOID_DWA2002410_HPP + +templatestatic PyObject*call( R( A0::*pmf )( ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); + if (!c9.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( ) const,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1 ) const,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) const,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) const,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) const,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) const,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) const,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) const,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) const,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) const,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); + if (!c9.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( ) volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1 ) volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); + if (!c9.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( ) const volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1 ) const volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) const volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) const volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) const volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) const volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) const volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) const volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) const volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) const volatile,PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); + if (!c9.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ) ); + return policies->postcall(args_,result); +} + +templatestatic PyObject*call( R(*pf )( ),PyObject*args_,PyObject*,P const* policies) +{ + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (*pf)( ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R(*pf )( A0 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R(*pf )( A0,A1 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6,A7 ),PyObject*args_,PyObject*,P const* policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ) ); + return policies->postcall(args_,result); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6,A7,A8 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + if (!policies->precall(args_)) return 0; + PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ) ); + return policies->postcall(args_,result); +} + +#endif // RETURNING_NON_VOID_DWA2002410_HPP diff --git a/include/boost/python/preprocessed/returning_void.hpp b/include/boost/python/preprocessed/returning_void.hpp new file mode 100644 index 00000000..945c4318 --- /dev/null +++ b/include/boost/python/preprocessed/returning_void.hpp @@ -0,0 +1,842 @@ +//Copyright David Abrahams 2002.Permission to copy,use, +//modify,sell and distribute this software is granted provided this +//copyright notice appears in all copies.This software is provided +//"as is" without express or implied warranty,and with no claim as +//to its suitability for any purpose. +#ifndef RETURNING_VOID_DWA2002410_HPP +#define RETURNING_VOID_DWA2002410_HPP + +templatestatic PyObject*call( R( A0::*pmf )( ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); + if (!c9.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( ) const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1 ) const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); + if (!c9.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( ) volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1 ) volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); + if (!c9.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( ) const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1 ) const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); + if (!c9.convertible()) return 0; + if (!policies->precall(args_)) return 0; + ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ); + return policies->postcall(args_,detail::none()); +} + + + +templatestatic PyObject*call( R(*pf )( ),PyObject*args_,PyObject*,P const*policies) +{ + (*pf)( ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R(*pf )( A0 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + if (!policies->precall(args_)) return 0; + (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R(*pf )( A0,A1 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + if (!policies->precall(args_)) return 0; + (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + if (!policies->precall(args_)) return 0; + (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + if (!policies->precall(args_)) return 0; + (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + if (!policies->precall(args_)) return 0; + (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + if (!policies->precall(args_)) return 0; + (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + if (!policies->precall(args_)) return 0; + (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6,A7 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + if (!policies->precall(args_)) return 0; + (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ); + return policies->postcall(args_,detail::none()); +} +templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6,A7,A8 ),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); + if (!c0.convertible()) return 0; + from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); + if (!c1.convertible()) return 0; + from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); + if (!c2.convertible()) return 0; + from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); + if (!c3.convertible()) return 0; + from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); + if (!c4.convertible()) return 0; + from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); + if (!c5.convertible()) return 0; + from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); + if (!c6.convertible()) return 0; + from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); + if (!c7.convertible()) return 0; + from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); + if (!c8.convertible()) return 0; + if (!policies->precall(args_)) return 0; + (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ); + return policies->postcall(args_,detail::none()); +} + +#endif//RETURNING_VOID_DWA2002410_HPP From 47ad802ab6663b94ee34f111e9ba680fad82bef1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 11 Apr 2002 12:44:37 +0000 Subject: [PATCH 0385/1042] Pass policies to returning<> by-pointer for GCC 2.95.2 :( [SVN r13443] --- include/boost/python/detail/caller.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index 4a779e19..87ea5405 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -42,7 +42,7 @@ PyObject* operator()( , P const& policies \ ) const \ { \ - return returning::call(f, args, keywords, policies); \ + return returning::call(f, args, keywords,&policies); \ } BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CALLER_PF, nil) @@ -56,7 +56,7 @@ PyObject* operator()( , P const& policies \ ) const \ { \ - return returning::call(f, args, keywords, policies); \ + return returning::call(f, args, keywords,&policies); \ } BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_CALLER_PMF) From a47fbc18f740b7667871619c8d0eed5229b42ee5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 11 Apr 2002 18:58:10 +0000 Subject: [PATCH 0386/1042] Use PP lib for holders [SVN r13447] --- include/boost/python/detail/preprocessor.hpp | 8 + include/boost/python/detail/signature.hpp | 217 ------------- include/boost/python/object/class.hpp | 2 + .../boost/python/object/pointer_holder.hpp | 295 +++--------------- include/boost/python/object/value_holder.hpp | 293 +++-------------- .../python/preprocessed/pointer_holder.hpp | 105 +++++++ .../pointer_holder_back_reference.hpp | 115 +++++++ .../python/preprocessed/value_holder.hpp | 105 +++++++ .../value_holder_back_reference.hpp | 117 +++++++ 9 files changed, 523 insertions(+), 734 deletions(-) delete mode 100644 include/boost/python/detail/signature.hpp create mode 100644 include/boost/python/preprocessed/pointer_holder.hpp create mode 100644 include/boost/python/preprocessed/pointer_holder_back_reference.hpp create mode 100644 include/boost/python/preprocessed/value_holder.hpp create mode 100644 include/boost/python/preprocessed/value_holder_back_reference.hpp diff --git a/include/boost/python/detail/preprocessor.hpp b/include/boost/python/detail/preprocessor.hpp index 23278436..728c4699 100644 --- a/include/boost/python/detail/preprocessor.hpp +++ b/include/boost/python/detail/preprocessor.hpp @@ -8,10 +8,12 @@ # include # include +# include # include # include # include # include +# include # include namespace boost { namespace python { namespace detail { @@ -83,6 +85,12 @@ namespace boost { namespace python { namespace detail { # define BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(function) \ BOOST_PP_LIST_FOR_EACH(BOOST_PYTHON_REPEAT_PMF_CV,function,BOOST_PYTHON_ALL_CV) +#define BOOST_PYTHON_NUMBER_PAIR(Index, Pair) \ + BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,Pair),Index) \ + BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,1,Pair),Index) + +#define BOOST_PYTHON_ENUM_PARAMS2(N, Pair) BOOST_PP_ENUM(N, BOOST_PYTHON_NUMBER_PAIR, Pair) + }}} // namespace boost::python::detail diff --git a/include/boost/python/detail/signature.hpp b/include/boost/python/detail/signature.hpp deleted file mode 100644 index db8b39a4..00000000 --- a/include/boost/python/detail/signature.hpp +++ /dev/null @@ -1,217 +0,0 @@ -// (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley and Lawrence -// Livermore National Labs -// -// This file generated for 5-argument member functions and 6-argument free -// functions by gen_signature.py - -#ifndef SIGNATURE_DWA2002128_HPP -# define SIGNATURE_DWA2002128_HPP - -# include - -namespace boost { namespace python { namespace detail { - -template -mpl::type_list -signature(R (*)()) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0)) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0, A1)) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0, A1, A2)) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0, A1, A2, A3)) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0, A1, A2, A3, A4)) -{ - return mpl::type_list(); -} - -template -mpl::type_list -signature(R (*)(A0, A1, A2, A3, A4, A5)) -{ - return mpl::type_list(); -} -template -mpl::type_list signature(R (A0::*)()) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1)) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2)) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3)) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4)) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5)) -{ - return mpl::type_list(); -} - - -template -mpl::type_list signature(R (A0::*)() const) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1) const) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2) const) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3) const) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4) const) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5) const) -{ - return mpl::type_list(); -} - - -template -mpl::type_list signature(R (A0::*)() volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1) volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2) volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3) volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4) volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5) volatile) -{ - return mpl::type_list(); -} - - -template -mpl::type_list signature(R (A0::*)() const volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1) const volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2) const volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3) const volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4) const volatile) -{ - return mpl::type_list(); -} - -template -mpl::type_list signature(R (A0::*)(A1, A2, A3, A4, A5) const volatile) -{ - return mpl::type_list(); -} - -}}} // namespace boost::python::detail - -#endif // SIGNATURE_DWA2002128_HPP - diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 5ca8c41e..10c54629 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -59,6 +59,8 @@ struct BOOST_PYTHON_DECL instance_holder : private noncopyable private: instance_holder* m_next; }; +// This macro is needed for implementation of derived holders +# define BOOST_PYTHON_UNFORWARD(N,ignored) (typename unforward::type)(a##N) // Each extension instance will be one of these struct instance diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 3a8e2cec..31e8fead 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -15,6 +15,8 @@ # include # include # include +# include +# include namespace boost { namespace python { namespace objects { @@ -22,125 +24,27 @@ template struct pointer_holder : instance_holder { pointer_holder(Pointer); - + // Forward construction to the held object - pointer_holder(PyObject*) - : m_p(new Value) {} +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif - - template - pointer_holder(PyObject*, A1 a1) - : m_p(new Value( - (typename unforward::type)(a1) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2) - : m_p(new Value( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3) - : m_p(new Value( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) - : m_p(new Value( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - : m_p(new Value( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - )) {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - : m_p(new Value( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - )) {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) - : m_p(new Value( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) - : m_p(new Value( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) - : m_p(new Value( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - , (typename unforward::type)(a9) - )) - {} - - template - pointer_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) - : m_p(new Value( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - , (typename unforward::type)(a9) - , (typename unforward::type)(a10) - )) + +# define BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER(nargs, ignored) \ + BOOST_PP_EXPR_IF(nargs, template <) \ + BOOST_PP_ENUM_PARAMS(nargs, class A) \ + BOOST_PP_EXPR_IF(nargs, >) \ + pointer_holder(PyObject* \ + BOOST_PP_COMMA_IF(nargs) \ + BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ + : m_p(new Value( \ + BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ + )) \ {} + BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER,nil) + private: // required holder implementation void* holds(converter::undecorated_type_id_t); @@ -158,153 +62,26 @@ struct pointer_holder_back_reference : instance_holder pointer_holder_back_reference(Pointer); // Forward construction to the held object - pointer_holder_back_reference(PyObject* p) - : m_p(new held_type(p)) { - void const* x = &instance_finder::registration; (void)x; - } - - template - pointer_holder_back_reference(PyObject* p, A1 a1) - : m_p(new held_type(p - , (typename unforward::type)(a1) - )) - { - void const* x = &instance_finder::registration; (void)x; - } - +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif - template - pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2) - : m_p(new held_type(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - )) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3) - : m_p(new held_type(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - )) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4) - : m_p(new held_type(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - )) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - : m_p(new held_type(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - )) { - void const* x = &instance_finder::registration; (void)x; - } - - - template - pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - : m_p(new held_type(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - )) { - void const* x = &instance_finder::registration; (void)x; - } - - - template - pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) - : m_p(new held_type(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - )) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) - : m_p(new held_type(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - )) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) - : m_p(new held_type(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - , (typename unforward::type)(a9) - )) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - pointer_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) - : m_p(new held_type(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - , (typename unforward::type)(a9) - , (typename unforward::type)(a10) - )) - { - void const* x = &instance_finder::registration; (void)x; +# define BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER_BACK_REFERENCE(nargs, ignored) \ + BOOST_PP_EXPR_IF(nargs, template <) \ + BOOST_PP_ENUM_PARAMS(nargs, class A) \ + BOOST_PP_EXPR_IF(nargs, >) \ + pointer_holder_back_reference(PyObject* p \ + BOOST_PP_COMMA_IF(nargs) \ + BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ + : m_p(new held_type( \ + p, \ + BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ + )) \ + { \ + void const* x = &instance_finder::registration; (void)x; \ } + BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER_BACK_REFERENCE,nil) private: // required holder implementation void* holds(converter::undecorated_type_id_t); diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index d98d1d10..49251921 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -12,6 +12,8 @@ # include # include # include +# include +# include namespace boost { namespace python { namespace objects { @@ -19,122 +21,24 @@ template struct value_holder : instance_holder { // Forward construction to the held object - value_holder(PyObject*) - : m_held() {} - - template - value_holder(PyObject*, A1 a1) - : m_held( - (typename unforward::type)(a1) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2) - : m_held( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3) - : m_held( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) - : m_held( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - : m_held( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - ) {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - : m_held( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - ) {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) - : m_held( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) - : m_held( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) - : m_held( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - , (typename unforward::type)(a9) - ) - {} - - template - value_holder(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) - : m_held( - (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - , (typename unforward::type)(a9) - , (typename unforward::type)(a10) - ) +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif + +# define BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER(nargs, ignored) \ + BOOST_PP_EXPR_IF(nargs, template <) \ + BOOST_PP_ENUM_PARAMS(nargs, class A) \ + BOOST_PP_EXPR_IF(nargs, >) \ + value_holder(PyObject* \ + BOOST_PP_COMMA_IF(nargs) \ + BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ + : m_held( \ + BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ + ) \ {} + BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER,nil) + private: // required holder implementation void* holds(converter::undecorated_type_id_t); @@ -146,154 +50,27 @@ template struct value_holder_back_reference : instance_holder { // Forward construction to the held object - value_holder_back_reference(PyObject* p) - : m_held() { - void const* x = &instance_finder::registration; (void)x; - } - +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif - template - value_holder_back_reference(PyObject* p, A1 a1) - : m_held(p - , (typename unforward::type)(a1) - ) - { - void const* x = &instance_finder::registration; (void)x; +# define BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER_BACK_REFERENCE(nargs, ignored) \ + BOOST_PP_EXPR_IF(nargs, template <) \ + BOOST_PP_ENUM_PARAMS(nargs, class A) \ + BOOST_PP_EXPR_IF(nargs, >) \ + value_holder_back_reference(PyObject* p \ + BOOST_PP_COMMA_IF(nargs) \ + BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ + : m_held( \ + p BOOST_PP_COMMA_IF(nargs) \ + BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ + ) \ + { \ + void const* x = &instance_finder::registration; (void)x; \ } + BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER_BACK_REFERENCE,nil) - template - value_holder_back_reference(PyObject* p, A1 a1, A2 a2) - : m_held(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - ) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3) - : m_held(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - ) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4) - : m_held(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - ) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) - : m_held(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - ) { - void const* x = &instance_finder::registration; (void)x; - } - - - template - value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) - : m_held(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - ) { - void const* x = &instance_finder::registration; (void)x; - } - - - template - value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) - : m_held(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - ) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) - : m_held(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - ) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) - : m_held(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - , (typename unforward::type)(a9) - ) - { - void const* x = &instance_finder::registration; (void)x; - } - - - template - value_holder_back_reference(PyObject* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) - : m_held(p - , (typename unforward::type)(a1) - , (typename unforward::type)(a2) - , (typename unforward::type)(a3) - , (typename unforward::type)(a4) - , (typename unforward::type)(a5) - , (typename unforward::type)(a6) - , (typename unforward::type)(a7) - , (typename unforward::type)(a8) - , (typename unforward::type)(a9) - , (typename unforward::type)(a10) - ) - { - void const* x = &instance_finder::registration; (void)x; - } - private: // required holder implementation void* holds(converter::undecorated_type_id_t); diff --git a/include/boost/python/preprocessed/pointer_holder.hpp b/include/boost/python/preprocessed/pointer_holder.hpp new file mode 100644 index 00000000..0f2bf149 --- /dev/null +++ b/include/boost/python/preprocessed/pointer_holder.hpp @@ -0,0 +1,105 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef POINTER_HOLDER_DWA2002411_HPP +# define POINTER_HOLDER_DWA2002411_HPP + +pointer_holder(PyObject*) + :m_p(new Value()) +{ + +} +templatepointer_holder(PyObject*,A0 a0) + :m_p(new Value( + (typename unforward::type)(a0))) +{ + +} +templatepointer_holder(PyObject*,A0 a0,A1 a1) + :m_p(new Value( + (typename unforward::type)(a0), + (typename unforward::type)(a1))) +{ + +} +templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2) + :m_p(new Value( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2))) +{ + +} +templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3) + :m_p(new Value( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3))) +{ + +} +templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) + :m_p(new Value( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4))) +{ + +} +templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) + :m_p(new Value( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5))) +{ + +} +templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) + :m_p(new Value( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6))) +{ + +} +templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) + :m_p(new Value( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6), + (typename unforward::type)(a7))) +{ + +} +templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) + :m_p(new Value( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6), + (typename unforward::type)(a7), + (typename unforward::type)(a8))) +{ + +} + +#endif // POINTER_HOLDER_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/pointer_holder_back_reference.hpp b/include/boost/python/preprocessed/pointer_holder_back_reference.hpp new file mode 100644 index 00000000..b07242cc --- /dev/null +++ b/include/boost/python/preprocessed/pointer_holder_back_reference.hpp @@ -0,0 +1,115 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP +# define POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP + +pointer_holder_back_reference(PyObject*p) + :m_p(new held_type(p,)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatepointer_holder_back_reference(PyObject*p,A0 a0) + :m_p(new held_type(p, + (typename unforward::type)(a0))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1) + :m_p(new held_type(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) + :m_p(new held_type(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) + :m_p(new held_type(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) + :m_p(new held_type(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) + :m_p(new held_type(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) + :m_p(new held_type(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) + :m_p(new held_type(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6), + (typename unforward::type)(a7))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) + :m_p(new held_type(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6), + (typename unforward::type)(a7), + (typename unforward::type)(a8))) +{ + void const*x=&instance_finder::registration; + (void)x; +} + +#endif // POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/value_holder.hpp b/include/boost/python/preprocessed/value_holder.hpp new file mode 100644 index 00000000..88ba56dd --- /dev/null +++ b/include/boost/python/preprocessed/value_holder.hpp @@ -0,0 +1,105 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef VALUE_HOLDER_DWA2002411_HPP +# define VALUE_HOLDER_DWA2002411_HPP + +value_holder(PyObject*) + :m_held() +{ + +} +templatevalue_holder(PyObject*,A0 a0) + :m_held( + (typename unforward::type)(a0)) +{ + +} +templatevalue_holder(PyObject*,A0 a0,A1 a1) + :m_held( + (typename unforward::type)(a0), + (typename unforward::type)(a1)) +{ + +} +templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2) + :m_held( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2)) +{ + +} +templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3) + :m_held( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3)) +{ + +} +templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) + :m_held( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4)) +{ + +} +templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) + :m_held( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5)) +{ + +} +templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) + :m_held( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6)) +{ + +} +templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) + :m_held( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6), + (typename unforward::type)(a7)) +{ + +} +templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) + :m_held( + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6), + (typename unforward::type)(a7), + (typename unforward::type)(a8)) +{ + +} + +#endif // VALUE_HOLDER_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/value_holder_back_reference.hpp b/include/boost/python/preprocessed/value_holder_back_reference.hpp new file mode 100644 index 00000000..c9d91434 --- /dev/null +++ b/include/boost/python/preprocessed/value_holder_back_reference.hpp @@ -0,0 +1,117 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef VALUE_HOLDER_BACK_REFERENCE_DWA2002411_HPP +# define VALUE_HOLDER_BACK_REFERENCE_DWA2002411_HPP + +value_holder_back_reference(PyObject*p) + :m_held(p) +{ + void const*x=&instance_finder::registration; + (void)x; +} + + +templatevalue_holder_back_reference(PyObject*p,A0 a0) + :m_held(p, + (typename unforward::type)(a0)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1) + :m_held(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) + :m_held(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) + :m_held(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) + :m_held(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) + :m_held(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) + :m_held(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) + :m_held(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6), + (typename unforward::type)(a7)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) + :m_held(p, + (typename unforward::type)(a0), + (typename unforward::type)(a1), + (typename unforward::type)(a2), + (typename unforward::type)(a3), + (typename unforward::type)(a4), + (typename unforward::type)(a5), + (typename unforward::type)(a6), + (typename unforward::type)(a7), + (typename unforward::type)(a8)) +{ + void const*x=&instance_finder::registration; + (void)x; +} + +#endif // VALUE_HOLDER_BACK_REFERENCE_DWA2002411_HPP From 7d8b6d149ead39baff11c01957d6dbe5befd53d8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 11 Apr 2002 21:01:10 +0000 Subject: [PATCH 0387/1042] Fixed installation/configuration checks [SVN r13451] --- build/Jamfile | 2 +- build/__init__.py | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index 00bb22dd..c8cf3d4e 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -63,7 +63,7 @@ include python.jam ; # This nasty hack works with versions of Python 1.5.2 -> 2.2 to avoid # building any Python stuff if there's no installation. -SEARCH on __init__.py = $(PYTHON_LIB_PATH)/test $(SUBDIR) ; +SEARCH on __init__.py = $(PYTHON_STDLIB_PATH)/test $(SUBDIR) ; include __init__.py ; if ! $(gNO_PYTHON_INSTALL) { diff --git a/build/__init__.py b/build/__init__.py index 94f3b100..f89be274 100644 --- a/build/__init__.py +++ b/build/__init__.py @@ -3,12 +3,15 @@ if ! $(gNO_PYTHON_INSTALL) { - ECHO Couldn't find Python $(PYTHON_VERSION) installation in $(PYTHON_ROOT) ; + ECHO "Couldn't find Python $(PYTHON_VERSION) installation in $(PYTHON_ROOT)" ; ECHO skipping Boost.Python library build ; ECHO You can configure the location of your python installation, by setting: ; ECHO PYTHON_ROOT - currently \"$(PYTHON_ROOT)\" ; ECHO PYTHON_VERSION - currently \"$(PYTHON_VERSION)\" ; - ECHO PYTHON_INCLUDES - configured from PYTHON_ROOT, currently \"$(PYTHON_INCLUDES)\" ; - ECHO PYTHON_LIB_PATH - configured from PYTHON_ROOT, currently \"$(PYTHON_LIB_PATH)\" ; + ECHO ; + ECHO "The following are automatically configured from PYTHON_ROOT if not otherwise set" ; + ECHO " PYTHON_INCLUDES - path to Python #include directories; currently" \"$(PYTHON_INCLUDES)\" ; + ECHO " PYTHON_LIB_PATH - path to Python library; currently" \"$(PYTHON_LIB_PATH)\" ; + ECHO " PYTHON_STDLIB_PATH - path to Python standard library modules; currently" \"$(PYTHON_STDLIB_PATH)\" ; } gNO_PYTHON_INSTALL ?= true ; From be0ae2389c45b750b1a5fd26195dfd953dce39f2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 12 Apr 2002 05:06:12 +0000 Subject: [PATCH 0388/1042] fixed spelling of filename [SVN r13454] --- .../{member_Function_cast.hpp => member_function_cast.hpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename include/boost/python/preprocessed/{member_Function_cast.hpp => member_function_cast.hpp} (100%) diff --git a/include/boost/python/preprocessed/member_Function_cast.hpp b/include/boost/python/preprocessed/member_function_cast.hpp similarity index 100% rename from include/boost/python/preprocessed/member_Function_cast.hpp rename to include/boost/python/preprocessed/member_function_cast.hpp From 6aa80b07e7e5b34dfdf98c53ea65f75e676a5321 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 12 Apr 2002 05:08:02 +0000 Subject: [PATCH 0389/1042] killed extra semicolon [SVN r13455] --- include/boost/python/detail/member_function_cast.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp index 18af9700..f31c1aed 100644 --- a/include/boost/python/detail/member_function_cast.hpp +++ b/include/boost/python/detail/member_function_cast.hpp @@ -72,7 +72,7 @@ stage1(BOOST_PYTHON_FN(S::*,1,args)cv()) return cast_helper(); \ } -BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_MEMBER_FUNCTION_CAST_STAGE1); +BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_MEMBER_FUNCTION_CAST_STAGE1) }; From e5f2b0c0a9b0a52e8aab5a368626739fb86ed127 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 12 Apr 2002 17:20:49 +0000 Subject: [PATCH 0390/1042] initial checkin [SVN r13461] --- include/boost/python/preprocessed/call.hpp | 125 +++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 include/boost/python/preprocessed/call.hpp diff --git a/include/boost/python/preprocessed/call.hpp b/include/boost/python/preprocessed/call.hpp new file mode 100644 index 00000000..4346116a --- /dev/null +++ b/include/boost/python/preprocessed/call.hpp @@ -0,0 +1,125 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CALL_PP_DWA2002411_HPP +# define CALL_PP_DWA2002411_HPP + +call(PyObject*self) + :m_result( + PyEval_CallFunction(self,const_cast("(" ")"))) +{ + +} +template +call(PyObject*self,A0 const&a0) + :m_result( + PyEval_CallFunction(self,const_cast("(" "O" ")"), + converter::callback_to_python(a0).get())) +{ + +} +template +call(PyObject*self,A0 const&a0,A1 const&a1) + :m_result( + PyEval_CallFunction(self,const_cast("(" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get())) +{ + +} +template +call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2) + :m_result( + PyEval_CallFunction(self,const_cast("(" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get())) +{ + +} +template +call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3) + :m_result( + PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get())) +{ + +} +template +call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4) + :m_result( + PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get(), + converter::callback_to_python(a4).get())) +{ + +} +template +call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5) + :m_result( + PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get(), + converter::callback_to_python(a4).get(), + converter::callback_to_python(a5).get())) +{ + +} +template +call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6) + :m_result( + PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get(), + converter::callback_to_python(a4).get(), + converter::callback_to_python(a5).get(), + converter::callback_to_python(a6).get())) +{ + +} +template +call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7) + :m_result( + PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get(), + converter::callback_to_python(a4).get(), + converter::callback_to_python(a5).get(), + converter::callback_to_python(a6).get(), + converter::callback_to_python(a7).get())) +{ + +} +template +call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8) + :m_result( + PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get(), + converter::callback_to_python(a4).get(), + converter::callback_to_python(a5).get(), + converter::callback_to_python(a6).get(), + converter::callback_to_python(a7).get(), + converter::callback_to_python(a8).get() + )) +{ + +} + +#endif // CALL_PP_DWA2002411_HPP From d23daf225ded571bd60d5711803817994ad9dfaf Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 12 Apr 2002 18:21:42 +0000 Subject: [PATCH 0391/1042] Choose BOOST_PYTHON_DYNAMIC_LIB by default [SVN r13462] --- include/boost/python/detail/config.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index c0cb41e2..ab21a37b 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -79,6 +79,8 @@ // backwards compatibility: #ifdef BOOST_PYTHON_STATIC_LIB # define BOOST_PYTHON_STATIC_LINK +# elif !defined(BOOST_PYTHON_DYNAMIC_LIB) +# define BOOST_PYTHON_DYNAMIC_LIB #endif #if defined(__MWERKS__) \ From 962a08700ef632c399b2087d09b8bec22d2502fa Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 12 Apr 2002 18:29:14 +0000 Subject: [PATCH 0392/1042] Use PP lib [SVN r13463] --- include/boost/python/call.hpp | 49 ++++++ include/boost/python/call_method.hpp | 50 ++++++ include/boost/python/converter/callback.hpp | 36 +++++ include/boost/python/detail/preprocessor.hpp | 2 + .../boost/python/object/pointer_holder.hpp | 2 +- include/boost/python/preprocessed/call.hpp | 151 +++++++++--------- .../boost/python/preprocessed/call_method.hpp | 147 +++++++++++++++++ .../pointer_holder_back_reference.hpp | 17 +- test/callbacks.cpp | 27 ++-- test/virtual_functions.cpp | 6 +- 10 files changed, 387 insertions(+), 100 deletions(-) create mode 100644 include/boost/python/call.hpp create mode 100644 include/boost/python/call_method.hpp create mode 100644 include/boost/python/preprocessed/call_method.hpp diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp new file mode 100644 index 00000000..746b7075 --- /dev/null +++ b/include/boost/python/call.hpp @@ -0,0 +1,49 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CALL_DWA2002411_HPP +# define CALL_DWA2002411_HPP + +# include +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif + +# define BOOST_PYTHON_CALL_FUNCTION(nargs,ignored) \ +template < \ + class R \ + BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM_PARAMS(nargs, class A) \ + > \ +typename converter::callback_from_python::result_type \ +call(PyObject* callable \ + BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a)) \ + , boost::type* = 0 \ + ) \ +{ \ + converter::callback_from_python converter; \ + return converter( \ + PyEval_CallFunction( \ + callable \ + , const_cast(BOOST_PYTHON_ARG_STRING(nargs)) \ + BOOST_PP_COMMA_IF(nargs) \ + BOOST_PP_ENUM(nargs,BOOST_PYTHON_CALLBACK_TO_PYTHON_GET,nil) \ + )); \ +} + +BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CALL_FUNCTION,data) + +}} // namespace boost::python + +#endif // CALL_DWA2002411_HPP diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp new file mode 100644 index 00000000..219b1e19 --- /dev/null +++ b/include/boost/python/call_method.hpp @@ -0,0 +1,50 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CALL_METHOD_DWA2002411_HPP +# define CALL_METHOD_DWA2002411_HPP + +# include +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif + +# define BOOST_PYTHON_CALL_METHOD_FUNCTION(nargs,ignored) \ +template < \ + class R \ + BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM_PARAMS(nargs, class A) \ + > \ +typename converter::callback_from_python::result_type \ +call_method(PyObject* self, char const* name \ + BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a)) \ + , boost::type* = 0 \ + ) \ +{ \ + converter::callback_from_python converter; \ + return converter( \ + PyEval_CallMethod( \ + self \ + , const_cast(name) \ + , const_cast(BOOST_PYTHON_ARG_STRING(nargs)) \ + BOOST_PP_COMMA_IF(nargs) \ + BOOST_PP_ENUM(nargs,BOOST_PYTHON_CALLBACK_TO_PYTHON_GET,nil) \ + )); \ +} + +BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CALL_METHOD_FUNCTION,data) + +}} // namespace boost::python + +#endif // CALL_METHOD_DWA2002411_HPP diff --git a/include/boost/python/converter/callback.hpp b/include/boost/python/converter/callback.hpp index a8fceb53..9e9c694f 100644 --- a/include/boost/python/converter/callback.hpp +++ b/include/boost/python/converter/callback.hpp @@ -17,6 +17,7 @@ # include # include # include +# include namespace boost { namespace python { namespace converter { @@ -132,6 +133,33 @@ template struct callback_from_python : detail::select_callback_from_python::type { + typedef T result_type; +}; + +struct void_result +{ + private: + void_result() {} + void operator=(void_result const&); + + // I would prefer to make this completely untouchable, but few + // compilers support template friends +# if 0 + void_result(void_result const&); +# endif + friend struct callback_from_python; +}; + +// Specialization as a convenience for call and call_method +template <> +struct callback_from_python +{ + typedef void_result result_type; + result_type operator()(PyObject* x) const + { + Py_DECREF(expect_non_null(x)); + return result_type(); + } }; template @@ -144,6 +172,14 @@ struct callback_to_python callback_to_python(T const& x); }; +// Convenience macros for call<> and call_method<> code generation +# define BOOST_PYTHON_CALLBACK_TO_PYTHON_GET(index,ignored) \ + converter::callback_to_python( \ + BOOST_PP_CAT(a,index)).get() + +# define BOOST_PYTHON_ARG_STRING(nargs) \ + "(" BOOST_PP_REPEAT(nargs,BOOST_PYTHON_PROJECT_2ND,"O") ")" + // // Implementations // diff --git a/include/boost/python/detail/preprocessor.hpp b/include/boost/python/detail/preprocessor.hpp index 728c4699..510e0755 100644 --- a/include/boost/python/detail/preprocessor.hpp +++ b/include/boost/python/detail/preprocessor.hpp @@ -91,6 +91,8 @@ namespace boost { namespace python { namespace detail { #define BOOST_PYTHON_ENUM_PARAMS2(N, Pair) BOOST_PP_ENUM(N, BOOST_PYTHON_NUMBER_PAIR, Pair) +# define BOOST_PYTHON_PROJECT_1ST(a1,a2) a1 +# define BOOST_PYTHON_PROJECT_2ND(a1,a2) a2 }}} // namespace boost::python::detail diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 31e8fead..8ae778b4 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -74,7 +74,7 @@ struct pointer_holder_back_reference : instance_holder BOOST_PP_COMMA_IF(nargs) \ BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ : m_p(new held_type( \ - p, \ + p BOOST_PP_COMMA_IF(nargs) \ BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ )) \ { \ diff --git a/include/boost/python/preprocessed/call.hpp b/include/boost/python/preprocessed/call.hpp index 4346116a..2e0e31a1 100644 --- a/include/boost/python/preprocessed/call.hpp +++ b/include/boost/python/preprocessed/call.hpp @@ -1,98 +1,101 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. +//Copyright David Abrahams 2002.Permission to copy,use, +//modify,sell and distribute this software is granted provided this +//copyright notice appears in all copies.This software is provided +//"as is" without express or implied warranty,and with no claim as +//to its suitability for any purpose. #ifndef CALL_PP_DWA2002411_HPP -# define CALL_PP_DWA2002411_HPP +#define CALL_PP_DWA2002411_HPP -call(PyObject*self) - :m_result( - PyEval_CallFunction(self,const_cast("(" ")"))) +template +typename converter::callback_from_python::result_type call(PyObject*callable,boost::type* =0) { - + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction(callable,const_cast("(" ")"))); } -template -call(PyObject*self,A0 const&a0) - :m_result( - PyEval_CallFunction(self,const_cast("(" "O" ")"), - converter::callback_to_python(a0).get())) +template +typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,boost::type* =0) { - + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction(callable,const_cast("(" "O" ")"), + converter::callback_to_python(a0).get())); } -template -call(PyObject*self,A0 const&a0,A1 const&a1) - :m_result( - PyEval_CallFunction(self,const_cast("(" "O" "O" ")"), +template +typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction(callable,const_cast("(" "O" "O" ")"), converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get())) -{ - + converter::callback_to_python(a1).get())); } -template -call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2) - :m_result( - PyEval_CallFunction(self,const_cast("(" "O" "O" "O" ")"), +template +typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" ")"), converter::callback_to_python(a0).get(), converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get())) -{ - + converter::callback_to_python(a2).get())); } -template -call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3) - :m_result( - PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" ")"), +template +typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" ")"), converter::callback_to_python(a0).get(), converter::callback_to_python(a1).get(), converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get())) -{ - + converter::callback_to_python(a3).get())); } -template -call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4) - :m_result( - PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" "O" ")"), +template +typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" "O" ")"), converter::callback_to_python(a0).get(), converter::callback_to_python(a1).get(), converter::callback_to_python(a2).get(), converter::callback_to_python(a3).get(), - converter::callback_to_python(a4).get())) -{ - + converter::callback_to_python(a4).get())); } -template -call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5) - :m_result( - PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" "O" "O" ")"), +template +typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" "O" "O" ")"), converter::callback_to_python(a0).get(), converter::callback_to_python(a1).get(), converter::callback_to_python(a2).get(), converter::callback_to_python(a3).get(), converter::callback_to_python(a4).get(), - converter::callback_to_python(a5).get())) -{ - + converter::callback_to_python(a5).get())); } -template -call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6) - :m_result( - PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")"), +template +typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")"), converter::callback_to_python(a0).get(), converter::callback_to_python(a1).get(), converter::callback_to_python(a2).get(), converter::callback_to_python(a3).get(), converter::callback_to_python(a4).get(), converter::callback_to_python(a5).get(), - converter::callback_to_python(a6).get())) -{ - + converter::callback_to_python(a6).get())); } -template -call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7) - :m_result( - PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")"), +template +typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")"), converter::callback_to_python(a0).get(), converter::callback_to_python(a1).get(), converter::callback_to_python(a2).get(), @@ -100,14 +103,14 @@ call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A converter::callback_to_python(a4).get(), converter::callback_to_python(a5).get(), converter::callback_to_python(a6).get(), - converter::callback_to_python(a7).get())) -{ - + converter::callback_to_python(a7).get())); } -template -call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8) - :m_result( - PyEval_CallFunction(self,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")"), +template +typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")"), converter::callback_to_python(a0).get(), converter::callback_to_python(a1).get(), converter::callback_to_python(a2).get(), @@ -116,10 +119,8 @@ call(PyObject*self,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A converter::callback_to_python(a5).get(), converter::callback_to_python(a6).get(), converter::callback_to_python(a7).get(), - converter::callback_to_python(a8).get() - )) -{ + converter::callback_to_python(a8).get())); +} + -} - -#endif // CALL_PP_DWA2002411_HPP +#endif//CALL_PP_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/call_method.hpp b/include/boost/python/preprocessed/call_method.hpp new file mode 100644 index 00000000..1e395e4a --- /dev/null +++ b/include/boost/python/preprocessed/call_method.hpp @@ -0,0 +1,147 @@ +//Copyright David Abrahams 2002.Permission to copy,use, +//modify,sell and distribute this software is granted provided this +//copyright notice appears in all copies.This software is provided +//"as is" without express or implied warranty,and with no claim as +//to its suitability for any purpose. +#ifndef CALL_METHOD_PP_DWA2002411_HPP +# define CALL_METHOD_PP_DWA2002411_HPP + +templatetypename +converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,boost::type* =0) +{ + + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod(self,const_cast(name),const_cast("(" ")"))); +} +templatetypename +converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,boost::type* =0) +{ + + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" ")"), + converter::callback_to_python(a0).get())); +} +templatetypename +converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,boost::type* =0) +{ + + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get())); +} +templatetypename +converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) +{ + + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get())); +} +templatetypename +converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::type* =0) +{ + + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get())); +} +templatetypename +converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,boost::type* =0) +{ + + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get(), + converter::callback_to_python(a4).get())); +} +templatetypename +converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,boost::type* =0) +{ + + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get(), + converter::callback_to_python(a4).get(), + converter::callback_to_python(a5).get())); +} +templatetypename +converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,boost::type* =0) +{ + + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get(), + converter::callback_to_python(a4).get(), + converter::callback_to_python(a5).get(), + converter::callback_to_python(a6).get())); +} +templatetypename +converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,boost::type* =0) +{ + + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get(), + converter::callback_to_python(a4).get(), + converter::callback_to_python(a5).get(), + converter::callback_to_python(a6).get(), + converter::callback_to_python(a7).get())); +} +templatetypename +converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,boost::type* =0) +{ + + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")"), + converter::callback_to_python(a0).get(), + converter::callback_to_python(a1).get(), + converter::callback_to_python(a2).get(), + converter::callback_to_python(a3).get(), + converter::callback_to_python(a4).get(), + converter::callback_to_python(a5).get(), + converter::callback_to_python(a6).get(), + converter::callback_to_python(a7).get(), + converter::callback_to_python(a8).get())); +} + + +#endif// +CALL_METHOD_PP_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/pointer_holder_back_reference.hpp b/include/boost/python/preprocessed/pointer_holder_back_reference.hpp index b07242cc..9d86a172 100644 --- a/include/boost/python/preprocessed/pointer_holder_back_reference.hpp +++ b/include/boost/python/preprocessed/pointer_holder_back_reference.hpp @@ -1,13 +1,13 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. +//Copyright David Abrahams 2002.Permission to copy,use, +//modify,sell and distribute this software is granted provided this +//copyright notice appears in all copies.This software is provided +//"as is" without express or implied warranty,and with no claim as +//to its suitability for any purpose. #ifndef POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP -# define POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP +#define POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP pointer_holder_back_reference(PyObject*p) - :m_p(new held_type(p,)) + :m_p(new held_type(p)) { void const*x=&instance_finder::registration; (void)x; @@ -111,5 +111,6 @@ template::registration; (void)x; } + -#endif // POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP +#endif//POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 6d1b8fba..2778c7b6 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -4,23 +4,24 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #include -#include +//#include #include #include #include #include #include +#include using namespace boost::python; int apply_int_int(PyObject* f, int x) { - return returning::call(f, x); + return call(f, x); } void apply_void_int(PyObject* f, int x) { - returning::call(f, x); + call(f, x); } struct X @@ -42,52 +43,52 @@ struct X X apply_X_X(PyObject* f, X x) { - return returning::call(f, x); + return call(f, x); } void apply_void_X_ref(PyObject* f, X& x) { - returning::call(f, boost::ref(x)); + call(f, boost::ref(x)); } X& apply_X_ref_pyobject(PyObject* f, PyObject* obj) { - return returning::call(f, obj); + return call(f, obj); } X* apply_X_ptr_pyobject(PyObject* f, PyObject* obj) { - return returning::call(f, obj); + return call(f, obj); } void apply_void_X_cref(PyObject* f, X const& x) { - returning::call(f, boost::cref(x)); + call(f, boost::cref(x)); } void apply_void_X_ptr(PyObject* f, X* x) { - returning::call(f, ptr(x)); + call(f, ptr(x)); } void apply_void_X_deep_ptr(PyObject* f, X* x) { - returning::call(f, x); + call(f, x); } char const* apply_cstring_cstring(PyObject* f, char const* s) { - return returning ::call(f, s); + return call(f, s); } char const* apply_cstring_pyobject(PyObject* f, PyObject* s) { - return returning ::call(f, s); + return call(f, s); } char apply_char_char(PyObject* f, char c) { - return returning ::call(f, c); + return call(f, c); } int X::counter; diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp index 586048d5..3f516bf7 100644 --- a/test/virtual_functions.cpp +++ b/test/virtual_functions.cpp @@ -5,7 +5,7 @@ // to its suitability for any purpose. #include #include -#include +#include #include #include @@ -55,7 +55,7 @@ struct abstract_callback : abstract int f(Y const& y) { - return returning::call_method(self, "f", boost::ref(y)); + return call_method(self, "f", boost::ref(y)); } PyObject* self; @@ -73,7 +73,7 @@ struct concrete_callback : concrete int f(Y const& y) { - return returning::call_method(self, "f", boost::ref(y)); + return call_method(self, "f", boost::ref(y)); } int f_impl(Y const& y) From b7f93bd4ea5adedbf9f7c3fcffe834172bc66cf8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 12 Apr 2002 18:35:35 +0000 Subject: [PATCH 0393/1042] obsolete [SVN r13467] --- include/boost/python/returning.hpp | 159 ----------------------------- 1 file changed, 159 deletions(-) delete mode 100644 include/boost/python/returning.hpp diff --git a/include/boost/python/returning.hpp b/include/boost/python/returning.hpp deleted file mode 100644 index c34f97f6..00000000 --- a/include/boost/python/returning.hpp +++ /dev/null @@ -1,159 +0,0 @@ -// (C) Copyright David Abrahams 2001,2002. Permission to copy, use, modify, sell -// and distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for 5-argument member functions and 6-argument free -// functions by gen_returning.py - -#ifndef RETURNING_DWA20020228_HPP -# define RETURNING_DWA20020228_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { - -// Calling C++ from Python -template -struct returning -{ - static R call(char const* name, PyObject* self) - { - converter::callback_from_python cr; - return cr(PyEval_CallMethod( - self - , const_cast(name) - , const_cast("()") - )); - } - - static R call(PyObject* self) - { - converter::callback_from_python cr; - return cr(PyEval_CallFunction(self, const_cast("()") - )); - } - - template - static R call_method(PyObject* self, const char* name, A1 const& a1) - { - converter::callback_from_python cr; - return cr(PyEval_CallMethod( - self - , const_cast(name) - , const_cast("(O)") - , converter::callback_to_python(a1).get() - )); - } - - template - static R call(PyObject* self, A1 const& a1) - { - converter::callback_from_python cr; - return cr(PyEval_CallFunction( - self - , const_cast("(O)") - , converter::callback_to_python(a1).get() - )); - } - - template - static R call_method(PyObject* self, const char* name, A1 const& a1, A2 const& a2) - { - converter::callback_from_python cr; - return cr(PyEval_CallMethod( - self - , const_cast(name) - , const_cast("(O)") - , converter::callback_to_python(a1).get() - , converter::callback_to_python(a2).get() - )); - } - - template - static R call(PyObject* self, A1 const& a1, A2 const& a2) - { - converter::callback_from_python cr; - return cr(PyEval_CallFunction( - self - , const_cast("(O)") - , converter::callback_to_python(a1).get() - , converter::callback_to_python(a2).get() - )); - } - -}; - -template <> -struct returning -{ - typedef void R; - static R call(char const* name, PyObject* self) - { - ref x(PyEval_CallMethod( - self - , const_cast(name) - , const_cast("()") - )); - } - - static R call(PyObject* self) - { - ref x(PyEval_CallFunction(self, const_cast("()") - )); - } - - template - static R call_method(PyObject* self, const char* name, A1 const& a1) - { - ref x(PyEval_CallMethod( - self - , const_cast(name) - , const_cast("(O)") - , converter::callback_to_python(a1).get() - )); - } - - template - static R call(PyObject* self, A1 const& a1) - { - ref x(PyEval_CallFunction( - self - , const_cast("(O)") - , converter::callback_to_python(a1).get() - )); - } - - template - static R call_method(PyObject* self, const char* name, A1 const& a1, A2 const& a2) - { - ref x(PyEval_CallMethod( - self - , const_cast(name) - , const_cast("(O)") - , converter::callback_to_python(a1).get() - , converter::callback_to_python(a2).get() - )); - } - - template - static R call(PyObject* self, A1 const& a1, A2 const& a2) - { - ref x(PyEval_CallFunction( - self - , const_cast("(O)") - , converter::callback_to_python(a1).get() - , converter::callback_to_python(a2).get() - )); - } -}; - -}} // namespace boost::python - -#endif // RETURNING_DWA20020228_HPP - From 4cf7ab3425eb69b3d68b4edb0ac8906c0d08d7ab Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 13 Apr 2002 04:06:26 +0000 Subject: [PATCH 0394/1042] fixes for GCC .so/exception problems [SVN r13469] --- include/boost/python/classes.hpp | 8 ++++--- include/boost/python/cross_module.hpp | 12 +++++----- .../boost/python/detail/extension_class.hpp | 9 +++----- include/boost/python/detail/init_function.hpp | 22 +++++++++---------- include/boost/python/errors.hpp | 7 ++++-- include/boost/python/operators.hpp | 4 ++-- 6 files changed, 33 insertions(+), 29 deletions(-) diff --git a/include/boost/python/classes.hpp b/include/boost/python/classes.hpp index 114bb16a..22fcb3d2 100644 --- a/include/boost/python/classes.hpp +++ b/include/boost/python/classes.hpp @@ -349,19 +349,21 @@ int class_t::instance_mapping_ass_subscript(PyObject* obj, PyObject* key, PyO return 0; } -void BOOST_PYTHON_DECL adjust_slice_indices(PyObject* obj, int& start, int& finish); +bool BOOST_PYTHON_DECL adjust_slice_indices(PyObject* obj, int& start, int& finish); template PyObject* class_t::instance_sequence_slice(PyObject* obj, int start, int finish) const { - adjust_slice_indices(obj, start, finish); + if (!adjust_slice_indices(obj, start, finish)) + return 0; return downcast(obj)->get_slice(start, finish); } template int class_t::instance_sequence_ass_slice(PyObject* obj, int start, int finish, PyObject* value) const { - adjust_slice_indices(obj, start, finish); + if (!adjust_slice_indices(obj, start, finish)) + return -1; downcast(obj)->set_slice(start, finish, value); return 0; } diff --git a/include/boost/python/cross_module.hpp b/include/boost/python/cross_module.hpp index f5ca315d..c6ac8c22 100644 --- a/include/boost/python/cross_module.hpp +++ b/include/boost/python/cross_module.hpp @@ -18,8 +18,12 @@ # include namespace boost { namespace python { - struct BOOST_PYTHON_DECL import_error: error_already_set {}; - struct BOOST_PYTHON_DECL export_error : error_already_set {}; + +struct BOOST_PYTHON_DECL import_error: error_already_set {}; +struct BOOST_PYTHON_DECL export_error : error_already_set {}; + +void BOOST_PYTHON_DECL throw_import_error(); +void BOOST_PYTHON_DECL throw_export_error(); namespace detail { @@ -170,10 +174,8 @@ struct export_converter_object_noncopyable : export_converter_object_base virtual PyObject* to_python(const T& x) { PyErr_SetString(PyExc_RuntimeError, "to_python(const T&) converter not exported"); - throw import_error(); -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 + throw_import_error(); return 0; -#endif } virtual T* from_python_Ts(PyObject* p, boost::python::type t) { diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index d3016744..19aec0eb 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -255,10 +255,8 @@ class python_extension_class_converters return static_cast(target); } boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); - throw boost::python::argument_error(); -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 + boost::python::throw_argument_error(); return 0; -#endif } // Convert to T* @@ -286,10 +284,9 @@ class python_extension_class_converters return held->ptr(); } boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); - throw boost::python::argument_error(); -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 + boost::python::throw_argument_error(); + return *(PtrType*)0; -#endif } // Extract from obj a reference to the PtrType object which is holding a diff --git a/include/boost/python/detail/init_function.hpp b/include/boost/python/detail/init_function.hpp index 048c90dd..928159c2 100644 --- a/include/boost/python/detail/init_function.hpp +++ b/include/boost/python/detail/init_function.hpp @@ -299,7 +299,7 @@ struct init0 : init virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const { if (!PyArg_ParseTuple(args, const_cast(""))) - throw argument_error(); + throw_argument_error(); return new T(self ); } @@ -314,7 +314,7 @@ struct init1 : init { PyObject* a1; if (!PyArg_ParseTuple(args, const_cast("O"), &a1)) - throw argument_error(); + throw_argument_error(); return new T(self, boost::python::detail::reference_parameter(from_python(a1, type())) ); @@ -331,7 +331,7 @@ struct init2 : init PyObject* a1; PyObject* a2; if (!PyArg_ParseTuple(args, const_cast("OO"), &a1, &a2)) - throw argument_error(); + throw_argument_error(); return new T(self, boost::python::detail::reference_parameter(from_python(a1, type())), boost::python::detail::reference_parameter(from_python(a2, type())) @@ -350,7 +350,7 @@ struct init3 : init PyObject* a2; PyObject* a3; if (!PyArg_ParseTuple(args, const_cast("OOO"), &a1, &a2, &a3)) - throw argument_error(); + throw_argument_error(); return new T(self, boost::python::detail::reference_parameter(from_python(a1, type())), boost::python::detail::reference_parameter(from_python(a2, type())), @@ -371,7 +371,7 @@ struct init4 : init PyObject* a3; PyObject* a4; if (!PyArg_ParseTuple(args, const_cast("OOOO"), &a1, &a2, &a3, &a4)) - throw argument_error(); + throw_argument_error(); return new T(self, boost::python::detail::reference_parameter(from_python(a1, type())), boost::python::detail::reference_parameter(from_python(a2, type())), @@ -394,7 +394,7 @@ struct init5 : init PyObject* a4; PyObject* a5; if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &a1, &a2, &a3, &a4, &a5)) - throw argument_error(); + throw_argument_error(); return new T(self, boost::python::detail::reference_parameter(from_python(a1, type())), boost::python::detail::reference_parameter(from_python(a2, type())), @@ -419,7 +419,7 @@ struct init6 : init PyObject* a5; PyObject* a6; if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6)) - throw argument_error(); + throw_argument_error(); return new T(self, boost::python::detail::reference_parameter(from_python(a1, type())), boost::python::detail::reference_parameter(from_python(a2, type())), @@ -446,7 +446,7 @@ struct init7 : init PyObject* a6; PyObject* a7; if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - throw argument_error(); + throw_argument_error(); return new T(self, boost::python::detail::reference_parameter(from_python(a1, type())), boost::python::detail::reference_parameter(from_python(a2, type())), @@ -475,7 +475,7 @@ struct init8 : init PyObject* a7; PyObject* a8; if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - throw argument_error(); + throw_argument_error(); return new T(self, boost::python::detail::reference_parameter(from_python(a1, type())), boost::python::detail::reference_parameter(from_python(a2, type())), @@ -506,7 +506,7 @@ struct init9 : init PyObject* a8; PyObject* a9; if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - throw argument_error(); + throw_argument_error(); return new T(self, boost::python::detail::reference_parameter(from_python(a1, type())), boost::python::detail::reference_parameter(from_python(a2, type())), @@ -539,7 +539,7 @@ struct init10 : init PyObject* a9; PyObject* a10; if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - throw argument_error(); + throw_argument_error(); return new T(self, boost::python::detail::reference_parameter(from_python(a1, type())), boost::python::detail::reference_parameter(from_python(a2, type())), diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp index d0f71a24..02fbeff9 100644 --- a/include/boost/python/errors.hpp +++ b/include/boost/python/errors.hpp @@ -15,8 +15,8 @@ namespace boost { namespace python { -struct error_already_set {}; -struct argument_error : error_already_set {}; +struct BOOST_PYTHON_DECL error_already_set {}; +struct BOOST_PYTHON_DECL argument_error : error_already_set {}; // Handles exceptions caught just before returning to Python code. // Returns true iff an exception was caught. @@ -43,6 +43,9 @@ T* expect_non_null(T* x) return (T*)expect_non_null((PyObject*)x); } +BOOST_PYTHON_DECL void throw_argument_error(); +BOOST_PYTHON_DECL void throw_error_already_set(); + }} // namespace boost::python #endif // ERRORS_DWA052500_H_ diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp index c766c8b6..70e57b71 100644 --- a/include/boost/python/operators.hpp +++ b/include/boost/python/operators.hpp @@ -344,7 +344,7 @@ namespace detail if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type) { PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3"); - throw argument_error(); + throw_argument_error(); } return BOOST_PYTHON_CONVERSION::to_python( @@ -367,7 +367,7 @@ namespace detail if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type) { PyErr_SetString(PyExc_TypeError, "bad operand type(s) for pow()"); - throw argument_error(); + throw_argument_error(); } return BOOST_PYTHON_CONVERSION::to_python( From 5fbba7bc01496bc10cea657005b3ac6096a484f5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 13 Apr 2002 04:21:01 +0000 Subject: [PATCH 0395/1042] initial checkin [SVN r13470] --- test/bienstman5.cpp | 29 +++++++++++++++++++++++++++++ test/bienstman5.py | 16 ++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 test/bienstman5.cpp create mode 100644 test/bienstman5.py diff --git a/test/bienstman5.cpp b/test/bienstman5.cpp new file mode 100644 index 00000000..96eb7023 --- /dev/null +++ b/test/bienstman5.cpp @@ -0,0 +1,29 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include + +#include + +struct M {M(const std::complex&) {} }; + +BOOST_PYTHON_MODULE_INIT(bienstman5_ext) +{ + using namespace boost::python; + using boost::mpl::type_list; + + module m("bienstman5_ext"); + + m + .add(class_("M") + .def_init(args const&>())) + ; + +} + + diff --git a/test/bienstman5.py b/test/bienstman5.py new file mode 100644 index 00000000..10c35ff4 --- /dev/null +++ b/test/bienstman5.py @@ -0,0 +1,16 @@ +''' +>>> from bienstman5_ext import * +>>> m = M(1j) +''' +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 9a140643c8bc925caa12de02e708e0da07384f7c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 13 Apr 2002 04:23:41 +0000 Subject: [PATCH 0396/1042] fixes for GCC .so/exception problems [SVN r13471] --- doc/index.html | 51 +++++++++++++++++++++------- doc/special.html | 2 +- example/do_it_yourself_convts.cpp | 2 +- example/pickle2.cpp | 2 +- example/pickle3.cpp | 6 ++-- example/richcmp1.cpp | 2 +- example/richcmp3.cpp | 2 +- example/simple_vector.cpp | 4 +-- example/vector_wrapper.h | 2 +- src/classes.cpp | 20 +++++++---- src/conversions.cpp | 18 +++++----- src/converter/builtin_converters.cpp | 2 +- src/converter/callback.cpp | 14 ++++---- src/cross_module.cpp | 20 ++++++++--- src/errors.cpp | 14 ++++++-- src/extension_class.cpp | 12 +++---- src/functions.cpp | 2 +- src/gen_extclass.py | 4 +-- src/gen_init_function.py | 2 +- src/object/class.cpp | 6 ++-- src/object/function.cpp | 4 +-- src/objects.cpp | 28 +++++++-------- test/comprehensive.cpp | 18 +++++----- 23 files changed, 144 insertions(+), 93 deletions(-) diff --git a/doc/index.html b/doc/index.html index f636e7a8..01e5d13e 100644 --- a/doc/index.html +++ b/doc/index.html @@ -29,26 +29,53 @@ among others.

    Supported Platforms

    Boost.Python is known to have been tested in the following configurations: +

      -
    • Against Python 2.0 using the following compiler/library combinations: +
    • Against Python 2.2.1 using +the following compilers (Note that pickling doesn't work with Python +2.2 due to a core language bug; +2.2.1 fixes that). +
      • MSVC++6sp4 - with the native library. + href="http://msdn.microsoft.com/vstudio/downloads/updates/sp/vs6/sp5/default.asp">MSVC++6sp5. All + tests pass. -
      • An upcoming release of Metrowerks - CodeWarrior Pro6 for Windows with the native library (the first - release has a bug that's fatal to Boost.Python) +
      • Metrowerks + CodeWarrior Pro7.2 for Windows. All tests pass. -
      • GCC 3.0.4 under Cygwin. All tests pass. + +
      • GCC 2.95.2 under MinGW. Comprehensive test fails at + runtime due to a compiler code-generation bug. Other tests seem to + work. + +
      • Intel - C++ 5.0. Compilation succeeds, but tests FAILED at runtime due to a bug in its - exception-handling implementation. + C++ 6.0 beta: Comprehensive test fails to link due to a + linker bug. Other tests seem to work. + +
      • Intel + C++ 5.0 Comprehensive test fails at runtime due to an + exception-handling bug. Other tests seem to work. + +
      • MSVC++7 (Visual + Studio .NET). Some tests fail to compile (comprehensive.cpp, + ivect.cpp, dvect.cpp, noncopyable_export.cpp); others seem to work.
      -
    • Against Python 1.5.2 using the following compiler/library: + +
    • Against Python 2.0 using the following compilers: + + +
    • Against Python 1.5.2 using the following compiler/library combinations: diff --git a/include/boost/python/conversions.hpp b/include/boost/python/conversions.hpp index f328981e..83823494 100644 --- a/include/boost/python/conversions.hpp +++ b/include/boost/python/conversions.hpp @@ -160,7 +160,7 @@ unsigned char from_python(PyObject*, boost::python::type); BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type); BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type); -# ifndef BOOST_MSVC6_OR_EARLIER +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 PyObject* to_python(float); PyObject* to_python(double); # else @@ -260,7 +260,7 @@ PyObject* from_python(PyObject*, boost::python::type); // #endif // }} // namespace boost::python -#if !defined(BOOST_MSVC6_OR_EARLIER) +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) template boost::shared_ptr from_python(PyObject*p, boost::python::type >) { @@ -286,7 +286,7 @@ PyObject* to_python(boost::shared_ptr p) // inline implementations // -#ifndef BOOST_MSVC6_OR_EARLIER +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 inline PyObject* to_python(double d) { return PyFloat_FromDouble(d); @@ -296,7 +296,7 @@ inline PyObject* to_python(float f) { return PyFloat_FromDouble(f); } -#endif // BOOST_MSVC6_OR_EARLIER +#endif inline PyObject* to_python(long l) { diff --git a/src/conversions.cpp b/src/conversions.cpp index 2818276b..3c5edad5 100644 --- a/src/conversions.cpp +++ b/src/conversions.cpp @@ -206,7 +206,7 @@ BOOST_PYTHON_DECL bool from_python(PyObject* p, boost::python::type) return true; } -#ifdef BOOST_MSVC6_OR_EARLIER +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 // An optimizer bug prevents these from being inlined. BOOST_PYTHON_DECL PyObject* to_python(double d) { @@ -217,7 +217,7 @@ BOOST_PYTHON_DECL PyObject* to_python(float f) { return PyFloat_FromDouble(f); } -#endif // BOOST_MSVC6_OR_EARLIER +#endif BOOST_PYTHON_END_CONVERSION_NAMESPACE diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 531180d6..6cb78865 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -103,7 +103,14 @@ StringMapPythonClass::StringMapPythonClass(boost::python::module_builder& m) : boost::python::class_builder(m, "StringMap") { def(boost::python::constructor<>()); +#if defined(BOOST_MSVC) && BOOST_MSVC == 1300 + // MSVC7 incorrectly makes this the target of this function + // pointer the same type as the class in which it is defined (some + // standard library class), instead of StringMap. + def((std::size_t (StringMap::*)()const)&StringMap::size, "__len__"); +#else def(&StringMap::size, "__len__"); +#endif def(&get_item, "__getitem__"); def(&set_item, "__setitem__"); def(&del_item, "__delitem__"); @@ -884,7 +891,7 @@ namespace bpl_test { // This doesn't test anything but the compiler, since it has the same signature as the above. // Since MSVC is broken and gets the signature wrong, we'll skip it. std::string use_const_plain_char( -#ifndef BOOST_MSVC6_OR_EARLIER +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 const #endif char c) { return std::string(5, c); } From 8c4f9d913db7b9d159859fb8ec69e9af86a6629b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 13 Apr 2002 16:43:17 +0000 Subject: [PATCH 0399/1042] Suppress warning for smart compilers [SVN r13478] --- include/boost/python/detail/extension_class.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp index 19aec0eb..f92bb83b 100644 --- a/include/boost/python/detail/extension_class.hpp +++ b/include/boost/python/detail/extension_class.hpp @@ -286,7 +286,7 @@ class python_extension_class_converters boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); boost::python::throw_argument_error(); - return *(PtrType*)0; + return *(PtrType*)obj; } // Extract from obj a reference to the PtrType object which is holding a From 360dbd9e5ed5471efca42a8aaa708a888cf33c85 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 13 Apr 2002 17:04:11 +0000 Subject: [PATCH 0400/1042] Fixes for linking with Intel 6 [SVN r13479] --- test/comprehensive.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp index 6cb78865..be638066 100644 --- a/test/comprehensive.cpp +++ b/test/comprehensive.cpp @@ -103,14 +103,11 @@ StringMapPythonClass::StringMapPythonClass(boost::python::module_builder& m) : boost::python::class_builder(m, "StringMap") { def(boost::python::constructor<>()); -#if defined(BOOST_MSVC) && BOOST_MSVC == 1300 - // MSVC7 incorrectly makes this the target of this function + // Some compilers make the target of this function // pointer the same type as the class in which it is defined (some // standard library class), instead of StringMap. def((std::size_t (StringMap::*)()const)&StringMap::size, "__len__"); -#else - def(&StringMap::size, "__len__"); -#endif + def(&get_item, "__getitem__"); def(&set_item, "__setitem__"); def(&del_item, "__delitem__"); @@ -980,8 +977,8 @@ void init_module(boost::python::module_builder& m) boost::python::class_builder range(m, "Range"); range.def(boost::python::constructor()); range.def(boost::python::constructor()); - range.def((void (Range::*)(std::size_t))&Range::length, "__len__"); range.def((std::size_t (Range::*)() const)&Range::length, "__len__"); + range.def((void (Range::*)(std::size_t))&Range::length, "__len__"); range.def(&Range::operator[], "__getitem__"); range.def(&Range::slice, "__getslice__"); range.def(&range_str, "__str__"); From a9fb1b25a817689d9fa0cd1badac01d95f6ff051 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 14 Apr 2002 15:24:19 +0000 Subject: [PATCH 0401/1042] comment at beginning of file updated. [SVN r13483] --- build/vc60.mak | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/vc60.mak b/build/vc60.mak index 1709073c..2903c0c7 100644 --- a/build/vc60.mak +++ b/build/vc60.mak @@ -1,5 +1,9 @@ # Usage: # +# Create a new empty directory anywhere (preferably not in the boost tree). +# Copy this Makefile to that new directory and rename it to "Makefile" +# Adjust the pathnames below. +# # make copy Copy the sources and tests # make Compile all sources # make test Run doctest tests From 473d38c846c9fa2fc5caf54ddbb7867b0c458f64 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 15 Apr 2002 04:08:49 +0000 Subject: [PATCH 0402/1042] Warning suppression for Cygwin 2.95.2 [SVN r13488] --- include/boost/python/detail/wrap_python.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index 3807eae1..0e417ad3 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -47,7 +47,7 @@ typedef int pid_t; # define HAVE_STRERROR # endif # define NT_THREADS -# if __GNUC__ < 3 || __GNUC__ == 3 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ < 3 +# if !defined(__CYGWIN__) && (__GNUC__ < 3 || __GNUC__ == 3 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ < 3) # define WITH_THREAD # endif # ifndef NETSCAPE_PI From 8eab74ea81846b3ea669d99ff7aacb5ec77fbc11 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 15 Apr 2002 04:09:52 +0000 Subject: [PATCH 0403/1042] Make 2.95.2 workaround MINGW-specific [SVN r13489] --- include/boost/python/detail/config.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index ab21a37b..cd0377b5 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -98,7 +98,7 @@ # endif // MinGW, at least, has some problems exporting template instantiations -# if defined(__GNUC__) && __GNUC__ < 3 +# if defined(__GNUC__) && __GNUC__ < 3 && !defined(__CYGWIN__) # define BOOST_PYTHON_NO_TEMPLATE_EXPORT # endif From 722036f10e45b7c1ce5a2ef9adf9f1e633362f21 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 16 Apr 2002 21:10:55 +0000 Subject: [PATCH 0404/1042] trivial changes for MPL v2 [SVN r13506] --- test/m1.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/m1.cpp b/test/m1.cpp index 61c2848b..4aa81f36 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include // Declare some straightforward extension types @@ -200,7 +199,6 @@ D take_d(D const& d) { return d; } BOOST_PYTHON_MODULE_INIT(m1) { using namespace boost::python; - using boost::mpl::type_list; using boost::shared_ptr; simple_to_python(); @@ -280,8 +278,8 @@ BOOST_PYTHON_MODULE_INIT(m1) .add( class_("complicated") - .def_init(type_list()) - .def_init(type_list()) + .def_init(args()) + .def_init(args()) .def("get_n", &complicated::get_n) ) ; From d5c35a1d83a6ed018ad6f38dca390848ea1ffa5f Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 16 Apr 2002 22:02:00 +0000 Subject: [PATCH 0405/1042] Supported Platform section overhaul. [SVN r13507] --- doc/index.html | 96 ++++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 49 deletions(-) diff --git a/doc/index.html b/doc/index.html index 97bec88d..cdadb8e1 100644 --- a/doc/index.html +++ b/doc/index.html @@ -27,39 +27,60 @@ among others.

      Supported Platforms

      -

      Boost.Python is known to have been tested in the following configurations: - - -

        -
      • Against Python 2.2.1 using -the following compilers (Note that pickling doesn't work with Python -2.2 due to a core language bug; -2.2.1 fixes that). +

        Boost.Python is known to have been tested +against Python 2.2.1 using +the following compilers:

        • MSVC++6sp5. All - tests pass. + href="http://msdn.microsoft.com/vstudio/downloads/updates/sp/vs6/sp5/default.asp">MSVC++6sp5. + All tests pass. +

        • MSVC++7 (Visual Studio .NET). All tests pass. +

        • Metrowerks - CodeWarrior Pro7.2 for Windows. All tests pass. + CodeWarrior Pro7.2 and Pro7.0 for Windows. All tests pass. +

        • GCC 3.0.4 under Cygwin. All tests pass. + href="www.cygwin.com">Cygwin and + RedHat Linux 7.1. + All tests pass. +

          +

        • Compaq C++ V6.2-024 for Digital UNIX (an EDG-based compiler). + All tests pass.
          + Note that the Boost.Compatibility + library must be included (see e.g. tru64_cxx.mak in the build + directory). + +

          +

        • Silicon Graphics MIPSpro Version 7.3.1.2m (an EDG-based compiler). + All tests pass.
          + Note that the Boost.Compatibility + library must be included (see e.g. irix_CC.mak in the build + directory). + +

        • GCC 2.95.2 under MinGW. Comprehensive test fails at - runtime due to a compiler code-generation bug. Other tests seem to - work. + href="www.mingw.org">MinGW and RedHat Linux 7.1. + Compilation succeeds, but some tests fail at runtime due to + exception handling bugs. It is therefore highly recommended + to use GCC 3.0.4 instead. +

        • Intel C++ 6.0 beta: Comprehensive test fails to link due to a linker bug. Other tests seem to work. +

        • Intel C++ 5.0 Comprehensive test fails at runtime due to an @@ -67,38 +88,15 @@ the following compilers (Note that pickling doesn't work with Python
        +

        +Note that pickling doesn't work with Python 2.2 +due to a core language bug. This is fixed in +2.2.1. -

      • Against Python 2.0 using the following compilers: - - -
      • Against Python 1.5.2 using the following compiler/library combinations: - - -
      +

      +Boost.Python has also been used with other versions of Python back to +Python 1.5.2. It is expected that the older Python releases still work, +but we are not regularly testing for backward compatibility.

      Credits

        @@ -179,8 +177,8 @@ the following compilers (Note that pickling doesn't work with Python href="../test/comprehensive.cpp">cpp]

        - Questions should be directed to the boost mailing list. + Questions should be directed to the Python C++ SIG.

        © Copyright David Abrahams 2001. Permission to copy, use, modify, @@ -189,5 +187,5 @@ the following compilers (Note that pickling doesn't work with Python express or implied warranty, and with no claim as to its suitability for any purpose.

        - Updated: Mar 6, 2001 + Updated: Apr 2002 From 0c1e2a734706be155051aee63bdbea76ce44820f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Apr 2002 00:20:04 +0000 Subject: [PATCH 0406/1042] copy_mutable_reference -> copy_non_const_reference arbitrary arg support for constructors [SVN r13508] --- include/boost/python/class_fwd.hpp | 2 + include/boost/python/data_members.hpp | 4 +- include/boost/python/object/make_holder.hpp | 176 +++----------- .../boost/python/preprocessed/make_holder.hpp | 230 ++++++++++++++++++ 4 files changed, 267 insertions(+), 145 deletions(-) create mode 100644 include/boost/python/preprocessed/make_holder.hpp diff --git a/include/boost/python/class_fwd.hpp b/include/boost/python/class_fwd.hpp index 1ef941aa..d88ec271 100644 --- a/include/boost/python/class_fwd.hpp +++ b/include/boost/python/class_fwd.hpp @@ -6,6 +6,8 @@ #ifndef CLASS_FWD_DWA200222_HPP # define CLASS_FWD_DWA200222_HPP # include +# include +# include namespace boost { namespace python { diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp index fec774ae..b0f3f7b6 100644 --- a/include/boost/python/data_members.hpp +++ b/include/boost/python/data_members.hpp @@ -12,7 +12,7 @@ # include # include # include -# include +# include namespace boost { namespace python { @@ -63,7 +63,7 @@ namespace detail template objects::function* make_getter(D C::*pm) { - typedef return_value_policy default_policy; + typedef return_value_policy default_policy; return new objects::function( objects::py_function( ::boost::bind( diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 59043317..1d55512c 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -10,158 +10,48 @@ # include # include # include +# include +# include +# include namespace boost { namespace python { namespace objects { template struct make_holder; -template <> -struct make_holder<0> -{ - template - struct apply - { - static void execute( - PyObject* p) - { - (new Holder(p))->install(p); - } - }; -}; +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif -template <> -struct make_holder<1> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - - static void execute( - PyObject* p - , t0 a0) - { - (new Holder(p, f0(a0)))->install(p); - } - }; +# define BOOST_PYTHON_FORWARD_ARG(index, ignored) \ + typedef typename mpl::at::type BOOST_PP_CAT(t,index); \ + typedef typename forward::type BOOST_PP_CAT(f,index); + +# define BOOST_PYTHON_DO_FORWARD_ARG(index, ignored) \ + BOOST_PP_CAT(f,index)(BOOST_PP_CAT(a, index)) + +# define BOOST_PYTHON_MAKE_HOLDER(nargs,ignored) \ +template <> \ +struct make_holder \ +{ \ + template \ + struct apply \ + { \ + BOOST_PP_REPEAT(nargs, BOOST_PYTHON_FORWARD_ARG, nil) \ + \ + static void execute( \ + PyObject* p \ + BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (t,a)) ) \ + { \ + (new Holder( \ + p \ + BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM( \ + nargs,BOOST_PYTHON_DO_FORWARD_ARG,nil)))->install(p); \ + } \ + }; \ }; -template <> -struct make_holder<2> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - - static void execute( - PyObject* p, t0 a0, t1 a1) - { - (new Holder(p, f0(a0), f1(a1)))->install(p); - } - }; -}; - -template <> -struct make_holder<3> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - - static void execute( - PyObject* p, t0 a0, t1 a1, t2 a2) - { - (new Holder(p, f0(a0), f1(a1), f2(a2)))->install(p); - } - }; -}; - -template <> -struct make_holder<4> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - - static void execute( - PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3) - { - (new Holder(p, f0(a0), f1(a1), f2(a2), f3(a3)))->install(p); - } - }; -}; - -template <> -struct make_holder<5> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - - static void execute( - PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3, t4 a4) - { - (new Holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4)))->install(p); - } - }; -}; - -template <> -struct make_holder<6> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; - typedef typename forward::type f5; - - static void execute( - PyObject* p, t0 a0, t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) - { - (new Holder(p, f0(a0), f1(a1), f2(a2), f3(a3), f4(a4), f5(a5)))->install(p); - } - }; -}; +BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_MAKE_HOLDER,nil) }}} // namespace boost::python::objects diff --git a/include/boost/python/preprocessed/make_holder.hpp b/include/boost/python/preprocessed/make_holder.hpp new file mode 100644 index 00000000..88eecbc1 --- /dev/null +++ b/include/boost/python/preprocessed/make_holder.hpp @@ -0,0 +1,230 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MAKE_HOLDER_DWA2002416_HPP +# define MAKE_HOLDER_DWA2002416_HPP + +template<> +struct make_holder<0> +{ + template + struct apply + { + static void execute(PyObject*p) + { + (new Holder(p))->install(p); + } + + }; +}; +template<> +struct make_holder<1> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + static void execute(PyObject*p,t0 a0) + { + (new Holder(p,f0(a0)))->install(p); + } + + }; +}; +template<> +struct make_holder<2> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + static void execute(PyObject*p,t0 a0,t1 a1) + { + (new Holder(p,f0(a0),f1(a1)))->install(p); + } + + }; +}; +template<> +struct make_holder<3> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + static void execute(PyObject*p,t0 a0,t1 a1,t2 a2) + { + (new Holder(p,f0(a0),f1(a1),f2(a2)))->install(p); + } + + }; +}; +template<> +struct make_holder<4> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3) + { + (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3)))->install(p); + } + + }; +}; +template<> +struct make_holder<5> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4) + { + (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4)))->install(p); + } + + }; +}; +template<> +struct make_holder<6> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + typedef typename mpl::at<5,ArgList>::type t5; + typedef typename forward::type f5; + static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5) + { + (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5)))->install(p); + } + + }; +}; +template<> +struct make_holder<7> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + typedef typename mpl::at<5,ArgList>::type t5; + typedef typename forward::type f5; + typedef typename mpl::at<6,ArgList>::type t6; + typedef typename forward::type f6; + static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6) + { + (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6)))->install(p); + } + + }; +}; +template<> +struct make_holder<8> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + typedef typename mpl::at<5,ArgList>::type t5; + typedef typename forward::type f5; + typedef typename mpl::at<6,ArgList>::type t6; + typedef typename forward::type f6; + typedef typename mpl::at<7,ArgList>::type t7; + typedef typename forward::type f7; + static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7) + { + (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7)))->install(p); + } + + }; +}; +template<> +struct make_holder<9> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + typedef typename mpl::at<5,ArgList>::type t5; + typedef typename forward::type f5; + typedef typename mpl::at<6,ArgList>::type t6; + typedef typename forward::type f6; + typedef typename mpl::at<7,ArgList>::type t7; + typedef typename forward::type f7; + typedef typename mpl::at<8,ArgList>::type t8; + typedef typename forward::type f8; + static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8) + { + (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8)))->install(p); + } + + }; +}; + +#endif // MAKE_HOLDER_DWA2002416_HPP From 4250893d2f73a85d319d421b20dcd8fa833daaea Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Apr 2002 00:22:38 +0000 Subject: [PATCH 0407/1042] doc updates, arbitrary arity constructors [SVN r13511] --- doc/v2/call.html | 9 +- doc/v2/make_function.html | 2 +- doc/v2/reference.html | 251 ++++++++++++++++++++++----------- test/Jamfile | 1 + test/multi_arg_constructor.cpp | 22 +++ test/multi_arg_constructor.py | 16 +++ 6 files changed, 214 insertions(+), 87 deletions(-) create mode 100644 test/multi_arg_constructor.cpp create mode 100644 test/multi_arg_constructor.py diff --git a/doc/v2/call.html b/doc/v2/call.html index eb3e706c..4ba3dd96 100644 --- a/doc/v2/call.html +++ b/doc/v2/call.html @@ -21,7 +21,6 @@

        Contents

        Introduction
        -
        Functions
        call
        @@ -32,11 +31,15 @@

        Introduction

        -

        {{Introductory text}}

        +

        + <boost/python/call.hpp> defines the call family of overloaded function + templates, used to invoke Python callable objects from C++.

        Functions

        -call
        +template <class R, class A1, class A2, ... class An>
        +result-type call(PyObject* callable, A1 const&, A2 const&, ... An const&)
         
        Requires: {{text}}
        diff --git a/doc/v2/make_function.html b/doc/v2/make_function.html index 7f40703b..4e3c0bd1 100644 --- a/doc/v2/make_function.html +++ b/doc/v2/make_function.html @@ -51,7 +51,7 @@

        Functions

         template <class F>
        -objects::function* make_function(F f)</a>
        +objects::function* make_function(F f)
         
         template <class F, class Policies>
         objects::function* make_function(F f, Policies const& policies)
        diff --git a/doc/v2/reference.html b/doc/v2/reference.html
        index 5f82fe4d..78505ff6 100644
        --- a/doc/v2/reference.html
        +++ b/doc/v2/reference.html
        @@ -24,9 +24,11 @@
             
        High Level Components -
        Framework Elements +
        Models of CallPolicies -
        Utilities +
        Models of ReturnHandlerGenerator + +
        To/From Python Type Conversion
        Index By Name
        @@ -41,6 +43,31 @@

        General Purpose

        + +
        call.hpp +
        +
        +
        Functions + +
        +
        +
        call +
        +
        + +
        call_method.hpp +
        +
        +
        Functions + +
        +
        +
        call_method +
        +
        +
        class.hpp/class_fwd.hpp
        @@ -57,6 +84,22 @@
        +
        data_members.hpp + +
        +
        +
        Functions + +
        +
        +
        make_getter + +
        make_setter +
        +
        +
        errors.hpp
        @@ -140,89 +183,8 @@
        - -

        To/From Python Type Conversion

        -
        -
        from_python.hpp - -
        -
        -
        Classes - -
        -
        -
        from_python -
        -
        - -
        to_python_converter.hpp - -
        -
        -
        Classes - -
        -
        -
        to_python_converter -
        -
        - -
        to_python_indirect.hpp - -
        -
        -
        Classes - -
        -
        -
        to_python_indirect -
        -
        - -
        to_python_value.hpp - -
        -
        -
        Classes - -
        -
        -
        to_python_value -
        -
        - -
        type_from_python.hpp - -
        -
        -
        Classes - -
        -
        -
        type_from_python -
        -
        - -
        value_from_python.hpp - -
        -
        -
        Classes - -
        -
        -
        value_from_python -
        -
        -

        Models of CallPolicies

        @@ -369,6 +331,129 @@ + + + +

        To/From Python Type Conversion

        + +
        +
        from_python.hpp + +
        +
        +
        Classes + +
        +
        +
        from_python +
        +
        + +
        has_back_reference.hpp + +
        +
        +
        Classes + +
        +
        +
        has_back_reference +
        +
        + +
        implicit.hpp + +
        +
        +
        Functions + +
        +
        +
        implicitly_convertible +
        +
        + +
        ptr.hpp + +
        +
        +
        Classes + +
        +
        +
        ptr +
        +
        + +
        to_python_converter.hpp + +
        +
        +
        Classes + +
        +
        +
        to_python_converter +
        +
        + +
        to_python_indirect.hpp + +
        +
        +
        Classes + +
        +
        +
        to_python_indirect +
        +
        + +
        to_python_value.hpp + +
        +
        +
        Classes + +
        +
        +
        to_python_value +
        +
        + +
        type_from_python.hpp + +
        +
        +
        Classes + +
        +
        +
        type_from_python +
        +
        + +
        value_from_python.hpp + +
        +
        +
        Classes + +
        +
        +
        value_from_python +
        +
        +
        +
        diff --git a/test/Jamfile b/test/Jamfile index 6e7ce5ea..36b9a476 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -63,6 +63,7 @@ bpl-test data_members ; bpl-test bienstman1 ; bpl-test bienstman2 ; bpl-test bienstman3 ; +bpl-test multi_arg_constructor ; if $(TEST_BIENSTMAN_NON_BUGS) { bpl-test bienstman4 ; diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp new file mode 100644 index 00000000..50710519 --- /dev/null +++ b/test/multi_arg_constructor.cpp @@ -0,0 +1,22 @@ +#include +#include + +struct A +{ + A(const double, const double, const double, const double, const double, const double, const double) {} +}; + +BOOST_PYTHON_MODULE_INIT(multi_arg_constructor_ext) +{ + using namespace boost::python; + using boost::shared_ptr; + + module("multi_arg_constructor_ext") + + .add(class_ >("A") + .def_init(args()) + ) + ; + +} + diff --git a/test/multi_arg_constructor.py b/test/multi_arg_constructor.py new file mode 100644 index 00000000..d6d1ef37 --- /dev/null +++ b/test/multi_arg_constructor.py @@ -0,0 +1,16 @@ +''' +>>> from multi_arg_constructor_ext import * +>>> a = A(1.0, 2, 3, 4, 5, 6, 7.0) +''' +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From a203214ef97d2dc93422ec746a3bb112b8e716b8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Apr 2002 04:34:34 +0000 Subject: [PATCH 0408/1042] More cleanups for mpl_v2 [SVN r13516] --- .../boost/python/copy_mutable_reference.hpp | 41 ------------------- test/bienstman3.cpp | 5 +-- test/test_pointer_adoption.cpp | 2 - 3 files changed, 1 insertion(+), 47 deletions(-) delete mode 100644 include/boost/python/copy_mutable_reference.hpp diff --git a/include/boost/python/copy_mutable_reference.hpp b/include/boost/python/copy_mutable_reference.hpp deleted file mode 100644 index f7594ccd..00000000 --- a/include/boost/python/copy_mutable_reference.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef COPY_MUTABLE_REFERENCE_DWA2002131_HPP -# define COPY_MUTABLE_REFERENCE_DWA2002131_HPP -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - template - struct copy_mutable_reference_expects_a_reference_to_non_const_return_type -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) - {} -# endif - ; -} - -template struct to_python_value; - -struct copy_mutable_reference -{ - template - struct apply - { - typedef typename mpl::select_type< - detail::is_reference_to_non_const::value - , to_python_value - , detail::copy_mutable_reference_expects_a_reference_to_non_const_return_type - >::type type; - }; -}; - -}} // namespace boost::python - -#endif // COPY_MUTABLE_REFERENCE_DWA2002131_HPP diff --git a/test/bienstman3.cpp b/test/bienstman3.cpp index 60ddc385..eb2bb30a 100644 --- a/test/bienstman3.cpp +++ b/test/bienstman3.cpp @@ -1,6 +1,5 @@ #include #include -#include struct V { @@ -15,19 +14,17 @@ struct B BOOST_PYTHON_MODULE_INIT(bienstman3_ext) { using namespace boost::python; - using boost::mpl::type_list; module m("bienstman3_ext"); m - .add( class_("V") ) .add( class_("B") - .def_init(type_list()) + .def_init(args()) ) ; } diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index 33cd4dc2..74c869ed 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -8,10 +8,8 @@ #include #include #include -#include using namespace boost::python; -using boost::mpl::type_list; int a_instances = 0; From 8388163aafe96095e21b2c863e8e6f37aaad3234 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 18 Apr 2002 03:45:27 +0000 Subject: [PATCH 0409/1042] corrected BOOST_PYTHON_MAX_ARITY response made things compile in time on EDG increased BOOST_PYTHON_DEBUGGABLE_ARITY to 15 [SVN r13519] --- include/boost/python/args.hpp | 58 +- include/boost/python/detail/preprocessor.hpp | 27 +- .../python/preprocessed/arg_tuple_size.hpp | 741 +++- include/boost/python/preprocessed/args.hpp | 169 + include/boost/python/preprocessed/call.hpp | 288 +- .../boost/python/preprocessed/call_method.hpp | 308 +- include/boost/python/preprocessed/caller.hpp | 254 +- .../boost/python/preprocessed/make_holder.hpp | 319 +- .../preprocessed/member_function_cast.hpp | 148 +- .../python/preprocessed/pointer_holder.hpp | 233 +- .../pointer_holder_back_reference.hpp | 357 +- .../preprocessed/returning_non_void.hpp | 3676 ++++++++++++----- .../python/preprocessed/returning_void.hpp | 3331 +++++++++++---- .../python/preprocessed/value_holder.hpp | 231 +- .../value_holder_back_reference.hpp | 258 +- 15 files changed, 7927 insertions(+), 2471 deletions(-) create mode 100644 include/boost/python/preprocessed/args.hpp diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index b584506b..1656fe1e 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -5,15 +5,69 @@ // to its suitability for any purpose. #ifndef ARGS_DWA2002323_HPP # define ARGS_DWA2002323_HPP +# include # include +# include +# include +# include +# include +# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245 namespace boost { namespace python { + // A type list for specifying arguments -template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename A, ::boost::mpl::null_argument) > -struct args : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(A) >::type +template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename A, boost::mpl::null_argument) > +struct args : boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(A) >::type {}; }} // namespace boost::python +# else // slow template instantiators need this other version with + // explicit specializations of mpl::size<> and + // mpl::at<>. Eventually, however, inheritance from mpl::list + // *should* be eliminated and the two versions unified, just in + // order to get true arity independence + +namespace boost { namespace python { + +template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_MAX_ARITY, class A, boost::mpl::null_argument) > +struct args +{}; + +}} // namespace boost::python + +namespace boost { namespace mpl { + +template struct size; +template struct at; + +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif + +# define BOOST_PYTHON_ARGS_SIZE(index,ignored) \ +template \ +struct size > \ +{ \ + BOOST_STATIC_CONSTANT(long, value = index); \ +}; \ + +BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_ARGS_SIZE, nil) + +# define BOOST_PYTHON_ARGS_AT(index,ignored) \ +template < \ + BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_PYTHON_ARITY_FINISH), class A)> \ +struct at > \ +{ \ + typedef BOOST_PP_CAT(A,index) type; \ +}; \ + +BOOST_PP_REPEAT_FROM_TO_2ND( + BOOST_PP_DEC(BOOST_PYTHON_ARITY_START), BOOST_PP_DEC(BOOST_PYTHON_ARITY_FINISH) + , BOOST_PYTHON_ARGS_AT, data) + +}} +# endif #endif // ARGS_DWA2002323_HPP diff --git a/include/boost/python/detail/preprocessor.hpp b/include/boost/python/detail/preprocessor.hpp index 510e0755..fc492155 100644 --- a/include/boost/python/detail/preprocessor.hpp +++ b/include/boost/python/detail/preprocessor.hpp @@ -35,13 +35,13 @@ namespace boost { namespace python { namespace detail { # endif #ifndef BOOST_PYTHON_DEBUGGABLE_ARITY -# define BOOST_PYTHON_DEBUGGABLE_ARITY 10 +# define BOOST_PYTHON_DEBUGGABLE_ARITY 15 #endif #ifndef BOOST_PYTHON_MAX_ARITY # if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245 // Generate at least two more arguments just to test the syntax -# define BOOST_PYTHON_MAX_ARITY 12 +# define BOOST_PYTHON_MAX_ARITY 17 # else // Current EDG compilers have a really slow preprocessor which makes // it important not to generate new functions with it unless @@ -53,16 +53,18 @@ namespace boost { namespace python { namespace detail { #ifdef BOOST_PYTHON_GENERATE_CODE # undef BOOST_STATIC_CONSTANT # define BOOST_PYTHON_ARITY_START 0 -# define BOOST_PYTHON_ARITY_FINISH BOOST_PYTHON_DEBUGGABLE_ARITY +# define BOOST_PYTHON_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY) # define BOOST_PYTHON_MF_ARITY_START 1 -# define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY) +# define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY)) #else -# define BOOST_PYTHON_ARITY_START BOOST_PYTHON_DEBUGGABLE_ARITY -# define BOOST_PYTHON_ARITY_FINISH BOOST_PYTHON_MAX_ARITY -# define BOOST_PYTHON_MF_ARITY_START BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY) -# define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY) +# define BOOST_PYTHON_ARITY_START BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY) +# define BOOST_PYTHON_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY) +# define BOOST_PYTHON_MF_ARITY_START BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY)) +# define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY)) #endif +#if BOOST_PYTHON_MAX_ARITY > BOOST_PYTHON_DEBUGGABLE_ARITY + # define BOOST_PYTHON_FN(inner,start,count) \ R(inner)(BOOST_MPL_TEMPLATE_PARAMETERS(start,count,A)) @@ -93,6 +95,15 @@ namespace boost { namespace python { namespace detail { # define BOOST_PYTHON_PROJECT_1ST(a1,a2) a1 # define BOOST_PYTHON_PROJECT_2ND(a1,a2) a2 +#else + +# define BOOST_PYTHON_REPEAT_ARITY_2ND(function,data) +# define BOOST_PYTHON_REPEAT_MF_ARITY_2ND(function,data) +# define BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(function) +# define BOOST_PYTHON_REPEAT_MF_CV_2ND(function) +# define BOOST_PYTHON_REPEAT_PMF_CV(index, function, cv) + +#endif }}} // namespace boost::python::detail diff --git a/include/boost/python/preprocessed/arg_tuple_size.hpp b/include/boost/python/preprocessed/arg_tuple_size.hpp index b22590ae..cc85236a 100644 --- a/include/boost/python/preprocessed/arg_tuple_size.hpp +++ b/include/boost/python/preprocessed/arg_tuple_size.hpp @@ -8,268 +8,575 @@ # if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=0); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=0); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=1); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=1); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=2); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=2); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=3); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=3); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=4); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=4); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=5); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=5); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=6); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=6); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=7); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=7); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=8); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=8); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=9); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=9); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=10); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=11); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=12); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=13); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=14); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=15); +}; + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=1); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=2); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=3); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=4); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=5); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=6); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=7); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=8); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=9); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=10); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=11); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=12); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=13); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=14); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=15); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=16); }; - - templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=1); -}; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=2); -}; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=3); -}; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=4); -}; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=5); -}; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=6); -}; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=7); -}; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=8); -}; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=9); -}; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=10); -}; // Metrowerks thinks this creates ambiguities # if !defined(__MWERKS__) || __MWERKS__ > 0x2407 -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=1); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=1); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=2); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=2); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=3); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=3); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=4); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=4); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=5); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=5); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=6); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=6); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=7); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=7); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=8); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=8); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=9); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=9); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=10); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=10); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=1); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=11); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=2); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=12); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=3); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=13); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=4); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=14); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=5); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=15); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=6); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=16); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=7); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=1); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=8); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=2); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=9); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=3); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=10); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=4); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=1); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=5); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=2); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=6); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=3); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=7); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=4); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=8); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=5); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=9); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=6); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=10); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=7); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=11); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=8); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=12); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=9); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=13); }; -templatestruct arg_tuple_size{ -BOOST_STATIC_CONSTANT(std::size_t,value=10); +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=14); }; -# endif - +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=15); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=16); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=1); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=2); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=3); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=4); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=5); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=6); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=7); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=8); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=9); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=10); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=11); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=12); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=13); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=14); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=15); +}; +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t,value=16); +}; +# endif # else -template -char_array<0>arg_tuple_size_helper(R(*)()); -template -char_array<1>arg_tuple_size_helper(R(*)(A0)); -template -char_array<2>arg_tuple_size_helper(R(*)(A0,A1)); -template -char_array<3>arg_tuple_size_helper(R(*)(A0,A1,A2)); -template -char_array<4>arg_tuple_size_helper(R(*)(A0,A1,A2,A3)); -template -char_array<5>arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4)); -template -char_array<6>arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5)); -template -char_array<7>arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6)); -template -char_array<8>arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7)); -template -char_array<9>arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8)); - -template -char_array<1>arg_tuple_size_helper(R(A0::*)()); -template -char_array<2>arg_tuple_size_helper(R(A0::*)(A1)); -template -char_array<3>arg_tuple_size_helper(R(A0::*)(A1,A2)); -template -char_array<4>arg_tuple_size_helper(R(A0::*)(A1,A2,A3)); -template -char_array<5>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)); -template -char_array<6>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)); -template -char_array<7>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)); -template -char_array<8>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)); -template -char_array<9>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)); -template -char_array<10>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)); - -template -char_array<1>arg_tuple_size_helper(R(A0::*)()const); -template -char_array<2>arg_tuple_size_helper(R(A0::*)(A1)const); -template -char_array<3>arg_tuple_size_helper(R(A0::*)(A1,A2)const); -template -char_array<4>arg_tuple_size_helper(R(A0::*)(A1,A2,A3)const); -template -char_array<5>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)const); -template -char_array<6>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)const); -template -char_array<7>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)const); -template -char_array<8>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const); -template -char_array<9>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const); -template -char_array<10>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const); - -template -char_array<1>arg_tuple_size_helper(R(A0::*)()volatile); -template -char_array<2>arg_tuple_size_helper(R(A0::*)(A1)volatile); -template -char_array<3>arg_tuple_size_helper(R(A0::*)(A1,A2)volatile); -template -char_array<4>arg_tuple_size_helper(R(A0::*)(A1,A2,A3)volatile); -template -char_array<5>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)volatile); -template -char_array<6>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)volatile); -template -char_array<7>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)volatile); -template -char_array<8>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)volatile); -template -char_array<9>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile); -template -char_array<10>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile); - -template -char_array<1>arg_tuple_size_helper(R(A0::*)()const volatile); -template -char_array<2>arg_tuple_size_helper(R(A0::*)(A1)const volatile); -template -char_array<3>arg_tuple_size_helper(R(A0::*)(A1,A2)const volatile); -template -char_array<4>arg_tuple_size_helper(R(A0::*)(A1,A2,A3)const volatile); -template -char_array<5>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)const volatile); -template -char_array<6>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)const volatile); -template -char_array<7>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)const volatile); -template -char_array<8>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const volatile); -template -char_array<9>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile); -template -char_array<10>arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile); +templatechar_array<0> +arg_tuple_size_helper(R(*)()); +templatechar_array<1> +arg_tuple_size_helper(R(*)(A0)); +templatechar_array<2> +arg_tuple_size_helper(R(*)(A0,A1)); +templatechar_array<3> +arg_tuple_size_helper(R(*)(A0,A1,A2)); +templatechar_array<4> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3)); +templatechar_array<5> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4)); +templatechar_array<6> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5)); +templatechar_array<7> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6)); +templatechar_array<8> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7)); +templatechar_array<9> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8)); +templatechar_array<10> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9)); +templatechar_array<11> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)); +templatechar_array<12> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)); +templatechar_array<13> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)); +templatechar_array<14> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)); +templatechar_array<15> +arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)); + + +templatechar_array<1> +arg_tuple_size_helper(R(A0::*)()); +templatechar_array<2> +arg_tuple_size_helper(R(A0::*)(A1)); +templatechar_array<3> +arg_tuple_size_helper(R(A0::*)(A1,A2)); +templatechar_array<4> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3)); +templatechar_array<5> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)); +templatechar_array<6> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)); +templatechar_array<7> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)); +templatechar_array<8> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)); +templatechar_array<9> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)); +templatechar_array<10> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)); +templatechar_array<11> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)); +templatechar_array<12> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)); +templatechar_array<13> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)); +templatechar_array<14> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)); +templatechar_array<15> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)); +templatechar_array<16> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)); +templatechar_array<1> +arg_tuple_size_helper(R(A0::*)()const); +templatechar_array<2> +arg_tuple_size_helper(R(A0::*)(A1)const); +templatechar_array<3> +arg_tuple_size_helper(R(A0::*)(A1,A2)const); +templatechar_array<4> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3)const); +templatechar_array<5> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)const); +templatechar_array<6> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)const); +templatechar_array<7> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)const); +templatechar_array<8> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const); +templatechar_array<9> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const); +templatechar_array<10> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const); +templatechar_array<11> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const); +templatechar_array<12> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const); +templatechar_array<13> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const); +templatechar_array<14> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const); +templatechar_array<15> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const); +templatechar_array<16> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const); +templatechar_array<1> +arg_tuple_size_helper(R(A0::*)()volatile); +templatechar_array<2> +arg_tuple_size_helper(R(A0::*)(A1)volatile); +templatechar_array<3> +arg_tuple_size_helper(R(A0::*)(A1,A2)volatile); +templatechar_array<4> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3)volatile); +templatechar_array<5> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)volatile); +templatechar_array<6> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)volatile); +templatechar_array<7> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)volatile); +templatechar_array<8> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)volatile); +templatechar_array<9> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile); +templatechar_array<10> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile); +templatechar_array<11> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile); +templatechar_array<12> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile); +templatechar_array<13> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile); +templatechar_array<14> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile); +templatechar_array<15> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile); +templatechar_array<16> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile); +templatechar_array<1> +arg_tuple_size_helper(R(A0::*)()const volatile); +templatechar_array<2> +arg_tuple_size_helper(R(A0::*)(A1)const volatile); +templatechar_array<3> +arg_tuple_size_helper(R(A0::*)(A1,A2)const volatile); +templatechar_array<4> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3)const volatile); +templatechar_array<5> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)const volatile); +templatechar_array<6> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)const volatile); +templatechar_array<7> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)const volatile); +templatechar_array<8> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const volatile); +templatechar_array<9> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile); +templatechar_array<10> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile); +templatechar_array<11> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile); +templatechar_array<12> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile); +templatechar_array<13> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile); +templatechar_array<14> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile); +templatechar_array<15> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile); +templatechar_array<16> +arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile); # endif diff --git a/include/boost/python/preprocessed/args.hpp b/include/boost/python/preprocessed/args.hpp new file mode 100644 index 00000000..e33f4c52 --- /dev/null +++ b/include/boost/python/preprocessed/args.hpp @@ -0,0 +1,169 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ARGS_DWA2002417_HPP +# define ARGS_DWA2002417_HPP + +template<> +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=0); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=1); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=2); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=3); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=4); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=5); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=6); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=7); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=8); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=9); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=10); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=11); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=12); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=13); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=14); +}; +template +struct size > +{ + BOOST_STATIC_CONSTANT(long,value=15); +}; + + + + +template +struct at<0,boost::python::args > +{ + typedef A0 type; +}; +template +struct at<1,boost::python::args > +{ + typedef A1 type; +}; +template +struct at<2,boost::python::args > +{ + typedef A2 type; +}; +template +struct at<3,boost::python::args > +{ + typedef A3 type; +}; +template +struct at<4,boost::python::args > +{ + typedef A4 type; +}; +template +struct at<5,boost::python::args > +{ + typedef A5 type; +}; +template +struct at<6,boost::python::args > +{ + typedef A6 type; +}; +template +struct at<7,boost::python::args > +{ + typedef A7 type; +}; +template +struct at<8,boost::python::args > +{ + typedef A8 type; +}; +template +struct at<9,boost::python::args > +{ + typedef A9 type; +}; +template +struct at<10,boost::python::args > +{ + typedef A10 type; +}; +template +struct at<11,boost::python::args > +{ + typedef A11 type; +}; +template +struct at<12,boost::python::args > +{ + typedef A12 type; +}; +template +struct at<13,boost::python::args > +{ + typedef A13 type; +}; +template +struct at<14,boost::python::args > +{ + typedef A14 type; +}; + +#endif // ARGS_DWA2002417_HPP diff --git a/include/boost/python/preprocessed/call.hpp b/include/boost/python/preprocessed/call.hpp index 2e0e31a1..51b9aa79 100644 --- a/include/boost/python/preprocessed/call.hpp +++ b/include/boost/python/preprocessed/call.hpp @@ -4,123 +4,275 @@ //"as is" without express or implied warranty,and with no claim as //to its suitability for any purpose. #ifndef CALL_PP_DWA2002411_HPP -#define CALL_PP_DWA2002411_HPP +# define CALL_PP_DWA2002411_HPP + +// emacs commands used to pre-clean preprocessor output: +// (replace-regexp ", *converter" "\n, converter") +// (replace-string "PyEval_CallFunction(" "\nPyEval_CallFunction(\n") template -typename converter::callback_from_python::result_type call(PyObject*callable,boost::type* =0) +typename converter::callback_from_python::result_type +call(PyObject*callable,boost::type* =0) { converter::callback_from_pythonconverter; return converter( - PyEval_CallFunction(callable,const_cast("(" ")"))); + PyEval_CallFunction( + callable,const_cast("(" ")"))); } template -typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,boost::type* =0) +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,boost::type* =0) { converter::callback_from_pythonconverter; return converter( - PyEval_CallFunction(callable,const_cast("(" "O" ")"), - converter::callback_to_python(a0).get())); + PyEval_CallFunction( + callable,const_cast("(" "O" ")") + ,converter::callback_to_python(a0).get())); } template -typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,boost::type* =0) +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,boost::type* =0) { converter::callback_from_pythonconverter; return converter( - PyEval_CallFunction(callable,const_cast("(" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get())); + PyEval_CallFunction( + callable,const_cast("(" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get())); } template -typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) { converter::callback_from_pythonconverter; return converter( - PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get())); + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get())); } template -typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::type* =0) +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::type* =0) { converter::callback_from_pythonconverter; return converter( - PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get())); + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get())); } template -typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,boost::type* =0) +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,boost::type* =0) { converter::callback_from_pythonconverter; return converter( - PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get(), - converter::callback_to_python(a4).get())); + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get())); } template -typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,boost::type* =0) +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,boost::type* =0) { converter::callback_from_pythonconverter; return converter( - PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get(), - converter::callback_to_python(a4).get(), - converter::callback_to_python(a5).get())); + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get())); } template -typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,boost::type* =0) +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,boost::type* =0) { converter::callback_from_pythonconverter; return converter( - PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get(), - converter::callback_to_python(a4).get(), - converter::callback_to_python(a5).get(), - converter::callback_to_python(a6).get())); + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get())); } template -typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,boost::type* =0) +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,boost::type* =0) { converter::callback_from_pythonconverter; return converter( - PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get(), - converter::callback_to_python(a4).get(), - converter::callback_to_python(a5).get(), - converter::callback_to_python(a6).get(), - converter::callback_to_python(a7).get())); + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get())); } template -typename converter::callback_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,boost::type* =0) +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,boost::type* =0) { converter::callback_from_pythonconverter; return converter( - PyEval_CallFunction(callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get(), - converter::callback_to_python(a4).get(), - converter::callback_to_python(a5).get(), - converter::callback_to_python(a6).get(), - converter::callback_to_python(a7).get(), - converter::callback_to_python(a8).get())); + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get())); +} +template +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get())); +} +template +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get() + ,converter::callback_to_python(a10).get())); +} +template +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get() + ,converter::callback_to_python(a10).get() + ,converter::callback_to_python(a11).get())); +} +template +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get() + ,converter::callback_to_python(a10).get() + ,converter::callback_to_python(a11).get() + ,converter::callback_to_python(a12).get())); +} +template +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get() + ,converter::callback_to_python(a10).get() + ,converter::callback_to_python(a11).get() + ,converter::callback_to_python(a12).get() + ,converter::callback_to_python(a13).get())); +} +template +typename converter::callback_from_python::result_type +call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallFunction( + callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get() + ,converter::callback_to_python(a10).get() + ,converter::callback_to_python(a11).get() + ,converter::callback_to_python(a12).get() + ,converter::callback_to_python(a13).get() + ,converter::callback_to_python(a14).get())); } - -#endif//CALL_PP_DWA2002411_HPP +#endif // CALL_PP_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/call_method.hpp b/include/boost/python/preprocessed/call_method.hpp index 1e395e4a..ea989e63 100644 --- a/include/boost/python/preprocessed/call_method.hpp +++ b/include/boost/python/preprocessed/call_method.hpp @@ -6,142 +6,272 @@ #ifndef CALL_METHOD_PP_DWA2002411_HPP # define CALL_METHOD_PP_DWA2002411_HPP -templatetypename -converter::callback_from_python::result_type +// emacs commands used to pre-clean preprocessor output: +// (replace-regexp ", *converter" "\n, converter") +// (replace-string "PyEval_CallMethod(" "\nPyEval_CallMethod(\n") + +template +typename converter::callback_from_python::result_type call_method(PyObject*self,char const*name,boost::type* =0) { - converter::callback_from_pythonconverter; return converter( - PyEval_CallMethod(self,const_cast(name),const_cast("(" ")"))); + PyEval_CallMethod( + self,const_cast(name),const_cast("(" ")"))); } -templatetypename -converter::callback_from_python::result_type +template +typename converter::callback_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,boost::type* =0) { - converter::callback_from_pythonconverter; return converter( - PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" ")"), - converter::callback_to_python(a0).get())); + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" ")") + ,converter::callback_to_python(a0).get())); } -templatetypename -converter::callback_from_python::result_type +template +typename converter::callback_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,boost::type* =0) { - converter::callback_from_pythonconverter; return converter( - PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get())); + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get())); } -templatetypename -converter::callback_from_python::result_type +template +typename converter::callback_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) { - converter::callback_from_pythonconverter; return converter( - PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get())); + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get())); } -templatetypename -converter::callback_from_python::result_type +template +typename converter::callback_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::type* =0) { - converter::callback_from_pythonconverter; return converter( - PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get())); + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get())); } -templatetypename -converter::callback_from_python::result_type +template +typename converter::callback_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,boost::type* =0) { - converter::callback_from_pythonconverter; return converter( - PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get(), - converter::callback_to_python(a4).get())); + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get())); } -templatetypename -converter::callback_from_python::result_type +template +typename converter::callback_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,boost::type* =0) { - converter::callback_from_pythonconverter; return converter( - PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get(), - converter::callback_to_python(a4).get(), - converter::callback_to_python(a5).get())); + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get())); } -templatetypename -converter::callback_from_python::result_type +template +typename converter::callback_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,boost::type* =0) { - converter::callback_from_pythonconverter; return converter( - PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get(), - converter::callback_to_python(a4).get(), - converter::callback_to_python(a5).get(), - converter::callback_to_python(a6).get())); + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get())); } -templatetypename -converter::callback_from_python::result_type +template +typename converter::callback_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,boost::type* =0) { - converter::callback_from_pythonconverter; return converter( - PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get(), - converter::callback_to_python(a4).get(), - converter::callback_to_python(a5).get(), - converter::callback_to_python(a6).get(), - converter::callback_to_python(a7).get())); + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get())); } -templatetypename -converter::callback_from_python::result_type +template +typename converter::callback_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,boost::type* =0) { - converter::callback_from_pythonconverter; return converter( - PyEval_CallMethod(self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")"), - converter::callback_to_python(a0).get(), - converter::callback_to_python(a1).get(), - converter::callback_to_python(a2).get(), - converter::callback_to_python(a3).get(), - converter::callback_to_python(a4).get(), - converter::callback_to_python(a5).get(), - converter::callback_to_python(a6).get(), - converter::callback_to_python(a7).get(), - converter::callback_to_python(a8).get())); + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get())); } - - -#endif// -CALL_METHOD_PP_DWA2002411_HPP +template +typename converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get())); +} +template +typename converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get() + ,converter::callback_to_python(a10).get())); +} +template +typename converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get() + ,converter::callback_to_python(a10).get() + ,converter::callback_to_python(a11).get())); +} +template +typename converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get() + ,converter::callback_to_python(a10).get() + ,converter::callback_to_python(a11).get() + ,converter::callback_to_python(a12).get())); +} +template +typename converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get() + ,converter::callback_to_python(a10).get() + ,converter::callback_to_python(a11).get() + ,converter::callback_to_python(a12).get() + ,converter::callback_to_python(a13).get())); +} +template +typename converter::callback_from_python::result_type +call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14,boost::type* =0) +{ + converter::callback_from_pythonconverter; + return converter( + PyEval_CallMethod( + self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") + ,converter::callback_to_python(a0).get() + ,converter::callback_to_python(a1).get() + ,converter::callback_to_python(a2).get() + ,converter::callback_to_python(a3).get() + ,converter::callback_to_python(a4).get() + ,converter::callback_to_python(a5).get() + ,converter::callback_to_python(a6).get() + ,converter::callback_to_python(a7).get() + ,converter::callback_to_python(a8).get() + ,converter::callback_to_python(a9).get() + ,converter::callback_to_python(a10).get() + ,converter::callback_to_python(a11).get() + ,converter::callback_to_python(a12).get() + ,converter::callback_to_python(a13).get() + ,converter::callback_to_python(a14).get())); +} +#endif// CALL_METHOD_PP_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/caller.hpp b/include/boost/python/preprocessed/caller.hpp index 3a28a9bc..dfbe40fc 100644 --- a/include/boost/python/preprocessed/caller.hpp +++ b/include/boost/python/preprocessed/caller.hpp @@ -7,255 +7,407 @@ # define CALLER_DWA2002410_HPP template -PyObject*operator()(R(*f)(),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(*f)(),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(*f)(A0),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(*f)(A0),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(*f)(A0,A1),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(*f)(A0,A1),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(*f)(A0,A1,A2),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(*f)(A0,A1,A2),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(*f)(A0,A1,A2,A3),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(*f)(A0,A1,A2,A3),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } +template +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} + + + template -PyObject*operator()(R(A0::*f)(),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)()const,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)()const,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1)const,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1)const,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2)const,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2)const,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3)const,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3)const,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)const,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)const,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)const,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)const,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)const,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)const,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)()volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)()volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1)volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1)volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2)volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2)volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3)volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3)volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)()const volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)()const volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,PyObject*args,PyObject*keywords,P const&policies)const +{ + return returning::call(f,args,keywords,&policies); +} +template +PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,PyObject*args,PyObject*keywords,P const&policies)const { return returning::call(f,args,keywords,&policies); } - #endif // CALLER_DWA2002410_HPP diff --git a/include/boost/python/preprocessed/make_holder.hpp b/include/boost/python/preprocessed/make_holder.hpp index 88eecbc1..dd226a89 100644 --- a/include/boost/python/preprocessed/make_holder.hpp +++ b/include/boost/python/preprocessed/make_holder.hpp @@ -12,12 +12,15 @@ struct make_holder<0> template struct apply { - static void execute(PyObject*p) + static void + execute(PyObject*p) { - (new Holder(p))->install(p); + (new + Holder(p))->install(p); } }; + }; template<> struct make_holder<1> @@ -27,12 +30,15 @@ struct make_holder<1> { typedef typename mpl::at<0,ArgList>::type t0; typedef typename forward::type f0; - static void execute(PyObject*p,t0 a0) + static void + execute(PyObject*p,t0 a0) { - (new Holder(p,f0(a0)))->install(p); + (new + Holder(p,f0(a0)))->install(p); } }; + }; template<> struct make_holder<2> @@ -44,12 +50,15 @@ struct make_holder<2> typedef typename forward::type f0; typedef typename mpl::at<1,ArgList>::type t1; typedef typename forward::type f1; - static void execute(PyObject*p,t0 a0,t1 a1) + static void + execute(PyObject*p,t0 a0,t1 a1) { - (new Holder(p,f0(a0),f1(a1)))->install(p); + (new + Holder(p,f0(a0),f1(a1)))->install(p); } }; + }; template<> struct make_holder<3> @@ -63,12 +72,15 @@ struct make_holder<3> typedef typename forward::type f1; typedef typename mpl::at<2,ArgList>::type t2; typedef typename forward::type f2; - static void execute(PyObject*p,t0 a0,t1 a1,t2 a2) + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2) { - (new Holder(p,f0(a0),f1(a1),f2(a2)))->install(p); + (new + Holder(p,f0(a0),f1(a1),f2(a2)))->install(p); } }; + }; template<> struct make_holder<4> @@ -84,12 +96,15 @@ struct make_holder<4> typedef typename forward::type f2; typedef typename mpl::at<3,ArgList>::type t3; typedef typename forward::type f3; - static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3) + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3) { - (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3)))->install(p); + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3)))->install(p); } }; + }; template<> struct make_holder<5> @@ -107,12 +122,15 @@ struct make_holder<5> typedef typename forward::type f3; typedef typename mpl::at<4,ArgList>::type t4; typedef typename forward::type f4; - static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4) + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4) { - (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4)))->install(p); + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4)))->install(p); } }; + }; template<> struct make_holder<6> @@ -132,12 +150,15 @@ struct make_holder<6> typedef typename forward::type f4; typedef typename mpl::at<5,ArgList>::type t5; typedef typename forward::type f5; - static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5) + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5) { - (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5)))->install(p); + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5)))->install(p); } }; + }; template<> struct make_holder<7> @@ -159,12 +180,15 @@ struct make_holder<7> typedef typename forward::type f5; typedef typename mpl::at<6,ArgList>::type t6; typedef typename forward::type f6; - static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6) + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6) { - (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6)))->install(p); + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6)))->install(p); } }; + }; template<> struct make_holder<8> @@ -188,12 +212,15 @@ struct make_holder<8> typedef typename forward::type f6; typedef typename mpl::at<7,ArgList>::type t7; typedef typename forward::type f7; - static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7) + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7) { - (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7)))->install(p); + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7)))->install(p); } }; + }; template<> struct make_holder<9> @@ -219,12 +246,262 @@ struct make_holder<9> typedef typename forward::type f7; typedef typename mpl::at<8,ArgList>::type t8; typedef typename forward::type f8; - static void execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8) + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8) { - (new Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8)))->install(p); + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8)))->install(p); } }; -}; +}; +template<> +struct make_holder<10> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + typedef typename mpl::at<5,ArgList>::type t5; + typedef typename forward::type f5; + typedef typename mpl::at<6,ArgList>::type t6; + typedef typename forward::type f6; + typedef typename mpl::at<7,ArgList>::type t7; + typedef typename forward::type f7; + typedef typename mpl::at<8,ArgList>::type t8; + typedef typename forward::type f8; + typedef typename mpl::at<9,ArgList>::type t9; + typedef typename forward::type f9; + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9) + { + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9)))->install(p); + } + + }; + +}; +template<> +struct make_holder<11> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + typedef typename mpl::at<5,ArgList>::type t5; + typedef typename forward::type f5; + typedef typename mpl::at<6,ArgList>::type t6; + typedef typename forward::type f6; + typedef typename mpl::at<7,ArgList>::type t7; + typedef typename forward::type f7; + typedef typename mpl::at<8,ArgList>::type t8; + typedef typename forward::type f8; + typedef typename mpl::at<9,ArgList>::type t9; + typedef typename forward::type f9; + typedef typename mpl::at<10,ArgList>::type t10; + typedef typename forward::type f10; + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10) + { + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9),f10(a10)))->install(p); + } + + }; + +}; +template<> +struct make_holder<12> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + typedef typename mpl::at<5,ArgList>::type t5; + typedef typename forward::type f5; + typedef typename mpl::at<6,ArgList>::type t6; + typedef typename forward::type f6; + typedef typename mpl::at<7,ArgList>::type t7; + typedef typename forward::type f7; + typedef typename mpl::at<8,ArgList>::type t8; + typedef typename forward::type f8; + typedef typename mpl::at<9,ArgList>::type t9; + typedef typename forward::type f9; + typedef typename mpl::at<10,ArgList>::type t10; + typedef typename forward::type f10; + typedef typename mpl::at<11,ArgList>::type t11; + typedef typename forward::type f11; + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11) + { + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9),f10(a10),f11(a11)))->install(p); + } + + }; + +}; +template<> +struct make_holder<13> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + typedef typename mpl::at<5,ArgList>::type t5; + typedef typename forward::type f5; + typedef typename mpl::at<6,ArgList>::type t6; + typedef typename forward::type f6; + typedef typename mpl::at<7,ArgList>::type t7; + typedef typename forward::type f7; + typedef typename mpl::at<8,ArgList>::type t8; + typedef typename forward::type f8; + typedef typename mpl::at<9,ArgList>::type t9; + typedef typename forward::type f9; + typedef typename mpl::at<10,ArgList>::type t10; + typedef typename forward::type f10; + typedef typename mpl::at<11,ArgList>::type t11; + typedef typename forward::type f11; + typedef typename mpl::at<12,ArgList>::type t12; + typedef typename forward::type f12; + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12) + { + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9),f10(a10),f11(a11),f12(a12)))->install(p); + } + + }; + +}; +template<> +struct make_holder<14> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + typedef typename mpl::at<5,ArgList>::type t5; + typedef typename forward::type f5; + typedef typename mpl::at<6,ArgList>::type t6; + typedef typename forward::type f6; + typedef typename mpl::at<7,ArgList>::type t7; + typedef typename forward::type f7; + typedef typename mpl::at<8,ArgList>::type t8; + typedef typename forward::type f8; + typedef typename mpl::at<9,ArgList>::type t9; + typedef typename forward::type f9; + typedef typename mpl::at<10,ArgList>::type t10; + typedef typename forward::type f10; + typedef typename mpl::at<11,ArgList>::type t11; + typedef typename forward::type f11; + typedef typename mpl::at<12,ArgList>::type t12; + typedef typename forward::type f12; + typedef typename mpl::at<13,ArgList>::type t13; + typedef typename forward::type f13; + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12,t13 a13) + { + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9),f10(a10),f11(a11),f12(a12),f13(a13)))->install(p); + } + + }; + +}; +template<> +struct make_holder<15> +{ + template + struct apply + { + typedef typename mpl::at<0,ArgList>::type t0; + typedef typename forward::type f0; + typedef typename mpl::at<1,ArgList>::type t1; + typedef typename forward::type f1; + typedef typename mpl::at<2,ArgList>::type t2; + typedef typename forward::type f2; + typedef typename mpl::at<3,ArgList>::type t3; + typedef typename forward::type f3; + typedef typename mpl::at<4,ArgList>::type t4; + typedef typename forward::type f4; + typedef typename mpl::at<5,ArgList>::type t5; + typedef typename forward::type f5; + typedef typename mpl::at<6,ArgList>::type t6; + typedef typename forward::type f6; + typedef typename mpl::at<7,ArgList>::type t7; + typedef typename forward::type f7; + typedef typename mpl::at<8,ArgList>::type t8; + typedef typename forward::type f8; + typedef typename mpl::at<9,ArgList>::type t9; + typedef typename forward::type f9; + typedef typename mpl::at<10,ArgList>::type t10; + typedef typename forward::type f10; + typedef typename mpl::at<11,ArgList>::type t11; + typedef typename forward::type f11; + typedef typename mpl::at<12,ArgList>::type t12; + typedef typename forward::type f12; + typedef typename mpl::at<13,ArgList>::type t13; + typedef typename forward::type f13; + typedef typename mpl::at<14,ArgList>::type t14; + typedef typename forward::type f14; + static void + execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12,t13 a13,t14 a14) + { + (new + Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9),f10(a10),f11(a11),f12(a12),f13(a13),f14(a14)))->install(p); + } + + }; + +}; #endif // MAKE_HOLDER_DWA2002416_HPP + + diff --git a/include/boost/python/preprocessed/member_function_cast.hpp b/include/boost/python/preprocessed/member_function_cast.hpp index 691b16f5..d8a6a54e 100644 --- a/include/boost/python/preprocessed/member_function_cast.hpp +++ b/include/boost/python/preprocessed/member_function_cast.hpp @@ -6,6 +6,9 @@ #ifndef MEMBER_FUNCTION_CAST_DWA2002410_HPP # define MEMBER_FUNCTION_CAST_DWA2002410_HPP +// emacs commands used to pre-clean preprocessor output +// (replace-regexp "> *stage1(" ">\nstage1(") + template static cast_helper stage1(R(S::*)()) @@ -66,6 +69,42 @@ stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)) { return cast_helper(); } +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)) +{ + return cast_helper(); +} template static cast_helper stage1(R(S::*)()const) @@ -126,6 +165,42 @@ stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const) { return cast_helper(); } +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const) +{ + return cast_helper(); +} template static cast_helper stage1(R(S::*)()volatile) @@ -186,6 +261,42 @@ stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile) { return cast_helper(); } +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile) +{ + return cast_helper(); +} template static cast_helper stage1(R(S::*)()const volatile) @@ -246,5 +357,40 @@ stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile) { return cast_helper(); } - +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile) +{ + return cast_helper(); +} +template +static cast_helper +stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile) +{ + return cast_helper(); +} #endif // MEMBER_FUNCTION_CAST_DWA2002410_HPP diff --git a/include/boost/python/preprocessed/pointer_holder.hpp b/include/boost/python/preprocessed/pointer_holder.hpp index 0f2bf149..bce4d80c 100644 --- a/include/boost/python/preprocessed/pointer_holder.hpp +++ b/include/boost/python/preprocessed/pointer_holder.hpp @@ -6,100 +6,225 @@ #ifndef POINTER_HOLDER_DWA2002411_HPP # define POINTER_HOLDER_DWA2002411_HPP +// emacs commands used to pre-clean preprocessor output: +// (replace-regexp ": *m_p *(" "\n: m_p(") +// (replace-regexp "Value(" "Value(\n") +// (replace-regexp ", *(" "\n, (") + pointer_holder(PyObject*) - :m_p(new Value()) + :m_p(new Value( + )) { } -templatepointer_holder(PyObject*,A0 a0) +template +pointer_holder(PyObject*,A0 a0) :m_p(new Value( (typename unforward::type)(a0))) { } -templatepointer_holder(PyObject*,A0 a0,A1 a1) +template +pointer_holder(PyObject*,A0 a0,A1 a1) :m_p(new Value( - (typename unforward::type)(a0), - (typename unforward::type)(a1))) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1))) { } -templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2) +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2) :m_p(new Value( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2))) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2))) { } -templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3) +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3) :m_p(new Value( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3))) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3))) { } -templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) :m_p(new Value( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4))) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4))) { } -templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) :m_p(new Value( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5))) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5))) { } -templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) :m_p(new Value( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6))) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6))) { } -templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) :m_p(new Value( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6), - (typename unforward::type)(a7))) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7))) { } -templatepointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) :m_p(new Value( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6), - (typename unforward::type)(a7), - (typename unforward::type)(a8))) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8))) { } +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) + :m_p(new Value( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9))) +{ +} +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) + :m_p(new Value( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10))) +{ + +} +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11) + :m_p(new Value( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11))) +{ + +} +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12) + :m_p(new Value( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12))) +{ + +} +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13) + :m_p(new Value( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12) + ,(typename unforward::type)(a13))) +{ + +} +template +pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13,A14 a14) + :m_p(new Value( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12) + ,(typename unforward::type)(a13) + ,(typename unforward::type)(a14))) +{ + +} #endif // POINTER_HOLDER_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/pointer_holder_back_reference.hpp b/include/boost/python/preprocessed/pointer_holder_back_reference.hpp index 9d86a172..882e1788 100644 --- a/include/boost/python/preprocessed/pointer_holder_back_reference.hpp +++ b/include/boost/python/preprocessed/pointer_holder_back_reference.hpp @@ -6,111 +6,256 @@ #ifndef POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP #define POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP -pointer_holder_back_reference(PyObject*p) - :m_p(new held_type(p)) -{ - void const*x=&instance_finder::registration; - (void)x; -} -templatepointer_holder_back_reference(PyObject*p,A0 a0) - :m_p(new held_type(p, - (typename unforward::type)(a0))) -{ - void const*x=&instance_finder::registration; - (void)x; -} -templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1) - :m_p(new held_type(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1))) -{ - void const*x=&instance_finder::registration; - (void)x; -} -templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) - :m_p(new held_type(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2))) -{ - void const*x=&instance_finder::registration; - (void)x; -} -templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) - :m_p(new held_type(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3))) -{ - void const*x=&instance_finder::registration; - (void)x; -} -templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) - :m_p(new held_type(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4))) -{ - void const*x=&instance_finder::registration; - (void)x; -} -templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) - :m_p(new held_type(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5))) -{ - void const*x=&instance_finder::registration; - (void)x; -} -templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) - :m_p(new held_type(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6))) -{ - void const*x=&instance_finder::registration; - (void)x; -} -templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) - :m_p(new held_type(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6), - (typename unforward::type)(a7))) -{ - void const*x=&instance_finder::registration; - (void)x; -} -templatepointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) - :m_p(new held_type(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6), - (typename unforward::type)(a7), - (typename unforward::type)(a8))) -{ - void const*x=&instance_finder::registration; - (void)x; -} - +// emacs commands used to pre-clean preprocessor output: +// (replace-regexp ": *m_p *(" "\n: m_p(") +// (replace-regexp "held_type(" "held_type(\n") +// (replace-regexp ", *(" "\n, (") +pointer_holder_back_reference(PyObject*p) + :m_p(new held_type( + p)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0) + :m_p(new held_type( + p + ,(typename unforward::type)(a0))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12) + ,(typename unforward::type)(a13))) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13,A14 a14) + :m_p(new held_type( + p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12) + ,(typename unforward::type)(a13) + ,(typename unforward::type)(a14))) +{ + void const*x=&instance_finder::registration; + (void)x; +} #endif//POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/returning_non_void.hpp b/include/boost/python/preprocessed/returning_non_void.hpp index 4b39bebc..c677a072 100644 --- a/include/boost/python/preprocessed/returning_non_void.hpp +++ b/include/boost/python/preprocessed/returning_non_void.hpp @@ -6,986 +6,2800 @@ #ifndef RETURNING_NON_VOID_DWA2002410_HPP #define RETURNING_NON_VOID_DWA2002410_HPP -templatestatic PyObject*call( R( A0::*pmf )( ),PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1 ),PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ),PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ),PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ),PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ),PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ),PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ),PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ),PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ),PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); - if (!c9.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( ) const,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1 ) const,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) const,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) const,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) const,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) const,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) const,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) const,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) const,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) const,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); - if (!c9.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( ) volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1 ) volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); - if (!c9.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( ) const volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1 ) const volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) const volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) const volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) const volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) const volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) const volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) const volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) const volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ) ); - return policies->postcall(args_,result); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) const volatile,PyObject*args_,PyObject*,P const* policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); - if (!c9.convertible()) return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (( c0 (PyTuple_GET_ITEM(args_,0 )) )->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ) ); - return policies->postcall(args_,result); -} +// emacs commands used to pre-clean preprocessor output: +// (replace-regexp ", *\\(c[0-9]\\)" "\n, \\1") +// (replace-regexp "( *\\(c[0-9]\\)" "(\n\\1") -templatestatic PyObject*call( R(*pf )( ),PyObject*args_,PyObject*,P const* policies) +template +static PyObject*call(R(A0::*pmf)(),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)()); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)) + , c14(PyTuple_GET_ITEM(args_,14)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + from_pythonc15(PyTuple_GET_ITEM(args_,15)); + if(!c15.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)) + , c14(PyTuple_GET_ITEM(args_,14)) + , c15(PyTuple_GET_ITEM(args_,15)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)()const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)()); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)) + , c14(PyTuple_GET_ITEM(args_,14)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + from_pythonc15(PyTuple_GET_ITEM(args_,15)); + if(!c15.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)) + , c14(PyTuple_GET_ITEM(args_,14)) + , c15(PyTuple_GET_ITEM(args_,15)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)()volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)()); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)) + , c14(PyTuple_GET_ITEM(args_,14)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + from_pythonc15(PyTuple_GET_ITEM(args_,15)); + if(!c15.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)) + , c14(PyTuple_GET_ITEM(args_,14)) + , c15(PyTuple_GET_ITEM(args_,15)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)()const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)()); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)) + , c14(PyTuple_GET_ITEM(args_,14)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + from_pythonc15(PyTuple_GET_ITEM(args_,15)); + if(!c15.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)) + , c14(PyTuple_GET_ITEM(args_,14)) + , c15(PyTuple_GET_ITEM(args_,15)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(*pf)(),PyObject*args_,PyObject*,P const*policies) { typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (*pf)( ) ); + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)()); return policies->postcall(args_,result); } -templatestatic PyObject*call( R(*pf )( A0 ),PyObject*args_,PyObject*,P const* policies) +template +static PyObject*call(R(*pf)(A0),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )) ) ); + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)))); return policies->postcall(args_,result); } -templatestatic PyObject*call( R(*pf )( A0,A1 ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(*pf)(A0,A1),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )) ) ); + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)))); return policies->postcall(args_,result); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2 ),PyObject*args_,PyObject*,P const* policies) +template +static PyObject*call(R(*pf)(A0,A1,A2),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ) ); + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)))); return policies->postcall(args_,result); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3 ),PyObject*args_,PyObject*,P const* policies) +template +static PyObject*call(R(*pf)(A0,A1,A2,A3),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ) ); + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)))); return policies->postcall(args_,result); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4 ),PyObject*args_,PyObject*,P const* policies) +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ) ); + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)))); return policies->postcall(args_,result); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5 ),PyObject*args_,PyObject*,P const* policies) +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ) ); + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)))); return policies->postcall(args_,result); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6 ),PyObject*args_,PyObject*,P const* policies) +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ) ); + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)))); return policies->postcall(args_,result); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6,A7 ),PyObject*args_,PyObject*,P const* policies) +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ) ); + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)))); return policies->postcall(args_,result); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6,A7,A8 ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; - if (!policies->precall(args_)) return 0; - PyObject*result=cr( (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ) ); + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)))); + return policies->postcall(args_,result); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if(!cr.convertible())return 0; + if(!policies->precall(args_))return 0; + PyObject*result=cr((*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + , c1(PyTuple_GET_ITEM(args_,1)) + , c2(PyTuple_GET_ITEM(args_,2)) + , c3(PyTuple_GET_ITEM(args_,3)) + , c4(PyTuple_GET_ITEM(args_,4)) + , c5(PyTuple_GET_ITEM(args_,5)) + , c6(PyTuple_GET_ITEM(args_,6)) + , c7(PyTuple_GET_ITEM(args_,7)) + , c8(PyTuple_GET_ITEM(args_,8)) + , c9(PyTuple_GET_ITEM(args_,9)) + , c10(PyTuple_GET_ITEM(args_,10)) + , c11(PyTuple_GET_ITEM(args_,11)) + , c12(PyTuple_GET_ITEM(args_,12)) + , c13(PyTuple_GET_ITEM(args_,13)) + , c14(PyTuple_GET_ITEM(args_,14)))); return policies->postcall(args_,result); } - #endif // RETURNING_NON_VOID_DWA2002410_HPP diff --git a/include/boost/python/preprocessed/returning_void.hpp b/include/boost/python/preprocessed/returning_void.hpp index 945c4318..2179c9d9 100644 --- a/include/boost/python/preprocessed/returning_void.hpp +++ b/include/boost/python/preprocessed/returning_void.hpp @@ -4,839 +4,2562 @@ //"as is" without express or implied warranty,and with no claim as //to its suitability for any purpose. #ifndef RETURNING_VOID_DWA2002410_HPP -#define RETURNING_VOID_DWA2002410_HPP +# define RETURNING_VOID_DWA2002410_HPP -templatestatic PyObject*call( R( A0::*pmf )( ),PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1 ),PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ),PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ),PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ),PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ),PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ),PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ),PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ),PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ),PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); - if (!c9.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( ) const,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1 ) const,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) const,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) const,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) const,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) const,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) const,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) const,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) const,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) const,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); - if (!c9.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( ) volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1 ) volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); - if (!c9.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( ) const volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1 ) const volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2 ) const volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3 ) const volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4 ) const volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5 ) const volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6 ) const volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7 ) const volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8 ) const volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ); - return policies->postcall(args_,detail::none()); -} -templatestatic PyObject*call( R( A0::*pmf )( A1,A2,A3,A4,A5,A6,A7,A8,A9 ) const volatile,PyObject*args_,PyObject*,P const*policies) -{ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - from_pythonc9 (PyTuple_GET_ITEM(args_,9 )); - if (!c9.convertible()) return 0; - if (!policies->precall(args_)) return 0; - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )),c9 (PyTuple_GET_ITEM(args_,9 )) ); - return policies->postcall(args_,detail::none()); -} - - +// emacs commands used to pre-clean preprocessor output: +// (replace-regexp ", *\\(c[0-9]\\)" "\n, \\1") +// (replace-regexp "( *\\(c[0-9]\\)" "(\n\\1") -templatestatic PyObject*call( R(*pf )( ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(A0::*pmf)(),PyObject*args_,PyObject*,P const*policies) { - (*pf)( ); + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)(); return policies->postcall(args_,detail::none()); } -templatestatic PyObject*call( R(*pf )( A0 ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(A0::*pmf)(A1),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - if (!policies->precall(args_)) return 0; - (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )) ); + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1))); return policies->postcall(args_,detail::none()); } -templatestatic PyObject*call( R(*pf )( A0,A1 ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(A0::*pmf)(A1,A2),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - if (!policies->precall(args_)) return 0; - (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )) ); + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2))); return policies->postcall(args_,detail::none()); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2 ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - if (!policies->precall(args_)) return 0; - (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )) ); + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3))); return policies->postcall(args_,detail::none()); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3 ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - if (!policies->precall(args_)) return 0; - (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )) ); + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4))); return policies->postcall(args_,detail::none()); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4 ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - if (!policies->precall(args_)) return 0; - (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )) ); + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5))); return policies->postcall(args_,detail::none()); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5 ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - if (!policies->precall(args_)) return 0; - (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )) ); + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6))); return policies->postcall(args_,detail::none()); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6 ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - if (!policies->precall(args_)) return 0; - (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )) ); + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7))); return policies->postcall(args_,detail::none()); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6,A7 ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - if (!policies->precall(args_)) return 0; - (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )) ); + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8))); return policies->postcall(args_,detail::none()); } -templatestatic PyObject*call( R(*pf )( A0,A1,A2,A3,A4,A5,A6,A7,A8 ),PyObject*args_,PyObject*,P const*policies) +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0 (PyTuple_GET_ITEM(args_,0 )); - if (!c0.convertible()) return 0; - from_pythonc1 (PyTuple_GET_ITEM(args_,1 )); - if (!c1.convertible()) return 0; - from_pythonc2 (PyTuple_GET_ITEM(args_,2 )); - if (!c2.convertible()) return 0; - from_pythonc3 (PyTuple_GET_ITEM(args_,3 )); - if (!c3.convertible()) return 0; - from_pythonc4 (PyTuple_GET_ITEM(args_,4 )); - if (!c4.convertible()) return 0; - from_pythonc5 (PyTuple_GET_ITEM(args_,5 )); - if (!c5.convertible()) return 0; - from_pythonc6 (PyTuple_GET_ITEM(args_,6 )); - if (!c6.convertible()) return 0; - from_pythonc7 (PyTuple_GET_ITEM(args_,7 )); - if (!c7.convertible()) return 0; - from_pythonc8 (PyTuple_GET_ITEM(args_,8 )); - if (!c8.convertible()) return 0; - if (!policies->precall(args_)) return 0; - (*pf)( c0 (PyTuple_GET_ITEM(args_,0 )),c1 (PyTuple_GET_ITEM(args_,1 )),c2 (PyTuple_GET_ITEM(args_,2 )),c3 (PyTuple_GET_ITEM(args_,3 )),c4 (PyTuple_GET_ITEM(args_,4 )),c5 (PyTuple_GET_ITEM(args_,5 )),c6 (PyTuple_GET_ITEM(args_,6 )),c7 (PyTuple_GET_ITEM(args_,7 )),c8 (PyTuple_GET_ITEM(args_,8 )) ); + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9))); return policies->postcall(args_,detail::none()); } - -#endif//RETURNING_VOID_DWA2002410_HPP +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13)) + ,c14(PyTuple_GET_ITEM(args_,14))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + from_pythonc15(PyTuple_GET_ITEM(args_,15)); + if(!c15.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13)) + ,c14(PyTuple_GET_ITEM(args_,14)) + ,c15(PyTuple_GET_ITEM(args_,15))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)()const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)(); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13)) + ,c14(PyTuple_GET_ITEM(args_,14))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + from_pythonc15(PyTuple_GET_ITEM(args_,15)); + if(!c15.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13)) + ,c14(PyTuple_GET_ITEM(args_,14)) + ,c15(PyTuple_GET_ITEM(args_,15))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)()volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)(); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13)) + ,c14(PyTuple_GET_ITEM(args_,14))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + from_pythonc15(PyTuple_GET_ITEM(args_,15)); + if(!c15.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13)) + ,c14(PyTuple_GET_ITEM(args_,14)) + ,c15(PyTuple_GET_ITEM(args_,15))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)()const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)(); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13)) + ,c14(PyTuple_GET_ITEM(args_,14))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + from_pythonc15(PyTuple_GET_ITEM(args_,15)); + if(!c15.convertible())return 0; + if(!policies->precall(args_))return 0; + (( + c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13)) + ,c14(PyTuple_GET_ITEM(args_,14)) + ,c15(PyTuple_GET_ITEM(args_,15))); + return policies->postcall(args_,detail::none()); +} + +template +static PyObject*call(R(*pf)(),PyObject*args_,PyObject*,P const*policies) +{ + (*pf)(); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13))); + return policies->postcall(args_,detail::none()); +} +template +static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) +{ + from_pythonc0(PyTuple_GET_ITEM(args_,0)); + if(!c0.convertible())return 0; + from_pythonc1(PyTuple_GET_ITEM(args_,1)); + if(!c1.convertible())return 0; + from_pythonc2(PyTuple_GET_ITEM(args_,2)); + if(!c2.convertible())return 0; + from_pythonc3(PyTuple_GET_ITEM(args_,3)); + if(!c3.convertible())return 0; + from_pythonc4(PyTuple_GET_ITEM(args_,4)); + if(!c4.convertible())return 0; + from_pythonc5(PyTuple_GET_ITEM(args_,5)); + if(!c5.convertible())return 0; + from_pythonc6(PyTuple_GET_ITEM(args_,6)); + if(!c6.convertible())return 0; + from_pythonc7(PyTuple_GET_ITEM(args_,7)); + if(!c7.convertible())return 0; + from_pythonc8(PyTuple_GET_ITEM(args_,8)); + if(!c8.convertible())return 0; + from_pythonc9(PyTuple_GET_ITEM(args_,9)); + if(!c9.convertible())return 0; + from_pythonc10(PyTuple_GET_ITEM(args_,10)); + if(!c10.convertible())return 0; + from_pythonc11(PyTuple_GET_ITEM(args_,11)); + if(!c11.convertible())return 0; + from_pythonc12(PyTuple_GET_ITEM(args_,12)); + if(!c12.convertible())return 0; + from_pythonc13(PyTuple_GET_ITEM(args_,13)); + if(!c13.convertible())return 0; + from_pythonc14(PyTuple_GET_ITEM(args_,14)); + if(!c14.convertible())return 0; + if(!policies->precall(args_))return 0; + (*pf)( + c0(PyTuple_GET_ITEM(args_,0)) + ,c1(PyTuple_GET_ITEM(args_,1)) + ,c2(PyTuple_GET_ITEM(args_,2)) + ,c3(PyTuple_GET_ITEM(args_,3)) + ,c4(PyTuple_GET_ITEM(args_,4)) + ,c5(PyTuple_GET_ITEM(args_,5)) + ,c6(PyTuple_GET_ITEM(args_,6)) + ,c7(PyTuple_GET_ITEM(args_,7)) + ,c8(PyTuple_GET_ITEM(args_,8)) + ,c9(PyTuple_GET_ITEM(args_,9)) + ,c10(PyTuple_GET_ITEM(args_,10)) + ,c11(PyTuple_GET_ITEM(args_,11)) + ,c12(PyTuple_GET_ITEM(args_,12)) + ,c13(PyTuple_GET_ITEM(args_,13)) + ,c14(PyTuple_GET_ITEM(args_,14))); + return policies->postcall(args_,detail::none()); +} +#endif // RETURNING_VOID_DWA2002410_HPP diff --git a/include/boost/python/preprocessed/value_holder.hpp b/include/boost/python/preprocessed/value_holder.hpp index 88ba56dd..20437d8b 100644 --- a/include/boost/python/preprocessed/value_holder.hpp +++ b/include/boost/python/preprocessed/value_holder.hpp @@ -6,100 +6,223 @@ #ifndef VALUE_HOLDER_DWA2002411_HPP # define VALUE_HOLDER_DWA2002411_HPP +// emacs commands used to pre-clean preprocessor output: +// (replace-regexp ": *m_held *(" "\n: m_held(") +// (replace-regexp ", *(" "\n, (") + value_holder(PyObject*) :m_held() { } -templatevalue_holder(PyObject*,A0 a0) +template +value_holder(PyObject*,A0 a0) :m_held( (typename unforward::type)(a0)) { } -templatevalue_holder(PyObject*,A0 a0,A1 a1) +template +value_holder(PyObject*,A0 a0,A1 a1) :m_held( - (typename unforward::type)(a0), - (typename unforward::type)(a1)) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1)) { } -templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2) +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2) :m_held( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2)) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2)) { } -templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3) +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3) :m_held( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3)) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3)) { } -templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) :m_held( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4)) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4)) { } -templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) :m_held( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5)) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5)) { } -templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) :m_held( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6)) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6)) { } -templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) :m_held( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6), - (typename unforward::type)(a7)) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7)) { } -templatevalue_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) :m_held( - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6), - (typename unforward::type)(a7), - (typename unforward::type)(a8)) + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8)) { -} +} +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) + :m_held( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9)) +{ +} +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) + :m_held( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10)) +{ + +} +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11) + :m_held( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11)) +{ + +} +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12) + :m_held( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12)) +{ + +} +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13) + :m_held( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12) + ,(typename unforward::type)(a13)) +{ + +} +template +value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13,A14 a14) + :m_held( + (typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12) + ,(typename unforward::type)(a13) + ,(typename unforward::type)(a14)) +{ + +} #endif // VALUE_HOLDER_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/value_holder_back_reference.hpp b/include/boost/python/preprocessed/value_holder_back_reference.hpp index c9d91434..76fc18ed 100644 --- a/include/boost/python/preprocessed/value_holder_back_reference.hpp +++ b/include/boost/python/preprocessed/value_holder_back_reference.hpp @@ -6,109 +6,237 @@ #ifndef VALUE_HOLDER_BACK_REFERENCE_DWA2002411_HPP # define VALUE_HOLDER_BACK_REFERENCE_DWA2002411_HPP +// emacs commands used to pre-clean preprocessor output: +// (replace-regexp ": *m_held *(" "\n: m_held(") +// (replace-regexp ", *(" "\n, (") + value_holder_back_reference(PyObject*p) :m_held(p) { void const*x=&instance_finder::registration; (void)x; } - - -templatevalue_holder_back_reference(PyObject*p,A0 a0) - :m_held(p, - (typename unforward::type)(a0)) +template +value_holder_back_reference(PyObject*p,A0 a0) + :m_held(p + ,(typename unforward::type)(a0)) { void const*x=&instance_finder::registration; (void)x; } -templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1) - :m_held(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1)) +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1)) { void const*x=&instance_finder::registration; (void)x; } -templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) - :m_held(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2)) +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2)) { void const*x=&instance_finder::registration; (void)x; } -templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) - :m_held(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3)) +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3)) { void const*x=&instance_finder::registration; (void)x; } -templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) - :m_held(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4)) +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4)) { void const*x=&instance_finder::registration; (void)x; } -templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) - :m_held(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5)) +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5)) { void const*x=&instance_finder::registration; (void)x; } -templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) - :m_held(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6)) +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6)) { void const*x=&instance_finder::registration; (void)x; } -templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) - :m_held(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6), - (typename unforward::type)(a7)) +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7)) { void const*x=&instance_finder::registration; (void)x; } -templatevalue_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) - :m_held(p, - (typename unforward::type)(a0), - (typename unforward::type)(a1), - (typename unforward::type)(a2), - (typename unforward::type)(a3), - (typename unforward::type)(a4), - (typename unforward::type)(a5), - (typename unforward::type)(a6), - (typename unforward::type)(a7), - (typename unforward::type)(a8)) +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12) + ,(typename unforward::type)(a13)) +{ + void const*x=&instance_finder::registration; + (void)x; +} +template +value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13,A14 a14) + :m_held(p + ,(typename unforward::type)(a0) + ,(typename unforward::type)(a1) + ,(typename unforward::type)(a2) + ,(typename unforward::type)(a3) + ,(typename unforward::type)(a4) + ,(typename unforward::type)(a5) + ,(typename unforward::type)(a6) + ,(typename unforward::type)(a7) + ,(typename unforward::type)(a8) + ,(typename unforward::type)(a9) + ,(typename unforward::type)(a10) + ,(typename unforward::type)(a11) + ,(typename unforward::type)(a12) + ,(typename unforward::type)(a13) + ,(typename unforward::type)(a14)) { void const*x=&instance_finder::registration; (void)x; From f0e3fd9e721f2c9bf9e956f15231de7cc774bb6f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 18 Apr 2002 04:00:30 +0000 Subject: [PATCH 0410/1042] *** empty log message *** [SVN r13520] --- doc/v2/call.html | 20 +++++++++++++------- test/multi_arg_constructor.cpp | 8 ++++++-- test/multi_arg_constructor.py | 2 +- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/doc/v2/call.html b/doc/v2/call.html index 4ba3dd96..e75d5597 100644 --- a/doc/v2/call.html +++ b/doc/v2/call.html @@ -39,16 +39,22 @@

        Functions

         template <class R, class A1, class A2, ... class An>
        -result-type call(PyObject* callable, A1 const&, A2 const&, ... An const&)
        +R call(PyObject* callable, A1 const&, A2 const&, ... An const&)
         
        -
        Requires: {{text}}
        -
        Effects: {{text}}
        +
        Requires: R is a complete type with an accessible copy constructor
        + +
        Effects: Invokes callable(a1, a2, ...an) in + Python, where a1...an are the arguments to + call(), converted to Python objects.
        Postconditions: {{text}}
        -
        Returns: {{text}}
        -
        Throws: {{text}}
        -
        Complexity: {{text}}
        -
        Rationale: {{text}}
        +
        Returns: The result of the Python call, converted to the + C++ type R.
        + +
    +
    Rationale: + +

    Example(s)

    diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp index 50710519..9b8f071b 100644 --- a/test/multi_arg_constructor.cpp +++ b/test/multi_arg_constructor.cpp @@ -3,7 +3,9 @@ struct A { - A(const double, const double, const double, const double, const double, const double, const double) {} + A(const double, const double, const double, const double, const double + , const double, const double + ) {} }; BOOST_PYTHON_MODULE_INIT(multi_arg_constructor_ext) @@ -14,7 +16,9 @@ BOOST_PYTHON_MODULE_INIT(multi_arg_constructor_ext) module("multi_arg_constructor_ext") .add(class_ >("A") - .def_init(args()) + .def_init(args()) ) ; diff --git a/test/multi_arg_constructor.py b/test/multi_arg_constructor.py index d6d1ef37..fb062e8a 100644 --- a/test/multi_arg_constructor.py +++ b/test/multi_arg_constructor.py @@ -1,6 +1,6 @@ ''' >>> from multi_arg_constructor_ext import * ->>> a = A(1.0, 2, 3, 4, 5, 6, 7.0) +>>> a = A(1.0, 2, 3, 4, 5, 6, 7.0, 8.1, 9.3) ''' def run(args = None): import sys From cca3acc035c6d597cc1dc651e1498bba327a0e1c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 18 Apr 2002 04:11:49 +0000 Subject: [PATCH 0411/1042] Test for 9 arguments [SVN r13521] --- test/multi_arg_constructor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp index 9b8f071b..c4c91aea 100644 --- a/test/multi_arg_constructor.cpp +++ b/test/multi_arg_constructor.cpp @@ -4,6 +4,7 @@ struct A { A(const double, const double, const double, const double, const double + , const double, const double , const double, const double ) {} }; @@ -17,6 +18,7 @@ BOOST_PYTHON_MODULE_INIT(multi_arg_constructor_ext) .add(class_ >("A") .def_init(args()) ) From 94cfe30b77f3763d6d6ea785187e45b212ee7e91 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 26 Apr 2002 14:15:33 +0000 Subject: [PATCH 0412/1042] Workarounds for VC7.01 [SVN r13565] --- include/boost/python/detail/indirect_traits.hpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index a3e67dd3..bcfdd79a 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -25,6 +25,14 @@ struct is_reference_to_const BOOST_STATIC_CONSTANT(bool, value = true); }; +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13012108 // vc7.01 alpha workaround +template +struct is_reference_to_const +{ + static const bool value = true; +}; +# endif + # if 0 // Corresponding code doesn't work on MSVC yet template struct is_reference_to_function @@ -112,6 +120,15 @@ struct is_reference_to_volatile BOOST_STATIC_CONSTANT(bool, value = true); }; +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13012108 // vc7.01 alpha workaround +template +struct is_reference_to_volatile +{ + static const bool value = true; +}; +# endif + + template struct is_reference_to_pointer { From 6e86a498ad160bf84c1e80535d017f21c91c8909 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 1 May 2002 02:49:45 +0000 Subject: [PATCH 0413/1042] vc7.01 alpha workaround [SVN r13599] --- include/boost/python/converter/implicit.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/boost/python/converter/implicit.hpp b/include/boost/python/converter/implicit.hpp index 23c2ece5..6a22a3d6 100644 --- a/include/boost/python/converter/implicit.hpp +++ b/include/boost/python/converter/implicit.hpp @@ -37,7 +37,12 @@ struct implicit registration->construct(obj, &intermediate_data.stage1); void* storage = ((rvalue_base_data*)data)->storage.bytes; +# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13012108 // vc7.01 alpha workaround new (storage) Target(*static_cast(intermediate_data.stage1.convertible)); +# else + Target x(*static_cast(intermediate_data.stage1.convertible)); + new (storage) Target(x); +# endif // record successful construction data->convertible = storage; From 93ca98d3a84d84c527d9c0c5968d4058ba4ff119 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 1 May 2002 02:50:19 +0000 Subject: [PATCH 0414/1042] Some tweaks for gcc-stlport [SVN r13600] --- build/Jamfile | 3 ++- include/boost/python/detail/wrap_python.hpp | 11 ++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index c8cf3d4e..6c38b082 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -93,7 +93,8 @@ lib boost_python_static : ../src/$(CPP_SOURCES).cpp : $(BOOST_PYTHON_INCLUDES) true BOOST_PYTHON_STATIC_LIB=1 - $(PYTHON_PROPERTIES) ; + [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] + ; dll boost_python # $(SUFDLL[1]) diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index 0e417ad3..9c9bc2e4 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -36,20 +36,25 @@ // #if defined(_WIN32) || defined(__CYGWIN__) # if defined(__GNUC__) && defined(__CYGWIN__) + +# define SIZEOF_LONG 4 + # if PY_MAJOR_VERSION < 2 || PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 2 + typedef int pid_t; + # define WORD_BIT 32 # define hypot _hypot # include + # if PY_MAJOR_VERSION < 2 # define HAVE_CLOCK # define HAVE_STRFTIME # define HAVE_STRERROR # endif + # define NT_THREADS -# if !defined(__CYGWIN__) && (__GNUC__ < 3 || __GNUC__ == 3 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ < 3) -# define WITH_THREAD -# endif + # ifndef NETSCAPE_PI # define USE_SOCKET # endif From 365ce297612dd483e0d207a2d6b417ee7bc985a6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 1 May 2002 12:30:20 +0000 Subject: [PATCH 0415/1042] Removed outdated msvc projects [SVN r13603] --- build/bpl_static.dsp | 241 ------------------------------------------- build/build.dsw | 108 ------------------- build/build.opt | Bin 116224 -> 0 bytes 3 files changed, 349 deletions(-) delete mode 100644 build/bpl_static.dsp delete mode 100644 build/build.dsw delete mode 100644 build/build.opt diff --git a/build/bpl_static.dsp b/build/bpl_static.dsp deleted file mode 100644 index ca70236d..00000000 --- a/build/bpl_static.dsp +++ /dev/null @@ -1,241 +0,0 @@ -# Microsoft Developer Studio Project File - Name="bpl_static" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=bpl_static - Win32 DebugPython -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "bpl_static.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "bpl_static.mak" CFG="bpl_static - Win32 DebugPython" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "bpl_static - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "bpl_static - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE "bpl_static - Win32 DebugPython" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "bpl_static - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MD /W4 /WX /GR /GX /O2 /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ELSEIF "$(CFG)" == "bpl_static - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W4 /WX /Gm- /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ELSEIF "$(CFG)" == "bpl_static - Win32 DebugPython" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "bpl_static___Win32_DebugPython" -# PROP BASE Intermediate_Dir "bpl_static___Win32_DebugPython" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "DebugPython" -# PROP Intermediate_Dir "DebugPython" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W4 /WX /Gm- /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /EHs /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ENDIF - -# Begin Target - -# Name "bpl_static - Win32 Release" -# Name "bpl_static - Win32 Debug" -# Name "bpl_static - Win32 DebugPython" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\src\classes.cpp -# ADD CPP /W3 -# End Source File -# Begin Source File - -SOURCE=..\src\conversions.cpp -# ADD CPP /W3 -# End Source File -# Begin Source File - -SOURCE=..\src\extension_class.cpp -# ADD CPP /W3 -# End Source File -# Begin Source File - -SOURCE=..\src\functions.cpp -# ADD CPP /W3 -# End Source File -# Begin Source File - -SOURCE=..\src\init_function.cpp -# ADD CPP /W3 -# End Source File -# Begin Source File - -SOURCE=..\src\module_builder.cpp -# ADD CPP /W3 -# End Source File -# Begin Source File - -SOURCE=..\src\objects.cpp -# ADD CPP /W3 -# End Source File -# Begin Source File - -SOURCE=..\src\types.cpp -# ADD CPP /W3 -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\..\boost\python\detail\base_object.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\callback.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\caller.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\detail\cast.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\class_builder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\classes.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\detail\config.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\conversions.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\errors.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\detail\extension_class.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\detail\functions.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\detail\init_function.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\module_builder.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\detail\none.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\objects.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\operators.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\reference.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\detail\signatures.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\detail\singleton.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\detail\types.hpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\boost\python\detail\wrap_python.hpp -# End Source File -# End Group -# End Target -# End Project diff --git a/build/build.dsw b/build/build.dsw deleted file mode 100644 index 8de38493..00000000 --- a/build/build.dsw +++ /dev/null @@ -1,108 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "bpl_static"=.\bpl_static.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "example1"=.\example1\example1.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name bpl_static - End Project Dependency -}}} - -############################################################################### - -Project: "getting_started1"=.\getting_started1\getting_started1.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name bpl_static - End Project Dependency -}}} - -############################################################################### - -Project: "getting_started2"=.\getting_started2\getting_started2.dsp - Package Owner=<4> - -Package=<5> -{{{ - begin source code control - getting_started2 - .\getting_started2 - end source code control -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name bpl_static - End Project Dependency -}}} - -############################################################################### - -Project: "rwgk1"=.\rwgk1\rwgk1.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name bpl_static - End Project Dependency -}}} - -############################################################################### - -Project: "test"=.\test\test.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name bpl_static - End Project Dependency -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/build/build.opt b/build/build.opt deleted file mode 100644 index 89eb84a706504d37bff9685be4808fda8baf9b81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116224 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 Date: Wed, 1 May 2002 17:28:37 +0000 Subject: [PATCH 0416/1042] Removed teaser index; updated compiler results for MSVC6/STLPort. [SVN r13609] --- doc/index.html | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/doc/index.html b/doc/index.html index cdadb8e1..b70019ed 100644 --- a/doc/index.html +++ b/doc/index.html @@ -16,15 +16,7 @@ intrusive on your C++ design. In most cases, you should not have to alter your C++ classes in any way in order to use them with Boost.Python. The system should simply ``reflect'' your C++ classes and functions into - Python. The major features of Boost.Python include support for: - -among others. - + Python.

    Supported Platforms

    Boost.Python is known to have been tested @@ -36,6 +28,13 @@ the following compilers: href="http://msdn.microsoft.com/vstudio/downloads/updates/sp/vs6/sp5/default.asp">MSVC++6sp5. All tests pass. +

  • MSVC++6sp5 + with STLPort-4.5.3. A compiler bug interferes with + libs/python/example/simple_vector.cpp. All + other tests pass. +

  • MSVC++7 (Visual Studio .NET). All tests pass. From fa64ef6f008752e864f86b08b19f088948bbe946 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 3 May 2002 03:35:18 +0000 Subject: [PATCH 0417/1042] Removed flotsam [SVN r13629] --- test/newtest.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/test/newtest.py b/test/newtest.py index b89764d1..59b25e74 100644 --- a/test/newtest.py +++ b/test/newtest.py @@ -152,20 +152,12 @@ are a complicated constructor and member function, respectively. def run(args = None): - ### Strange bug somewhere: with Metrowerks: it will crash in - ### garbage-collection code unless traceback and sre have been - ### loaded before m1. - -# import traceback -# import sre -# import m2 -# import m1 import sys import doctest if args is not None: sys.argv = args - # import sys + return doctest.testmod(sys.modules.get(__name__)) if __name__ == '__main__': From 2151bf8f9ad89f7a2fad36002ff03de53ac9a6ec Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 3 May 2002 19:05:03 +0000 Subject: [PATCH 0418/1042] obsolete [SVN r13650] --- .../python/detail/python_library_include.hpp | 183 ------------------ 1 file changed, 183 deletions(-) delete mode 100644 include/boost/python/detail/python_library_include.hpp diff --git a/include/boost/python/detail/python_library_include.hpp b/include/boost/python/detail/python_library_include.hpp deleted file mode 100644 index d2b78c6e..00000000 --- a/include/boost/python/detail/python_library_include.hpp +++ /dev/null @@ -1,183 +0,0 @@ -#error obsolete -/* - * - * Copyright (c) 1998-2000 - * Dr John Maddock - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Dr John Maddock makes no representations - * about the suitability of this software for any purpose. - * It is provided "as is" without express or implied warranty. - * - */ - - /* - * LOCATION: see http://www.boost.org for most recent version. - * FILE regex_libary_include.hpp - * VERSION see - * DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers. - * Note this is an internal header file included - * by regex.hpp, do not include on its own. - */ - - -#ifndef BOOST_REGEX_LIBRARY_INCLUDE_HPP -#define BOOST_REGEX_LIBRARY_INCLUDE_HPP -#ifndef BOOST_REGEX_NO_LIB - -#if defined(BOOST_MSVC) && !defined(BOOST_REGEX_BUILD_DLL) -#ifdef __SGI_STL_PORT - #ifdef _DLL - // All these are multithreaded: - #if defined(_DEBUG) && defined(__STL_DEBUG) - #pragma comment(lib, "vc6-stlport-re300ddl.lib") - #elif defined(_DEBUG) - #pragma comment(lib, "vc6-stlport-re300dl.lib") - #elif defined(BOOST_REGEX_STATIC_LINK) - // static regex lib, dll runtime - #pragma comment(lib, "vc6-stlport-re300ls.lib") - #else // DEBUG - #pragma comment(lib, "vc6-stlport-re300l.lib") - #endif // _DEBUG - #else // _DLL - #ifdef _MT - #if defined(_DEBUG) && defined(__STL_DEBUG) - #pragma comment(lib, "vc6-stlport-re300ddm.lib") - #elif defined(_DEBUG) - #pragma comment(lib, "vc6-stlport-re300dm.lib") - #else //_DEBUG - #pragma comment(lib, "vc6-stlport-re300m.lib") - #endif //_DEBUG - #else //_MT - // STLPort does not support single threaded builds: - #error STLPort does not support single threaded builds - #endif //_MT - #endif //_DLL -#elif _MSC_VER < 1300 - #ifdef _DLL - // All these are multithreaded: - #ifdef _DEBUG - #pragma comment(lib, "vc6-re300dl.lib") - #elif defined(BOOST_REGEX_STATIC_LINK) - // static regex lib, dll runtime - #pragma comment(lib, "vc6-re300ls.lib") - #else // DEBUG - #pragma comment(lib, "vc6-re300l.lib") - #endif // _DEBUG - #else // _DLL - #ifdef _MT - #ifdef _DEBUG - #pragma comment(lib, "vc6-re300dm.lib") - #else //_DEBUG - #pragma comment(lib, "vc6-re300m.lib") - #endif //_DEBUG - #else //_MT - #ifdef _DEBUG - #pragma comment(lib, "vc6-re300d.lib") - #else //_DEBUG - #pragma comment(lib, "vc6-re300.lib") - #endif //_DEBUG - #endif //_MT - #endif //_DLL -#else - #ifdef _DLL - // All these are multithreaded: - #ifdef _DEBUG - #pragma comment(lib, "vc7-re300dl.lib") - #elif defined(BOOST_REGEX_STATIC_LINK) - // static regex lib, dll runtime - #pragma comment(lib, "vc7-re300ls.lib") - #else // DEBUG - #pragma comment(lib, "vc7-re300l.lib") - #endif // _DEBUG - #else // _DLL - #ifdef _MT - #ifdef _DEBUG - #pragma comment(lib, "vc7-re300dm.lib") - #else //_DEBUG - #pragma comment(lib, "vc7-re300m.lib") - #endif //_DEBUG - #else //_MT - #ifdef _DEBUG - #pragma comment(lib, "vc7-re300d.lib") - #else //_DEBUG - #pragma comment(lib, "vc7-re300.lib") - #endif //_DEBUG - #endif //_MT - #endif //_DLL -#endif // __SGI_STL_PORT -#endif //BOOST_MSVC - - -#if defined(__BORLANDC__) && !defined(BOOST_REGEX_BUILD_DLL) - - #if __BORLANDC__ < 0x550 - - #ifdef BOOST_REGEX_USE_VCL - - #ifdef _RTLDLL - #pragma comment(lib, "bcb4re300lv.lib") - #else - #pragma comment(lib, "bcb4re300v.lib") - #endif - - #else // VCL - - #ifdef _RTLDLL - #ifdef __MT__ - #pragma comment(lib, "bcb4re300lm.lib") - #else // __MT__ - #pragma comment(lib, "bcb4re300l.lib") - #endif // __MT__ - #else //_RTLDLL - #ifdef __MT__ - #pragma comment(lib, "bcb4re300m.lib") - #else // __MT__ - #pragma comment(lib, "bcb4re300.lib") - #endif // __MT__ - #endif // _RTLDLL - - #endif // VCL - - #else // C++ Builder 5: - - #ifdef BOOST_REGEX_USE_VCL - - #ifdef _RTLDLL - #pragma comment(lib, "bcb5re300lv.lib") - #else - #pragma comment(lib, "bcb5re300v.lib") - #endif - - #else // VCL - - #ifdef _RTLDLL - #ifdef __MT__ - #pragma comment(lib, "bcb5re300lm.lib") - #else // __MT__ - #pragma comment(lib, "bcb5re300l.lib") - #endif // __MT__ - #else //_RTLDLL - #ifdef __MT__ - #pragma comment(lib, "bcb5re300m.lib") - #else // __MT__ - #pragma comment(lib, "bcb5re300.lib") - #endif // __MT__ - #endif // _RTLDLL - - #endif // VCL - - #endif - -#endif //__BORLANDC__ - -#endif //BOOST_REGEX_NO_LIB - -#endif // BOOST_REGEX_LIBRARY_INCLUDE_HPP - - - - From c9b4fb418ad3e384de8e314f6eac2dc679ad55d8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 3 May 2002 21:20:12 +0000 Subject: [PATCH 0419/1042] Removed flotsam [SVN r13653] --- include/boost/python/object/select_holder.hpp | 2 +- test/if_else.cpp | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index 72446358..95330d10 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -9,11 +9,11 @@ # include # include # include -# include # include # include # include # include +# include namespace boost { namespace python { namespace objects { diff --git a/test/if_else.cpp b/test/if_else.cpp index d8bd34ca..e2b50f28 100644 --- a/test/if_else.cpp +++ b/test/if_else.cpp @@ -15,7 +15,6 @@ template struct choose { -#if 1 typedef typename boost::python::detail::if_< (sizeof(c1) == size) >::template then< @@ -33,21 +32,6 @@ struct choose >::template then< c4 >::template else_::type type; -#else - typedef typename boost::python::detail::if_< - (sizeof(c1) == size) - , c1 - >::template elif< - (sizeof(c2) == size) - , c2 - >::template elif< - (sizeof(c3) == size) - , c3 - >::template elif< - (sizeof(c4) == size) - , c4 - >::template else_::type type; -#endif }; int main() From 93a10f33d50b12d67796b333fde7f7aa260b3262 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 3 May 2002 22:16:42 +0000 Subject: [PATCH 0420/1042] initial checkin [SVN r13655] --- doc/v2/Apr2002.html | 162 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 doc/v2/Apr2002.html diff --git a/doc/v2/Apr2002.html b/doc/v2/Apr2002.html new file mode 100644 index 00000000..cd71d66f --- /dev/null +++ b/doc/v2/Apr2002.html @@ -0,0 +1,162 @@ + + + + +Boost.Python - April 2002 Progress Report + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    April 2002 Progress Report

    +
    +
    +

    Contents

    +
    +
    Accomplishments
    +
    +
    Arbitrary Arity Support
    +
    New Callback Interface
    +
    Call Policies for Construtors
    +
    Real Users, Real Bugs
    +
    New Insights
    +
    Boost.Python V1 Maintenance
    +
    + +
    What's Missing
    + +
    + +

    Accomplishments

    + +April was a short month as far as Boost.Python was concerned, since +the spring ISO C++ Committee Meeting (and associated vacation) +occupied me for the 2nd half of the month. However, a suprising amount +of work got done... + +

    Arbitrary Arity Support

    + +I began using the Boost.Preprocessor +metaprogramming library to generate support for functions and member +functions of arbitrary arity, which was, to say the least, quite an +adventure. The feedback cycle resulting from my foray into +Boost.Preprocessor resulted in several improvements to the library, +most notably in its documentation. + +

    + +Boost.Python now supports calls of up to 17 arguments on most +compilers. Because most EDG-based compilers have dismal preprocessor +performance, I had to "manually" expand the metaprograms for +arities from zero to fifteen arguments, and EDG-based compilers with +__EDG_VERSION__ <= 245 only support 15 +arguments by default. If some crazy program finds a need for more than +the default arity support, users can increase the base support by +setting the BOOST_PYTHON_MAX_ARITY preprocessor symbol. + +

    New Callback Interface

    + +I mentioned in last month's report that I +wasn't pleased with the interface for the interface for calling into +Python, so now it has been redesigned. The new interface is outlined +in this +message (though the GCC 2.95.3 bugs have been fixed). + +

    Call Policies for Constructors

    + +On April 2nd, I announced +support for the use of call policies with constructors. + +

    Real Users, Real Bugs

    + +At least two people outside of Kull began actually using Boost.Python +v2 in earnest this month. Peter Bienstman and Pearu Pearson both +provided valuable real-world bug reports that helped me to improve the +library's robustness. + +

    New Insights

    + +Answering some of Pearu's questions about explicitly converting +objects between Python and C++ actually led me to a new understanding +of the role of the current conversion facilities. In Boost.Python v1, +all conversions between Python and C++ were handled by a single family +of functions, called to_python() and +from_python(). Since the primary role of Boost.Python is +to wrap C++ functions in Python, I used these names for the first kind +of converters I needed: those that extract C++ objects to be used as +function arguments and which C++ function return values to +Python. The better-considered approach in Boost.Python v2 uses a +completely different mechanism for conversions used when calling +Python from C++, as in wrapped virtual function implementations. I +usually think of this as a "callback", as in "calling +back into Python", and I named the converters used in callbacks +accordingly: to_python_callback and +from_python_callback. However, as it turns out, the +behavior of the "callback" converters is the appropriate one +for users who want to explicitly extract a C++ value from a Python +object, or create a Python object from a C++ value. The upshot is that +it probably makes sense to change the name of the existing to_python and +from_python so those names are available for the +user-friendly explicit converters. + +

    +Another +of Pearu's questions pushes momentum further in the direction of a +more-sophisticated overloading mechanism than the current +simple-minded "first match" approach, as I suggested last month. + +

    Boost.Python V1 Mainenance

    + +As much as I'm looking forward to retiring Boost.Python v1, a +significant amount of effort has been being spent dealing with support +problems; the saying that code rots when left alone is true, and +Boost.Python is no exception. Eventually it became obvious to me that +we were going to have to invest some effort in keeping V1 healthy +while working on V2. Ralf and I have expanded support for various +compilers and stabilized the V1 codebase considerably. We discarded +the obsolete Visual Studio projects which were causing so much +confusion. Still to do before the next Boost release: +
      +
    1. Update the build/test documentation with detailed instructions for +configuring various toolsets. +
    2. Provide some links to Boost.Python v2 to let people know what's +coming. +
    + + +

    What's Missing

    + +Last month I announced that I would implement the following which are +not yet complete: +
      +
    1. Document all implemented features +
    2. Implement conversions for char types. This is +implemented but not tested, so we have to assume it doesn't work. +
    + +These are my first priority for this month (especially the +documentation). + +

    Revised + + 3 May, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + From 525979afaa7afee02dfddab81177c1dd538df4a6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 7 May 2002 23:23:32 +0000 Subject: [PATCH 0421/1042] testing for char conversions [SVN r13735] --- test/comprehensive.py | 4 ++++ test/m1.cpp | 7 +------ test/test_builtin_converters.cpp | 7 +++++++ test/test_builtin_converters.py | 22 ++++++++++++++++++++++ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/test/comprehensive.py b/test/comprehensive.py index 7d0bec79..4aa951f3 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -1273,6 +1273,10 @@ import sys def run(args = None): if args is not None: sys.argv = args + + if hasattr(sys,'setdlopenflags'): + sys.setdlopenflags( 6 ) # dl.RTLD_NOW | dl.RTLD_GLOBAL) + import doctest, comprehensive return doctest.testmod(comprehensive) diff --git a/test/m1.cpp b/test/m1.cpp index 4aa81f36..42412c5d 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -10,9 +10,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -98,9 +95,7 @@ PyObject* new_simple() // // Declare some wrappers/unwrappers to test the low-level conversion -// mechanism. See boost/python/converter/source.hpp,target.hpp for a -// description of how the type parameters to wrapper<> and unwrapper<> -// are selected. +// mechanism. // using boost::python::to_python_converter; diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp index 939f9dc4..2066e0f8 100644 --- a/test/test_builtin_converters.cpp +++ b/test/test_builtin_converters.cpp @@ -25,11 +25,14 @@ struct by_const_reference } }; +char const* rewrap_value_mutable_cstring(char* x) { return x; } + BOOST_PYTHON_MODULE_INIT(builtin_converters) { boost::python::module("builtin_converters") .def("rewrap_value_bool", by_value::rewrap) + .def("rewrap_value_char", by_value::rewrap) .def("rewrap_value_signed_char", by_value::rewrap) .def("rewrap_value_unsigned_char", by_value::rewrap) .def("rewrap_value_int", by_value::rewrap) @@ -47,8 +50,12 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters) .def("rewrap_value_string", by_value::rewrap) .def("rewrap_value_cstring", by_value::rewrap) + // Expose this to illustrate our failings ;-). See test_builtin_converters.py + .def("rewrap_value_mutable_cstring", rewrap_value_mutable_cstring) + .def("rewrap_const_reference_bool", by_const_reference::rewrap) + .def("rewrap_const_reference_char", by_const_reference::rewrap) .def("rewrap_const_reference_signed_char", by_const_reference::rewrap) .def("rewrap_const_reference_unsigned_char", by_const_reference::rewrap) .def("rewrap_const_reference_int", by_const_reference::rewrap) diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index 3958c15a..8f7b5e58 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -6,6 +6,14 @@ 0 >>> rewrap_value_bool(33) 1 +>>> rewrap_value_char('x') +'x' + + Note that there's currently silent truncation of strings passed to + char arguments. + +>>> rewrap_value_char('xy') +'x' >>> rewrap_value_signed_char(42) 42 >>> rewrap_value_unsigned_char(42) @@ -42,12 +50,26 @@ >>> rewrap_value_string('yo, wassup?') 'yo, wassup?' + Note that we can currently get a mutable pointer into an immutable + Python string: + +>>> rewrap_value_mutable_cstring('hello, world') +'hello, world' + >>> rewrap_const_reference_bool(None) 0 >>> rewrap_const_reference_bool(0) 0 >>> rewrap_const_reference_bool('yes') 1 +>>> rewrap_const_reference_char('x') +'x' + + Note that there's currently silent truncation of strings passed to + char arguments. + +>>> rewrap_const_reference_char('xy') +'x' >>> rewrap_const_reference_signed_char(42) 42 >>> rewrap_const_reference_unsigned_char(42) From 4fe681506201b4420fb41b745d047618540fbd3d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 7 May 2002 23:25:33 +0000 Subject: [PATCH 0422/1042] roll back mistaken checkin [SVN r13736] --- test/comprehensive.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/comprehensive.py b/test/comprehensive.py index 4aa951f3..f64ed661 100644 --- a/test/comprehensive.py +++ b/test/comprehensive.py @@ -1273,10 +1273,7 @@ import sys def run(args = None): if args is not None: sys.argv = args - - if hasattr(sys,'setdlopenflags'): - sys.setdlopenflags( 6 ) # dl.RTLD_NOW | dl.RTLD_GLOBAL) - + import doctest, comprehensive return doctest.testmod(comprehensive) From 152a3f2e5fa997d4168163db3386d8143067f8e6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 8 May 2002 03:23:58 +0000 Subject: [PATCH 0423/1042] initial commit [SVN r13737] --- doc/v2/ptr.html | 261 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 doc/v2/ptr.html diff --git a/doc/v2/ptr.html b/doc/v2/ptr.html new file mode 100644 index 00000000..d404ba1a --- /dev/null +++ b/doc/v2/ptr.html @@ -0,0 +1,261 @@ + + + + + + Boost.Python - <boost/python/ptr.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/ptr.hpp>

    +
    +
    + +

    Contents

    + +
    +
    Introduction + +
    Functions +
    +
    +
    ptr +
    + +
    Classes +
    +
    +
    Class template pointer_wrapper + +
    +
    +
    Class template pointer_wrapper synopsis + +
    Class + pointer_wrapper types + +
    Class + pointer_wrapper constructors and destructor + +
    Class + pointer_wrapper observer functions + +
    +
    + +
    Metafunctions +
    +
    +
    Class template is_pointer_wrapper + +
    +
    +
    Class template is_pointer_wrapper synopsis +
    + + +
    Class template unwrap_pointer + +
    +
    +
    Class template unwrap_pointer synopsis +
    + +
    + + +
    Example(s) +
    +
    + +

    Introduction

    + +

    <boost/python/ptr.hpp> defines the + ptr() function template, which allows users to + specify how to convert C++ pointer values to python in the context + of implementing overridable virtual functions, invoking Python + callable objects, or explicitly converting C++ objects to + Python. Normally, when passing pointers to Python callbacks, the + pointee is copied to ensure that the Python object + never holds a dangling reference. To specify that the new Python + object should merely contain a copy of a pointer p, + the user can pass ptr(p) instead of passing + p directly. This interface is meant to mirror the use + of boost::ref(), + which can be similarly used to prevent copying of referents. + +

    ptr(p) returns an instance of pointer_wrapper<>, which + can be detected using the is_pointer_wrapper<> + metafunction; unwrap_pointer<> is a + metafunction which extracts the original pointer type from a + pointer_wrapper<>. These classes can be thought + of as implementation details. + +

    Functions

    +
    +
    +template <class T>
    +pointer_wrapper<T> ptr(T x);
    +
    + +
    +
    Requires: T is a pointer type. + +
    Returns: pointer_wrapper<T>(x) + +
    Throws: nothing. +
    + +

    Classes

    + +

    Class template pointer_wrapper

    + +

    A "type envelope" which is returned by ptr(), used to indicate reference semantics + for pointers passed to Python callbacks. + +

    Class + pointer_wrapper synopsis

    +
    +namespace boost
    +{
    +    template<class Ptr> class pointer_wrapper
    +    { 
    +     public:
    +        typedef Ptr type;
    +
    +        explicit pointer_wrapper(Ptr x);
    +        operator Ptr() const;
    +        Ptr get() const;
    +    };
    +};
    +
    + +

    Class template pointer_wrapper types

    +
    +typedef Ptr type;
    +
    +The type of the pointer being wrapped. + +

    Class template pointer_wrapper constructors and + destructor

    +
    +explicit pointer_wrapper(Ptr x);
    +
    + +
    +
    Requires: Ptr is a pointer type. + +
    Effects: Stores x in a the pointer_wrapper<>. +
    Throws: nothing. +
    + +

    Class template pointer_wrapper observer + functions

    +
    +operator Ptr() const;
    +Ptr get() const;
    +
    + +
    +
    Returns: a copy of the stored pointer. +
    Rationale: pointer_wrapper is intended + to be a stand-in for the actual pointer type, but sometimes it's + better to have an explicit way to retrieve the pointer. +
    + +

    Class template is_pointer_wrapper

    + +

    A unary metafunction whose value is true iff its + argument is a pointer_wrapper<>. + +

    Class template is_pointer_wrapper synopsis

    +
    +namespace boost
    +{
    +    template<class T> class is_pointer_wrapper
    +    { 
    +        static unspecified value = ...;
    +    };
    +};
    +
    + + +
    +
    Returns: true iff T is a + specialization of +pointer_wrapper<>. +
    value is an integral constant convertible to bool of +unspecified type + +
    + +

    Class template unwrap_pointer

    + +A unary metafunction which extracts the wrapped pointer type from a +specialization of pointer_wrapper<>. + +

    Class template unwrap_pointer synopsis

    +
    +namespace boost
    +{
    +    template<class T> class unwrap_pointer
    +    { 
    +        typedef unspecified type;
    +    };
    +};
    +
    + +
    +
    Returns: T::type if T is a + specialization of +pointer_wrapper<>, T otherwise +
    + + +

    Example(s)

    + +This example illustrates the use of ptr() to prevent an +object from being copied: +
    +#include <boost/python/call.hpp>
    +#include <boost/python/ptr.hpp>
    +
    +class expensive_to_copy
    +{
    +   ...
    +};
    +
    +void pass_as_arg(expensive_to_copy* x, PyObject* f)
    +{
    +   // call the Python function f, passing a Python object built around
    +   // which refers to *x by-pointer.
    +   //
    +   // *** Note: ensuring that *x outlives the argument to f() is    ***
    +   // *** up to the user! Failure to do so could result in a crash! ***
    +
    +   boost::python::call<void>(f, ptr(x));
    +}
    +...
    +
    + +

    Revised + + 07 May, 2002 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From bd32dce19afc8adad415579dfd0ee10aa92d4cf1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 8 May 2002 03:59:53 +0000 Subject: [PATCH 0424/1042] *** empty log message *** [SVN r13738] --- doc/v2/ptr.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/v2/ptr.html b/doc/v2/ptr.html index d404ba1a..3b68451b 100644 --- a/doc/v2/ptr.html +++ b/doc/v2/ptr.html @@ -128,7 +128,7 @@ pointer_wrapper<T> ptr(T x);

    Class pointer_wrapper synopsis

    -namespace boost
    +namespace boost { namespace python
     {
         template<class Ptr> class pointer_wrapper
         { 
    @@ -139,7 +139,7 @@ namespace boost
             operator Ptr() const;
             Ptr get() const;
         };
    -};
    +}}
     

    Class template pointer_wrapper types

    @@ -182,13 +182,13 @@ Ptr get() const;

    Class template is_pointer_wrapper synopsis

    -namespace boost
    +namespace boost { namespace python
     {
         template<class T> class is_pointer_wrapper
         { 
             static unspecified value = ...;
         };
    -};
    +}}
     
    @@ -208,13 +208,13 @@ specialization of pointer_wrapper<>.

    Class template unwrap_pointer synopsis

    -namespace boost
    +namespace boost { namespace python
     {
         template<class T> class unwrap_pointer
         { 
             typedef unspecified type;
         };
    -};
    +}}
     
    From e26556c6317d723f1380c998bca994ec83cca0fa Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 8 May 2002 04:22:34 +0000 Subject: [PATCH 0425/1042] initial checkin [SVN r13739] --- doc/v2/implicit.html | 149 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 doc/v2/implicit.html diff --git a/doc/v2/implicit.html b/doc/v2/implicit.html new file mode 100644 index 00000000..99ce9ad8 --- /dev/null +++ b/doc/v2/implicit.html @@ -0,0 +1,149 @@ + + + + + + Boost.Python - <boost/python/implicit.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/implicit.hpp>

    +
    +
    + +

    Contents

    + +
    +
    Introduction + + +
    Functions + +
    +
    +
    Function Template implicitly_convertible + +
    + +
    Example +
    +
    + +

    Introduction

    + + implicitly_convertible allows Boost.Python to + implicitly take advantage of a C++ implicit or explicit conversion + when matching Python objects to C++ argument types. + +

    Functions

    + +

    Function template implicitly_convertible

    +
    +template <class Source, class Target>
    +void implicitly_convertible();
    +
    + + + + + + + +
    + implicitly_convertible template parameters
    +
    Parameter + Description + +
    Source + The source type of the implicit conversion + +
    Target + The target type of the implicit conversion +
    + +
    +
    Requires: The expression Target(s), + where s is of type Source, is valid. + +
    Effects: registers an rvalue from_python + converter to Target which can succeed for any + PyObject* p iff there exists any registered + converter which can produce Source rvalues + +
    Rationale: C++ users expect to be able to take + advantage of the same sort of interoperability in Python as they + do in C++. +
    + + +

    Example

    + + +

    C++ module definition

    + +
    +#include <boost/python/class.hpp>
    +#include <boost/python/implicit.hpp>
    +#include <boost/python/module.hpp>
    +
    +using namespace boost::python;
    +
    +struct X
    +{
    +    X(int x) : v(x) {}
    +    operator int() { return v; }
    +    int v;
    +};
    +
    +int x_value(X const& x)
    +{
    +    return x.v;
    +}
    +
    +X make_x(int n) { return X(n); }
    +
    +BOOST_PYTHON_MODULE_INIT(implicit_ext)
    +{
    +    module("implicit_ext")
    +        .def("x_value", x_value)
    +        .def("make_x", make_x)
    +        .add(
    +            class_<X>("X")
    +            .def_init(args<int>())
    +            )
    +        ;
    +    implicitly_convertible<X,int>();
    +    implicitly_convertible<int,X>();
    +}
    +
    + +

    Python code

    + +
    +>>> from implicit_ext import *
    +>>> x_value(X(42))
    +42
    +>>> x_value(42)
    +42
    +>>> x = make_x(X(42))
    +>>> x_value(x)
    +42
    +
    + +

    Revised + + 08 May, 2002 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From c9097566e22bfb9a064c5e7ec9ab4176d7ec19e5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 8 May 2002 04:23:03 +0000 Subject: [PATCH 0426/1042] *** empty log message *** [SVN r13740] --- doc/v2/reference.html | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 78505ff6..86362af0 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -367,7 +367,7 @@

    -
    Functions +
    Functions
    @@ -376,16 +376,29 @@
    -
    ptr.hpp +
    ptr.hpp
    -
    Classes - +
    Functions
    -
    ptr +
    ptr
    + +
    Classes +
    +
    +
    pointer_wrapper +
    + +
    MetaFunctions +
    +
    +
    is_pointer_wrapper +
    unwrap_pointer +
    +
    to_python_converter.hpp From 7cd32fc4ebbf151fa314d0565e8e7747c9defb47 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 8 May 2002 19:07:22 +0000 Subject: [PATCH 0427/1042] initial commit [SVN r13755] --- doc/v2/has_back_reference.html | 217 +++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 doc/v2/has_back_reference.html diff --git a/doc/v2/has_back_reference.html b/doc/v2/has_back_reference.html new file mode 100644 index 00000000..a31cf448 --- /dev/null +++ b/doc/v2/has_back_reference.html @@ -0,0 +1,217 @@ + + + + + + + Boost.Python - + <boost/python/has_back_reference.hpp> + + + + +
    +

    C++ Boost

    + +
    +

    Boost.Python

    + +

    Header + <boost/python/has_back_reference.hpp>

    +
    +
    + +

    Contents

    + +
    +
    Introduction + +
    Classes + +
    +
    +
    Class template + has_back_reference + +
    +
    +
    Class template + has_back_reference synopsis +
    + +
    Example(s) +
    +
    +
    + +

    Introduction

    + +

    <boost/python/has_back_reference.hpp> + defines the traits class template + has_back_reference<>, which can be + specialized by the user to indicate that a wrapped class + instance holds a PyObject* corresponding to a + Python object. + +

    Classes

    + +

    Class template + has_back_reference

    + +

    A unary metafunction whose value is true iff + its argument is a pointer_wrapper<>. + +

    Class + template has_back_reference synopsis

    +
    +namespace boost { namespace python
    +{
    +    template<class WrappedClass> class has_back_reference
    +    { 
    +        static unspecified value = false;
    +    };
    +}}
    +
    + +

    A "traits + class" which is inspected by Boost.Python to + determine how wrapped classes can be constructed. + +

    + +
    value is an integral constant convertible + to bool of unspecified type. + +
    Specializations may substitute a value convertible to + true for value iff for each invocation of + class_<WrappedClass>::def_init(args<type-sequence...>()), + there exists a corresponding constructor + WrappedClass::WrappedClass(PyObject*, type-sequence...). If + such a specialization exists, the WrappedClass + constructors will be called with a "back reference" pointer + to the corresponding Python object whenever they are invoked from + Python. + +
    + +

    Example

    + +

    C++ module definition

    + +
    +#include <boost/python/class.hpp>
    +#include <boost/python/module.hpp>
    +#include <boost/python/has_back_reference.hpp>
    +#include <boost/shared_ptr.hpp>
    +
    +using namespace boost::python;
    +
    +struct X
    +{
    +    X(PyObject* self) : m_self(self), m_x(0) {}
    +    X(PyObject* self, int x) : m_self(self), m_x(x) {}
    +    
    +    PyObject* self() { return m_self; }
    +    int get() { return m_x; }
    +    void set(int x) { m_x = x; }
    +
    +    PyObject* m_self;
    +    int x;
    +};
    +
    +// specialize has_back_reference for X
    +namespace boost { namespace python
    +{
    +  template <>
    +  struct has_back_reference<X>
    +  {
    +     enum { value = true; }
    +  }
    +}}
    +
    +struct Y
    +{
    +    Y() : m_x(0) {}
    +    Y(int x) : m_x(x) {}
    +    int get() { return m_x; }
    +    void set(int x) { m_x = x; }
    +
    +    int x;
    +};
    +
    +boost::shared_ptr<Y> Y_self(boost::shared_ptr<Y> self) const { return self; }
    +
    +BOOST_PYTHON_MODULE_INIT(back_references)
    +{
    +    module("back_references")
    +        .add(
    +            class_<X>("X")
    +               .def_init()
    +               .def_init(args<int>())
    +               .def("self", &X::self)
    +               .def("get", &X::get)
    +               .def("set", &X::set)
    +            )
    +        .add(
    +            class_<Y, shared_ptr<Y> >("Y")
    +               .def_init()
    +               .def_init(args<int>())
    +               .def("get", &Y::get)
    +               .def("set", &Y::set)
    +               .def("self", Y_self)
    +            )
    +        ;
    +}
    +
    + +The following Python session illustrates that x.self() +returns the same Python object on which it is invoked, while +y.self() must create a new Python object which refers to +the same Y instance. + +

    Python code

    + +
    +>>> from back_references import *
    +>>> x = X(1)
    +>>> x2 = x.self()
    +>>> x2 is x
    +1
    +>>> (x.get(), x2.get())
    +(1, 1)
    +>>> x.set(10)
    +>>> (x.get(), x2.get())
    +(10, 10)
    +>>>
    +>>>
    +>>> y = Y(2)
    +>>> y2 = y.self()
    +>>> y2 is y
    +0
    +>>> (y.get(), y2.get())
    +(2, 2)
    +>>> y.set(20)
    +>>> (y.get(), y2.get())
    +(20, 20)
    +
    + +

    Revised + + 07 May, 2002 + + + +

    © Copyright Dave Abrahams + 2002. All Rights Reserved. + From 34424d7a00821de8688e9c9faa8b2ff16a2e4439 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 8 May 2002 20:04:37 +0000 Subject: [PATCH 0428/1042] function* -> PyObject* simplifies documentation [SVN r13757] --- include/boost/python/data_members.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp index b0f3f7b6..7af72198 100644 --- a/include/boost/python/data_members.hpp +++ b/include/boost/python/data_members.hpp @@ -61,7 +61,7 @@ namespace detail } template -objects::function* make_getter(D C::*pm) +PyObject* make_getter(D C::*pm) { typedef return_value_policy default_policy; return new objects::function( @@ -73,7 +73,7 @@ objects::function* make_getter(D C::*pm) } template -objects::function* make_getter(D C::*pm, Policies const& policies) +PyObject* make_getter(D C::*pm, Policies const& policies) { return new objects::function( objects::py_function( @@ -84,7 +84,7 @@ objects::function* make_getter(D C::*pm, Policies const& policies) } template -objects::function* make_setter(D C::*pm) +PyObject* make_setter(D C::*pm) { return new objects::function( objects::py_function( @@ -95,7 +95,7 @@ objects::function* make_setter(D C::*pm) } template -objects::function* make_setter(D C::*pm, Policies const& policies) +PyObject* make_setter(D C::*pm, Policies const& policies) { return new objects::function( objects::py_function( From 4b9931c41724e262ed806705c771ce902744c44b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 8 May 2002 20:10:40 +0000 Subject: [PATCH 0429/1042] undo last change; not worth it. [SVN r13758] --- include/boost/python/data_members.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp index 7af72198..b0f3f7b6 100644 --- a/include/boost/python/data_members.hpp +++ b/include/boost/python/data_members.hpp @@ -61,7 +61,7 @@ namespace detail } template -PyObject* make_getter(D C::*pm) +objects::function* make_getter(D C::*pm) { typedef return_value_policy default_policy; return new objects::function( @@ -73,7 +73,7 @@ PyObject* make_getter(D C::*pm) } template -PyObject* make_getter(D C::*pm, Policies const& policies) +objects::function* make_getter(D C::*pm, Policies const& policies) { return new objects::function( objects::py_function( @@ -84,7 +84,7 @@ PyObject* make_getter(D C::*pm, Policies const& policies) } template -PyObject* make_setter(D C::*pm) +objects::function* make_setter(D C::*pm) { return new objects::function( objects::py_function( @@ -95,7 +95,7 @@ PyObject* make_setter(D C::*pm) } template -PyObject* make_setter(D C::*pm, Policies const& policies) +objects::function* make_setter(D C::*pm, Policies const& policies) { return new objects::function( objects::py_function( From b45b9e5ccf63a24b40eae41914261bae79819908 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 8 May 2002 21:51:09 +0000 Subject: [PATCH 0430/1042] bug fix [SVN r13759] --- doc/v2/make_function.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/make_function.html b/doc/v2/make_function.html index 4e3c0bd1..f3189672 100644 --- a/doc/v2/make_function.html +++ b/doc/v2/make_function.html @@ -80,7 +80,7 @@ objects::function* make_function(F f, Policies const& policies) objects::function* make_constructor();

  • -
    +
    Requires: T is a class type. ArgList is an MPL sequence of C++ argument types (A1, A2,... AN) such that if From 1d160762b55804ff87b84c5b859ed713ebcf88bc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 8 May 2002 22:13:30 +0000 Subject: [PATCH 0431/1042] initial commit [SVN r13762] --- doc/v2/data_members.html | 150 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 doc/v2/data_members.html diff --git a/doc/v2/data_members.html b/doc/v2/data_members.html new file mode 100644 index 00000000..820bb1d4 --- /dev/null +++ b/doc/v2/data_members.html @@ -0,0 +1,150 @@ + + + + + + Boost.Python - <boost/python/data_members.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/data_members.hpp>

    +
    +
    + +

    Contents

    + +
    +
    Introduction + +
    Functions + +
    +
    +
    make_getter + +
    make_setter +
    + +
    Example +
    +
    + +

    Introduction

    + +

    make_getter() and + make_setter() are + the functions used internally by class_<>::def_readonly and + class_<>::def_readwrite to + produce Python callable objects which wrap C++ data members. + +

    Functions

    + +
    +template <class C, class D>
    +objects::function* make_getter(D C::*pm);
    +
    +template <class C, class D, class Policies>
    +objects::function* make_getter(D C::*pm, Policies const& policies);
    +
    + +
    +
    Requires: Policies is a model of CallPolicies. + +
    Effects: Creates a Python callable object which + accepts a single argument that can be converted + from_python to C*, and returns the + corresponding member D member of the C + object, converted to_python. If + policies is supplied, it will be applied to the + function as described here. + +
    Returns: A pointer convertible to PyObject* which + refers to the new Python callable object. +
    +
    +template <class C, class D>
    +objects::function* make_setter(D C::*pm);
    +
    +template <class C, class D, class Policies>
    +objects::function* make_setter(D C::*pm, Policies const& policies);
    +
    + +
    +
    Requires: Policies is a model of CallPolicies. + +
    Effects: Creates a Python callable object which, when + called from Python, expects two arguments which can be converted + from_python to C* and + D const&, respectively, and sets the + corresponding D member of the C + object. If policies is supplied, it will be applied + to the function as described here. + +
    Returns: A pointer convertible to + PyObject* which refers to the new Python callable + object. +
    + +

    Example

    + +

    The code below uses make_getter and make_setter to expose a + data member as functions: + +

    +#include <boost/python/data_members.hpp>
    +#include <boost/python/module.hpp>
    +#include <boost/python/class.hpp>
    +
    +struct X
    +{
    +    X(int x) : y(x) {}
    +    int y;
    +};
    +
    +using namespace boost::python;
    +
    +BOOST_PYTHON_MODULE_INIT(data_members_example)
    +{
    +    module("data_members_example")
    +        .add(
    +            class_<X>("X")
    +               .def_init(args<int>())
    +               .def("get", make_getter(&X::y))
    +               .def("set", make_setter(&X::y))
    +        )
    +        ;
    +}
    +
    + It can be used this way in Python: +
    +>>> from data_members_example import *
    +>>> x = X(1)
    +>>> x.get()
    +1
    +>>> x.set(2)
    +>>> x.get()
    +2
    +
    + +

    + + 8 May 2002 + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From c5d90745a03b1aa91bd7919eef32fd9aa4fad23c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 01:59:32 +0000 Subject: [PATCH 0432/1042] pointer_holder_back_reference.hpp -> ptr_holder_back_reference.hpp (31 character limit) [SVN r13767] --- include/boost/python/object/pointer_holder.hpp | 2 +- ..._holder_back_reference.hpp => ptr_holder_back_reference.hpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename include/boost/python/preprocessed/{pointer_holder_back_reference.hpp => ptr_holder_back_reference.hpp} (100%) diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 8ae778b4..94e239f1 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -63,7 +63,7 @@ struct pointer_holder_back_reference : instance_holder // Forward construction to the held object # ifndef BOOST_PYTHON_GENERATE_CODE -# include +# include # endif # define BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER_BACK_REFERENCE(nargs, ignored) \ diff --git a/include/boost/python/preprocessed/pointer_holder_back_reference.hpp b/include/boost/python/preprocessed/ptr_holder_back_reference.hpp similarity index 100% rename from include/boost/python/preprocessed/pointer_holder_back_reference.hpp rename to include/boost/python/preprocessed/ptr_holder_back_reference.hpp From aef987d832f0f6d70e31762a2683e1db13dec9b5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 02:00:22 +0000 Subject: [PATCH 0433/1042] work around OSF linker problem [SVN r13768] --- include/boost/python/errors.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp index 02fbeff9..fdf8e11a 100644 --- a/include/boost/python/errors.hpp +++ b/include/boost/python/errors.hpp @@ -35,12 +35,12 @@ inline void handle_exception() handle_exception(detail::rethrow); } -BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x); +BOOST_PYTHON_DECL PyObject* expect_non_null_impl(PyObject* x); template -T* expect_non_null(T* x) +inline T* expect_non_null(T* x) { - return (T*)expect_non_null((PyObject*)x); + return (T*)expect_non_null_impl((PyObject*)x); } BOOST_PYTHON_DECL void throw_argument_error(); From 2d522de7017fda75d7a7dd41fd50bff5b5a14cc4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 14:07:22 +0000 Subject: [PATCH 0434/1042] untabify [SVN r13773] --- src/object/class.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index f5f87140..c98a7414 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -57,7 +57,7 @@ PyTypeObject class_metatype_object = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /* tp_flags */ + | Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -77,7 +77,7 @@ PyTypeObject class_metatype_object = { 0, /* tp_alloc */ 0, // filled in with type_new /* tp_new */ 0, // filled in with __PyObject_GC_Del /* tp_free */ - (inquiry)type_is_gc, /* tp_is_gc */ + (inquiry)type_is_gc, /* tp_is_gc */ }; // Get the metatype object for all extension classes. @@ -132,7 +132,7 @@ PyTypeObject class_type_object = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT // | Py_TPFLAGS_HAVE_GC - | Py_TPFLAGS_BASETYPE, /* tp_flags */ + | Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ From 5956d3ec7726176964d8b78c93735fb98dc12763 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 14:24:57 +0000 Subject: [PATCH 0435/1042] fix tabs and line-endings [SVN r13774] --- src/classes.cpp | 2 +- src/errors.cpp | 2 +- src/module_builder.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/classes.cpp b/src/classes.cpp index a06ff5cf..440fe6a7 100644 --- a/src/classes.cpp +++ b/src/classes.cpp @@ -364,7 +364,7 @@ PyObject* instance::getattr(const char* name, bool use_special_function) if (PyEval_GetRestricted()) { PyErr_SetString(PyExc_RuntimeError, "instance.__dict__ not accessible in restricted mode"); - return 0; + return 0; } Py_INCREF(m_name_space.get()); return m_name_space.get(); diff --git a/src/errors.cpp b/src/errors.cpp index b84cd8ec..91ac7b99 100644 --- a/src/errors.cpp +++ b/src/errors.cpp @@ -49,7 +49,7 @@ void BOOST_PYTHON_DECL throw_error_already_set() throw error_already_set(); } -BOOST_PYTHON_DECL PyObject* expect_non_null(PyObject* x) +BOOST_PYTHON_DECL PyObject* expect_non_null_impl(PyObject* x) { if (x == 0) throw_error_already_set(); diff --git a/src/module_builder.cpp b/src/module_builder.cpp index 0a195621..1e47badb 100644 --- a/src/module_builder.cpp +++ b/src/module_builder.cpp @@ -1,4 +1,4 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and + // (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and // distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. @@ -50,7 +50,7 @@ module_builder_base::add(detail::function* x, const char* name) void module_builder_base::add(ref x, const char* name) { - PyObject* dictionary = PyModule_GetDict(m_module); + PyObject* dictionary = PyModule_GetDict(m_module); PyDict_SetItemString(dictionary, const_cast(name), x.get()); } From 57002aca3668c9893423eaa7933733641ae7a3df Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 14:28:37 +0000 Subject: [PATCH 0436/1042] Removed flotsam [SVN r13775] --- build/Jamfile | 1 - 1 file changed, 1 deletion(-) diff --git a/build/Jamfile b/build/Jamfile index 6c38b082..1f44ff7f 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -103,7 +103,6 @@ dll boost_python : $(BOOST_PYTHON_INCLUDES) true dynamic - BOOST_PYTHON_HAS_DLL_RUNTIME=1 $(PYTHON_PROPERTIES) ; From e7cb8c8b4f80e6d7bc84eb31d2103546456144f6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 14:29:07 +0000 Subject: [PATCH 0437/1042] Continuing updates [SVN r13776] --- doc/v2/reference.html | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 86362af0..335382a6 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -351,20 +351,18 @@

    has_back_reference.hpp -
    Classes -
    -
    has_back_reference +
    has_back_reference
    +
    -
    implicit.hpp +
    implicit.hpp
    Functions @@ -392,7 +390,7 @@
    pointer_wrapper
    -
    MetaFunctions +
    MetaFunctions
    is_pointer_wrapper From 8e57090a754ed313d574b1c0d24341a6443abbbf Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 16:04:17 +0000 Subject: [PATCH 0438/1042] Fix broken links [SVN r13777] --- doc/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index b70019ed..3d5f66c3 100644 --- a/doc/index.html +++ b/doc/index.html @@ -45,7 +45,7 @@ the following compilers:

  • GCC 3.0.4 under Cygwin and + href="http://www.cygwin.com">Cygwin and RedHat Linux 7.1. All tests pass. @@ -67,7 +67,7 @@ the following compilers:

  • GCC 2.95.2 under MinGW and MinGW and RedHat Linux 7.1. Compilation succeeds, but some tests fail at runtime due to exception handling bugs. It is therefore highly recommended From 45aa77079dd8fd8bf02f7195e427359cb8bbfc0c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 16:53:33 +0000 Subject: [PATCH 0439/1042] initial commit [SVN r13778] --- doc/v2/callbacks.html | 245 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 doc/v2/callbacks.html diff --git a/doc/v2/callbacks.html b/doc/v2/callbacks.html new file mode 100644 index 00000000..d47d290a --- /dev/null +++ b/doc/v2/callbacks.html @@ -0,0 +1,245 @@ + + + + +Boost.Python - Calling Python Functions and Methods + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Calling Python Functions and Methods

    +
    +
    +

    Contents

    +
    +
    Introduction
    +
    Argument Handling
    +
    Result Handling
    +
    Rationale
    +
    +
    + +

    Introduction

    +

    +Boost.Python provides two families of function templates, +call and call_method, for +invoking Python functions and methods respectively. The interface for +calling a Python function object (or any Python callable object) looks +like: + +

    +call<ResultType>(callable_object, a1, a2... aN);
    +
    + +Calling a method of a Python object is similarly easy: + +
    +call_method<ResultType>(self_object, "method-name", a1, a2... aN);
    +
    + + +

    Argument Handling

    +

    + +Arguments are converted to Python according to their type. By default, +the arguments a1...aN are copied into +new Python objects, but this behavior can be overridden by the use of +ptr() and ref(): + +

    +class X : boost::noncopyable
    +{
    +   ...
    +};
    +
    +void apply(PyObject* callable, X& x)
    +{
    +   // Invoke callable, passing a Python object which holds a reference to x
    +   boost::python::call<void>(callable, boost::ref(x));
    +}
    +
    + +In the table below, x denotes the actual argument +object and cv denotes an optional +cv-qualification: "const", +"volatile", or "const +volatile". + + + + + + + +
    Argument Type + + Behavior + +
    T cv&
    + T cv + +
    The Python argument is created by the same means used + for the return value of a wrapped C++ function returning + T. When + T is a class type, that normally means + *x is copy-constructed into the new Python + object. + +
    T* + + If x == 0, the Python argument will + be None. Otherwise, + the Python argument is created by the same means used for the + return value of a wrapped C++ function returning + T. When + T is a class type, that normally means + *x is copy-constructed into the new Python + object. + +
    boost::reference_wrapper<T> + + The Python argument contains a pointer to, rather than a + copy of, x.get(). Note: failure to ensure that no + Python code holds a reference to the resulting object beyond + the lifetime of *x.get() may result in a + crash! + +
    pointer_wrapper<T> + + If x.get() == 0, the Python + argument will be None. + Otherwise, the Python argument contains a pointer to, rather + than a copy of, *x.get(). Note: failure to ensure + that no Python code holds a reference to the resulting object + beyond the lifetime of *x.get() may result in + a crash! + +
    + +

    Result Handling

    + +In general, call<ResultType>() and +call_method<ResultType>() return +ResultType by exploiting all lvalue and rvalue +from_python converters registered for ResultType and +returning a copy of the result. However, when +ResultType is a pointer or reference type, Boost.Python +searches only for lvalue converters. To prevent dangling pointers and +references, an exception will be thrown if the Python result object +has only a single reference count. + +

    Rationale

    + +In general, to get Python arguments corresponding to +a1...aN, a new Python object must be +created for each one; should the C++ object be copied into that Python +object, or should the Python object simply hold a reference/pointer to +the C++ object? In general, the latter approach is unsafe, since the +called function may store a reference to the Python object +somewhere. If the Python object is used after the C++ object is +destroyed, we'll crash Python. + +

    In keeping with the philosophy that users on the Python side +shouldn't have to worry about crashing the interpreter, the default +behavior is to copy the C++ object, and to allow a non-copying +behavior only if the user writes boost::ref(a1) instead of a1 +directly. At least this way, the user doesn't get dangerous behavior +"by accident". It's also worth noting that the non-copying +("by-reference") behavior is in general only available for +class types, and will fail at runtime with a Python exception if used +otherwise[1]. + +

    +However, pointer types present a problem: one approach is to refuse +to compile if any aN has pointer type: after all, a user can always pass +*aN to pass "by-value" or ref(*aN) +to indicate a pass-by-reference behavior. However, this creates a +problem for the expected null pointer to +None conversion: it's illegal to dereference a null +pointer value. + +

    + +The compromise I've settled on is this: + +

      +
    1. The default behavior is pass-by-value. If you pass a non-null + pointer, the pointee is copied into a new Python object; otherwise + the corresponding Python argument will be None. + +
    2. if you want by-reference behavior, use ptr(aN) if + aN is a pointer and ref(aN) otherwise. If + a null pointer is passed to ptr(aN), the corresponding + Python argument will be None. +
    + +

    +As for results, we have a similar problem: if ResultType +is allowed to be a pointer or reference type, the lifetime of the +object it refers to is probably being managed by a Python object. When +that Python object is destroyed, our pointer dangles. The problem is +particularly bad when the ResultType is char const* - the +corresponding Python String object is typically uniquely-referenced, +meaning that the pointer dangles as soon as call<char +const*>(...) returns. + +

    +The old Boost.Python v1 deals with this issue by refusing to compile +any uses of call<char const*>(), but this goes both +too far and not far enough. It goes too far because there are cases +where the owning Python string object survives beyond the call (just +for instance, when it's the name of a Python class), and it goes not +far enough because we might just as well have the same problem with a +returned pointer or reference of any other type. + +

    + +In Boost.Python v2 this is dealt with by: + +

      +
    1. lifting the compile-time restriction on const + char* callback returns + + +
    2. detecting the case when the reference count on the result + Python object is 1 and throwing an exception inside of + call<U>(...) when U is a pointer + or reference type. +
    + +This should be acceptably safe because users have to explicitly +specify a pointer/reference for U in +call<U>, and they will be protected against dangles +at runtime, at least long enough to get out of the +call<U>(...) invocation. + +
    + +[1] It would be possible to make it fail at compile-time for non-class +types such as int and char, but I'm not sure it's a good idea to impose +this restriction yet. + +

    Revised + + 17 April, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + From c639ac0c5a210ce47380ff13cb4d72a73e68f0aa Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 17:01:27 +0000 Subject: [PATCH 0440/1042] finished [SVN r13779] --- doc/v2/call.html | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/doc/v2/call.html b/doc/v2/call.html index e75d5597..c76c01f7 100644 --- a/doc/v2/call.html +++ b/doc/v2/call.html @@ -47,22 +47,31 @@ R call(PyObject* callable, A1 const&, A2 const&, ... An const&
    Effects: Invokes callable(a1, a2, ...an) in Python, where a1...an are the arguments to call(), converted to Python objects. -
    Postconditions: {{text}}
    -
    Returns: The result of the Python call, converted to the - C++ type R.
    +
    Returns: The result of the Python call, converted to the C++ type R.
  • -
    Rationale: - +
    Rationale: For a complete semantic description of and + rationale, see this page.

    Example(s)

    -

    {{Example(s)}}

    +The following C++ function applies a Python callable object to its two +arguments and returns the result. If a Python exception is raised or +the result can't be converted to a double, an exception +is thrown. + +
    +double apply2(PyObject* func, double x, double y)
    +{
    +   return boost::python::call<double>(func, x, y);
    +}
    +
    +

    Revised - 05 November, 2002 + 9 May, 2002

    © Copyright Dave Abrahams From aa0fc6dfe7371a93f4dce027d055f0c1bed13592 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 17:37:06 +0000 Subject: [PATCH 0441/1042] trivial bugfix [SVN r13784] --- doc/v2/copy_non_const_reference.html | 2 +- doc/v2/manage_new_object.html | 2 +- doc/v2/reference_existing_object.html | 2 +- doc/v2/return_value_policy.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/v2/copy_non_const_reference.html b/doc/v2/copy_non_const_reference.html index ea2a99c7..a33bba55 100644 --- a/doc/v2/copy_non_const_reference.html +++ b/doc/v2/copy_non_const_reference.html @@ -105,7 +105,7 @@ struct Foo { using namespace boost::python; BOOST_PYTHON_MODULE_INIT(my_module) { - module m("my_module") + module("my_module") .add( class_<Bar>() ) diff --git a/doc/v2/manage_new_object.html b/doc/v2/manage_new_object.html index 112e540f..342c49ce 100644 --- a/doc/v2/manage_new_object.html +++ b/doc/v2/manage_new_object.html @@ -104,7 +104,7 @@ Foo* make_foo(int x) { return new Foo(x); } using namespace boost::python; BOOST_PYTHON_MODULE_INIT(my_module) { - module m("my_module") + module("my_module") .def("make_foo", make_foo) .add( class_<Foo>() diff --git a/doc/v2/reference_existing_object.html b/doc/v2/reference_existing_object.html index c5d39756..e7668a18 100644 --- a/doc/v2/reference_existing_object.html +++ b/doc/v2/reference_existing_object.html @@ -130,7 +130,7 @@ Singleton& get_it() using namespace boost::python; BOOST_PYTHON_MODULE_INIT(singleton) { - module m("singleton") + module("singleton") .def("get_it", get_it) .add( class_<Singleton>() diff --git a/doc/v2/return_value_policy.html b/doc/v2/return_value_policy.html index 5741be8f..f351af70 100644 --- a/doc/v2/return_value_policy.html +++ b/doc/v2/return_value_policy.html @@ -118,7 +118,7 @@ struct Foo { using namespace boost::python; BOOST_PYTHON_MODULE_INIT(my_module) { - module m("my_module") + module("my_module") .add( class_<Bar>() ) From fff4cc8b0dde1a07edd120fe22c33a12f34343ef Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 17:48:42 +0000 Subject: [PATCH 0442/1042] tweaks [SVN r13787] --- doc/v2/call.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/v2/call.html b/doc/v2/call.html index c76c01f7..6c1e2e39 100644 --- a/doc/v2/call.html +++ b/doc/v2/call.html @@ -42,7 +42,8 @@ R call(PyObject* callable, A1 const&, A2 const&, ... An const&)

    -
    Requires: R is a complete type with an accessible copy constructor
    +
    Requires: R is a pointer type, reference + type, or a complete type with an accessible copy constructor
    Effects: Invokes callable(a1, a2, ...an) in Python, where a1...an are the arguments to @@ -50,7 +51,7 @@ R call(PyObject* callable, A1 const&, A2 const&, ... An const&
    Returns: The result of the Python call, converted to the C++ type R.
    -
    Rationale: For a complete semantic description of and +
    Rationale: For a complete semantic description and rationale, see this page.
    From a2a1a557f5e0a75e87782551ac6e1177aeecefeb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 9 May 2002 17:49:18 +0000 Subject: [PATCH 0443/1042] initial commit [SVN r13788] --- doc/v2/call_method.html | 140 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 doc/v2/call_method.html diff --git a/doc/v2/call_method.html b/doc/v2/call_method.html new file mode 100644 index 00000000..81b913f6 --- /dev/null +++ b/doc/v2/call_method.html @@ -0,0 +1,140 @@ + + + + +Boost.Python - <call_method.hpp> + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Header <call_method.hpp>

    +
    +
    +

    Contents

    +
    +
    Introduction
    +
    Functions
    +
    +
    call_method
    +
    + +
    Example(s)
    + +
    +
    +

    Introduction

    +

    + <boost/python/call_method.hpp> defines the call_method family of overloaded function + templates, used to invoke Python callable objects from C++. + +

    Functions

    +
    +template <class R, class A1, class A2, ... class An>
    +R call_method(PyObject* self, char const* method, A1 const&, A2 const&, ... An const&)
    +
    +
    +
    Requires: R is a pointer type, reference + type, or a complete type with an accessible copy constructor
    + +
    Effects: Invokes self.method(a1, a2, ...an) in + Python, where a1...an are the arguments to + call_method(), converted to Python objects. For a + complete semantic description, see this + page. + +
    Returns: The result of the Python call, converted to the + C++ type R.
    + +
    +
    Rationale: call_method is critical to + implementing C++ virtual functions which are overridable in Python, + as shown by the example below. +
    + + +

    Example(s)

    + +The following C++ illustrates the use of call_method in +wrapping a class with a virtual function that can be overridden in +Python: + +

    C++ Module Definition

    +
    +#include <boost/python/module.hpp>
    +#include <boost/python/class.hpp>
    +#include <boost/utility.hpp>
    +#include <cstring>
    +
    +// class to be wrapped
    +class Base
    +{
    + public:
    +   virtual char const* class_name() const { return "Base"; }
    +   virtual ~Base();
    +};
    +
    +bool is_base(Base* b)
    +{
    +   return !std::strcmp(b->class_name(), "Base");
    +}
    +
    +// Wrapper code begins here
    +using namespace boost::python;
    +
    +// Callback class
    +class Base_callback : public Base
    +{
    + public:
    +   Base_callback(PyObject* self) : m_self(self) {}
    +
    +   char const* class_name() const { return call_method(m_self, "class_name"); }
    +   char const* Base_name() const { return Base::class_name(); }
    + private:
    +   PyObject* m_self;
    +};
    +
    +using namespace boost::python;
    +BOOST_PYTHON_MODULE_INIT(my_module)
    +{
    +   module("my_module")
    +      .def("is_base", is_base)
    +      .add(
    +         class_<Base,Base_callback, noncopyable>("Base")
    +             .def("class_name", Base_callback::Base_name);
    +         )
    +       ;
    +}
    +
    + +

    Python Code

    +
    +>>> from my_module import *
    +>>> class Derived(Base):
    +...    def __init__(self):
    +...       Base.__init__(self)
    +...    def class_name(self):
    +...       return self.__class__.__name__
    +...
    +>>> is_base(Base()) # calls the class_name() method from C++
    +1
    +>>> is_base(Derived())
    +0
    +
    +

    Revised + + 9 May, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + From 13331d3eab81296c1d59b15ca4c3469eab4f14ca Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 May 2002 00:58:31 +0000 Subject: [PATCH 0444/1042] updated [SVN r13792] --- doc/v2/class.html | 374 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 294 insertions(+), 80 deletions(-) diff --git a/doc/v2/class.html b/doc/v2/class.html index c28f0317..1299f482 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -72,30 +72,35 @@

    <boost/python/class.hpp> defines the interface through which users expose their C++ classes to Python. It declares the - class_ class template, which is parameterized on the class - type being exposed, and the args and bases - utility class templates in the anonymous namespace (the latter definitions - will probably be moved in a future release). + class_ class template, which is parameterized on the + class type being exposed. It also exposes the args + and bases utility class templates, which are used in + conjunction with class_.

    <boost/python/class_fwd.hpp> contains a forward declaration of the class_ class template. -

    Classes

    +

    Classes

    Class template class_<T, Bases, HolderGenerator>

    -

    Creates a Python class associated with the C++ type passed as its first - parameter. Its template arguments are:
    +

    Creates a Python class associated with the C++ type passed as + its first parameter. Although it has four template parameters, + only the first one is required. The three optional arguments can + actually be supplied in any + order; Boost.Python determines the role of the argument + from its type.

    - - @@ -103,57 +108,151 @@ - - + +
    Parameter + Template Parameter Requirements + Semantics + Default
    A class type. -
    Bases - - An MPL sequence of - C++ base classes of T. - - An unspecified empty sequence + The class being wrapped
    HolderGenerator + Bases - A model of HolderGenerator. + A specialization of bases<...> which + specifies previously-exposed C++ base classes of T[1]. + + Registers from_python conversions from + wrapped T instances to each of its exposed direct + and indirect bases. For each polymorphic base B, + registers conversions from indirectly-held wrapped + B instances to T. + + bases<> + +
    HeldType + + Must be T, a class derived + from T, or a Dereferenceable type for which + pointee<HeldType>::type + is T or a class derived from T. + + + Specifies the type which is actually embedded in a Python + object wrapping a T instance. More details below. + + T + +
    NonCopyable + + If supplied, must be boost::noncopyable. + + Suppresses automatic registration of to_python + conversions which copy + T instances. Required when T has no + publicly-accessible copy constructor. + + An unspecified type other than boost::noncopyable. - boost::python::objects::value_holder_generator
    -

    Class template class_ - synopsis

    +

    HeldType Semantics

    + +
      +
    1. + If HeldType is derived from T, its + exposed constructor(s) must accept an initial + PyObject* argument which refers back to the Python + object that contains it, as shown in this example. This argument is + not included in the argument list type passed to def_init(), below, nor is + it passed explicitly by users when Python instances of + T are created. This is the idiom which allows C++ virtual + functions to be overridden in Python. Boost.Python automatically + registers additional converters which allow wrapped instances of + T to be passed to wrapped C++ functions expecting + HeldType arguments. + +
    2. Because Boost.Python will always allow + wrapped instances of T to be passed in place of + HeldType arguments, specifying a smart pointer for + HeldType allows users to pass Python + T instances where a smart pointer-to-T is + expected. Smart pointers such as std::auto_ptr<> + or boost::shared_ptr<> + which contain a nested type element_type designating + the referent type are automatically supported; additional smart + pointer types can be supported by specializing pointee<HeldType>. + +
    3. + As in case 1 above, when HeldType is a smart pointer to + a class derived from T, the initial + PyObject* argument must be supplied by all exposed + constructors. + +
    4. + Except in cases 1 and 3, users may optionally specify that T itself + gets initialized with a similar initial PyObject* + argument by specializing has_back_reference. +
    + +

    Class template + class_ synopsis

     namespace boost { namespace python
     {
    -
       template <class T
    -            , class Bases = none
    -            , class HolderGenerator = objects::value_holder_generator>
    -  class class_
    +            , class Bases = bases<>
    +            , class HeldType = T
    +            , class NonCopyable = unspecified
    +           >
    +  class class_
       {
         class_();
         class_(char const* name);
     
    -    template <class F>
    -    class_& def(char const* name, F f);
    +    // exposing constructors
    +    class_& def_init();
     
    -    template <class Fn, class CallPolicy>
    -    class_& def(char const* name, Fn fn, CallPolicy policy);
    -    
         template <class Args>
         class_& def_init(Args const& = Args());
     
    -    class_& def_init();
    +    template <class Args, class CallPolicy>
    +    self& def_init(Args const&, CallPolicy policy);
     
    +    // exposing member functions
    +    template <class F>
    +    class_& def(char const* name, F f);
    +
    +    template <class Fn, class CallPolies>
    +    class_& def(char const* name, Fn fn, CallPolies);
    +
    +    // exposing data members
    +    template <class D>
    +    self& def_readonly(char const* name, D T::*pm);
    +
    +    template <class D>
    +    self& def_readwrite(char const* name, D T::*pm);
    +
    +    // property creation
    +    void add_property(char const* name, ref const& fget);
    +    void add_property(char const* name, ref const& fget, ref const& fset);
    +
    +    // accessing the Python class object
         ref object() const;
       };
     }}
     
    -

    Class template class_ - constructors

    +

    Class template class_ constructors

    +
    -class_()
    +class_();
     
    @@ -169,7 +268,7 @@ class_() Python classes without user intervention.
    -class_(char const* name)
    +class_(char const* name);
     
    @@ -186,12 +285,57 @@ class_(char const* name)

    Class template class_ modifier functions

    + +
    +class_& def_init();
    +
    +template <class Args>
    +class_& def_init(Args const& argument_types);
    +
    +template <class Args, class CallPolicies>
    +class_& def_init(Args const& argument_types, CallPolicies policies);
    +
    + +
    +
    Requires: Args is an MPL sequence of C++ argument + types (A1, A2,... AN) such that if + a1, a2... aN are objects of type + A1, A2,... AN respectively, the expression + T(a1, a2... aN) is valid. In the first form, + the expression T() must be valid. + +
    Effects: Adds the result of + +make_constructor<args<>,Holder>(), + +make_constructor<Args,Holder>(), or + +make_constructor<Args,Holder>(policies), + respectively, to the Boost.Python extension class being defined under the name + "__init__". Holder is a model of Holder which contains the + HeldType. If the extension class + already has an "__init__" attribute, the usual overloading procedure applies. + +
    Returns: *this + +
    Rationale: Allows users to easily expose a class' constructor + to Python. +
    + +
    +
     template <class F>
    -class_& def(char const* name, F f)
    +class_& def(char const* name, F f);
     
    -template <class Fn, class CallPolicy>
    -class_& def(char const* name, Fn f, CallPolicy policy)
    +template <class Fn, class CallPolicies>
    +class_& def(char const* name, Fn f, CallPolicies policies);
     
    @@ -202,7 +346,7 @@ class_& def(char const* name, Fn f, CallPolicy policy) naming rules. In the first form, the return type of f is not a reference and is not a pointer other than char const* or PyObject*. In the - second form policy is a model of policies is a model of CallPolicies.
    Effects: Adds the result of Returns: *this
    + +
    +
    -template <class Args>
    -class_& def_init(Args const& argument_types)
    -
    -class_& def_init()
    +void add_property(char const* name, ref const&amp; fget);
    +void add_property(char const* name, ref const&amp; fget, ref const&amp; fset);
     
    -
    -
    Requires: in the first form, argument_types must be an MPL sequence of C++ argument - types (A1, A2,... AN) such that if - a1, a2... aN are objects of type - A1, A2,... AN respectively, the expression - T(a1, a2... aN) is valid. In the second form, - the expression T() must be valid. -
    Effects: Adds the result of make_constructor<T,Args,HolderGenerator>() - to the Boost.Python extension class being defined with the name - "__init__". If the 2nd form is used, an unspecified empty MPL sequence type is substituted - for Args. If the extension class already has an "__init__" - attribute, the usual overloading - procedure applies. +
    Requires: name is a ntbs which conforms to + Python's identifier + naming rules. + +
    Effects: Creates a new Python property + class instance, passing fget.get() (and + fset.get() in the second form) to its constructor, + then adds that property to the Python class object under + construction with the given attribute name.
    Returns: *this -
    Rationale: Allows users to easily expose a class' constructor - to Python. +
    Rationale: Allows users to easily expose a class' + data member such that it can be inspected from Python with a + natural syntax.
    +
    +
    +    template <class D>
    +    self& def_readonly(char const* name, D T::*pm);
    +
    + +
    + +
    Requires: name is a ntbs which conforms to + Python's identifier + naming rules. + +
    Effects: +
    +this->add_property(name, ref(make_getter(pm)));
    +
    + +
    Returns: *this + +
    Rationale: Allows users to easily expose a class' + data member such that it can be inspected from Python with a + natural syntax. +
    + +
    + +
    +template <class D>
    +self& def_readwrite(char const* name, D T::*pm);
    +
    + +
    + +
    Effects: +
    +ref fget(make_getter(pm));
    +ref fset(make_setter(pm));
    +this->add_property(name, fget, fset);
    +
    + +
    Returns: *this + +
    Rationale: Allows users to easily expose a class' + data member such that it can be inspected and set from Python with a + natural syntax. +

    Class template class_ observer functions

    @@ -264,39 +452,42 @@ ref object() const;
         

    Class template args<T1, T2,...TN>

    -

    Essentially an alias for boost::mpl::type_list which users - can use in def_init calls to make their code more readable. - Currently it is in the global unnammed namespace, but that will probably - change. +

    A conveniently-named MPL sequence which + users pass to def_init calls to make + their code more readable.

    Class template args synopsis

    -namespace
    +namespace boost { namespace python
     {
       template <T1 = unspecified,...TN = unspecified>
    -  struct args : ::boost::mpl::type_list<T1,...TN>::type
    +  struct args
       {};
    -}
    +}}
     

    Class template bases<T1, T2,...TN>

    -

    Essentially an alias for boost::mpl::type_list which users - can use in class_<...> instantiations to - make their code more readable. Currently it is in the global unnammed - namespace, but that will probably change. +

    An MPL sequence which + can be used in class_<...> + instantiations indicate a list of base classes. Although users + can pass any MPL sequence in place of args, above, the use of + bases to indicate base classes is mandatory.

    Class template bases synopsis

    -namespace
    +namespace boost { namespace python
     {
       template <T1 = unspecified,...TN = unspecified>
    -  struct bases : ::boost::mpl::type_list<T1,...TN>::type
    +  struct bases
       {};
    -}
    +}}
     

    Example(s)

    @@ -311,24 +502,47 @@ class Foo : public Bar, public Baz std::string const& name() { return m_name; } void name(char const*); + + double value; // public data private: ... };
    - A corresponding Boost.Python extension class can be created with: + + A corresponding Boost.Python extension class can be created with:
     using namespace boost::python;
    -ref foo =
    -class_<Foo,bases<Bar,Baz> >()
    +
    +ref foo = class_<Foo,bases<Bar,Baz> >()
        .def_init(args<int,char const*>())
        .def_init(args<double>())
        .def("get_name", &Foo::get_name, return_internal_reference<>())
        .def("set_name", &Foo::set_name)
    +   .def_readwrite("value", &Foo::value)
        .object();
     
    + +
    + +[1] By "previously-exposed" we mean that the for each +B in bases, an instance of +class_<B> must have already been +constructed. Ensuring this in a portable manner when a class and its +bases are exposed in the same module entails using separate +full-expressions, rather than chaining consecutive definitions with +".add(...). + +
    +module m("module_name");
    +m.add(class_<Base>()
    +        .def_init());
    +m.add(class_<Derived, bases<Base>>()
    +        .def_init());
    +
    + Revised - 05 November, 2001 + 09 May, 2002 From 09046c53ef12f19f779265ae467bf58358e7d987 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 May 2002 04:00:33 +0000 Subject: [PATCH 0445/1042] ResultConverter/ResultConverterGenerator [SVN r13793] --- doc/v2/ResultConverter.html | 110 ++++++++++++++++++++++++++ doc/v2/copy_const_reference.html | 2 +- doc/v2/copy_non_const_reference.html | 2 +- doc/v2/default_call_policies.html | 2 +- doc/v2/manage_new_object.html | 2 +- doc/v2/reference.html | 12 ++- doc/v2/reference_existing_object.html | 2 +- doc/v2/return_value_policy.html | 4 +- doc/v2/to_python_indirect.html | 4 +- 9 files changed, 130 insertions(+), 10 deletions(-) create mode 100644 doc/v2/ResultConverter.html diff --git a/doc/v2/ResultConverter.html b/doc/v2/ResultConverter.html new file mode 100644 index 00000000..08d81b1a --- /dev/null +++ b/doc/v2/ResultConverter.html @@ -0,0 +1,110 @@ + + + + +Boost.Python - ResultConverter Concept + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    ResultConverter Concept

    +
    +
    +
    +
    Introduction
    +
    Concept Requirements
    +
    +
    ResultConverter Concept
    +
    ResultConverterGenerator Concept
    +
    +
    + +

    Introduction

    + +

    A ResultConverter for a type T is a type whose +instances can be used to convert C++ return values of type +T to_python. A ResultConverterGenerator is +an MPL unary metafunction class which, given the return type of a C++ +function, returns a ResultConverter for that type. ResultConverters in +Boost.Python generally inspect library's registry of converters to +find a suitable converter, but converters which don't use the registry +are also possible. + +

    Concept Requirements

    +

    ResultConverter Concept

    + +

    In the table below, C denotes a ResultConverter +type for a type R , c denotes +an object of type C , and r +denotes an object of type R. + + + + + + + + + + + + + + + + + + + + + + + + +
    ExpressionTypeSemantics
    C c; + Constructs a C object. +
    c.convertible()convertible to boolfalse iff no conversion from any R value + to a Python object is possible.
    c(r)convertible to PyObject*A pointer to a Python object corresponding to r, + or 0 iff r could not be converted + to_python, in which case PyErr_Occurred + should return non-zero.
    + +

    ResultConverterGenerator Concept

    +

    In the table below, G denotes a +ResultConverterGenerator type and R denotes a possible +C++ function return type. + + + + + + + + + +
    ExpressionRequirements
    G::apply<R>::typeA ResultConverter type for R.
    + +


    +

    Revised + + 09 May, 2002 + +

    +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + +

    Permission to copy, use, modify, sell + and distribute this software is granted provided this copyright notice appears + in all copies. This software is provided "as is" without express or implied + warranty, and with no claim as to its suitability for any purpose. + + diff --git a/doc/v2/copy_const_reference.html b/doc/v2/copy_const_reference.html index ec76fa1a..70da135b 100644 --- a/doc/v2/copy_const_reference.html +++ b/doc/v2/copy_const_reference.html @@ -50,7 +50,7 @@ copy_const_reference

    copy_const_reference is a model of ResultConverterGenerator which can be + "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator which can be used to wrap C++ functions returning a reference-to-const type such that the referenced value is copied into a new Python object. diff --git a/doc/v2/copy_non_const_reference.html b/doc/v2/copy_non_const_reference.html index a33bba55..ffa728db 100644 --- a/doc/v2/copy_non_const_reference.html +++ b/doc/v2/copy_non_const_reference.html @@ -51,7 +51,7 @@ copy_non_const_reference

    copy_non_const_reference is a model of ResultConverterGenerator which can be + "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator which can be used to wrap C++ functions returning a reference-to-non-const type such that the referenced value is copied into a new Python object. diff --git a/doc/v2/default_call_policies.html b/doc/v2/default_call_policies.html index 876baf7a..058b13e2 100644 --- a/doc/v2/default_call_policies.html +++ b/doc/v2/default_call_policies.html @@ -111,7 +111,7 @@ PyObject* postcall(PyObject*, PyObject* result); default_result_converter

    default_result_converter is a model of ResultConverterGenerator which can be + "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator which can be used to wrap C++ functions returning non-pointer types, char const*, and PyObject*, by-value. diff --git a/doc/v2/manage_new_object.html b/doc/v2/manage_new_object.html index 342c49ce..879cdc5e 100644 --- a/doc/v2/manage_new_object.html +++ b/doc/v2/manage_new_object.html @@ -50,7 +50,7 @@ manage_new_object

    manage_new_object is a model of ResultConverterGenerator which can be + "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator which can be used to wrap C++ functions which return a pointer to an object allocated with a new-expression, and expect the caller to take responsibility for deleting that object. diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 335382a6..24efbf61 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -164,8 +164,18 @@

    -
    reference.hpp +
    pointee.hpp +
    +
    +
    Classes +
    +
    +
    class template pointee +
    +
    + +
    reference.hpp
    Classes diff --git a/doc/v2/reference_existing_object.html b/doc/v2/reference_existing_object.html index e7668a18..dbb7a983 100644 --- a/doc/v2/reference_existing_object.html +++ b/doc/v2/reference_existing_object.html @@ -51,7 +51,7 @@ reference_existing_object

    reference_existing_object is a model of ResultConverterGenerator which can be + "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator which can be used to wrap C++ functions which return a reference or pointer to a C++ object. When the wrapped function is called, the value referenced by its return value is not copied. A new Python object is created which contains a diff --git a/doc/v2/return_value_policy.html b/doc/v2/return_value_policy.html index f351af70..950b024b 100644 --- a/doc/v2/return_value_policy.html +++ b/doc/v2/return_value_policy.html @@ -49,7 +49,7 @@ return_value_policy instantiations are simply models of CallPolicies which are composed of a ResultConverterGenerator and optional Base ResultConverterGenerator and optional Base CallPolicies.

    Classes

    @@ -69,7 +69,7 @@ Default - ResultConverterGenerator + ResultConverterGenerator A model of ResultConverterGenerator. diff --git a/doc/v2/to_python_indirect.html b/doc/v2/to_python_indirect.html index 8910cd97..d0b82f70 100644 --- a/doc/v2/to_python_indirect.html +++ b/doc/v2/to_python_indirect.html @@ -107,7 +107,7 @@ of its first argument type to python as extension class instances, using the own Instantiations of to_python_indirect are models of ResultConverter. + href="ResultConverter.html#ResultConverter-concept">ResultConverter.

    Class template to_python_indirect synopsis

    @@ -174,7 +174,7 @@ struct make_reference_holder struct reference_existing_object { - // metafunction returning the ResultConverter + // metafunction returning the ResultConverter template <class T> struct apply { From 3b000f080ec2aa6c1f9a593535d85fc15d4adf12 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 May 2002 09:38:07 +0000 Subject: [PATCH 0446/1042] tweak [SVN r13798] --- doc/v2/call_method.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/v2/call_method.html b/doc/v2/call_method.html index 81b913f6..2aa50c39 100644 --- a/doc/v2/call_method.html +++ b/doc/v2/call_method.html @@ -34,7 +34,7 @@

    <boost/python/call_method.hpp> defines the call_method family of overloaded function - templates, used to invoke Python callable objects from C++. + templates, used to invoke callable attributes of Python objects from C++.

    Functions

    @@ -131,7 +131,7 @@ BOOST_PYTHON_MODULE_INIT(my_module)
     

    Revised - 9 May, 2002 + 10 May, 2002

    © Copyright Dave Abrahams From ec3f5ff40bdaa25b286c98ed370c9562ba631689 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 May 2002 09:44:24 +0000 Subject: [PATCH 0447/1042] initial commit [SVN r13799] --- doc/v2/Dereferenceable.html | 66 +++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 doc/v2/Dereferenceable.html diff --git a/doc/v2/Dereferenceable.html b/doc/v2/Dereferenceable.html new file mode 100644 index 00000000..60ff06c2 --- /dev/null +++ b/doc/v2/Dereferenceable.html @@ -0,0 +1,66 @@ + + + + +Boost.Python - Dereferenceable Concept + + + + + + + +
    +

    C++ Boost

    +
    +

    Boost.Python

    +

    Dereferenceable Concept

    +
    +


    +
    +
    Introduction
    +
    Concept Requirements
    +
    +
    Dereferenceable Concept
    +
    +
    + +

    Introduction

    + +

    Instances of a dereferenceable type can be used like a pointer to access an lvalue. + +

    Concept Requirements

    +

    Dereferenceable Concept

    + +

    In the table below, x denotes an object whose +type is a model of Dereferenceable. + + + + + + + + + + + +
    ExpressionRequirements
    *xAn lvalue +
    + +


    +

    Revised + + 10 May, 2002 + +

    +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + +

    Permission to copy, use, modify, sell + and distribute this software is granted provided this copyright notice appears + in all copies. This software is provided "as is" without express or implied + warranty, and with no claim as to its suitability for any purpose. + + From 3328087de1e0e10cc6c3dfc293e3ffcabb401e51 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 May 2002 15:41:44 +0000 Subject: [PATCH 0448/1042] Added missing add_property chaining [SVN r13806] --- include/boost/python/class.hpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 8e921780..ae1705f6 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -172,8 +172,13 @@ class class_ : public objects::class_base return *this; } + // Property creation + self& add_property(char const* name, ref const& fget); + self& add_property(char const* name, ref const& fget, ref const& fset); + + // return the underlying object -// ref object() const; +// ref object() const; (implemented in base class) private: // types typedef objects::class_id class_id; @@ -236,6 +241,21 @@ inline class_::class_(char const* name) , this->object()); } + +template +inline class_& class_::add_property(char const* name, ref const& fget) +{ + class_base::add_property(name, fget); + return *this; +} + +template +inline class_& class_::add_property(char const* name, ref const& fget, ref const& fset) +{ + class_base::add_property(name, fget, fset); + return *this; +} + namespace detail { // This is an mpl BinaryMetaFunction object with a runtime behavior, From 9c3dd76e25594d54d38e90a97e947cee2854e201 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 May 2002 15:42:52 +0000 Subject: [PATCH 0449/1042] obsolete [SVN r13807] --- include/boost/python/detail/pointee.hpp | 36 ------------------------- 1 file changed, 36 deletions(-) delete mode 100644 include/boost/python/detail/pointee.hpp diff --git a/include/boost/python/detail/pointee.hpp b/include/boost/python/detail/pointee.hpp deleted file mode 100644 index 2af1535f..00000000 --- a/include/boost/python/detail/pointee.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef POINTEE_DWA2002323_HPP -# define POINTEE_DWA2002323_HPP - -# include - -namespace boost { namespace python { namespace detail { - -template -struct pointee_impl -{ - template struct apply : remove_pointer {}; -}; - -template <> -struct pointee_impl -{ - template struct apply - { - typedef typename T::element_type type; - }; -}; - -template -struct pointee - : pointee_impl::value>::template apply -{ -}; - -}}} // namespace boost::python::detail - -#endif // POINTEE_DWA2002323_HPP From 8f1dc2522adb55ab565cffa29c6435b9480e37c0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 May 2002 15:46:37 +0000 Subject: [PATCH 0450/1042] Added Dereferenceable [SVN r13808] --- doc/v2/class.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/class.html b/doc/v2/class.html index 1299f482..f7bc46db 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -130,7 +130,7 @@ Must be T, a class derived from T, or a Dereferenceable type for which + href="Dereferenceable.html">Dereferenceable type for which pointee<HeldType>::type is T or a class derived from T. From 710374ed1eda5fda72ea5346ed7e247f1cb10012 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 May 2002 15:47:04 +0000 Subject: [PATCH 0451/1042] Added Dereferenceable, ResultConverter [SVN r13809] --- doc/v2/reference.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 24efbf61..a05186c8 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -22,6 +22,13 @@

    Contents

    +
    Concepts +
    +
    Dereferenceable
    +
    ResultConverter
    +
    ResultConverterGenerator
    +
    +
    High Level Components
    Models of CallPolicies From 63deae3ab2da1255eae4b498a81fcec64bfa7d83 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 May 2002 15:47:59 +0000 Subject: [PATCH 0452/1042] Moved pointee up from detail [SVN r13810] --- .../boost/python/object/pointer_holder.hpp | 4 +- include/boost/python/object/select_holder.hpp | 4 +- include/boost/python/pointee.hpp | 39 +++++++++++++++++++ test/pointee.cpp | 8 ++-- 4 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 include/boost/python/pointee.hpp diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 94e239f1..c3bffa2c 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -14,7 +14,7 @@ # include # include # include -# include +# include # include # include @@ -56,7 +56,7 @@ template struct pointer_holder_back_reference : instance_holder { private: - typedef typename python::detail::pointee::type held_type; + typedef typename python::pointee::type held_type; public: pointer_holder_back_reference(Pointer); diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index 95330d10..b4e451c8 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -8,7 +8,7 @@ # include # include -# include +# include # include # include # include @@ -36,7 +36,7 @@ namespace detail template struct select_pointer_holder { - typedef typename python::detail::pointee::type pointee; + typedef typename python::pointee::type pointee; BOOST_STATIC_CONSTANT(bool, selector = (!is_same::value) | has_back_reference::value); typedef typename mpl::select_type< diff --git a/include/boost/python/pointee.hpp b/include/boost/python/pointee.hpp new file mode 100644 index 00000000..52d65d67 --- /dev/null +++ b/include/boost/python/pointee.hpp @@ -0,0 +1,39 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef POINTEE_DWA2002323_HPP +# define POINTEE_DWA2002323_HPP + +# include + +namespace boost { namespace python { + +namespace detail +{ + template + struct pointee_impl + { + template struct apply : remove_pointer {}; + }; + + template <> + struct pointee_impl + { + template struct apply + { + typedef typename T::element_type type; + }; + }; +} + +template +struct pointee + : detail::pointee_impl::value>::template apply +{ +}; + +}} // namespace boost::python::detail + +#endif // POINTEE_DWA2002323_HPP diff --git a/test/pointee.cpp b/test/pointee.cpp index 7935e897..44836b05 100644 --- a/test/pointee.cpp +++ b/test/pointee.cpp @@ -3,7 +3,7 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include #include #include #include @@ -15,19 +15,19 @@ int main() { BOOST_STATIC_ASSERT( (boost::is_same< - boost::python::detail::pointee >::type + boost::python::pointee >::type , char** >::value)); BOOST_STATIC_ASSERT( (boost::is_same< - boost::python::detail::pointee >::type + boost::python::pointee >::type , A>::value)); #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION BOOST_STATIC_ASSERT( (boost::is_same< - boost::python::detail::pointee::type + boost::python::pointee::type , char >::value)); #endif From 390bb1988d648a3f3e2b5b5aac49deadb3ec2ddd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 May 2002 15:48:27 +0000 Subject: [PATCH 0453/1042] implemented back_reference<> [SVN r13811] --- include/boost/python/back_reference.hpp | 97 +++++++++++++++++++ .../boost/python/converter/from_python.hpp | 44 ++++++++- test/back_reference.cpp | 14 +++ test/back_reference.py | 4 + 4 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 include/boost/python/back_reference.hpp diff --git a/include/boost/python/back_reference.hpp b/include/boost/python/back_reference.hpp new file mode 100644 index 00000000..bde26dcd --- /dev/null +++ b/include/boost/python/back_reference.hpp @@ -0,0 +1,97 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BACK_REFERENCE_DWA2002510_HPP +# define BACK_REFERENCE_DWA2002510_HPP + +# include + +namespace boost { namespace python { + +template +struct back_reference +{ + public: + typedef T type; + + back_reference(PyObject*, T); + ref reference() const; + T get() const; + private: + ref m_reference; + T m_value; +}; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +class is_back_reference +{ + public: + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +class is_back_reference > +{ + public: + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +# else // no partial specialization + +}} // namespace boost::python + +#include + +namespace boost { namespace python { + +namespace detail +{ + typedef char (&yes_back_reference_t)[1]; + typedef char (&no_back_reference_t)[2]; + + no_back_reference_t is_back_reference_test(...); + + template + yes_back_reference_t is_back_reference_test(type< back_reference >); +} + +template +class is_back_reference +{ + public: + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof(detail::is_back_reference_test(type())) + == sizeof(detail::yes_back_reference_t))); +}; + +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +// +// implementations +// +template +back_reference::back_reference(PyObject* p, T x) + : m_reference(p, ref::increment_count) + , m_value(x) +{ +} + +template +ref back_reference::reference() const +{ + return m_reference; +} + +template +T back_reference::get() const +{ + return m_value; +} + +}} // namespace boost::python + +#endif // BACK_REFERENCE_DWA2002510_HPP diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index 1c6a8b3c..a4923ae5 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -16,6 +16,12 @@ # include # include # include +# include + +namespace boost { namespace python +{ + template struct from_python; +}} namespace boost { namespace python { namespace converter { @@ -82,6 +88,21 @@ class rvalue_from_python rvalue_data m_data; }; +// ------- back-reference converters -------- + +// Converts to a (PyObject*,T) bundle, for when you need a reference +// back to the Python object + +template +struct back_reference_from_python + : boost::python::from_python +{ + back_reference_from_python(PyObject*); + T operator()(PyObject*); + private: + typedef boost::python::from_python base; +}; + template struct select_from_python { @@ -100,6 +121,10 @@ struct select_from_python boost::python::detail::is_reference_to_non_const::value || boost::python::detail::is_reference_to_volatile::value); + BOOST_STATIC_CONSTANT( + bool, back_ref = + boost::python::is_back_reference::value); + typedef typename mpl::select_type< ptr , pointer_from_python @@ -109,7 +134,11 @@ struct select_from_python , typename mpl::select_type< ref , reference_from_python - , rvalue_from_python + , typename mpl::select_type< + back_ref + , back_reference_from_python + , rvalue_from_python + >::type >::type >::type >::type type; @@ -232,6 +261,19 @@ rvalue_from_python::operator()(PyObject* p) return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0); } +template +back_reference_from_python::back_reference_from_python(PyObject* x) + : base(x) +{ +} + +template +inline T +back_reference_from_python::operator()(PyObject* x) +{ + return T(x, base::operator()(x)); +} + }}} // namespace boost::python::converter #endif // FROM_PYTHON_DWA2002127_HPP diff --git a/test/back_reference.cpp b/test/back_reference.cpp index e1338eaa..577aa6ef 100644 --- a/test/back_reference.cpp +++ b/test/back_reference.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,17 @@ namespace boost { namespace python }; }} +// prove that back_references get initialized with the right PyObject* +PyObject* y_identity(back_reference y) +{ + return y.reference().release(); +} + +// prove that back_references contain the right value +bool y_equality(back_reference y1, Y const& y2) +{ + return &y1.get() == &y2; +} BOOST_PYTHON_MODULE_INIT(back_reference_ext) { @@ -93,6 +105,8 @@ BOOST_PYTHON_MODULE_INIT(back_reference_ext) .def("value", &Z::value) .def("set", &Z::set) ) + .def("y_identity", y_identity) + .def("y_equality", y_equality) ; } diff --git a/test/back_reference.py b/test/back_reference.py index 552deec8..21d5d1c0 100644 --- a/test/back_reference.py +++ b/test/back_reference.py @@ -10,6 +10,10 @@ >>> z2 = copy_Z(z) >>> x_instances() 4 +>>> y_identity(y) is y +1 +>>> y_equality(y, y) +1 ''' def run(args = None): From 36be16b3e97c591a353729ef72ac42e7b82b9b85 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 11 May 2002 17:11:51 +0000 Subject: [PATCH 0454/1042] Quick bugfix [SVN r13825] --- test/Jamfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Jamfile b/test/Jamfile index 36b9a476..e684bcdd 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -98,10 +98,10 @@ unit-test select_holder unit-test select_from_python_test : select_from_python_test.cpp ../src/converter/type_id.cpp - # ../src/converter/registry.cpp # MWerks needs this for some reason - : $(BOOST_ROOT) BOOST_PYTHON_STATIC_LIB - $(PYTHON_V1_PROPERTIES) + : $(BOOST_ROOT) + [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] + BOOST_PYTHON_STATIC_LIB ; From 673d857bd85b52e44313f1ac944f3475c47bbb96 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 13 May 2002 16:29:43 +0000 Subject: [PATCH 0455/1042] Added setattr() [SVN r13835] --- include/boost/python/class.hpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index ae1705f6..16f6a4cf 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -168,17 +168,14 @@ class class_ : public objects::class_base { ref fget(make_getter(pm)); ref fset(make_setter(pm)); - this->add_property(name, fget, fset); - return *this; + return this->add_property(name, fget, fset); } // Property creation self& add_property(char const* name, ref const& fget); self& add_property(char const* name, ref const& fget, ref const& fset); - - // return the underlying object -// ref object() const; (implemented in base class) + self& setattr(char const* name, ref const&); private: // types typedef objects::class_id class_id; @@ -256,6 +253,13 @@ inline class_& class_::add_property(char const* name, re return *this; } +template +inline class_& class_::setattr(char const* name, ref const& x) +{ + class_base::setattr(name, x); + return *this; +} + namespace detail { // This is an mpl BinaryMetaFunction object with a runtime behavior, From 59f4ddf5af1669989eb533f2bcc4265a3bdb0ab4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 13 May 2002 16:30:09 +0000 Subject: [PATCH 0456/1042] Work around MSVC6 bug [SVN r13836] --- include/boost/python/class_fwd.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/boost/python/class_fwd.hpp b/include/boost/python/class_fwd.hpp index d88ec271..87f3ba32 100644 --- a/include/boost/python/class_fwd.hpp +++ b/include/boost/python/class_fwd.hpp @@ -18,9 +18,10 @@ namespace detail template < class T // class being wrapped - , class X1 = detail::not_specified - , class X2 = detail::not_specified - , class X3 = detail::not_specified + // arbitrarily-ordered optional arguments. Full qualification needed for MSVC6 + , class X1 = ::boost::python::detail::not_specified + , class X2 = ::boost::python::detail::not_specified + , class X3 = ::boost::python::detail::not_specified > class class_; From f2fa852f1affc430a756660ed97534ded059d293 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 13 May 2002 16:31:42 +0000 Subject: [PATCH 0457/1042] initial commit [SVN r13837] --- include/boost/python/detail/target.hpp | 89 ++++++++ include/boost/python/iterator.hpp | 114 ++++++++++ include/boost/python/object/iterator.hpp | 211 ++++++++++++++++++ include/boost/python/object/iterator_core.hpp | 18 ++ test/minimal.cpp | 13 ++ test/minimal.py | 2 + 6 files changed, 447 insertions(+) create mode 100644 include/boost/python/detail/target.hpp create mode 100644 include/boost/python/iterator.hpp create mode 100644 include/boost/python/object/iterator.hpp create mode 100644 include/boost/python/object/iterator_core.hpp create mode 100644 test/minimal.cpp create mode 100644 test/minimal.py diff --git a/include/boost/python/detail/target.hpp b/include/boost/python/detail/target.hpp new file mode 100644 index 00000000..e0c693dd --- /dev/null +++ b/include/boost/python/detail/target.hpp @@ -0,0 +1,89 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TARGET_DWA2002513_HPP +# define TARGET_DWA2002513_HPP + +# include + +namespace boost { namespace python { namespace detail { + +// +// target(x) - deduce the type of the first argument when bind(x) is +// invoked. +// + +// functions +template +boost::type* target(R (*)(Target)) { return 0; } + +template +boost::type* target(R (*)(Target, A1)) { return 0; } + +template +boost::type* target(R (*)(Target, A1, A2)) { return 0; } + +template +boost::type* target(R (*)(Target, A1, A2, A3)) { return 0; } + +// data member pointers +template +boost::type* target(R (Target::*)) { return 0; } + +// member Functions +template +boost::type* target(R (Target::*)()) { return 0; } + +template +boost::type* target(R (Target::*)(A1)) { return 0; } + +template +boost::type* target(R (Target::*)(A1,A2)) { return 0; } + +template +boost::type* target(R (Target::*)(A1,A2,A3)) { return 0; } + +// const member functions +template +boost::type* target(R (Target::*)() const) { return 0; } + +template +boost::type* target(R (Target::*)(A1) const) { return 0; } + +template +boost::type* target(R (Target::*)(A1,A2) const) { return 0; } + +template +boost::type* target(R (Target::*)(A1,A2,A3) const) { return 0; } + +// volatile member functions +template +boost::type* target(R (Target::*)() volatile) { return 0; } + +template +boost::type* target(R (Target::*)(A1) volatile) { return 0; } + +template +boost::type* target(R (Target::*)(A1,A2) volatile) { return 0; } + +template +boost::type* target(R (Target::*)(A1,A2,A3) volatile) { return 0; } + +// const volatile member functions +template +boost::type* target(R (Target::*)() const volatile) { return 0; } + +template +boost::type* target(R (Target::*)(A1) const volatile) { return 0; } + +template +boost::type* target(R (Target::*)(A1,A2) const volatile) { return 0; } + +template +boost::type* target(R (Target::*)(A1,A2,A3) const volatile) { return 0; } + +}}} // namespace boost::python::detail + +#endif // TARGET_DWA2002513_HPP diff --git a/include/boost/python/iterator.hpp b/include/boost/python/iterator.hpp new file mode 100644 index 00000000..0f1e8eeb --- /dev/null +++ b/include/boost/python/iterator.hpp @@ -0,0 +1,114 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ITERATOR_DWA2002512_HPP +# define ITERATOR_DWA2002512_HPP + +# include +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + // Adds an additional layer of binding to + // objects::make_iterator(...), which allows us to pass member + // function and member data pointers. + template + inline ref make_iterator( + Accessor1 get_start, Accessor2 get_finish, NextPolicies* = 0, boost::type* target = 0) + { + return objects::make_iterator_function( + boost::protect(boost::bind(get_start, _1)) + , boost::protect(boost::bind(get_finish, _1)) + , (NextPolicies*)0 + , target); + } + + // Guts of template class iterators<>, below. + template + struct iterators_impl + { + template + struct apply + { + typedef typename T::iterator iterator; + static iterator begin(T& x) { return x.begin(); } + static iterator end(T& x) { return x.end(); } + }; + }; + + template <> + struct iterators_impl + { + template + struct apply + { + typedef typename T::const_iterator iterator; + static iterator begin(T& x) { return x.begin(); } + static iterator end(T& x) { return x.end(); } + }; + }; +} + +// An "ordinary function generator" which contains static begin(x) and +// end(x) functions that invoke T::begin() and T::end(), respectively. +template +struct iterators + : detail::iterators_impl< + boost::is_const::value + >::template apply +{ +}; + +// Create an iterator-building function which uses the given +// accessors. Deduce the Target type from the accessors. The iterator +// returns copies of the inderlying elements. +template +ref range(Accessor1 start, Accessor2 finish) +{ + return detail::make_iterator(start, finish, (objects::default_iterator_call_policies*)0, detail::target(start)); +} + +// Create an iterator-building function which uses the given accessors +// and next() policies. Deduce the Target type. +template +ref range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) +{ + return detail::make_iterator(start, finish, (NextPolicies*)0, detail::target(start)); +} + +// Create an iterator-building function which uses the given accessors +// and next() policies, operating on the given Target type +template +ref range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type* = 0) +{ + typedef typename add_reference::type target; + return detail::make_iterator(start, finish, (NextPolicies*)0, + (boost::type*)0); +} + +// A Python callable object which produces an iterator traversing +// [x.begin(), x.end()), where x is an instance of the Container +// type. NextPolicies are used as the CallPolicies for the iterator's +// next() function. +template +struct iterator : ref +{ + iterator() + : ref( + range( + &iterators::begin, &iterators::end + )) + { + } +}; + +}} // namespace boost::python + +#endif // ITERATOR_DWA2002512_HPP diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp new file mode 100644 index 00000000..3207d1d4 --- /dev/null +++ b/include/boost/python/object/iterator.hpp @@ -0,0 +1,211 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ITERATOR_DWA2002510_HPP +# define ITERATOR_DWA2002510_HPP + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace objects { + +// CallPolicies for the next() method of iterators. We don't want +// users to have to explicitly specify that the references returned by +// iterators are copied, so we just replace the result_converter from +// the default_iterator_call_policies with a permissive one which +// always copies the result. +struct default_iterator_call_policies + : default_call_policies +{ + struct result_converter + { + template + struct apply + { + typedef to_python_value type; + }; + }; +}; + +// Instantiations of these are wrapped to produce Python iterators. +template +struct iterator_range +{ + iterator_range(ref sequence, Iterator start, Iterator finish); + + ref m_sequence; // Keeps the sequence alive while iterating. + Iterator m_start; + Iterator m_finish; +}; + +namespace detail +{ + // Guts of the iterator's next() function. We can't just wrap an + // ordinary function because we don't neccessarily know the result + // type of dereferencing the iterator. This also saves us from + // throwing C++ exceptions to indicate end-of-sequence. + template + struct iterator_next + { + static PyObject* execute(PyObject* args_, PyObject* kw, Policies const& policies) + { + typedef iterator_range range_; + + PyObject* py_self = PyTuple_GET_ITEM(args_, 0); + from_python c0(py_self); + range_* self = c0(py_self); + + // Done iterating? + if (self->m_start == self->m_finish) + { + objects::set_stop_iteration_error(); + return 0; + } + + // note: precall happens before we can check for the result + // converter in this case, to ensure it happens before the + // iterator is dereferenced. However, the arity is 1 so + // there's not much risk that this will amount to anything. + if (!policies.precall(args_)) return 0; + + PyObject* result = iterator_next::convert_result(*self->m_start); + ++self->m_start; + + return policies.postcall(args_, result); + } + private: + // Convert the result of dereferencing the iterator. Dispatched + // here because we can't neccessarily get the value_type of the + // iterator without PTS. This way, we deduce the value type by + // dereferencing. + template + static PyObject* convert_result(ValueType& x) + { + typedef typename Policies::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible()) return 0; + + return cr(x); + } + }; + + // Get a Python class which contains the given iterator and + // policies, creating it if neccessary. Requires: NextPolicies is + // default-constructible. + template + ref demand_iterator_class(char const* name, Iterator* = 0, NextPolicies const& policies = NextPolicies()) + { + typedef iterator_range range_; + + // Check the registry. If one is already registered, return it. + ref result( + objects::registered_class_object(converter::undecorated_type_id())); + + if (result.get() == 0) + { + // Make a callable object which can be used as the iterator's next() function. + ref next_function( + new objects::function( + objects::py_function( + bind(&detail::iterator_next::execute, _1, _2, policies)) + , 1)); + + result = class_(name) + .def("__iter__", identity_function()) + .setattr("next", next_function) + .object(); + + } + return result; + } + + // This class template acts as a generator for an ordinary function + // which builds a Python iterator. + template + struct make_iterator_help + { + // Extract an object x of the Target type from the first Python + // argument, and invoke get_start(x)/get_finish(x) to produce + // iterators, which are used to construct a new iterator_range<> + // object that gets wrapped into a Python iterator. + static PyObject* create( + Accessor1 const& get_start, Accessor2 const& get_finish + , PyObject* args_, PyObject* /*kw*/) + { + // Make sure the Python class is instantiated. + demand_iterator_class("iterator"); + + to_python_value > cr; + + // This check is probably redundant, since we ensure the + // type is registered above. + if (!cr.convertible()) + return 0; + + // Extract x from the first argument + PyObject* arg0 = PyTuple_GET_ITEM(args_, 0); + from_python c0(arg0); + if (!c0.convertible()) return 0; + typename from_python::result_type x = c0(arg0); + + // Build and convert the iterator_range<>. + return cr( + iterator_range( + ref(arg0, ref::increment_count) + , get_start(x), get_finish(x))); + } + }; +} + +// Create a Python callable object which accepts a single argument +// convertible to the C++ Target type and returns a Python +// iterator. The Python iterator uses get_start(x) and get_finish(x) +// (where x is an instance of Target) to produce begin and end +// iterators for the range, and an instance of NextPolicies is used as +// CallPolicies for the Python iterator's next() function. +template +inline ref make_iterator_function( + Accessor1 const& get_start, Accessor2 const& get_finish + , NextPolicies* , boost::type*) +{ + typedef typename Accessor1::result_type result_type; + + return ref( + new objects::function( + objects::py_function( + boost::bind( + &detail::make_iterator_help< + Target,result_type,Accessor1,Accessor2,NextPolicies + >::create + , get_start, get_finish, _1, _2) + ) + ,1 )); +} + +// +// implementation +// +template +inline iterator_range::iterator_range( + ref sequence, Iterator start, Iterator finish) + : m_sequence(sequence), m_start(start), m_finish(finish) +{ +} + +}}} // namespace boost::python::objects + +#endif // ITERATOR_DWA2002510_HPP diff --git a/include/boost/python/object/iterator_core.hpp b/include/boost/python/object/iterator_core.hpp new file mode 100644 index 00000000..dee87050 --- /dev/null +++ b/include/boost/python/object/iterator_core.hpp @@ -0,0 +1,18 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ITERATOR_CORE_DWA2002512_HPP +# define ITERATOR_CORE_DWA2002512_HPP + +# include + +namespace boost { namespace python { namespace objects { + +BOOST_PYTHON_DECL ref identity_function(); +BOOST_PYTHON_DECL void set_stop_iteration_error(); + +}}} // namespace boost::python::object + +#endif // ITERATOR_CORE_DWA2002512_HPP diff --git a/test/minimal.cpp b/test/minimal.cpp new file mode 100644 index 00000000..07bbb394 --- /dev/null +++ b/test/minimal.cpp @@ -0,0 +1,13 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include + +BOOST_PYTHON_MODULE_INIT(minimal_ext) +{ + boost::python::module m("minimal_ext"); +} + +#include "module_tail.cpp" diff --git a/test/minimal.py b/test/minimal.py new file mode 100644 index 00000000..fe5788f5 --- /dev/null +++ b/test/minimal.py @@ -0,0 +1,2 @@ +import minimal_ext + From 0a1b62a760d8adbd7ba731a43dc80a83d11c61a9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 13 May 2002 16:32:59 +0000 Subject: [PATCH 0458/1042] Added is_reference_to_class, is_pointer_to_class [SVN r13838] --- .../boost/python/detail/indirect_traits.hpp | 74 +++++++++++++++++++ test/indirect_traits_test.cpp | 24 ++++++ 2 files changed, 98 insertions(+) diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index bcfdd79a..dd4502cc 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -8,6 +8,7 @@ # include # include # include +# include # include namespace boost { namespace python { namespace detail { @@ -158,6 +159,39 @@ struct is_reference_to_pointer { BOOST_STATIC_CONSTANT(bool, value = true); }; + +template +struct is_reference_to_class +{ + BOOST_STATIC_CONSTANT( + bool, value + = (boost::type_traits::ice_and< + is_reference::value + , is_class< + typename remove_cv< + typename remove_reference::type + >::type + >::value + >::value) + ); +}; + +template +struct is_pointer_to_class +{ + BOOST_STATIC_CONSTANT( + bool, value + = (boost::type_traits::ice_and< + is_pointer::value + , is_class< + typename remove_cv< + typename remove_pointer::type + >::type + >::value + >::value) + ); +}; + # else typedef char (&inner_yes_type)[3]; @@ -194,6 +228,16 @@ struct is_pointer_help >::type type; }; +template +struct is_class_help +{ + typedef typename mpl::select_type< + is_class::value + , inner_yes_type + , inner_no_type + >::type type; +}; + # if 0 // doesn't seem to work yet template struct is_reference_to_function @@ -267,6 +311,36 @@ struct is_reference_to_pointer && sizeof(reference_to_pointer_helper(t)) == sizeof(inner_yes_type)) ); }; + +template +typename is_class_help::type reference_to_class_helper(V const volatile&); +outer_no_type reference_to_class_helper(...); + +template +struct is_reference_to_class +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = (is_reference::value + && sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type)) + ); +}; + +template +typename is_class_help::type pointer_to_class_helper(V const volatile*); +outer_no_type pointer_to_class_helper(...); + +template +struct is_pointer_to_class +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = (is_pointer::value + && sizeof(pointer_to_class_helper(t)) == sizeof(inner_yes_type)) + ); +}; # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION }}} // namespace boost::python::detail diff --git a/test/indirect_traits_test.cpp b/test/indirect_traits_test.cpp index 338e4d6a..7160b8eb 100644 --- a/test/indirect_traits_test.cpp +++ b/test/indirect_traits_test.cpp @@ -4,6 +4,9 @@ //#define print(expr) printf("%s ==> %s\n", #expr, expr) +// not all the compilers can handle an incomplete class type here. +struct X {}; + int main() { using namespace boost::python::detail; @@ -51,6 +54,27 @@ using namespace boost::python::detail; assert(!is_reference_to_volatile::value); assert(!is_reference_to_volatile::value); assert(!is_reference_to_volatile::value); + + assert(!is_reference_to_class::value); + assert(!is_reference_to_class::value); + assert(!is_reference_to_class::value); + + assert(!is_reference_to_class::value); + assert(is_reference_to_class::value); + assert(is_reference_to_class::value); + assert(is_reference_to_class::value); + assert(is_reference_to_class::value); + + assert(!is_pointer_to_class::value); + assert(!is_pointer_to_class::value); + assert(!is_pointer_to_class::value); + + assert(!is_pointer_to_class::value); + assert(!is_pointer_to_class::value); + assert(is_pointer_to_class::value); + assert(is_pointer_to_class::value); + assert(is_pointer_to_class::value); + assert(is_pointer_to_class::value); return 0; } From 97b863101ba7bf71a5eeeb827829d100e2d0673c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 13 May 2002 16:33:55 +0000 Subject: [PATCH 0459/1042] Add result_type definition [SVN r13839] --- include/boost/python/converter/from_python.hpp | 11 +++++++++-- include/boost/python/from_python.hpp | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index a4923ae5..40a75645 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -43,6 +43,8 @@ struct from_python_base template struct pointer_const_reference_from_python { + typedef T result_type; + pointer_const_reference_from_python(PyObject*); T operator()(PyObject*) const; bool convertible() const; @@ -55,6 +57,8 @@ struct pointer_const_reference_from_python template struct pointer_from_python : from_python_base { + typedef T result_type; + pointer_from_python(PyObject*); T operator()(PyObject*) const; }; @@ -63,6 +67,8 @@ struct pointer_from_python : from_python_base template struct reference_from_python : from_python_base { + typedef T result_type; + reference_from_python(PyObject*); T operator()(PyObject*) const; }; @@ -72,13 +78,12 @@ struct reference_from_python : from_python_base // Used for the case where T is a non-pointer, non-reference type OR // is a const non-volatile reference to a non-pointer type. template -class rvalue_from_python +struct rvalue_from_python { typedef typename boost::add_reference< typename boost::add_const::type >::type result_type; - public: rvalue_from_python(PyObject*); bool convertible() const; @@ -97,6 +102,8 @@ template struct back_reference_from_python : boost::python::from_python { + typedef T result_type; + back_reference_from_python(PyObject*); T operator()(PyObject*); private: diff --git a/include/boost/python/from_python.hpp b/include/boost/python/from_python.hpp index 726928ac..340a014a 100644 --- a/include/boost/python/from_python.hpp +++ b/include/boost/python/from_python.hpp @@ -22,6 +22,8 @@ struct from_python template <> struct from_python { + typedef PyObject* result_type; + from_python(PyObject*) {} bool convertible() const { return true; } PyObject* operator()(PyObject* source) const { return source; } @@ -30,6 +32,7 @@ struct from_python template <> struct from_python { + typedef PyObject* const& result_type; from_python(PyObject*) {} bool convertible() const { return true; } PyObject*const& operator()(PyObject*const& source) const { return source; } From dc1769b28a7d453181d0bf31fb32457d9aa39445 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 13 May 2002 16:35:07 +0000 Subject: [PATCH 0460/1042] Handle reference in make_function() calls. [SVN r13840] --- include/boost/python/detail/wrap_function.hpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/wrap_function.hpp b/include/boost/python/detail/wrap_function.hpp index 0dcccd70..57725efd 100644 --- a/include/boost/python/detail/wrap_function.hpp +++ b/include/boost/python/detail/wrap_function.hpp @@ -13,7 +13,11 @@ # include # include -namespace boost { namespace python { namespace detail { +namespace boost { namespace python { + +template class reference; + +namespace detail { // A function which converts its argument into a Python callable // object. Not very general yet! @@ -26,6 +30,9 @@ namespace boost { namespace python { namespace detail { template inline PyObject* wrap_function_aux(F f, PyObject*) { return f; } +template +inline PyObject* wrap_function_aux(F f, boost::python::reference x) { return x.release(); } + template inline PyObject* wrap_function_aux(F f, ...) { return make_function(f); } From 56abd7ba70829c0917ce6829d5632b22edb8ef24 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 13 May 2002 16:39:25 +0000 Subject: [PATCH 0461/1042] Added setattr() [SVN r13841] --- doc/v2/class.html | 44 ++++++++++++++++++++------- include/boost/python/object/class.hpp | 3 ++ 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/doc/v2/class.html b/doc/v2/class.html index f7bc46db..1c84c1c2 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -223,7 +223,7 @@ namespace boost { namespace python class_& def_init(Args const& = Args()); template <class Args, class CallPolicy> - self& def_init(Args const&, CallPolicy policy); + class_& def_init(Args const&, CallPolicy policy); // exposing member functions template <class F> @@ -234,10 +234,13 @@ namespace boost { namespace python // exposing data members template <class D> - self& def_readonly(char const* name, D T::*pm); + class_& def_readonly(char const* name, D T::*pm); template <class D> - self& def_readwrite(char const* name, D T::*pm); + class_& def_readwrite(char const* name, D T::*pm); + + // Raw attribute modification + class_& setattr(char const* name, ref const&); // property creation void add_property(char const* name, ref const& fget); @@ -339,9 +342,11 @@ class_& def(char const* name, Fn f, CallPolicies policies);
    type_from_python.hpp - +
    type_from_python.hpp
    Classes -
    type_from_python +
    identity_extractor +
    member_extractor
    diff --git a/test/m1.cpp b/test/m1.cpp index 42412c5d..fe5ef68d 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -9,7 +9,7 @@ #include "complicated.hpp" #include #include -#include +#include #include #include #include @@ -111,7 +111,7 @@ struct simple_to_python } }; -struct int_from_noddy_extractor +struct int_from_noddy { static int& execute(NoddyObject& p) { @@ -198,18 +198,18 @@ BOOST_PYTHON_MODULE_INIT(m1) simple_to_python(); - type_from_python<&NoddyType,int_from_noddy_extractor>(); + lvalue_from_pytype(); - boost::python::type_from_python< - &SimpleType -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - , member_extractor + lvalue_from_pytype< +#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // doesn't support non-type member pointer parameters + extract_member #else - , extract_simple_object + extract_simple_object #endif + , &SimpleType >(); - type_from_python<&SimpleType, identity_extractor >(); + lvalue_from_pytype,&SimpleType>(); module m1("m1"); From dd1b102282394698632367f514d7734fe23bf993 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 23 May 2002 22:42:09 +0000 Subject: [PATCH 0482/1042] result() fixes [SVN r14031] --- include/boost/python/detail/result.hpp | 24 ++- include/boost/python/preprocessed/result.hpp | 160 +++++++++---------- test/result.cpp | 24 +-- 3 files changed, 103 insertions(+), 105 deletions(-) diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp index d8bf1358..b00fd23f 100755 --- a/include/boost/python/detail/result.hpp +++ b/include/boost/python/detail/result.hpp @@ -31,23 +31,21 @@ namespace boost { namespace python { namespace detail { # define BOOST_PYTHON_FIRST_ARGUMENT_PF(args, ignored) \ template \ -boost::type* result(BOOST_PYTHON_FN(*,0,args), long = 0) { return 0; } +boost::type* result(BOOST_PYTHON_FN(*,0,args), int = 0) { return 0; } -# define BOOST_PYTHON_FIRST_ARGUMENT_PMF(args, cv) \ -template \ -boost::type* result(BOOST_PYTHON_FN(A0::*,1,args)cv(), long = 0) { return 0; } +# define BOOST_PYTHON_FIRST_ARGUMENT_PMF(args, cv) \ +template \ +boost::type* result(BOOST_PYTHON_FN(A0::*,1,args)cv(), int = 0) { return 0; } BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_FIRST_ARGUMENT_PF, nil) BOOST_PYTHON_REPEAT_MF_CV_2ND(BOOST_PYTHON_FIRST_ARGUMENT_PMF) template -boost::type* result(R (T::*), long = 0) { return 0; } +boost::type* result(R (T::*), int = 0) { return 0; } - -# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 /* it almost works with VC6, but not VC7 */ \ - || (defined(BOOST_MSVC) && _MSC_FULL_VER == 13012108) /* or the VC7.01 alpha */ \ - || defined(__GNUC__) && __GNUC__ < 3 \ - || defined(__MWERKS__) && __MWERKS__ < 3000 +# if (defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140) \ + || (defined(__GNUC__) && __GNUC__ < 3) \ + || (defined(__MWERKS__) && __MWERKS__ < 0x3000) // This code actually works on all implementations, but why use it when we don't have to? template struct get_result_type @@ -71,15 +69,15 @@ struct result_result typedef typename t1::type* type; }; + template typename result_result::type -result(X const&, int = 0) { return 0; } +result(X const&, short) { return 0; } # else // Simpler code for more-capable compilers - template boost::type* -result(X const&, int = 0) { return 0; } +result(X const&, short = 0) { return 0; } # endif diff --git a/include/boost/python/preprocessed/result.hpp b/include/boost/python/preprocessed/result.hpp index f9eb99c6..10180c99 100755 --- a/include/boost/python/preprocessed/result.hpp +++ b/include/boost/python/preprocessed/result.hpp @@ -7,403 +7,403 @@ # define RESULT2_DWA2002521_HPP template -boost::type*result(R(*)(),long=0) +boost::type*result(R(*)(),int=0) { return 0; } template -boost::type*result(R(*)(A0),long=0) +boost::type*result(R(*)(A0),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1),long=0) +boost::type*result(R(*)(A0,A1),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2),long=0) +boost::type*result(R(*)(A0,A1,A2),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3),long=0) +boost::type*result(R(*)(A0,A1,A2,A3),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3,A4),long=0) +boost::type*result(R(*)(A0,A1,A2,A3,A4),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5),long=0) +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6),long=0) +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7),long=0) +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8),long=0) +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),long=0) +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),long=0) +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),long=0) +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),long=0) +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),long=0) +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),int=0) { return 0; } template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),long=0) +boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),int=0) { return 0; } template -boost::type*result(R(A0::*)(),long=0) +boost::type*result(R(A0::*)(),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1),long=0) +boost::type*result(R(A0::*)(A1),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2),long=0) +boost::type*result(R(A0::*)(A1,A2),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3),long=0) +boost::type*result(R(A0::*)(A1,A2,A3),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),int=0) { return 0; } template -boost::type*result(R(A0::*)()const,long=0) +boost::type*result(R(A0::*)()const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1)const,long=0) +boost::type*result(R(A0::*)(A1)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2)const,long=0) +boost::type*result(R(A0::*)(A1,A2)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,int=0) { return 0; } template -boost::type*result(R(A0::*)()volatile,long=0) +boost::type*result(R(A0::*)()volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1)volatile,long=0) +boost::type*result(R(A0::*)(A1)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)()const volatile,long=0) +boost::type*result(R(A0::*)()const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1)const volatile,long=0) +boost::type*result(R(A0::*)(A1)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,int=0) { return 0; } template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,long=0) +boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,int=0) { return 0; } diff --git a/test/result.cpp b/test/result.cpp index caf0ec27..19b1cf41 100755 --- a/test/result.cpp +++ b/test/result.cpp @@ -61,51 +61,51 @@ int main() // Show that we can use the general version that works for // AdaptableFunctions expect_int( - result((int(*)())0,0L) + result((int(*)())0,0) ); expect_int( - result((int(*)(char))0,0L) + result((int(*)(char))0,0) ); expect_int( - result((int(X::*)())0,0L) + result((int(X::*)())0,0) ); expect_int( - result((int(X::*)(char))0,0L) + result((int(X::*)(char))0,0) ); expect_int( - result((int(X::*))0,0L) + result((int(X::*))0,0) ); expect_int( - result(std::plus(), 0L) + result(std::plus(),0) ); expect_string( - result((char*(*)())0,0L) + result((char*(*)())0,0) ); expect_string( - result((char*(*)(char))0,0L) + result((char*(*)(char))0,0) ); expect_string( - result((char*(X::*)())0,0L) + result((char*(X::*)())0,0) ); expect_string( - result((char*(X::*)(char))0,0L) + result((char*(X::*)(char))0,0) ); expect_string( - result((char*(X::*))0,0L) + result((char*(X::*))0,0) ); expect_string( - result(std::plus(), 0L) + result(std::plus(),0) ); return 0; From c15f8123660da312a6e65435872446b8a75879f8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 24 May 2002 11:16:22 +0000 Subject: [PATCH 0483/1042] bugfix [SVN r14035] --- doc/v2/from_python.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/from_python.html b/doc/v2/from_python.html index d888bb38..8bc2eda9 100644 --- a/doc/v2/from_python.html +++ b/doc/v2/from_python.html @@ -151,7 +151,7 @@ std::size_t length_if_string(PyObject* p) if (!converter.convertible()) return 0; else - return converter().size(); + return converter(p).size(); } From 502094439cf0063fee22c2f437fd6f4a038412da Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 28 May 2002 20:26:41 +0000 Subject: [PATCH 0484/1042] Kill superfluous forward declaration [SVN r14048] --- include/boost/python/manage_new_object.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/boost/python/manage_new_object.hpp b/include/boost/python/manage_new_object.hpp index 9c0912ab..e19035b7 100644 --- a/include/boost/python/manage_new_object.hpp +++ b/include/boost/python/manage_new_object.hpp @@ -22,8 +22,6 @@ namespace detail ; } -template struct to_python_value; - struct manage_new_object { template From b03dcfb7de3d2144dcf134e6969ef7f9d2910cb6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 28 May 2002 20:42:12 +0000 Subject: [PATCH 0485/1042] doc updates [SVN r14054] --- doc/v2/reference.html | 154 +++++++++++++++++--------------- doc/v2/to_python_converter.html | 2 +- doc/v2/to_python_value.html | 101 +++++++++++++++++++++ 3 files changed, 186 insertions(+), 71 deletions(-) create mode 100644 doc/v2/to_python_value.html diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 06fc346f..c36afe20 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -17,8 +17,8 @@

    C++ Boost -

    + "277" alt="C++ Boost" src="../../../../c++boost.gif" border= + "0">

    Boost.Python

    @@ -41,6 +41,9 @@
    Models of CallPolicies +
    Models of + ResultConverter +
    Models of ResultConverterGenerator @@ -48,31 +51,31 @@
    To/From Python Type Conversion
    Utility and Infrastructure - -
    +

    Concepts

    -
    -
    CallPolicies -
    Dereferenceable +
    +
    CallPolicies -
    Extractor +
    Dereferenceable -
    HolderGenerator +
    Extractor -
    ResultConverter +
    HolderGenerator -
    ResultConverterGenerator -
    +
    ResultConverter + +
    ResultConverterGenerator +

    High Level Components

    @@ -330,6 +333,38 @@ + + +

    Models of ResultConverter

    + +
    +
    to_python_indirect.hpp + +
    +
    +
    Classes + +
    +
    +
    to_python_indirect +
    +
    + +
    to_python_value.hpp + +
    +
    +
    Classes + +
    +
    +
    to_python_value +
    +
    +

    Models of ResultConverterGenerator

    @@ -353,6 +388,7 @@
    copy_non_const_reference.hpp +
    manage_new_object.hpp +
    Classes @@ -381,6 +418,7 @@
    reference_existing_object.hpp +
    -
    @@ -427,22 +464,24 @@ -
    lvalue_from_pytype.hpp +
    lvalue_from_pytype.hpp + +
    +
    +
    Classes +
    -
    Classes +
    lvalue_from_pytype -
    -
    -
    lvalue_from_pytype -
    extract_identity -
    extract_member -
    +
    extract_identity + +
    extract_member
    +
    to_python_converter.hpp @@ -458,42 +497,20 @@ -
    to_python_indirect.hpp - -
    -
    -
    Classes - -
    -
    -
    to_python_indirect -
    -
    - -
    to_python_value.hpp - -
    -
    -
    Classes - -
    -
    -
    to_python_value -
    -
    -
    type_from_python.hpp +
    Classes +
    type_from_python +
    identity_extractor +
    member_extractor
    @@ -529,21 +546,18 @@
    -
    instance_holder.hpp +
    instance_holder.hpp -
    -
    -
    Classes +
    +
    +
    Classes -
    -
    -
    - instance_holder -
    -
    +
    +
    +
    instance_holder +
    +
    pointee.hpp diff --git a/doc/v2/to_python_converter.html b/doc/v2/to_python_converter.html index 63db8c71..a2a985d8 100644 --- a/doc/v2/to_python_converter.html +++ b/doc/v2/to_python_converter.html @@ -146,7 +146,7 @@ struct tag_to_noddy BOOST_PYTHON_MODULE_INIT(to_python_converter) { - module to_python("to_python_converter") + module("to_python_converter") .def("make_tag", make_tag) ; to_python_converter<tag, tag_to_noddy>(); diff --git a/doc/v2/to_python_value.html b/doc/v2/to_python_value.html new file mode 100644 index 00000000..990cea41 --- /dev/null +++ b/doc/v2/to_python_value.html @@ -0,0 +1,101 @@ + + + + + + Boost.Python - <boost/python/to_python_value.hpp> + + + +
    +

    +

    + +
    +

    Boost.Python

    + +

    Header + <boost/python/to_python_value.hpp>

    +
    +
    + +

    Contents

    + +
    +
    Classes + +
    +
    +
    Class + to_python_value + +
    +
    +
    Class template + to_python_value synopsis + +
    Class template + to_python_value observer functions +
    +
    + +
    +
    + +

    Classes

    + +

    Class template + to_python_value

    + +

    to_python_value is a model of ResultConverter + which copies its argument into a new Python object. + +

    Class + to_python_value synopsis

    +
    +namespace boost { namespace python
    +{
    +   template <class T>
    +   struct to_python_value
    +   {
    +      typedef typename add_reference<
    +         typename add_const<T>::type
    +      >::type argument_type;
    +
    +      static bool convertible();
    +      PyObject* operator()(argument_type) const;
    +   };
    +}}
    +
    + +

    Class + to_python_value observers

    +
    +static bool convertible();
    +
    + +
    +
    Returns: true iff a converter has been registered which can convert T to python by-value. +
    + +
    +PyObject* operator()(argument_type x) const;
    +
    + +
    +
    Requires: convertible() == true +
    Effects: converts x to python +
    Returns: the resulting Python object iff a converter for T has been registered, 0 otherwise. +
    + +

    Revised + + 15 February, 2002 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + From f5a0b2fed8e98e1736ec013b9bafab5de1535edc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 28 May 2002 23:47:38 +0000 Subject: [PATCH 0486/1042] Bug fix, thanks to Pearu Pearson for pointing it out! [SVN r14055] --- include/boost/python/object/value_holder.hpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 3543d61b..e722d6b6 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -91,16 +91,14 @@ void* value_holder_back_reference::holds( type_info dst_t) { type_info src_t = python::type_id(); - if (src_t == dst_t) - { - Held* x = &m_held; + Held* x = &m_held; + + if (dst_t == src_t) return x; - } - - src_t = python::type_id(); - return src_t == dst_t - ? &m_held - : find_static_type(&m_held, src_t, dst_t); + else if (dst_t == python::type_id()) + return &m_held; + else + return find_static_type(x, src_t, dst_t); } }}} // namespace boost::python::objects From 033a3dd620c8aa83fbc86f19b9e407595af46a43 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 29 May 2002 12:59:39 +0000 Subject: [PATCH 0487/1042] doc updates [SVN r14056] --- doc/v2/instance_holder.html | 14 +- doc/v2/lvalue_from_python.html | 279 ---------------------- doc/v2/ptr.html | 8 +- doc/v2/reference.html | 33 +-- doc/v2/with_custodian_and_ward.html | 31 ++- include/boost/python/type_from_python.hpp | 104 -------- 6 files changed, 33 insertions(+), 436 deletions(-) delete mode 100644 doc/v2/lvalue_from_python.html delete mode 100644 include/boost/python/type_from_python.hpp diff --git a/doc/v2/instance_holder.html b/doc/v2/instance_holder.html index 5f5a751a..db524825 100755 --- a/doc/v2/instance_holder.html +++ b/doc/v2/instance_holder.html @@ -45,13 +45,13 @@

    Class instance_holder synopsis -
    Class +
    Class instance_holder destructor -
    Class +
    Class instance_holder modifier functions -
    Class +
    Class instance_holder observer functions @@ -112,7 +112,7 @@ namespace boost { namespace python }} -

    Class instance_holder +

    Class instance_holder destructor

     virtual ~instance_holder();
    @@ -122,7 +122,7 @@ virtual ~instance_holder();
           
    Effects: destroys the object -

    Class +

    Class instance_holder modifiers

     void install(PyObject* inst) throw();
    @@ -137,7 +137,7 @@ void install(PyObject* inst) throw();
           
    Throws: nothing -

    Class instance_holder +

    Class instance_holder observers

     virtual void* holds(type_info x) = 0;
    @@ -199,7 +199,7 @@ struct pointer_holder : instance_holder
     
         

    Revised - 19 November, 2002 + 29 May, 2002 diff --git a/doc/v2/lvalue_from_python.html b/doc/v2/lvalue_from_python.html deleted file mode 100644 index a0591128..00000000 --- a/doc/v2/lvalue_from_python.html +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - Boost.Python - <boost/python/lvalue_from_python.hpp> - - - -
    -

    -

    - -
    -

    Boost.Python

    - -

    Header <boost/python/lvalue_from_python.hpp>

    -
    -


    - -

    Contents

    - -
    -
    Introduction - - -
    Classes - -
    -
    -
    Class Template lvalue_from_python - -
    -
    - -
    Class Template - lvalue_from_python synopsis - -
    Class Template - lvalue_from_python constructor -
    -
    - -
    -
    Class Template get_member - -
    -
    - -
    Class Template - get_member synopsis - -
    Class Template - get_member static functions -
    -
    - -
    Example -
    -
    - -

    Introduction

    - - <boost/python/lvalue_from_python.hpp> supplies - a facility for extracting C++ objects from within instances of a - given Python type. This is typically useful for dealing with - "traditional" Python extension types. - -

    Classes

    - -

    Class template lvalue_from_python

    - -

    Class template lvalue_from_python will register - from_python converters which extract a references and pointers to - a C++ type which is held within an object of a given Python - type. Its template arguments are: - -

    - - - - - - - - - -
    - lvalue_from_python Requirements
    - - In the table below, x denotes an object of type PythonObject& - -
    Parameter - - Requirements - - Description - - Default - -
    python_type - - A compile-time constant PyTypeObject* - - The Python type of instances convertible by this - converter. Python subtypes are also convertible. - -
    Value - - A non-reference type. - - The C++ type to be extracted - -
    PythonObject - - initial sizeof(PyObject) bytes are - layout-compatible with PyObject. - - The C++ type used to hold Python instances of - python_type. - - Value - -
    Extract - - Value& v = Extract::execute(x); - - A type whose static execute function extracts a Value reference from within an object of type PythonObject. - - An unspecified type whose execute function consists of return x; -
    - - If only the first two template arguments are supplied, these - converters extract the entire PythonObject as a - whole. - -

    - - If the lifetime of the lvalue_from_python object ends - before the last attempt to convert to one its target types, the - behavior is undefined. The easiest way to ensure correct behavior - is to declare an lvalue_from_python instance as a - static local in a module init - function, as shown in the example - below. - -

    Class template lvalue_from_python synopsis

    -
    -namespace boost { namespace python
    -{
    -   template <
    -      PyTypeObject const* python_type
    -      , class Value
    -      , class PythonObject = Value
    -      , class Extract = unspecified
    -      >
    -   class lvalue_from_python
    -   {
    -      lvalue_from_python();
    -   };
    -}}
    -
    - -

    Class template lvalue_from_python constructor

    -
    -lvalue_from_python();
    -
    - -
    - -
    Effects: Registers from_python converters which - extract - Value&, Value const&, - Value*, or Value const* from Python - objects of type python_type using - Extract::execute(). - -
    - -

    Class template get_member

    - -

    get_member can be used with - lvalue_from_python in the common case where the C++ - type to be extracted is a member of the Python object. - -

    Class template get_member synopsis

    -
    -namespace boost { namespace python
    -{
    -  template <class Class, class Member, Member (Class::*mp)>
    -  struct get_member
    -  {
    -     static Member& execute(Class& c);
    -  };
    -}}
    -
    - -

    Class template get_member static functions

    -
    -Member& execute(Class& c);
    -
    - -
    - -
    Returns: c.*mp - -
    - - -

    Example

    - -This example presumes that someone has implemented the standard noddy -example module from the Python documentation, and we want to build -a module which manipulates Noddys. Since -noddy_NoddyObject is so simple that it carries no -interesting information, the example is a bit contrived: it assumes -you want to keep track of one particular object for some reason. - -

    C++ module definition

    - -
    -#include <boost/python/reference.hpp>
    -#include <boost/python/module.hpp>
    -
    -// definition lifted from the Python docs
    -typedef struct {
    -   PyObject_HEAD
    -} noddy_NoddyObject;
    -
    -using namespace boost::python;
    -static ref cache;
    -
    -bool is_cached(noddy_NoddyObject* x)
    -{
    -   return x == cache.get();
    -}
    -
    -void set_cache(noddy_NoddyObject* x)
    -{
    -   cache.reset((PyObject*)x, ref::increment_count);
    -}
    -
    -BOOST_PYTHON_MODULE_INIT(noddy_cache)
    -{
    -   module noddy_cache("noddy_cache")
    -      .def("is_cached", is_cached)
    -      .def("set_cache", set_cache)
    -      ;
    -}
    -
    - -

    Python code

    - -
    ->>> import noddy
    ->>> n = noddy.new_noddy()
    ->>> import noddy_cache
    ->>> noddy_cache.is_cached(n)
    -0
    ->>> noddy_cache.set_cache(n)
    ->>> noddy_cache.is_cached(n)
    -1
    ->>> noddy_cache.is_cached(noddy.new_noddy())
    -0
    -
    - -

    Revised - - 05 November, 2001 - - - -

    © Copyright Dave - Abrahams 2002. All Rights Reserved. - diff --git a/doc/v2/ptr.html b/doc/v2/ptr.html index 3b68451b..71cc6975 100644 --- a/doc/v2/ptr.html +++ b/doc/v2/ptr.html @@ -93,11 +93,11 @@ which can be similarly used to prevent copying of referents.

    ptr(p) returns an instance of pointer_wrapper<>, which + href="#pointer_wrapper-spec">pointer_wrapper<>, which can be detected using the is_pointer_wrapper<> + href="#is_pointer_wrapper-spec">is_pointer_wrapper<> metafunction; unwrap_pointer<> is a + href="#unwrap_pointer-spec">unwrap_pointer<> is a metafunction which extracts the original pointer type from a pointer_wrapper<>. These classes can be thought of as implementation details. @@ -252,7 +252,7 @@ void pass_as_arg(expensive_to_copy* x, PyObject* f)

    Revised - 07 May, 2002 + 29 May, 2002 diff --git a/doc/v2/reference.html b/doc/v2/reference.html index c36afe20..8bd19545 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -497,37 +497,6 @@ -

    type_from_python.hpp - -
    -
    -
    Classes - -
    -
    -
    type_from_python - -
    identity_extractor - -
    member_extractor -
    -
    - -
    value_from_python.hpp - -
    -
    -
    Classes - -
    -
    -
    value_from_python -
    -

    Utility and Infrastructure

    @@ -615,7 +584,7 @@

    Revised - 05 November, 2002 + 29 May, 2002 diff --git a/doc/v2/with_custodian_and_ward.html b/doc/v2/with_custodian_and_ward.html index ebcbcaa0..ae816063 100644 --- a/doc/v2/with_custodian_and_ward.html +++ b/doc/v2/with_custodian_and_ward.html @@ -26,11 +26,11 @@

    Classes -
    -
    -
    Class Template with_custodian_and_ward +
    + +
    Class Template with_custodian_and_ward
    @@ -40,6 +40,17 @@
    Class with_custodian_and_ward static functions
    + +
    Class Template with_custodian_and_ward_postcall +
    +
    + +
    Class Template + with_custodian_and_ward_postcall synopsis + +
    Class + with_custodian_and_ward_postcall static functions +
    @@ -141,8 +152,8 @@ namespace boost { namespace python }}
    -

    Class - default_call_policies static functions

    +

    Class + with_custodian_and_ward static functions

     bool precall(PyObject* args);
    @@ -229,8 +240,8 @@ namespace boost { namespace python
     }}
     
    -

    Class - default_call_policies static functions

    +

    Class + with_custodian_and_ward_postcall static functions

     PyObject* postcall(PyObject* args, PyObject* result);
    @@ -260,9 +271,9 @@ to implement return_internal_reference
     
     
    -template 
    +template <std::size_t owner_arg = 1, class Base = default_call_policies>
     struct return_internal_reference
    -    : with_custodian_and_ward_postcall<0, owner_arg, Base>
    +    : with_custodian_and_ward_postcall<0, owner_arg, Base>
     {
        typedef reference_existing_object result_converter;
     };
    @@ -270,7 +281,7 @@ struct return_internal_reference
     
         

    Revised - 19 February, 2002 + 29 May, 2002

    © Copyright Dave diff --git a/include/boost/python/type_from_python.hpp b/include/boost/python/type_from_python.hpp deleted file mode 100644 index 9fcd1f8f..00000000 --- a/include/boost/python/type_from_python.hpp +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TYPE_FROM_PYTHON_DWA2002130_HPP -# define TYPE_FROM_PYTHON_DWA2002130_HPP - -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - // Given a pointer-to-function of 1 parameter returning a reference - // type, return the type_id of the function's return type. - template - inline type_info extractor_type_id(T&(*)(U)) - { - return type_id(); - } - - // A function generator whose static execute() function is an lvalue - // from_python converter using the given Extractor. U is expected to - // be the actual type of the PyObject instance from which the result - // is being extracted. - template - struct normalized_extractor - { - static inline void* execute(PyObject* op) - { - typedef typename boost::add_reference::type param; - return &Extractor::execute( - boost::python::detail::void_ptr_to_reference( - op, (param(*)())0 ) - ); - } - }; - - // Given an Extractor type and a pointer to its execute function, - // return a new object whose static execute function does the same - // job but is a conforming lvalue from_python conversion function. - // - // usage: normalize(&Extractor::execute) - template - inline normalized_extractor - normalize(T(*)(U), Extractor* = 0) - { - return normalized_extractor(); - } -} - -// An Extractor which extracts the given member from a Python object -// whose instances are stored as InstanceType. -template -struct member_extractor -{ - static MemberType& execute(InstanceType& c) - { - (void)c.ob_type; // static assertion - return c.*member; - } -}; - -// An Extractor which simply extracts the entire python object -// instance of InstanceType. -template -struct identity_extractor -{ - static InstanceType& execute(InstanceType& c) - { - (void)c.ob_type; // static assertion - return c; - } -}; - -// Registers a from_python conversion which extracts lvalues using -// Extractor's static execute function from Python objects whose type -// object is python_type. -template -struct type_from_python -{ - type_from_python() - { - converter::registry::insert( - &extract, detail::extractor_type_id(&Extractor::execute)); - } - - static void* extract(PyObject* op) - { - return PyObject_TypeCheck(op, const_cast(python_type)) - ? const_cast( - static_cast( - detail::normalize(&Extractor::execute).execute(op))) - : 0 - ; - } -}; - -}} // namespace boost::python - -#endif // TYPE_FROM_PYTHON_DWA2002130_HPP From c7d16fbf9ea10558e65017a38cbcc9f15493194d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 29 May 2002 13:02:14 +0000 Subject: [PATCH 0488/1042] Pearu's test [SVN r14057] --- test/Jamfile | 1 + test/cltree.cpp | 85 +++++++++++++++++++++++++++++++++++++++++++++ test/test_cltree.py | 40 +++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100755 test/cltree.cpp create mode 100644 test/test_cltree.py diff --git a/test/Jamfile b/test/Jamfile index f5421f9b..80c7a916 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -52,6 +52,7 @@ rule bpl-test ( name ? : files * ) } bpl-test minimal ; +bpl-test pearu1 : test_cltree.py cltree.cpp ; bpl-test try : newtest.py m1.cpp m2.cpp ; bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ; bpl-test test_pointer_adoption ; diff --git a/test/cltree.cpp b/test/cltree.cpp new file mode 100755 index 00000000..a17fd659 --- /dev/null +++ b/test/cltree.cpp @@ -0,0 +1,85 @@ +#include +#include +#include + +/* Non-modifiable definitions */ + +class basic { +public: + basic() { name = "cltree.basic"; } + std::string repr() { return name+"()"; } +protected: + std::string name; +}; + +class constant: public basic { +public: + constant() { name = "cltree.constant"; } +}; + +class symbol: public basic { +public: + symbol() { name = "cltree.symbol"; } +}; + +class variable: public basic { +public: + variable() { name = "cltree.variable"; } +}; + +/* EOF: Non-modifiable definitions */ + +class symbol_wrapper: public symbol { +public: + symbol_wrapper(PyObject* self): symbol() { + name = "cltree.wrapped_symbol"; + } +}; + +class variable_wrapper: public variable { +public: + variable_wrapper(PyObject* self): variable() { + name = "cltree.wrapped_variable"; + } + + // This constructor is introduced only because cannot use + // boost::noncopyable, see below. + variable_wrapper(PyObject* self,variable v): variable(v) {} + +}; + +BOOST_PYTHON_MODULE_INIT(cltree) { + + boost::python::module m("cltree"); + m + .add( + boost::python::class_("basic") + .def_init(boost::python::args<>()) + .def("__repr__",&basic::repr) + ) + ; + + m + .add(boost::python::class_ + ,boost::noncopyable + >("constant") + .def_init(boost::python::args<>()) + ) + + .add(boost::python::class_("symbol") + .def_init(boost::python::args<>()) + ) + + .add(boost::python::class_ + ,variable_wrapper + //,boost::noncopyable // leads to compiler failure?! + >("variable") + .def_init(boost::python::args<>()) + ) + ; +} diff --git a/test/test_cltree.py b/test/test_cltree.py new file mode 100644 index 00000000..8408f7f2 --- /dev/null +++ b/test/test_cltree.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python + +from cltree import basic,symbol,constant,variable + +b = basic() +c = constant() +s = symbol() +v = variable() + +assert isinstance(b,basic) +assert not isinstance(b,symbol) +assert not isinstance(b,constant) +assert not isinstance(b,variable) + +assert isinstance(c,basic) +assert isinstance(c,constant) +assert not isinstance(c,symbol) +assert not isinstance(c,variable) + +assert not isinstance(s,basic) +assert isinstance(s,symbol) +assert not isinstance(s,constant) +assert not isinstance(s,variable) + +assert isinstance(v,basic) +assert not isinstance(v,symbol) +assert not isinstance(v,constant) +assert isinstance(v,variable) + +print 'b=',b +assert repr(b)=='cltree.basic()' +print 's=',s +assert repr(s)!='cltree.wrapped_symbol()' # because not isinstance(s,basic) +print 'c=',c +assert repr(c)=='cltree.constant()' +print 'v=',v +assert repr(v)=='cltree.wrapped_variable()' + + +print 'ok' From 23bfb84e38a65a720d37d29cebc7c417c76ce233 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 29 May 2002 20:32:49 +0000 Subject: [PATCH 0489/1042] Finally, it works on AIX! [SVN r14061] --- Jamfile | 9 ++ .../boost/python/detail/aix_init_module.hpp | 24 +++ include/boost/python/detail/config.hpp | 8 - include/boost/python/detail/module_init.hpp | 50 +++++++ include/boost/python/module.hpp | 1 + include/boost/python/module_builder.hpp | 1 + include/boost/python/type_id.hpp | 26 +++- src/aix_init_module.cpp | 140 ++++++++++++++++++ src/converter/registry.cpp | 12 +- 9 files changed, 258 insertions(+), 13 deletions(-) create mode 100644 include/boost/python/detail/aix_init_module.hpp create mode 100644 include/boost/python/detail/module_init.hpp create mode 100644 src/aix_init_module.cpp diff --git a/Jamfile b/Jamfile index 73a0a047..19b269b0 100644 --- a/Jamfile +++ b/Jamfile @@ -4,8 +4,16 @@ subproject libs/python ; SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; +local bpl-ldflags ; + +if $(UNIX) && ( $(OS) = AIX ) +{ + bpl-linkflags = "-e initlibbpl" ; +} + dll bpl : + src/aix_init_module.cpp src/converter/from_python.cpp src/converter/registry.cpp src/converter/type_id.cpp @@ -22,4 +30,5 @@ dll bpl : $(BOOST_PYTHON_V2_PROPERTIES) BOOST_PYTHON_SOURCE + $(bpl-linkflags) ; diff --git a/include/boost/python/detail/aix_init_module.hpp b/include/boost/python/detail/aix_init_module.hpp new file mode 100644 index 00000000..e73210d5 --- /dev/null +++ b/include/boost/python/detail/aix_init_module.hpp @@ -0,0 +1,24 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef AIX_INIT_MODULE_DWA2002529_HPP +# define AIX_INIT_MODULE_DWA2002529_HPP +# ifdef _AIX +# include +# include + +namespace boost { namespace python { namespace detail { + +extern "C" +{ + typedef PyObject* (*so_load_function)(char*,char*,FILE*); +} + +void aix_init_module(so_load_function, void (*init_module)()); + +}}} // namespace boost::python::detail +# endif + +#endif // AIX_INIT_MODULE_DWA2002529_HPP diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index cd0377b5..1867b4f3 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -62,14 +62,6 @@ # define BOOST_CSTD_ std # endif -# ifndef BOOST_PYTHON_MODULE_INIT -# if defined(_WIN32) || defined(__CYGWIN__) -# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" __declspec(dllexport) void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name() -# else -# define BOOST_PYTHON_MODULE_INIT(name) void init_module_##name(); extern "C" void init##name() { boost::python::handle_exception(&init_module_##name); } void init_module_##name() -# endif -# endif - /***************************************************************************** * * Set up dll import/export options: diff --git a/include/boost/python/detail/module_init.hpp b/include/boost/python/detail/module_init.hpp new file mode 100644 index 00000000..5b5ce9f5 --- /dev/null +++ b/include/boost/python/detail/module_init.hpp @@ -0,0 +1,50 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MODULE_INIT_DWA2002529_HPP +# define MODULE_INIT_DWA2002529_HPP + +# ifndef BOOST_PYTHON_MODULE_INIT + +# if defined(_WIN32) || defined(__CYGWIN__) + +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" __declspec(dllexport) void init##name() \ +{ \ + boost::python::handle_exception(&init_module_##name); \ +} \ +void init_module_##name() + +# elif defined(_AIX) + +# include +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" \ +{ \ + extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \ + void init##name() \ + { \ + boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_##name); \ + } \ +} \ +void init_module_##name() + +# else + +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" void init##name() \ +{ \ + boost::python::handle_exception(&init_module_##name); \ +} \ +void init_module_##name() + +# endif + +# endif + +#endif // MODULE_INIT_DWA2002529_HPP diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 7df183d5..c05d1032 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -12,6 +12,7 @@ # include # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/module_builder.hpp b/include/boost/python/module_builder.hpp index 180a6200..222b28d7 100644 --- a/include/boost/python/module_builder.hpp +++ b/include/boost/python/module_builder.hpp @@ -13,6 +13,7 @@ # include # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/type_id.hpp b/include/boost/python/type_id.hpp index fbceec66..3573239c 100755 --- a/include/boost/python/type_id.hpp +++ b/include/boost/python/type_id.hpp @@ -10,13 +10,16 @@ # include # include # include +# include +# include +# include namespace boost { namespace python { // for this compiler at least, cross-shared-library type_info // comparisons don't work, so use typeid(x).name() instead. It's not // yet clear what the best default strategy is. -# if defined(__GNUC__) && __GNUC__ >= 3 +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(_AIX) # define BOOST_PYTHON_TYPE_ID_NAME # endif @@ -56,6 +59,27 @@ inline type_info type_id(boost::type* = 0) ); } +# if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ <= 245 +// KCC on this platform seems to mistakenly distinguish "int" from +// "signed int", etc., but only in typeid() expressions. However +// though int == signed int, the "signed" decoration is propagated +// down into template instantiations. Explicit specialization stops +// that from taking hold. + +# define BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(T) \ +template <> \ +inline type_info type_id(boost::type*) \ +{ \ + return type_info(typeid(T)); \ +} + +BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short) +BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int) +BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long) +# undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID +# endif + + inline type_info::type_info(std::type_info const& id) : m_base_type( # ifdef BOOST_PYTHON_TYPE_ID_NAME diff --git a/src/aix_init_module.cpp b/src/aix_init_module.cpp new file mode 100644 index 00000000..61422e6b --- /dev/null +++ b/src/aix_init_module.cpp @@ -0,0 +1,140 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifdef _AIX +#include +#include + +extern "C" +{ +#include +#include +} + +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +namespace +{ + extern "C" void initlibbpl() + { + static PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; + Py_InitModule("libbpl", initial_methods); + } + + struct find_and_open_file + { + FILE* fp; + std::string libpath; // -- search path + std::string filename; // -- filename to look for + std::string fullpath; // -- full path to file + + find_and_open_file( + const std::string& libpath_env + , const std::string& file); + }; + + find_and_open_file::find_and_open_file( + const std::string& libpath_env + , const std::string& file) + : fp(0) + { + char* value = std::getenv(libpath_env.c_str()); + + if(value == 0) + return; + + libpath = value; + + if (libpath == "") + return; + + std::string::size_type pos = 0, prev_pos = 0; + + // -- loop through all search paths looking for file + while((pos = libpath.find_first_of(":",pos)) != std::string::npos) + { + fullpath = libpath.substr(prev_pos,pos - prev_pos) + "/" + file; + if (::access(fullpath.c_str(), R_OK) == 0) + { + struct stat filestat; + ::stat(fullpath.c_str(), &filestat); + if (!S_ISDIR(filestat.st_mode)) + { + fp = std::fopen(fullpath.c_str(), "r"); + if (fp) + { + filename = file; + } + return; + } + } + prev_pos = ++pos; + } + + // -- mop up odd path + if (libpath.find_first_of(":", prev_pos) == std::string::npos) + { + fullpath = libpath.substr(prev_pos, libpath.size() - prev_pos) + "/" + file; + if (::access(fullpath.c_str(), R_OK) == 0) + { + struct stat filestat; + ::stat(fullpath.c_str(),&filestat); + if (!S_ISDIR(filestat.st_mode)) + { + fp = std::fopen(fullpath.c_str(), "r"); + filename = file; + } + } + } + } +} + +void aix_init_module( + so_load_function load_dynamic_module + , void (*init_module)()) +{ + static bool initialized; + if (!initialized) + { + char const* const name = "libbpl.so"; + find_and_open_file dynlib("LIBPATH", name); + if (dynlib.fp == 0) + { + fprintf(stderr, " Error: could not find %s\n", name); + return; + } + + std::string::size_type pos = pos = dynlib.filename.find_first_of(".so",0); + if (pos == std::string::npos) + { + fprintf(stderr, "dynamic library %s must end with .so\n", dynlib.filename.c_str()); + return; + } + + PyObject* m = + load_dynamic_module( + const_cast(dynlib.filename.substr(0,pos).c_str()), + const_cast(dynlib.fullpath.c_str()), + dynlib.fp); + + if (m == 0) + { + fprintf(stderr, "failed to load library %s\n", name); + return; + } + Py_DECREF(m); + + initialized = true; + } + python::handle_exception(init_module); +} + +}}} // namespace boost::python +#endif diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index 3e0afdc2..d1ba57df 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -35,8 +35,8 @@ namespace // registry_t& entries() { static registry_t registry; - -#ifdef BOOST_PYTHON_DYNAMIC_LIB // this conditional should go away eventually. + +# ifdef BOOST_PYTHON_DYNAMIC_LIB // this conditional should go away eventually. static bool builtin_converters_initialized = false; if (!builtin_converters_initialized) { @@ -46,13 +46,17 @@ namespace // initialize_builtin_converters(); } -#endif +# endif return registry; } entry* find(type_info type) { - return &entries()[type]; + registry_t& assoc = entries(); + registry_t::iterator p = assoc.find(type); + return p != assoc.end() + ? &p->second + : &assoc[type]; } entry::entry() From fedf8d993559259a5766b157ca96fb66eb066127 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 29 May 2002 21:24:25 +0000 Subject: [PATCH 0490/1042] Apply Martin's KCC bug workaround [SVN r14062] --- test/data_members.cpp | 5 +++++ test/minimal.cpp | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/test/data_members.cpp b/test/data_members.cpp index 4657fe6d..e4eacf17 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -7,6 +7,11 @@ #include #include "test_class.hpp" +#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 +# include // works around a KCC intermediate code generation bug +#endif + + using namespace boost::python; typedef test_class<> X; diff --git a/test/minimal.cpp b/test/minimal.cpp index 07bbb394..d76922bf 100644 --- a/test/minimal.cpp +++ b/test/minimal.cpp @@ -5,6 +5,10 @@ // to its suitability for any purpose. #include +#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 +# include // works around a KCC intermediate code generation bug +#endif + BOOST_PYTHON_MODULE_INIT(minimal_ext) { boost::python::module m("minimal_ext"); From 97c87d0a99292026b00115f694084e2b7813c0bb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 2 Jun 2002 05:35:30 +0000 Subject: [PATCH 0491/1042] fixed #include guard [SVN r14065] --- include/boost/python/ptr.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/python/ptr.hpp b/include/boost/python/ptr.hpp index 4e0f067e..dfbb2153 100644 --- a/include/boost/python/ptr.hpp +++ b/include/boost/python/ptr.hpp @@ -1,5 +1,5 @@ -#ifndef BOOST_PTR_HPP_INCLUDED -# define BOOST_PTR_HPP_INCLUDED +#ifndef PTR_DWA20020601_HPP +# define PTR_DWA20020601_HPP // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided @@ -124,4 +124,4 @@ class unwrap_pointer }} // namespace boost::python -#endif // #ifndef BOOST_PTR_HPP_INCLUDED +#endif // #ifndef PTR_DWA20020601_HPP From a67b29a576eaffe4c7336b55a7a31c73ff1941b1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 2 Jun 2002 05:39:41 +0000 Subject: [PATCH 0492/1042] Flotsam removal; in theory this works around some Sun incompatibility also. See http://mail.python.org/pipermail/c++-sig/2002-May/001193.html [SVN r14066] --- include/boost/python/detail/config.hpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 1867b4f3..2a9ec35e 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -13,7 +13,6 @@ # define CONFIG_DWA052200_H_ # include -# include # ifdef BOOST_NO_OPERATORS_IN_NAMESPACE // A gcc bug forces some symbols into the global namespace @@ -41,18 +40,6 @@ # endif - -// Work around the broken library implementation/strict ansi checking on some -// EDG-based compilers (e.g. alpha), which incorrectly warn that the result of -// offsetof() is not an integer constant expression. -# if defined(__DECCXX_VER) && __DECCXX_VER <= 60290024 -# define BOOST_OFFSETOF(s_name, s_member) \ - ((size_t)__INTADDR__(&(((s_name *)0)->s_member))) -# else -# define BOOST_OFFSETOF(s_name, s_member) \ - offsetof(s_name, s_member) -# endif - // The STLport puts all of the standard 'C' library names in std (as far as the // user is concerned), but without it you need a fix if you're using MSVC or // Intel C++ From 97afc4bd0c73d82f0cf4ec6b146964f3383ac612 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 2 Jun 2002 05:44:06 +0000 Subject: [PATCH 0493/1042] operator support [SVN r14068] --- include/boost/python/class.hpp | 16 + .../python/converter/builtin_converters.hpp | 58 ++-- .../converter/callback_to_python_base.hpp | 10 +- include/boost/python/detail/msvc_typeinfo.hpp | 4 +- include/boost/python/detail/operator_id.hpp | 54 ++++ include/boost/python/operators2.hpp | 284 ++++++++++++++++++ include/boost/python/other.hpp | 113 +++++++ include/boost/python/self.hpp | 36 +++ src/object/class.cpp | 8 + src/object/function.cpp | 81 ++++- test/Jamfile | 1 + test/operators.cpp | 56 ++++ test/operators.py | 75 +++++ 13 files changed, 759 insertions(+), 37 deletions(-) create mode 100755 include/boost/python/detail/operator_id.hpp create mode 100755 include/boost/python/operators2.hpp create mode 100755 include/boost/python/other.hpp create mode 100755 include/boost/python/self.hpp create mode 100755 test/operators.cpp create mode 100644 test/operators.py diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 50afba85..51fef4fa 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -24,6 +24,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -37,6 +38,9 @@ namespace detail template struct has_noncopyable; + template + struct operator_; + // Register a to_python converter for a class T, depending on the // type of the first (tag) argument. The 2nd argument is a pointer // to the type of holder that must be created. The 3rd argument is a @@ -117,6 +121,18 @@ class class_ : public objects::class_base return *this; } + + template + self& def(detail::operator_ const& op) + { + typedef detail::operator_ op_t; + // Use function::add_to_namespace to achieve overloading if + // appropriate. + objects::function::add_to_namespace( + this->object(), op.name(), + ref(detail::wrap_function(&op_t::template apply::execute))); + return *this; + } // Define the constructor with the given Args, which should be an // MPL sequence of types. diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index c0d2ba09..c9c3142e 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -8,6 +8,7 @@ # include # include # include +# include # include # include @@ -33,40 +34,37 @@ namespace converter BOOST_PYTHON_DECL PyObject* do_callback_to_python(PyObject*); } -# define BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(T, expr) \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ - }; \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ +# define BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(T, expr) \ + template <> struct to_python_value \ + : detail::builtin_to_python \ + { \ + PyObject* operator()(T const& x) const \ + { \ + return (expr); \ + } \ + }; \ + template <> struct to_python_value \ + : detail::builtin_to_python \ + { \ + PyObject* operator()(T const& x) const \ + { \ + return (expr); \ + } \ }; -# define BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(T, expr) \ - namespace converter \ - { \ - template <> struct callback_to_python< T > \ - { \ - callback_to_python(T const& x) \ - : m_held(expr) {} \ - PyObject* get() const \ - { return m_held.get(); } \ - private: \ - ref m_held; \ - }; \ +# define BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(T, expr) \ + namespace converter \ + { \ + template <> struct callback_to_python< T > \ + : detail::callback_to_python_holder \ + { \ + callback_to_python(T const& x) \ + : detail::callback_to_python_holder(expr) {} \ + }; \ } -# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ - BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(T,expr) \ +# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ + BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(T,expr) \ BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(T,expr) # define BOOST_PYTHON_TO_INT(T) \ diff --git a/include/boost/python/converter/callback_to_python_base.hpp b/include/boost/python/converter/callback_to_python_base.hpp index c878850e..d03f2f60 100644 --- a/include/boost/python/converter/callback_to_python_base.hpp +++ b/include/boost/python/converter/callback_to_python_base.hpp @@ -16,7 +16,8 @@ namespace detail struct callback_to_python_holder { callback_to_python_holder(PyObject* obj); - inline PyObject* get() const; + PyObject* get() const; + PyObject* get_incref() const; private: ref m_held; }; @@ -38,6 +39,13 @@ namespace detail { return m_held.get(); } + + inline PyObject* callback_to_python_holder::get_incref() const + { + PyObject* result = m_held.get(); + Py_XINCREF(result); + return result; + } } }}} // namespace boost::python::converter diff --git a/include/boost/python/detail/msvc_typeinfo.hpp b/include/boost/python/detail/msvc_typeinfo.hpp index 3da411f0..21e47389 100644 --- a/include/boost/python/detail/msvc_typeinfo.hpp +++ b/include/boost/python/detail/msvc_typeinfo.hpp @@ -57,8 +57,8 @@ template struct bool_t{}; template inline typeinfo typeid_nonref(boost::type* = 0) { - BOOST_STATIC_CONSTANT(bool, c = is_const::value); - BOOST_STATIC_CONSTANT(bool, v = is_volatile::value); + bool const c = is_const::value; + bool const v = is_volatile::value; return value_id_accessor<(2 * v + c)>::get((T*)0); } diff --git a/include/boost/python/detail/operator_id.hpp b/include/boost/python/detail/operator_id.hpp new file mode 100755 index 00000000..9005c7ae --- /dev/null +++ b/include/boost/python/detail/operator_id.hpp @@ -0,0 +1,54 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OPERATOR_ID_DWA2002531_HPP +# define OPERATOR_ID_DWA2002531_HPP + +namespace boost { namespace python { namespace detail { + +enum operator_id +{ + op_add, + op_sub, + op_mul, + op_div, + op_mod, + op_divmod, + op_pow, + op_lshift, + op_rshift, + op_and, + op_xor, + op_or, + op_neg, + op_pos, + op_abs, + op_invert, + op_int, + op_long, + op_float, + op_str, + op_cmp, + op_gt, + op_ge, + op_lt, + op_le, + op_eq, + op_ne, + op_iadd, + op_isub, + op_imul, + op_idiv, + op_imod, + op_ilshift, + op_irshift, + op_iand, + op_ixor, + op_ior +}; + +}}} // namespace boost::python::detail + +#endif // OPERATOR_ID_DWA2002531_HPP diff --git a/include/boost/python/operators2.hpp b/include/boost/python/operators2.hpp new file mode 100755 index 00000000..c4365b35 --- /dev/null +++ b/include/boost/python/operators2.hpp @@ -0,0 +1,284 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OPERATORS2_DWA2002530_HPP +# define OPERATORS2_DWA2002530_HPP + +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + // This is essentially the old v1 to_python(). It will be eliminated + // once the public interface for to_python is settled on. + template + PyObject* convert_result(T const& x) + { + return converter::callback_to_python(x).get_incref(); + } + + // Operator implementation template declarations. The nested apply + // declaration here keeps MSVC6 happy. + template struct operator_l + { + template struct apply; + }; + + template struct operator_r + { + template struct apply; + }; + + template struct operator_1 + { + template struct apply; + }; + + // MSVC6 doesn't want us to do this sort of inheritance on a nested + // class template, so we use this layer of indirection to avoid + // ::template<...> on the nested apply functions below + template + struct operator_l_inner + : operator_l::template apply + {}; + + template + struct operator_r_inner + : operator_r::template apply + {}; + + template + struct operator_1_inner + : operator_1::template apply + {}; + + // Define three different binary_op templates which take care of + // these cases: + // self op self + // self op R + // L op self + // + // The inner apply metafunction is used to adjust the operator to + // the class type being defined. Inheritance of the outer class is + // simply used to provide convenient access to the operation's + // name(). + + // self op self + template + struct binary_op : operator_l + { + template + struct apply : operator_l_inner + { + }; + }; + + // self op R + template + struct binary_op_l : operator_l + { + template + struct apply : operator_l_inner + { + }; + }; + + // L op self + template + struct binary_op_r : operator_r + { + template + struct apply : operator_r_inner + { + }; + }; + + template + struct unary_op : operator_1 + { + template + struct apply : operator_1_inner + { + }; + }; + + // This type is what actually gets returned from operators used on + // self_t + template + struct operator_ + : mpl::select_type< + (is_same::value) + , typename mpl::select_type< + (is_same::value) + , binary_op + , binary_op_l::type> + >::type + , typename mpl::select_type< + (is_same::value) + , unary_op + , binary_op_r::type> + >::type + >::type + { + }; +} + +# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \ +namespace detail \ +{ \ + template <> \ + struct operator_l \ + { \ + template \ + struct apply \ + { \ + static inline PyObject* execute(L const& l, R const& r) \ + { \ + return detail::convert_result(l op r); \ + } \ + }; \ + static char const* name() { return "__" #id "__"; } \ + }; \ + \ + template <> \ + struct operator_r \ + { \ + template \ + struct apply \ + { \ + static inline PyObject* execute(R const& r, L const& l) \ + { \ + return detail::convert_result(l op r); \ + } \ + }; \ + static char const* name() { return "__" #rid "__"; } \ + }; \ +} \ +namespace self_ns \ +{ \ + template \ + inline detail::operator_ \ + operator##op(L const&, R const&) \ + { \ + return detail::operator_(); \ + } \ +} + +BOOST_PYTHON_BINARY_OPERATOR(add, radd, +) +BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -) +BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *) +BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /) +BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %) +BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<) +BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>) +BOOST_PYTHON_BINARY_OPERATOR(and, rand, &) +BOOST_PYTHON_BINARY_OPERATOR(xor, rxor, ^) +BOOST_PYTHON_BINARY_OPERATOR(or, ror, |) +BOOST_PYTHON_BINARY_OPERATOR(gt, lt, >) +BOOST_PYTHON_BINARY_OPERATOR(ge, le, >=) +BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <) +BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=) +BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==) +BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=) + +# define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \ +namespace detail \ +{ \ + template <> \ + struct operator_l \ + { \ + template \ + struct apply \ + { \ + static inline PyObject* \ + execute(back_reference l, R const& r) \ + { \ + l.get() op r; \ + return l.reference().release(); \ + } \ + }; \ + static char const* name() { return "__" #id "__"; } \ + }; \ +} \ +namespace self_ns \ +{ \ + template \ + inline detail::operator_ \ + operator##op(self_t const&, R const&) \ + { \ + return detail::operator_(); \ + } \ +} + +BOOST_PYTHON_INPLACE_OPERATOR(iadd,+=) +BOOST_PYTHON_INPLACE_OPERATOR(isub,-=) +BOOST_PYTHON_INPLACE_OPERATOR(imul,*=) +BOOST_PYTHON_INPLACE_OPERATOR(idiv,/=) +BOOST_PYTHON_INPLACE_OPERATOR(imod,%=) +BOOST_PYTHON_INPLACE_OPERATOR(ilshift,<<=) +BOOST_PYTHON_INPLACE_OPERATOR(irshift,>>=) +BOOST_PYTHON_INPLACE_OPERATOR(iand,&=) +BOOST_PYTHON_INPLACE_OPERATOR(ixor,^=) +BOOST_PYTHON_INPLACE_OPERATOR(ior,|=) + +# define BOOST_PYTHON_UNARY_OPERATOR(id, op, func_name) \ +namespace detail \ +{ \ + template <> \ + struct operator_1 \ + { \ + template \ + struct apply \ + { \ + static PyObject* execute(T const& x) \ + { \ + return detail::convert_result(op(x)); \ + } \ + }; \ + static char const* name() { return "__" #id "__"; } \ + }; \ +} \ +namespace self_ns \ +{ \ + inline detail::operator_ \ + func_name(self_t const&) \ + { \ + return detail::operator_(); \ + } \ +} + +BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-) +BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+) +BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs) +BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~) +BOOST_PYTHON_UNARY_OPERATOR(int, long, int_) +BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_) +BOOST_PYTHON_UNARY_OPERATOR(float, double, float_) + +}} // namespace boost::python + +# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +using boost::python::self_ns::abs; +using boost::python::self_ns::int_; +using boost::python::self_ns::long_; +using boost::python::self_ns::float_; +# endif + +#endif // OPERATORS2_DWA2002530_HPP + + + + + + + + diff --git a/include/boost/python/other.hpp b/include/boost/python/other.hpp new file mode 100755 index 00000000..0142da34 --- /dev/null +++ b/include/boost/python/other.hpp @@ -0,0 +1,113 @@ +#ifndef OTHER_DWA20020601_HPP +# define OTHER_DWA20020601_HPP +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +# if _MSC_VER+0 >= 1020 +# pragma once +# endif + +# include + +namespace boost { namespace python { + +template struct other +{ + typedef T type; +}; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +namespace detail +{ + template + class is_other + { + public: + BOOST_STATIC_CONSTANT(bool, value = false); + }; + + template + class is_other > + { + public: + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template + class unwrap_other + { + public: + typedef T type; + }; + + template + class unwrap_other > + { + public: + typedef T type; + }; +} +# else // no partial specialization + +}} // namespace boost::python + +#include + +namespace boost { namespace python { + +namespace detail +{ + typedef char (&yes_other_t)[1]; + typedef char (&no_other_t)[2]; + + no_other_t is_other_test(...); + + template + yes_other_t is_other_test(type< other >); + + template + struct other_unwrapper + { + template + struct apply + { + typedef T type; + }; + }; + + template<> + struct other_unwrapper + { + template + struct apply + { + typedef typename T::type type; + }; + }; + + template + class is_other + { + public: + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof(detail::is_other_test(type())) + == sizeof(detail::yes_other_t))); + }; + + template + class unwrap_other + : public detail::other_unwrapper< + is_other::value + >::template apply + {}; +} + +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +}} // namespace boost::python + +#endif // #ifndef OTHER_DWA20020601_HPP diff --git a/include/boost/python/self.hpp b/include/boost/python/self.hpp new file mode 100755 index 00000000..c7d3f670 --- /dev/null +++ b/include/boost/python/self.hpp @@ -0,0 +1,36 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef SELF_DWA2002531_HPP +# define SELF_DWA2002531_HPP + +# include + +namespace boost { namespace python { + +//# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 +# define BOOST_PYTHON_SELF_IS_CLASS +//# endif + +// Sink self_t into its own namespace so that we have a safe place to +// put the completely general operator templates which operate on +// it. It is possible to avoid this, but it turns out to be much more +// complicated and finally GCC 2.95.2 chokes on it. +namespace self_ns +{ +# ifndef BOOST_PYTHON_SELF_IS_CLASS + enum self_t { self }; +# else + struct self_t {}; + extern BOOST_PYTHON_DECL self_t self; +# endif +} + +using self_ns::self_t; +using self_ns::self; + +}} // namespace boost::python + +#endif // SELF_DWA2002531_HPP diff --git a/src/object/class.cpp b/src/object/class.cpp index 85fcb7d7..ea0c332b 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -8,12 +8,20 @@ #include #include #include +#include #include #include #include namespace boost { namespace python { +# ifdef BOOST_PYTHON_SELF_IS_CLASS +namespace self_ns +{ + self_t self; +} +# endif + instance_holder::instance_holder() : m_next(0) { diff --git a/src/object/function.cpp b/src/object/function.cpp index a05d7e92..f4913fd8 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -8,6 +8,10 @@ #include #include #include +#include +#include +#include +#include namespace boost { namespace python { namespace objects { @@ -77,6 +81,67 @@ void function::add_overload(function* overload_) parent->m_overloads = overload_; } +namespace +{ + char const* const binary_operator_names[] = + { + "add__", + "and__", + "div__", + "eq__", + "ge__", + "gt__", + "le__", + "lshift__", + "lt__", + "mod__", + "mul__", + "ne__", + "or__", + "radd__", + "rand__", + "rdiv__", + "rlshift__", + "rmod__", + "rmul__", + "ror__", + "rrshift__", + "rshift__", + "rsub__", + "rxor__", + "sub__", + "xor__", + }; + + inline bool is_binary_operator(char const* name) + { + return name[0] == '_' + && name[1] == '_' + && std::binary_search( + &binary_operator_names[0] + , binary_operator_names + sizeof(binary_operator_names)/sizeof(*binary_operator_names) + , name + 2 + , bind(std::less(), + bind(BOOST_CSTD_::strcmp, _1, _2), 0) + ); + } + + // Something for the end of the chain of binary operators + PyObject* not_implemented_impl(PyObject*, PyObject*) + { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + function* not_implemented_function() + { + static function* result = new function(py_function(¬_implemented_impl), 2, 3); + static ref keeper(result); + + return result; + } +} + void function::add_to_namespace( ref const& name_space, char const* name_, ref const& attribute) { @@ -99,11 +164,19 @@ void function::add_to_namespace( ref existing(PyObject_GetItem(dict, name.get()), ref::null_ok); - if (existing.get() && existing->ob_type == &function_type) + if (existing.get()) { - static_cast(existing.get())->add_overload( - static_cast(attribute.get())); - return; + if (existing->ob_type == &function_type) + { + static_cast(attribute.get())->add_overload( + static_cast(existing.get())); + } + } + // Binary operators need an additional overload which returns NotImplemented + else if (is_binary_operator(name_)) + { + static_cast(attribute.get())->add_overload( + not_implemented_function()); } } diff --git a/test/Jamfile b/test/Jamfile index 80c7a916..794dff42 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -56,6 +56,7 @@ bpl-test pearu1 : test_cltree.py cltree.cpp ; bpl-test try : newtest.py m1.cpp m2.cpp ; bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ; bpl-test test_pointer_adoption ; +bpl-test operators ; bpl-test callbacks ; bpl-test virtual_functions ; bpl-test back_reference ; diff --git a/test/operators.cpp b/test/operators.cpp new file mode 100755 index 00000000..3a33990f --- /dev/null +++ b/test/operators.cpp @@ -0,0 +1,56 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include "test_class.hpp" + +using namespace boost::python; + +typedef test_class<> X; + +X operator-(X const& l, X const& r) { return X(l.value() - r.value()); } +X operator-(int l, X const& r) { return X(l - r.value()); } +X operator-(X const& l, int r) { return X(l.value() - r); } + +X operator-(X const& x) { return X(-x.value()); } + +X& operator-=(X& l, X const& r) { l.set(l.value() - r.value()); return l; } + +bool operator<(X const& x, X const& y) { return x.value() < y.value(); } +bool operator<(X const& x, int y) { return x.value() < y; } +bool operator<(int x, X const& y) { return x < y.value(); } + +X abs(X x) { return X(x.value() < 0 ? -x.value() : x.value()); } + +BOOST_PYTHON_MODULE_INIT(operators_ext) +{ + module("operators_ext") + .add( + class_("X") + .def_init(args()) + .def("value", &X::value) + .def(self - self) + .def(self - int()) + .def(other() - self) + .def(-self) + .def(self < other()) + .def(self < self) + .def(1 < self) + .def(self -= self) + .def(abs(self)) + ) + .add( + class_ >("Z") + .def_init(args()) + .def(int_(self)) + .def(float_(self)) + ) + ; +} + +#include "module_tail.cpp" diff --git a/test/operators.py b/test/operators.py new file mode 100644 index 00000000..951ac806 --- /dev/null +++ b/test/operators.py @@ -0,0 +1,75 @@ +''' +>>> from operators_ext import * +>>> x = X(42) +>>> x.value() +42 +>>> y = x - X(5) +>>> y.value() +37 +>>> y = x - 4 +>>> y.value() +38 +>>> y = 3 - x +>>> y.value() +-39 +>>> (-y).value() +39 + +>>> abs(y).value() +39 + +>>> x < 10 +0 +>>> x < 43 +1 + +>>> 10 < x +1 +>>> 43 < x +0 + +>>> x < y +0 +>>> y < x +1 + + ------ +>>> x > 10 +1 +>>> x > 43 +0 + +>>> 10 > x +0 +>>> 43 > x +1 + +>>> x > y +1 +>>> y > x +0 + +>>> y = x - 5 +>>> x -= y +>>> x.value() +5 + +>>> z = Z(10) +>>> int(z) +10 +>>> float(z) +10.0 +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From b042644c85b16a11d8a352168c169f83e3b52af1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 2 Jun 2002 12:01:35 +0000 Subject: [PATCH 0494/1042] bind() doesn't work on extern "C" functions [SVN r14069] --- src/object/function.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/object/function.cpp b/src/object/function.cpp index f4913fd8..021770b0 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -8,9 +8,7 @@ #include #include #include -#include #include -#include #include namespace boost { namespace python { namespace objects { @@ -113,6 +111,14 @@ namespace "xor__", }; + struct less_cstring + { + bool operator()(char const* x, char const* y) const + { + return BOOST_CSTD_::strcmp(x,y) < 0; + } + }; + inline bool is_binary_operator(char const* name) { return name[0] == '_' @@ -121,8 +127,7 @@ namespace &binary_operator_names[0] , binary_operator_names + sizeof(binary_operator_names)/sizeof(*binary_operator_names) , name + 2 - , bind(std::less(), - bind(BOOST_CSTD_::strcmp, _1, _2), 0) + , less_cstring() ); } From 92aae63af2995dd0f0cd16a44b461ddec4ca96e5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 2 Jun 2002 18:35:09 +0000 Subject: [PATCH 0495/1042] str(), pow(), complex() support [SVN r14070] --- include/boost/python/detail/operator_id.hpp | 3 +- include/boost/python/operators2.hpp | 57 +++++++++++++++++++-- src/object/function.cpp | 10 +++- test/operators.cpp | 35 +++++++++++++ test/operators.py | 11 ++++ 5 files changed, 110 insertions(+), 6 deletions(-) diff --git a/include/boost/python/detail/operator_id.hpp b/include/boost/python/detail/operator_id.hpp index 9005c7ae..0c28b2d4 100755 --- a/include/boost/python/detail/operator_id.hpp +++ b/include/boost/python/detail/operator_id.hpp @@ -46,7 +46,8 @@ enum operator_id op_irshift, op_iand, op_ixor, - op_ior + op_ior, + op_complex, }; }}} // namespace boost::python::detail diff --git a/include/boost/python/operators2.hpp b/include/boost/python/operators2.hpp index c4365b35..36d5e16b 100755 --- a/include/boost/python/operators2.hpp +++ b/include/boost/python/operators2.hpp @@ -13,6 +13,9 @@ # include # include # include +# include +# include +# include namespace boost { namespace python { @@ -132,7 +135,7 @@ namespace detail }; } -# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \ +# define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \ namespace detail \ { \ template <> \ @@ -143,7 +146,7 @@ namespace detail \ { \ static inline PyObject* execute(L const& l, R const& r) \ { \ - return detail::convert_result(l op r); \ + return detail::convert_result(expr); \ } \ }; \ static char const* name() { return "__" #id "__"; } \ @@ -157,12 +160,15 @@ namespace detail \ { \ static inline PyObject* execute(R const& r, L const& l) \ { \ - return detail::convert_result(l op r); \ + return detail::convert_result(expr); \ } \ }; \ static char const* name() { return "__" #rid "__"; } \ }; \ -} \ +} + +# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \ +BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \ namespace self_ns \ { \ template \ @@ -190,6 +196,44 @@ BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=) BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==) BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=) +// pow isn't an operator in C++; handle it specially. +BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r)) +namespace self_ns +{ +# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + template + inline detail::operator_ + pow(L const&, R const&) + { + return detail::operator_(); + } +# else + // When there's no argument-dependent lookup, we need these + // overloads to handle the case when everything is imported into the + // global namespace. Note that the plain overload below does /not/ + // take const& arguments. This is needed by MSVC6 at least, or it + // complains of ambiguities, since there's no partial ordering. + inline detail::operator_ + pow(self_t, self_t) + { + return detail::operator_(); + } + template + inline detail::operator_ + pow(self_t const&, R const&) + { + return detail::operator_(); + } + template + inline detail::operator_ + pow(L const&, self_t const&) + { + return detail::operator_(); + } +# endif +} + + # define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \ namespace detail \ { \ @@ -263,6 +307,8 @@ BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~) BOOST_PYTHON_UNARY_OPERATOR(int, long, int_) BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_) BOOST_PYTHON_UNARY_OPERATOR(float, double, float_) +BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex, complex_) +BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast, str) }} // namespace boost::python @@ -271,6 +317,9 @@ using boost::python::self_ns::abs; using boost::python::self_ns::int_; using boost::python::self_ns::long_; using boost::python::self_ns::float_; +using boost::python::self_ns::complex_; +using boost::python::self_ns::str; +using boost::python::self_ns::pow; # endif #endif // OPERATORS2_DWA2002530_HPP diff --git a/src/object/function.cpp b/src/object/function.cpp index 021770b0..0d89791c 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -86,7 +86,9 @@ namespace "add__", "and__", "div__", + "divmod__", "eq__", + "floordiv__", "ge__", "gt__", "le__", @@ -96,19 +98,25 @@ namespace "mul__", "ne__", "or__", + "pow__", "radd__", "rand__", "rdiv__", + "rdivmod__", + "rfloordiv__", "rlshift__", "rmod__", "rmul__", "ror__", + "rpow__", "rrshift__", "rshift__", "rsub__", + "rtruediv__", "rxor__", "sub__", - "xor__", + "truediv__", + "xor__" }; struct less_cstring diff --git a/test/operators.cpp b/test/operators.cpp index 3a33990f..8a0c57d1 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -8,6 +8,15 @@ #include #include #include "test_class.hpp" +#if __GNUC__ != 2 +# include +#else +# include +#endif + +// Just use math.h here; trying to use std::pow() causes too much +// trouble for non-conforming compilers and libraries. +#include using namespace boost::python; @@ -27,6 +36,26 @@ bool operator<(int x, X const& y) { return x < y.value(); } X abs(X x) { return X(x.value() < 0 ? -x.value() : x.value()); } +X pow(X x, int y) +{ + return X(int(pow(double(x.value()), y))); +} + +X pow(X x, X y) +{ + return X(int(pow(double(x.value()), y.value()))); +} + +int pow(int x, X y) +{ + return int(pow(double(x), y.value())); +} + +std::ostream& operator<<(std::ostream& s, X const& x) +{ + return s << x.value(); +} + BOOST_PYTHON_MODULE_INIT(operators_ext) { module("operators_ext") @@ -43,12 +72,18 @@ BOOST_PYTHON_MODULE_INIT(operators_ext) .def(1 < self) .def(self -= self) .def(abs(self)) + .def(str(self)) + + .def(pow(self,self)) + .def(pow(self,int())) + .def(pow(int(),self)) ) .add( class_ >("Z") .def_init(args()) .def(int_(self)) .def(float_(self)) + .def(complex_(self)) ) ; } diff --git a/test/operators.py b/test/operators.py index 951ac806..58ffb5eb 100644 --- a/test/operators.py +++ b/test/operators.py @@ -53,12 +53,23 @@ >>> x -= y >>> x.value() 5 +>>> str(x) +'5' >>> z = Z(10) >>> int(z) 10 >>> float(z) 10.0 +>>> complex(z) +(10+0j) + +>>> pow(2,x) +32 +>>> pow(x,2).value() +25 +>>> pow(X(2),x).value() +32 ''' def run(args = None): From 16c391c78cec656a9165de7d5a2fb18ce6ef68cc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 2 Jun 2002 19:09:03 +0000 Subject: [PATCH 0496/1042] enable operators.hpp for v2 eliminate dependence on full boost/function.hpp [SVN r14071] --- include/boost/python/errors.hpp | 2 +- include/boost/python/make_function.hpp | 1 - include/boost/python/object/function.hpp | 2 +- include/boost/python/operators.hpp | 48 +++++++++++++----------- test/operators.cpp | 2 +- 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp index fdf8e11a..5b138ce4 100644 --- a/include/boost/python/errors.hpp +++ b/include/boost/python/errors.hpp @@ -11,7 +11,7 @@ # include # include -# include +# include namespace boost { namespace python { diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index 47579fd5..7b2ba79d 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -11,7 +11,6 @@ # include # include # include -# include # include # include diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index d750ad80..37f86e7d 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -9,7 +9,7 @@ # include # include # include -# include +# include namespace boost { namespace python { namespace objects { diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp index 70e57b71..df401f85 100644 --- a/include/boost/python/operators.hpp +++ b/include/boost/python/operators.hpp @@ -11,23 +11,28 @@ // 23 Jan 2001 - Another stupid typo fix by Ralf W. Grosse-Kunstleve (David Abrahams) // 20 Jan 2001 - Added a fix from Ralf W. Grosse-Kunstleve (David Abrahams) #ifndef OPERATORS_UK112000_H_ -#define OPERATORS_UK112000_H_ +# define OPERATORS_UK112000_H_ +# ifdef BOOST_PYTHON_V2 -# include -# include +# include + +# else + +# include +# include // When STLport is used with native streams, _STL::ostringstream().str() is not // _STL::string, but std::string. This confuses to_python(), so we'll use // strstream instead. Also, GCC 2.95.2 doesn't have sstream. -# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) -# define BOOST_PYTHON_USE_SSTREAM -# endif +# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) +# define BOOST_PYTHON_USE_SSTREAM +# endif -#if defined(BOOST_PYTHON_USE_SSTREAM) -# include -# else -# include -# endif +# if defined(BOOST_PYTHON_USE_SSTREAM) +# include +# else +# include +# endif namespace boost { namespace python { @@ -234,7 +239,7 @@ namespace detail // Specializations for most operators follow a standard pattern: execute the expression // that uses the operator in question. This standard pattern is realized by the following // macros so that the actual specialization can be done by just calling a macro. -#define PY_DEFINE_BINARY_OPERATORS(id, oper) \ +# define PY_DEFINE_BINARY_OPERATORS(id, oper) \ template <> \ struct define_operator \ { \ @@ -275,7 +280,7 @@ namespace detail static const char * rname() { return "__r" #id "__"; } \ } -#define PY_DEFINE_UNARY_OPERATORS(id, oper) \ +# define PY_DEFINE_UNARY_OPERATORS(id, oper) \ template <> \ struct define_operator \ { \ @@ -322,8 +327,8 @@ namespace detail PY_DEFINE_UNARY_OPERATORS(long, PyLong_FromLong); PY_DEFINE_UNARY_OPERATORS(float, double); -#undef PY_DEFINE_BINARY_OPERATORS -#undef PY_DEFINE_UNARY_OPERATORS +# undef PY_DEFINE_BINARY_OPERATORS +# undef PY_DEFINE_UNARY_OPERATORS // Some operators need special treatment, e.g. because there is no corresponding // expression in C++. These are specialized manually. @@ -496,7 +501,7 @@ namespace detail static const char * rname() { return "__rcmp__"; } }; -# ifndef BOOST_PYTHON_USE_SSTREAM +# ifndef BOOST_PYTHON_USE_SSTREAM class unfreezer { public: unfreezer(std::ostrstream& s) : m_stream(s) {} @@ -504,7 +509,7 @@ namespace detail private: std::ostrstream& m_stream; }; -# endif +# endif // str(): Manual specialization needed because the string conversion does not follow // the standard pattern relized by the macros. @@ -520,16 +525,16 @@ namespace detail // When STLport is used with native streams, _STL::ostringstream().str() is not // _STL::string, but std::string. -# ifdef BOOST_PYTHON_USE_SSTREAM +# ifdef BOOST_PYTHON_USE_SSTREAM std::ostringstream s; s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()); return BOOST_PYTHON_CONVERSION::to_python(s.str()); -# else +# else std::ostrstream s; s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) << char(); auto unfreezer unfreeze(s); return BOOST_PYTHON_CONVERSION::to_python(const_cast(s.str())); -# endif +# endif } const char* description() const @@ -545,5 +550,6 @@ namespace detail }} // namespace boost::python -# undef BOOST_PYTHON_USE_SSTREAM +# undef BOOST_PYTHON_USE_SSTREAM +# endif #endif /* OPERATORS_UK112000_H_ */ diff --git a/test/operators.cpp b/test/operators.cpp index 8a0c57d1..336207f4 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -4,7 +4,7 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #include -#include +#include #include #include #include "test_class.hpp" From 7a832f1fdb625cf0fabfdb12df039720e7aa1de6 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 3 Jun 2002 18:35:59 +0000 Subject: [PATCH 0497/1042] automatic addition of __module__ to class dict [SVN r14072] --- include/boost/python/detail/module_base.hpp | 3 +++ include/boost/python/module.hpp | 3 +-- src/module.cpp | 11 +++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp index e8a00ba6..043a6f47 100644 --- a/include/boost/python/detail/module_base.hpp +++ b/include/boost/python/detail/module_base.hpp @@ -26,6 +26,9 @@ class BOOST_PYTHON_DECL module_base // Return a reference to the Python module object being built inline ref object() const; + protected: + void generic_add_class(ref class_obj); + private: ref m_module; static PyMethodDef initial_methods[1]; diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index c05d1032..41286ac2 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -31,8 +31,7 @@ class module : public detail::module_base template module& add(class_ const& c) { - Py_INCREF(c.object()); - this->add_type(c.object()); + this->generic_add_class(c.object()); return *this; } diff --git a/src/module.cpp b/src/module.cpp index 0291c9c1..5020170c 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -45,6 +45,17 @@ void module_base::add_type(ref x) add((PyTypeObject*)x.release()); } +void module_base::generic_add_class(ref class_obj) +{ + Py_INCREF(class_obj.get()); + this->add_type(class_obj); + ref module_name(PyObject_GetAttrString(m_module.get(), + const_cast("__name__"))); + int status = PyObject_SetAttrString(class_obj.get(), + const_cast("__module__"), module_name.get()); + if (status == -1) throw_error_already_set(); +} + PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; }}} // namespace boost::python::detail From 9a49d267ebac9c85b118e6e0415299c6198bcc16 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 3 Jun 2002 19:12:40 +0000 Subject: [PATCH 0498/1042] EDG 245: trailing comma is nonstandard [SVN r14073] --- include/boost/python/detail/operator_id.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/operator_id.hpp b/include/boost/python/detail/operator_id.hpp index 0c28b2d4..8edb310b 100755 --- a/include/boost/python/detail/operator_id.hpp +++ b/include/boost/python/detail/operator_id.hpp @@ -47,7 +47,7 @@ enum operator_id op_iand, op_ixor, op_ior, - op_complex, + op_complex }; }}} // namespace boost::python::detail From 1a0baef147f0d9e538ee6f1d9d9f0e83ae8d83fb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 4 Jun 2002 02:41:30 +0000 Subject: [PATCH 0499/1042] fixed mod. date [SVN r14074] --- doc/v2/iterator.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/iterator.html b/doc/v2/iterator.html index 944ccd29..3c52ae0b 100644 --- a/doc/v2/iterator.html +++ b/doc/v2/iterator.html @@ -355,7 +355,7 @@ A more comprehensive example can be found in:

    Revised - 17 November, 2002 + 17 May, 2002 From e36aba8c668fc1d3c22e9f04bf742e71ee406035 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 4 Jun 2002 03:22:37 +0000 Subject: [PATCH 0500/1042] bug fix [SVN r14075] --- doc/v2/iterator.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/iterator.html b/doc/v2/iterator.html index 3c52ae0b..1e367cce 100644 --- a/doc/v2/iterator.html +++ b/doc/v2/iterator.html @@ -336,7 +336,7 @@ The first form creates a Python callable using namespace boost::python; BOOST_PYTHON_MODULE_INIT(demo) { - module m("demo") + module("demo") .add( class_<std::vector<double> >("dvec") .def("__iter__", iterator<std::vector<double> >()) From 241a5bf4e5e9bb762d7dac253ead4b1856594737 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 4 Jun 2002 03:30:34 +0000 Subject: [PATCH 0501/1042] operators documentation [SVN r14076] --- doc/v2/class.html | 22 +- doc/v2/operators.html | 531 ++++++++++++++++++++++++++++++++++++++++++ doc/v2/reference.html | 27 ++- 3 files changed, 572 insertions(+), 8 deletions(-) create mode 100755 doc/v2/operators.html diff --git a/doc/v2/class.html b/doc/v2/class.html index fd2b1434..0496d2ca 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -82,8 +82,7 @@

    Classes

    -

    Class template class_<T, Bases, HolderGenerator>

    +

    Class template class_<T, Bases, HeldType, NonCopyable>

    Creates a Python class associated with the C++ type passed as its first parameter. Although it has four template parameters, @@ -182,7 +181,7 @@ T instances where a smart pointer-to-T is expected. Smart pointers such as std::auto_ptr<> or boost::shared_ptr<> + href="../../../smart_ptr/shared_ptr.htm">boost::shared_ptr<> which contain a nested type element_type designating the referent type are automatically supported; additional smart pointer types can be supported by specializing unspecified> + class_& def(detail::operator_<unspecified>); + // exposing data members template <class D> class_& def_readonly(char const* name, D T::*pm); @@ -365,6 +368,19 @@ class_& def(char const* name, Fn f, CallPolicies policies);

    Returns: *this +
    +template <unspecified>
    +class_& def(detail::operator_<unspecified>);
    +
    + +
    +
    Effects: Adds a Python special + method as described here. + +
    Returns: *this +
    +
     template <class F>
     class_& setattr(char const* name, ref x);
    diff --git a/doc/v2/operators.html b/doc/v2/operators.html
    new file mode 100755
    index 00000000..a43df858
    --- /dev/null
    +++ b/doc/v2/operators.html
    @@ -0,0 +1,531 @@
    +
    +    
    +    
    +    
    +
    +    Boost.Python - <boost/python/operators.hpp>
    +
    +    
    +      
    +        
    +

    +

    + +
    +

    Boost.Python

    + +

    Header <boost/python/operators.hpp>

    +
    +
    + +

    Contents

    + +
    +
    Introduction + +
    Classes +
    +
    + +
    Class self_ns::self_t +
    +
    +
    Class self_t synopsis + +
    Class self_t inplace operators + +
    Class self_t comparison functions + +
    Class self_t non-member operations + +
    Class self_t unary operations + +
    Class self_t value operations +
    + +
    Class template other +
    +
    +
    Class other synopsis +
    + +
    Class template operator_ +
    +
    +
    Class operator_ synopsis +
    + +
    + +
    Objects +
    +
    +
    self +
    + +
    Examples +
    +
    + +

    Introduction

    + +

    <boost/python/operators.hpp> provides types + and functions for automatically generating Python special + methods from the corresponding C++ constructs. Most of these + constructs are operator expressions, hence the name. To use the + facility, substitute the self object for an object of the + class type being wrapped in the expression to be exposed, and pass + the result to class_<>::def(). Much + of what is exposed in this header should be considered part of the + implementation, so is not documented in detail here. + +

    Classes

    + +

    Class self_ns::self_t

    + +

    self_ns::self_t is the actual type of the self object. The library + isolates self_t in its own namespace, + self_ns, in order to prevent the generalized operator + templates which operate on it from being found by + argument-dependent lookup in other contexts. This should be + considered an implementation detail, since users should never have + to mention self_t directly. + +

    Class self_ns::self_t synopsis

    +
    +namespace boost { namespace python { namespace self_ns {
    +{
    +   class self_t {};
    +
    +   // inplace operators
    +   template <class T> operator_<unspecified> operator+=(self_t, T);
    +   template <class T> operator_<unspecified> operator-=(self_t, T);
    +   template <class T> operator_<unspecified> operator*=(self_t, T);
    +   template <class T> operator_<unspecified> operator/=(self_t, T);
    +   template <class T> operator_<unspecified> operator%=(self_t, T);
    +   template <class T> operator_<unspecified> operator>>=(self_t, T);
    +   template <class T> operator_<unspecified> operator<<=(self_t, T);
    +   template <class T> operator_<unspecified> operator&=(self_t, T);
    +   template <class T> operator_<unspecified> operator^=(self_t, T);
    +   template <class T> operator_<unspecified> operator|=(self_t, T);
    +
    +   // comparisons
    +   template <class L, class R> operator_<unspecified> operator==(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator!=(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator<(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator>(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator<=(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator>=(L const&, R const&);
    +
    +   // non-member operations
    +   template <class L, class R> operator_<unspecified> operator+(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator-(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator*(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator/(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator%(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator>>(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator<<(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator&(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator^(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> operator|(L const&, R const&);
    +   template <class L, class R> operator_<unspecified> pow(L const&, R const&);
    +
    +   // unary operations
    +   operator_<unspecified> operator-(self_t);
    +   operator_<unspecified> operator+(self_t);
    +   operator_<unspecified> operator~(self_t);
    +
    +   // value operations
    +   operator_<unspecified> int_(self_t);
    +   operator_<unspecified> long_(self_t);
    +   operator_<unspecified> float_(self_t);
    +   operator_<unspecified> complex_(self_t);
    +   operator_<unspecified> str(self_t);
    +
    +}}};
    +
    + +The tables below describe the methods generated when the results of +the expressions described are passed as arguments to class_<>::def(). +x is an object of the class type being wrapped. + + +

    Class self_t inplace operators

    + + + +In the table below, If r is an object of type +other<T>, +y is an object of type T; otherwise, +y is an object of the same type as +r. + + + +
    C++ Expression + Python Method Name + C++ Implementation + +
    self += r +__iadd__ +x += y + +
    self -= r +__isub__ +x -= y + +
    self *= r +__imul__ +x *= y + +
    self /= r +__idiv__ +x /= y + +
    self %= r +__imod__ +x %= y + +
    self >>= r +__irshift__ +x >>= y + +
    self <<= r +__ilshift__ +x <<= y + +
    self &= r +__iand__ +x &= y + +
    self ^= r +__ixor__ +x ^= y + +
    self |= r +__ior__ +x |= y +
    + +

    Class self_t comparison + functions

    + +In the tables below, if r is of type self_t, y is an object +of the same type as x; +
    +if l or r is an object of type other<T>, +y is an object of type T; +
    +otherwise, y is an object of the same type as +l or r.
    +l +is never of type self_t. + +

    +The column of Python Expressions illustrates the expressions +that will be supported in Python for objects convertible to the types +of x and y. The secondary operation arises +due to Python's reflection +rules for rich comparison operators, and are only used when the +corresponding operation is not defined as a method of the +y object. + + +
    C++ Expression Python Method Name C++ Implementation +Python Expressions
    (primary, secondary) + + +
    self == r __eq__ x == y +x == y, y == x + +
    l == self __eq__ y == x +y == x, x == y + +
    self != r __ne__ x != y +x != y, y != x + +
    l != self __ne__ y != x +y != x, x != y + +
    self < r __lt__ x < y +x < y, y > x + +
    l < self __gt__ y < x +y > x, x < y + +
    self > r __gt__ x > y +x > y, y < x + +
    l > self __lt__ y > x +y < x, x > y + +
    self <= r __le__ x <= y +x <= y, y >= x + +
    l <= self __ge__ y <= x +y >= x, x <= y + +
    self >= r __ge__ x >= y +x >= y, y <= x + +
    l >= self __le__ y >= x +y <= x, x >= y + + +
    + + +

    Class + self_t non-member operations

    + +The operations whose names begin with "__r" +below will only be called if the left-hand operand does not already +support the given operation, as described here. + + +
    C++ Expression Python Method Name C++ Implementation + + +
    self + r __add__ x + y +
    l + self __radd__ y + x + +
    self - r __sub__ x - y +
    l - self __rsub__ y - x + +
    self * r __mul__ x * y +
    l * self __rmul__ y * x + +
    self / r __div__ x / y +
    l / self __rdiv__ y / x + +
    self % r __mod__ x % y +
    l % self __rmod__ y % x + +
    self >> r __rshift__ x >> y +
    l >> self __rrshift__ y >> x + +
    self << r __lshift__ x << y +
    l << self __rlshift__ y << x + +
    self & r __and__ x & y +
    l & self __rand__ y & x + +
    self ^ r __xor__ x ^ y +
    l ^ self __rxor__ y ^ x + +
    self | r __or__ x | y +
    l | self __ror__ y | x + +
    pow(self, r) __pow__ pow(x, y) +
    pow(l, self) __rpow__ pow(y, x) + + +
    + + +

    Class + self_t unary operations

    + + +
    C++ Expression Python Method Name C++ Implementation + + +
    -self __neg__ -x +
    +self__pos__ +x +
    ~self__invert__ ~x + + +
    + + +

    Class + self_t value operations

    + + +
    C++ Expression Python Method Name C++ Implementation + + +
    int_(self)__int__ long(x) +
    long___long__ PyLong_FromLong(x) +
    float___float__ double(x) +
    complex___complex__ std::complex<double>(x) +
    str__str__ lexical_cast<std::string>(x) + + +
    + + + +

    Class Template other

    + +

    Instances of other<T> can be used in + operator expressions with self; the + result is equivalent to the same expression with a T + object in place of other<T>. Use + other<T> to prevent construction of a + T object in case it is heavyweight, when no + constructor is available, or simply for clarity. + +

    Class Template other synopsis

    +
    +namespace boost { namespace python
    +{
    +  template <class T>
    +  struct other
    +  {
    +  };
    +}}
    +
    + + + +

    Class Template detail::operator_

    + +

    Instantiations of detail::operator_<> are + used as the return type of operator expressions involving self. This should be considered an + implementation detail and is only documented here as a way of + showing how the result of self-expressions match + calls to class_<>::def(). + +

    Class Template + detail::operator_ synopsis

    +
    +namespace boost { namespace python { namespace detail
    +{
    +  template <unspecified>
    +  struct operator_
    +  {
    +  };
    +}}}
    +
    + +

    Objects

    + +

    self + +

    +namespace boost { namespace python
    +{
    +  extern self_ns self;
    +}}
    +
    + +

    Example

    + +
    +#include <boost/python/module.hpp>
    +#include <boost/python/class.hpp>
    +#include <boost/python/operators.hpp>
    +#include <boost/operators.hpp>
    +
    +struct number
    +   : boost::integer_arithmetic<number>
    +{
    +   number(long x_) : x(x_) {}
    +   operator long() const { return x; }
    +
    +   number& operator+=(number const& rhs)
    +      { x += rhs }
    +   number& operator-=(number const& rhs);
    +      { x -= rhs }
    +   number& operator*=(number const& rhs)
    +      { x *= rhs }
    +   number& operator/=(number const& rhs);
    +      { x /= rhs }
    +   number& operator%=(number const& rhs);
    +      { x %= rhs }
    +
    +   long x;
    +};
    +
    +using namespace boost::python;
    +BOOST_PYTHON_MODULE_INIT(demo)
    +{
    +   module("demo")
    +      .add(
    +         class_<number>("number")
    +            // interoperate with self
    +            .def(self += self)
    +            .def(self + self)
    +            .def(self -= self)
    +            .def(self - self)
    +            .def(self *= self)
    +            .def(self * self)
    +            .def(self /= self)
    +            .def(self / self)
    +            .def(self %= self)
    +            .def(self % self)
    +            
    +            // Convert to Python int
    +            .def(int_(self))
    +
    +            // interoperate with long
    +            .def(self += long())
    +            .def(self + long())
    +            .def(long() + self)
    +            .def(self -= long())
    +            .def(self - long())
    +            .def(long() - self)
    +            .def(self *= long())
    +            .def(self * long())
    +            .def(long() * self)
    +            .def(self /= long())
    +            .def(self / long())
    +            .def(long() / self)
    +            .def(self %= long())
    +            .def(self % long())
    +            .def(long() % self)
    +
    +         )
    +      ;
    +}
    +
    + +

    Revised + + 3 June, 2002 + + + +

    © Copyright Dave + Abrahams 2002. All Rights Reserved. + diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 8bd19545..9db8240b 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -124,8 +124,8 @@

    -
    Classes +
    Classes
    iterator @@ -142,7 +142,6 @@
    module.hpp -
    Classes @@ -154,7 +153,6 @@
    objects.hpp -
    Classes @@ -165,6 +163,26 @@ documented
    + +
    operators.hpp +
    +
    +
    Classes +
    +
    +
    self_t +
    other +
    operator_ +
    + +
    Objects +
    +
    +
    self +
    + +
    +

    Function Invocation and Creation

    @@ -175,7 +193,6 @@
    Functions -
    call @@ -584,7 +601,7 @@

    Revised - 29 May, 2002 + 3 June, 2002 From ccae1cc43016fd66fbcfba5c6bd4fcc1d670bdf6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 4 Jun 2002 04:18:47 +0000 Subject: [PATCH 0502/1042] cleanup refcounting/naming [SVN r14077] --- include/boost/python/module.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 41286ac2..61d8f664 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -31,7 +31,7 @@ class module : public detail::module_base template module& add(class_ const& c) { - this->generic_add_class(c.object()); + this->add_class(c.object()); return *this; } From 6741698f71573bc98e3229a9873cdb7aca6468b2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 4 Jun 2002 12:38:14 +0000 Subject: [PATCH 0503/1042] Added comment as syncmail test [SVN r14080] --- test/Jamfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Jamfile b/test/Jamfile index 794dff42..ef6c0b7d 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -7,7 +7,7 @@ include python.jam ; local PYTHON_V1_PROPERTIES = $(PYTHON_PROPERTIES) ; local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) ; -# +# Convenience rule makes declaring tests faster rule bpl-test ( name ? : files * ) { files ?= $(name).py $(name).cpp ; From 2e3ae9decb9a8e607756b0afca2f4bf1c620455b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 4 Jun 2002 20:26:18 +0000 Subject: [PATCH 0504/1042] fixup for __module__ attribute setting [SVN r14082] --- include/boost/python/detail/module_base.hpp | 2 +- src/module.cpp | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp index 043a6f47..ecd13aa4 100644 --- a/include/boost/python/detail/module_base.hpp +++ b/include/boost/python/detail/module_base.hpp @@ -27,7 +27,7 @@ class BOOST_PYTHON_DECL module_base inline ref object() const; protected: - void generic_add_class(ref class_obj); + void add_class(ref const& class_obj); private: ref m_module; diff --git a/src/module.cpp b/src/module.cpp index 5020170c..e958c6d8 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -45,15 +45,20 @@ void module_base::add_type(ref x) add((PyTypeObject*)x.release()); } -void module_base::generic_add_class(ref class_obj) +void module_base::add_class(ref const& class_obj) { - Py_INCREF(class_obj.get()); this->add_type(class_obj); - ref module_name(PyObject_GetAttrString(m_module.get(), - const_cast("__name__"))); - int status = PyObject_SetAttrString(class_obj.get(), - const_cast("__module__"), module_name.get()); - if (status == -1) throw_error_already_set(); + + ref module_name( + PyObject_GetAttrString( + m_module.get(), const_cast("__name__")) + ); + + int status = PyObject_SetAttrString( + class_obj.get(), const_cast("__module__"), module_name.get()); + + if (status == -1) + throw_error_already_set(); } PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; From 266954be990fb1c074ba831575e8586725ff5d55 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 5 Jun 2002 22:13:34 +0000 Subject: [PATCH 0505/1042] adjustments for SGI MIPSpro 7.3.1.3m; tested with gcc, tru64_cxx65, vc7 tool sets. [SVN r14084] --- include/boost/python/class.hpp | 4 ++++ include/boost/python/detail/decorated_type_id.hpp | 4 ++-- include/boost/python/module.hpp | 4 ++++ include/boost/python/object/class_converters.hpp | 9 ++++----- include/boost/python/type_id.hpp | 4 ++-- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 51fef4fa..ebb016f4 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -72,6 +72,10 @@ template < > class class_ : public objects::class_base { +#if defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238) + typedef objects::class_base class_base; +#endif + typedef class_ self; BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable::value)); diff --git a/include/boost/python/detail/decorated_type_id.hpp b/include/boost/python/detail/decorated_type_id.hpp index f70e369a..c43a4160 100755 --- a/include/boost/python/detail/decorated_type_id.hpp +++ b/include/boost/python/detail/decorated_type_id.hpp @@ -18,8 +18,8 @@ struct decorated_type_info : totally_ordered decorated_type_info(type_info, decoration = decoration()); - bool operator<(decorated_type_info const& rhs) const; - bool operator==(decorated_type_info const& rhs) const; + inline bool operator<(decorated_type_info const& rhs) const; + inline bool operator==(decorated_type_info const& rhs) const; friend BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream&, decorated_type_info const&); diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 61d8f664..8090ccd9 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -19,6 +19,10 @@ namespace boost { namespace python { class module : public detail::module_base { public: +#if defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238) + typedef detail::module_base module_base; +#endif + module(const char* name) : module_base(name) {} diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index 86fcd64b..23260701 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -69,17 +69,16 @@ struct register_base_of }; }; +template +inline void force_instantiate(T const&) {} // Brings into existence all converters associated with a class Bases // is expected to be an mpl sequence of base types. template inline void register_class_from_python(Derived* = 0, Bases* = 0) { - // cause the static registration to be instantiated. Can't just - // cast it to void on all compilers; some will skip its - // initialization. - void const* ignored = &instance_finder::registration; - (void)ignored; + // cause the static registration to be instantiated. + force_instantiate(instance_finder::registration); // register all up/downcasts here register_dynamic_id(); diff --git a/include/boost/python/type_id.hpp b/include/boost/python/type_id.hpp index 3573239c..2432af00 100755 --- a/include/boost/python/type_id.hpp +++ b/include/boost/python/type_id.hpp @@ -30,8 +30,8 @@ struct type_info : private totally_ordered { type_info(std::type_info const& = typeid(void)); - bool operator<(type_info const& rhs) const; - bool operator==(type_info const& rhs) const; + inline bool operator<(type_info const& rhs) const; + inline bool operator==(type_info const& rhs) const; char const* name() const; friend BOOST_PYTHON_DECL std::ostream& operator<<( From e2b4178f427bd823041f728280c0c4a4ec382f7c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 5 Jun 2002 23:47:18 +0000 Subject: [PATCH 0506/1042] work-around for MIPSpro 7.3.1.3 problems that avoids #ifdef [SVN r14085] --- include/boost/python/class.hpp | 14 ++++++-------- include/boost/python/module.hpp | 14 ++++++-------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index ebb016f4..ec21ba8e 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -72,9 +72,7 @@ template < > class class_ : public objects::class_base { -#if defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238) - typedef objects::class_base class_base; -#endif + typedef objects::class_base base; typedef class_ self; BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable::value)); @@ -234,7 +232,7 @@ class class_ : public objects::class_base // template inline class_::class_() - : class_base(typeid(T).name(), id_vector::size, id_vector().ids) + : base(typeid(T).name(), id_vector::size, id_vector().ids) { // register converters objects::register_class_from_python(); @@ -247,7 +245,7 @@ inline class_::class_() template inline class_::class_(char const* name) - : class_base(name, id_vector::size, id_vector().ids) + : base(name, id_vector::size, id_vector().ids) { // register converters objects::register_class_from_python(); @@ -262,21 +260,21 @@ inline class_::class_(char const* name) template inline class_& class_::add_property(char const* name, ref const& fget) { - class_base::add_property(name, fget); + base::add_property(name, fget); return *this; } template inline class_& class_::add_property(char const* name, ref const& fget, ref const& fset) { - class_base::add_property(name, fget, fset); + base::add_property(name, fget, fset); return *this; } template inline class_& class_::setattr(char const* name, ref const& x) { - class_base::setattr(name, x); + base::setattr(name, x); return *this; } diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 8090ccd9..38a80dca 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -19,12 +19,10 @@ namespace boost { namespace python { class module : public detail::module_base { public: -#if defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238) - typedef detail::module_base module_base; -#endif + typedef detail::module_base base; module(const char* name) - : module_base(name) {} + : base(name) {} // Add elements to the module module& setattr(const char* name, PyObject*); @@ -60,25 +58,25 @@ class module : public detail::module_base // inline module& module::setattr(const char* name, PyObject* x) { - this->module_base::setattr(name, x); + this->base::setattr(name, x); return *this; } inline module& module::setattr(const char* name, PyTypeObject* x) { - this->module_base::setattr(name, (PyObject*)x); + this->base::setattr(name, (PyObject*)x); return *this; } inline module& module::setattr(const char* name, ref const& x) { - this->module_base::setattr(name, x); + this->base::setattr(name, x); return *this; } inline module& module::add(PyTypeObject* x) { - this->module_base::add(x); + this->base::add(x); return *this; } From ac2746f6808486b10c2b45d0a473af54d32c247f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 6 Jun 2002 20:24:39 +0000 Subject: [PATCH 0507/1042] * Generalized use of force_instantiate() * Proper handling for numeric conversion overflows * Moved internal converter names out of the way to prepare for user conversions * Added comments * Fixed a bug where None could be converted to the NULL target of a member function call, causing a crash. * Wiped out and restarted todo.txt * long long support * Added more regression tests and checks for current limitations [SVN r14094] --- include/boost/python/arg_from_python.hpp | 52 + include/boost/python/call.hpp | 9 +- include/boost/python/call_method.hpp | 9 +- .../python/converter/arg_from_python.hpp | 320 ++++ .../boost/python/converter/arg_to_python.hpp | 158 ++ .../python/converter/arg_to_python_base.hpp | 53 + .../python/converter/builtin_converters.hpp | 105 +- .../converter/lvalue_from_python_chain.hpp | 10 +- .../python/converter/return_from_python.hpp | 134 ++ include/boost/python/data_members.hpp | 6 +- .../boost/python/detail/force_instantiate.hpp | 18 + include/boost/python/detail/returning.hpp | 12 +- include/boost/python/detail/unwind_type.hpp | 2 + include/boost/python/from_python.hpp | 3 +- .../boost/python/object/class_converters.hpp | 6 +- include/boost/python/object/iterator.hpp | 8 +- .../boost/python/object/pointer_holder.hpp | 27 +- include/boost/python/object/value_holder.hpp | 27 +- include/boost/python/operators2.hpp | 5 +- include/boost/python/preprocessed/call.hpp | 304 ++-- .../boost/python/preprocessed/call_method.hpp | 304 ++-- .../ptr_holder_back_reference.hpp | 64 +- .../preprocessed/returning_non_void.hpp | 1456 ++++++++--------- .../python/preprocessed/returning_void.hpp | 1456 ++++++++--------- .../value_holder_back_reference.hpp | 64 +- include/boost/python/to_python_indirect.hpp | 1 + src/converter/builtin_converters.cpp | 116 +- src/converter/callback.cpp | 6 +- src/errors.cpp | 5 + test/callbacks.cpp | 6 + test/callbacks.py | 7 + test/newtest.py | 13 +- test/select_from_python_test.cpp | 58 +- test/test_builtin_converters.cpp | 8 + test/test_builtin_converters.py | 36 + todo.txt | 427 +---- 36 files changed, 2899 insertions(+), 2396 deletions(-) create mode 100755 include/boost/python/arg_from_python.hpp create mode 100755 include/boost/python/converter/arg_from_python.hpp create mode 100755 include/boost/python/converter/arg_to_python.hpp create mode 100755 include/boost/python/converter/arg_to_python_base.hpp create mode 100755 include/boost/python/converter/return_from_python.hpp create mode 100755 include/boost/python/detail/force_instantiate.hpp diff --git a/include/boost/python/arg_from_python.hpp b/include/boost/python/arg_from_python.hpp new file mode 100755 index 00000000..1d033acd --- /dev/null +++ b/include/boost/python/arg_from_python.hpp @@ -0,0 +1,52 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ARG_FROM_PYTHON_DWA2002128_HPP +# define ARG_FROM_PYTHON_DWA2002128_HPP + +# include + +namespace boost { namespace python { + +template +struct arg_from_python + : converter::select_arg_from_python::type +{ + typedef typename converter::select_arg_from_python::type base; + arg_from_python(PyObject*); +}; + +// specialization for PyObject* +template <> +struct arg_from_python +{ + typedef PyObject* result_type; + + arg_from_python(PyObject*) {} + bool convertible() const { return true; } + PyObject* operator()(PyObject* source) const { return source; } +}; + +template <> +struct arg_from_python +{ + typedef PyObject* const& result_type; + arg_from_python(PyObject*) {} + bool convertible() const { return true; } + PyObject*const& operator()(PyObject*const& source) const { return source; } +}; + +// +// implementations +// +template +inline arg_from_python::arg_from_python(PyObject* source) + : base(source) +{ +} + +}} // namespace boost::python + +#endif // ARG_FROM_PYTHON_DWA2002128_HPP diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp index 746b7075..92661a68 100644 --- a/include/boost/python/call.hpp +++ b/include/boost/python/call.hpp @@ -6,7 +6,8 @@ #ifndef CALL_DWA2002411_HPP # define CALL_DWA2002411_HPP -# include +# include +# include # include # include # include @@ -26,19 +27,19 @@ template < class R \ BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM_PARAMS(nargs, class A) \ > \ -typename converter::callback_from_python::result_type \ +typename converter::return_from_python::result_type \ call(PyObject* callable \ BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a)) \ , boost::type* = 0 \ ) \ { \ - converter::callback_from_python converter; \ + converter::return_from_python converter; \ return converter( \ PyEval_CallFunction( \ callable \ , const_cast(BOOST_PYTHON_ARG_STRING(nargs)) \ BOOST_PP_COMMA_IF(nargs) \ - BOOST_PP_ENUM(nargs,BOOST_PYTHON_CALLBACK_TO_PYTHON_GET,nil) \ + BOOST_PP_ENUM(nargs,BOOST_PYTHON_ARG_TO_PYTHON_GET,nil) \ )); \ } diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp index 219b1e19..9bd07375 100644 --- a/include/boost/python/call_method.hpp +++ b/include/boost/python/call_method.hpp @@ -6,7 +6,8 @@ #ifndef CALL_METHOD_DWA2002411_HPP # define CALL_METHOD_DWA2002411_HPP -# include +# include +# include # include # include # include @@ -26,20 +27,20 @@ template < class R \ BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM_PARAMS(nargs, class A) \ > \ -typename converter::callback_from_python::result_type \ +typename converter::return_from_python::result_type \ call_method(PyObject* self, char const* name \ BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a)) \ , boost::type* = 0 \ ) \ { \ - converter::callback_from_python converter; \ + converter::return_from_python converter; \ return converter( \ PyEval_CallMethod( \ self \ , const_cast(name) \ , const_cast(BOOST_PYTHON_ARG_STRING(nargs)) \ BOOST_PP_COMMA_IF(nargs) \ - BOOST_PP_ENUM(nargs,BOOST_PYTHON_CALLBACK_TO_PYTHON_GET,nil) \ + BOOST_PP_ENUM(nargs,BOOST_PYTHON_ARG_TO_PYTHON_GET,nil) \ )); \ } diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp new file mode 100755 index 00000000..ccdb961c --- /dev/null +++ b/include/boost/python/converter/arg_from_python.hpp @@ -0,0 +1,320 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ARG_FROM_PYTHON_DWA2002127_HPP +# define ARG_FROM_PYTHON_DWA2002127_HPP + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python +{ + template struct arg_from_python; +}} + +// This header defines Python->C++ function argument converters, +// parametrized on the argument type. + +namespace boost { namespace python { namespace converter { + +// +// lvalue converters +// +// These require that an lvalue of the type U is stored somewhere in +// the Python object being converted. + +// Used when T == U*const& +template +struct pointer_cref_arg_from_python +{ + typedef T result_type; + + pointer_cref_arg_from_python(PyObject*); + T operator()(PyObject*) const; + bool convertible() const; + + private: // storage for a U* + // needed because not all compilers will let us declare U* as the + // return type of operator() -- we return U*const& instead + typename detail::referent_storage::type m_result; +}; + +// Base class for pointer and reference converters +struct arg_lvalue_from_python_base +{ + public: // member functions + arg_lvalue_from_python_base(void* result); + bool convertible() const; + + protected: // member functions + void*const& result() const; + + private: // data members + void* m_result; +}; + +// Used when T == U* +template +struct pointer_arg_from_python : arg_lvalue_from_python_base +{ + typedef T result_type; + + pointer_arg_from_python(PyObject*); + T operator()(PyObject*) const; +}; + +// Used when T == U& and (T != V const& or T == W volatile&) +template +struct reference_arg_from_python : arg_lvalue_from_python_base +{ + typedef T result_type; + + reference_arg_from_python(PyObject*); + T operator()(PyObject*) const; +}; + +// =================== + +// +// rvalue converters +// +// These require only that an object of type T can be created from +// the given Python object, but not that the T object exist +// somewhere in storage. +// + +// Used when T is a plain value (non-pointer, non-reference) type or +// a (non-volatile) const reference to a plain value type. +template +struct arg_rvalue_from_python +{ + typedef typename boost::add_reference< + typename boost::add_const::type + >::type result_type; + + arg_rvalue_from_python(PyObject*); + bool convertible() const; + + result_type operator()(PyObject*); + + private: + rvalue_data m_data; +}; + + +// ================== + +// Converts to a (PyObject*,T) bundle, for when you need a reference +// back to the Python object +template +struct back_reference_arg_from_python + : boost::python::arg_from_python +{ + typedef T result_type; + + back_reference_arg_from_python(PyObject*); + T operator()(PyObject*); + private: + typedef boost::python::arg_from_python base; +}; + + +// ================== + +// This metafunction selects the appropriate arg_from_python converter +// type for an argument of type T. +template +struct select_arg_from_python +{ + BOOST_STATIC_CONSTANT( + bool, ptr = is_pointer::value); + + BOOST_STATIC_CONSTANT( + bool, ptr_cref + = boost::python::detail::is_reference_to_pointer::value + && boost::python::detail::is_reference_to_const::value + && !boost::python::detail::is_reference_to_volatile::value); + + + BOOST_STATIC_CONSTANT( + bool, ref = + boost::python::detail::is_reference_to_non_const::value + || boost::python::detail::is_reference_to_volatile::value); + + BOOST_STATIC_CONSTANT( + bool, back_ref = + boost::python::is_back_reference::value); + + typedef typename mpl::select_type< + ptr + , pointer_arg_from_python + , typename mpl::select_type< + ptr_cref + , pointer_cref_arg_from_python + , typename mpl::select_type< + ref + , reference_arg_from_python + , typename mpl::select_type< + back_ref + , back_reference_arg_from_python + , arg_rvalue_from_python + >::type + >::type + >::type + >::type type; +}; + +// ================== + +// +// implementations +// + +// arg_lvalue_from_python_base +// +inline arg_lvalue_from_python_base::arg_lvalue_from_python_base(void* result) + : m_result(result) +{ +} + +inline bool arg_lvalue_from_python_base::convertible() const +{ + return m_result != 0; +} + +inline void*const& arg_lvalue_from_python_base::result() const +{ + return m_result; +} + +// pointer_cref_arg_from_python +// +namespace detail +{ + // null_ptr_reference -- a function returning a reference to a null + // pointer of type U. Needed so that extractors for T*const& can + // convert Python's None. + template + struct null_ptr_owner + { + static T value; + }; + template T null_ptr_owner::value = 0; + + template + inline U& null_ptr_reference(U&(*)()) + { + return null_ptr_owner::value; + } +} + +template +inline pointer_cref_arg_from_python::pointer_cref_arg_from_python(PyObject* p) +{ + // T == U*const&: store a U* in the m_result storage. Nonzero + // indicates success. If find returns nonzero, it's a pointer to + // a U object. + python::detail::write_void_ptr_reference( + m_result.bytes + , p == Py_None ? p : find(p, lvalue_from_python_chain::value) + , (T(*)())0); +} + +template +inline bool pointer_cref_arg_from_python::convertible() const +{ + return python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0; +} +template +inline T pointer_cref_arg_from_python::operator()(PyObject* p) const +{ + return (p == Py_None) // None ==> 0 + ? detail::null_ptr_reference((T(*)())0) + // Otherwise, return a U*const& to the m_result storage. + : python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0); +} + +// pointer_arg_from_python +// +template +inline pointer_arg_from_python::pointer_arg_from_python(PyObject* p) + : arg_lvalue_from_python_base( + p == Py_None ? p : find(p, lvalue_from_python_chain::value)) +{ +} + +template +inline T pointer_arg_from_python::operator()(PyObject* p) const +{ + return (p == Py_None) ? 0 : T(result()); +} + +// reference_arg_from_python +// +template +inline reference_arg_from_python::reference_arg_from_python(PyObject* p) + : arg_lvalue_from_python_base(find(p,lvalue_from_python_chain::value)) +{ +} + +template +inline T reference_arg_from_python::operator()(PyObject*) const +{ + return python::detail::void_ptr_to_reference(result(), (T(*)())0); +} + + +// arg_rvalue_from_python +// +template +inline arg_rvalue_from_python::arg_rvalue_from_python(PyObject* obj) + : m_data(find(obj, rvalue_from_python_chain::value)) +{ +} + +template +inline bool arg_rvalue_from_python::convertible() const +{ + return m_data.stage1.convertible != 0; +} + +template +inline typename arg_rvalue_from_python::result_type +arg_rvalue_from_python::operator()(PyObject* p) +{ + if (m_data.stage1.construct != 0) + m_data.stage1.construct(p, &m_data.stage1); + + return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0); +} + +// back_reference_arg_from_python +// +template +back_reference_arg_from_python::back_reference_arg_from_python(PyObject* x) + : base(x) +{ +} + +template +inline T +back_reference_arg_from_python::operator()(PyObject* x) +{ + return T(x, base::operator()(x)); +} + +}}} // namespace boost::python::converter + +#endif // ARG_FROM_PYTHON_DWA2002127_HPP diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp new file mode 100755 index 00000000..6cd9836c --- /dev/null +++ b/include/boost/python/converter/arg_to_python.hpp @@ -0,0 +1,158 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ARG_TO_PYTHON_DWA200265_HPP +# define ARG_TO_PYTHON_DWA200265_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +namespace detail +{ + BOOST_PYTHON_DECL void throw_no_class_registered(); + + template + struct reference_arg_to_python : arg_to_python_holder + { + reference_arg_to_python(T& x); + private: + static PyObject* get_object(T& x); + }; + + template + struct value_arg_to_python : arg_to_python_base + { + // Throw an exception if the conversion can't succeed + value_arg_to_python(T const&); + }; + + template + struct pointer_deep_arg_to_python : arg_to_python_base + { + // Throw an exception if the conversion can't succeed + pointer_deep_arg_to_python(Ptr); + }; + + template + struct pointer_shallow_arg_to_python : arg_to_python_holder + { + // Throw an exception if the conversion can't succeed + pointer_shallow_arg_to_python(Ptr); + private: + static PyObject* get_object(Ptr p); + }; + + template + struct select_arg_to_python + { + BOOST_STATIC_CONSTANT( + bool, ptr = is_pointer::value); + + BOOST_STATIC_CONSTANT( + bool, ref_wrapper = is_reference_wrapper::value); + + BOOST_STATIC_CONSTANT( + bool, ptr_wrapper = is_pointer_wrapper::value); + + typedef typename unwrap_reference::type unwrapped_referent; + typedef typename unwrap_pointer::type unwrapped_ptr; + + typedef typename mpl::select_type< + ptr + , pointer_deep_arg_to_python + , typename mpl::select_type< + ptr_wrapper + , pointer_shallow_arg_to_python + , typename mpl::select_type< + ref_wrapper + , reference_arg_to_python + , value_arg_to_python + >::type + >::type + >::type type; + }; +} + +template +struct arg_to_python + : detail::select_arg_to_python::type +{ + typedef typename detail::select_arg_to_python::type base; + public: // member functions + // Throw an exception if the conversion can't succeed + arg_to_python(T const& x); +}; + +// +// Convenience macros for call<> and call_method<> code generation +// +# define BOOST_PYTHON_ARG_TO_PYTHON_GET(index,ignored) \ + converter::arg_to_python( \ + BOOST_PP_CAT(a,index)).get() + +# define BOOST_PYTHON_ARG_STRING(nargs) \ + "(" BOOST_PP_REPEAT(nargs,BOOST_PYTHON_PROJECT_2ND,"O") ")" + + +// +// implementations +// +namespace detail +{ + template + inline value_arg_to_python::value_arg_to_python(T const& x) + : arg_to_python_base(&x, to_python_function::value) + { + } + + template + inline pointer_deep_arg_to_python::pointer_deep_arg_to_python(Ptr x) + : arg_to_python_base(x, pointee_to_python_function::value) + { + } + + template + inline PyObject* reference_arg_to_python::get_object(T& x) + { + to_python_indirect convert; + if (!convert.convertible()) + throw_no_class_registered(); + return convert(x); + } + + template + inline reference_arg_to_python::reference_arg_to_python(T& x) + : arg_to_python_holder(get_object(x)) + { + } + + template + inline pointer_shallow_arg_to_python::pointer_shallow_arg_to_python(Ptr x) + : arg_to_python_holder(get_object(x)) + {} + + template + inline PyObject* pointer_shallow_arg_to_python::get_object(Ptr x) + { + to_python_indirect convert; + if (!convert.convertible()) + throw_no_class_registered(); + return x ? convert(x) : python::detail::none(); + } +} + +template +inline arg_to_python::arg_to_python(T const& x) + : base(x) +{} + +}}} // namespace boost::python::converter + +#endif // ARG_TO_PYTHON_DWA200265_HPP diff --git a/include/boost/python/converter/arg_to_python_base.hpp b/include/boost/python/converter/arg_to_python_base.hpp new file mode 100755 index 00000000..7573b499 --- /dev/null +++ b/include/boost/python/converter/arg_to_python_base.hpp @@ -0,0 +1,53 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ARG_TO_PYTHON_BASE_DWA200237_HPP +# define ARG_TO_PYTHON_BASE_DWA200237_HPP +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +namespace detail +{ + struct arg_to_python_holder + { + arg_to_python_holder(PyObject* obj); + PyObject* get() const; + PyObject* get_incref() const; + private: + ref m_held; + }; + + struct BOOST_PYTHON_DECL arg_to_python_base : arg_to_python_holder + { + arg_to_python_base(void const volatile* source, to_python_function_t); + }; + + // + // implmentation + // + inline arg_to_python_holder::arg_to_python_holder(PyObject* obj) + : m_held(obj) + { + } + + inline PyObject* arg_to_python_holder::get() const + { + return m_held.get(); + } + + inline PyObject* arg_to_python_holder::get_incref() const + { + PyObject* result = m_held.get(); + Py_XINCREF(result); + return result; + } +} + +}}} // namespace boost::python::converter + +#endif // ARG_TO_PYTHON_BASE_DWA200237_HPP diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index c9c3142e..9d072498 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -8,84 +8,105 @@ # include # include # include -# include +# include # include # include +// Since all we can use to decide how to convert an object to_python +// is its C++ type, there can be only one such converter for each +// type. Therefore, for built-in conversions we can bypass registry +// lookups using explicit specializations of arg_to_python and +// result_to_python. + namespace boost { namespace python { +namespace converter +{ + template struct arg_to_python; + BOOST_PYTHON_DECL PyObject* do_return_to_python(char); + BOOST_PYTHON_DECL PyObject* do_return_to_python(char const*); + BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject*); + BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject*); +} + // Provide specializations of to_python_value template struct to_python_value; namespace detail { + // Since there's no registry lookup, always report the existence of + // a converter. struct builtin_to_python { static bool convertible() { return true; } }; } -namespace converter -{ - template struct callback_to_python; - BOOST_PYTHON_DECL PyObject* do_call_to_python(char); - BOOST_PYTHON_DECL PyObject* do_call_to_python(char const*); - BOOST_PYTHON_DECL PyObject* do_call_to_python(PyObject*); - BOOST_PYTHON_DECL PyObject* do_callback_to_python(PyObject*); -} - -# define BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(T, expr) \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ - }; \ - template <> struct to_python_value \ - : detail::builtin_to_python \ - { \ - PyObject* operator()(T const& x) const \ - { \ - return (expr); \ - } \ +// Use expr to create the PyObject corresponding to x +# define BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T, expr) \ + template <> struct to_python_value \ + : detail::builtin_to_python \ + { \ + inline PyObject* operator()(T const& x) const \ + { \ + return (expr); \ + } \ + }; \ + template <> struct to_python_value \ + : detail::builtin_to_python \ + { \ + inline PyObject* operator()(T const& x) const \ + { \ + return (expr); \ + } \ }; -# define BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(T, expr) \ - namespace converter \ - { \ - template <> struct callback_to_python< T > \ - : detail::callback_to_python_holder \ - { \ - callback_to_python(T const& x) \ - : detail::callback_to_python_holder(expr) {} \ - }; \ +# define BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T, expr) \ + namespace converter \ + { \ + template <> struct arg_to_python< T > \ + : detail::arg_to_python_holder \ + { \ + arg_to_python(T const& x) \ + : detail::arg_to_python_holder(expr) {} \ + }; \ } -# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ - BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(T,expr) \ - BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(T,expr) +// Specialize argument and return value converters for T using expr +# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr) \ + BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(T,expr) \ + BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr) +// Specialize converters for signed and unsigned T to Python Int # define BOOST_PYTHON_TO_INT(T) \ BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \ BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x)) +// Bool is not signed. BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, PyInt_FromLong(x)) + +// note: handles signed char and unsigned char, but not char (see below) BOOST_PYTHON_TO_INT(char) + BOOST_PYTHON_TO_INT(short) BOOST_PYTHON_TO_INT(int) BOOST_PYTHON_TO_INT(long) + +# ifdef BOOST_HAS_LONG_LONG +BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed long long, PyLong_FromLongLong(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned long long, PyLong_FromUnsignedLongLong(x)) +# endif + # undef BOOST_TO_PYTHON_INT -BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_call_to_python(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_call_to_python(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) -BOOST_PYTHON_CALL_TO_PYTHON_BY_VALUE(PyObject*, converter::do_call_to_python(x)) -BOOST_PYTHON_CALLBACK_TO_PYTHON_BY_VALUE(PyObject*, converter::do_callback_to_python(x)) +BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x)) +BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(PyObject*, converter::do_arg_to_python(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) diff --git a/include/boost/python/converter/lvalue_from_python_chain.hpp b/include/boost/python/converter/lvalue_from_python_chain.hpp index 7a064841..387c1863 100644 --- a/include/boost/python/converter/lvalue_from_python_chain.hpp +++ b/include/boost/python/converter/lvalue_from_python_chain.hpp @@ -16,7 +16,7 @@ namespace boost { namespace python { namespace converter { // Given T == U*cv&, T == U*, or T == U&, lvalue_from_python_chain // declares a "templated global reference" to the lvalue from_python -// converter chain for U. The optional bool second argument callback, +// converter chain for U. The optional bool second argument is_return, // when true, removes special treatment for T == U*cv& so that the // converter for U* is found. namespace detail @@ -43,12 +43,12 @@ namespace detail ref_lvalue_from_python_chain::value = registry::lvalue_converters(type_id()); - template + template struct select_lvalue_from_python_chain { BOOST_STATIC_CONSTANT( bool, ptr - = !callback && boost::python::detail::is_reference_to_pointer::value + = !is_return && boost::python::detail::is_reference_to_pointer::value || is_pointer::value); typedef typename add_reference::type>::type normalized; @@ -61,9 +61,9 @@ namespace detail }; } -template +template struct lvalue_from_python_chain - : detail::select_lvalue_from_python_chain::type + : detail::select_lvalue_from_python_chain::type { }; diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp new file mode 100755 index 00000000..249bb6e3 --- /dev/null +++ b/include/boost/python/converter/return_from_python.hpp @@ -0,0 +1,134 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef RETURN_FROM_PYTHON_DWA200265_HPP +# define RETURN_FROM_PYTHON_DWA200265_HPP + +# include + +namespace boost { namespace python { namespace converter { + +namespace detail +{ + template + struct return_pointer_from_python + { + return_pointer_from_python(); + T operator()(PyObject*) const; + }; + + template + struct return_reference_from_python + { + return_reference_from_python(); + T operator()(PyObject*) const; + }; + + template + struct return_rvalue_from_python + { + return_rvalue_from_python(); + T const& operator()(PyObject*); + private: + rvalue_data m_data; + }; + + template + struct select_return_from_python + { + BOOST_STATIC_CONSTANT( + bool, ptr = is_pointer::value); + + BOOST_STATIC_CONSTANT( + bool, ref = is_reference::value); + + typedef typename mpl::select_type< + ptr + , return_pointer_from_python + , typename mpl::select_type< + ref + , return_reference_from_python + , return_rvalue_from_python + >::type + >::type type; + }; +} + +template +struct return_from_python + : detail::select_return_from_python::type +{ + typedef T result_type; +}; + +struct void_result +{ + private: + void_result() {} + void operator=(void_result const&); + + friend struct return_from_python; +}; + +// Specialization as a convenience for call and call_method +template <> +struct return_from_python +{ + typedef void_result result_type; + result_type operator()(PyObject* x) const + { + Py_DECREF(expect_non_null(x)); + return result_type(); + } +}; + +// +// Implementations +// +namespace detail +{ + template + inline return_rvalue_from_python::return_rvalue_from_python() + : m_data(rvalue_from_python_chain::value) + { + throw_if_not_registered(m_data.stage1); + } + + template + inline T const& return_rvalue_from_python::operator()(PyObject* obj) + { + return *(T*)convert_rvalue(obj, m_data.stage1, m_data.storage.bytes); + } + + template + inline return_reference_from_python::return_reference_from_python() + { + detail::throw_if_not_registered(lvalue_from_python_chain::value); + } + + template + inline T return_reference_from_python::operator()(PyObject* obj) const + { + return python::detail::void_ptr_to_reference( + callback_convert_reference(obj, lvalue_from_python_chain::value) + , (T(*)())0); + } + + template + inline return_pointer_from_python::return_pointer_from_python() + { + detail::throw_if_not_registered(lvalue_from_python_chain::value); + } + + template + inline T return_pointer_from_python::operator()(PyObject* obj) const + { + return T(callback_convert_pointer(obj, lvalue_from_python_chain::value)); + } +} + +}}} // namespace boost::python::converter + +#endif // RETURN_FROM_PYTHON_DWA200265_HPP diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp index b0f3f7b6..b9114403 100644 --- a/include/boost/python/data_members.hpp +++ b/include/boost/python/data_members.hpp @@ -23,7 +23,7 @@ namespace detail { static PyObject* get(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies) { - from_python c0(PyTuple_GET_ITEM(args_, 0)); + arg_from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; // find the result converter @@ -42,12 +42,12 @@ namespace detail static PyObject* set(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies) { // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); + arg_from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; typedef typename add_const::type target1; typedef typename add_reference::type target; - from_python c1(PyTuple_GET_ITEM(args_, 1)); + arg_from_python c1(PyTuple_GET_ITEM(args_, 1)); if (!c1.convertible()) return 0; diff --git a/include/boost/python/detail/force_instantiate.hpp b/include/boost/python/detail/force_instantiate.hpp new file mode 100755 index 00000000..6248501c --- /dev/null +++ b/include/boost/python/detail/force_instantiate.hpp @@ -0,0 +1,18 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FORCE_INSTANTIATE_DWA200265_HPP +# define FORCE_INSTANTIATE_DWA200265_HPP + +namespace boost { namespace python { namespace detail { + +// Allows us to force the argument to be instantiated without +// incurring unused variable warnings +template +inline void force_instantiate(T const&) {} + +}}} // namespace boost::python::detail + +#endif // FORCE_INSTANTIATE_DWA200265_HPP diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 8ffc2286..441460ea 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -14,7 +14,7 @@ # include # include # include -# include +# include # include # include @@ -38,7 +38,7 @@ struct returning # endif # define BOOST_PYTHON_ARG_CONVERTIBLE(index,ignored) \ - from_python \ + arg_from_python \ BOOST_PP_CAT(c,index)(PyTuple_GET_ITEM(args_, index)); \ if (!BOOST_PP_CAT(c,index).convertible()) return 0; @@ -54,7 +54,7 @@ struct returning { \ /* check that each of the arguments is convertible */ \ /* self argument is special */ \ - from_python c0(PyTuple_GET_ITEM(args_, 0)); \ + arg_from_python c0(PyTuple_GET_ITEM(args_, 0)); \ if (!c0.convertible()) return 0; \ \ /* Unroll a loop for the rest of them */ \ @@ -68,7 +68,7 @@ struct returning if (!policies->precall(args_)) return 0; \ \ PyObject* result = cr( \ - ((BOOST_PYTHON_GET_ARG(0,nil))->*pmf)( \ + ((BOOST_PYTHON_GET_ARG(0,nil)).*pmf)( \ BOOST_PP_ENUM_SHIFTED(args,BOOST_PYTHON_GET_ARG,nil)) \ ); \ \ @@ -125,7 +125,7 @@ static PyObject*call( \ { \ /* check that each of the arguments is convertible */ \ /* self argument is special */ \ - from_pythonc0(PyTuple_GET_ITEM(args_,0)); \ + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); \ if (!c0.convertible()) return 0; \ \ /* Unroll a loop for the rest of them */ \ @@ -133,7 +133,7 @@ static PyObject*call( \ \ if (!policies->precall(args_)) return 0; \ \ - ((c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( \ + ((c0(PyTuple_GET_ITEM(args_,0))).*pmf)( \ BOOST_PP_ENUM_SHIFTED(args,BOOST_PYTHON_GET_ARG,nil) \ ); \ \ diff --git a/include/boost/python/detail/unwind_type.hpp b/include/boost/python/detail/unwind_type.hpp index 72ebef71..7d1fe390 100644 --- a/include/boost/python/detail/unwind_type.hpp +++ b/include/boost/python/detail/unwind_type.hpp @@ -7,6 +7,8 @@ # define UNWIND_TYPE_DWA200222_HPP # include +# include +# include namespace boost { namespace python { namespace detail { diff --git a/include/boost/python/from_python.hpp b/include/boost/python/from_python.hpp index 340a014a..4219bc2d 100644 --- a/include/boost/python/from_python.hpp +++ b/include/boost/python/from_python.hpp @@ -1,3 +1,4 @@ +#error obsolete // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided @@ -12,7 +13,7 @@ namespace boost { namespace python { template struct from_python - : converter::select_from_python::type + : converter::select_arg_from_python::type { typedef typename converter::select_from_python::type base; from_python(PyObject*); diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index 23260701..e396dc25 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -12,6 +12,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -69,16 +70,13 @@ struct register_base_of }; }; -template -inline void force_instantiate(T const&) {} - // Brings into existence all converters associated with a class Bases // is expected to be an mpl sequence of base types. template inline void register_class_from_python(Derived* = 0, Bases* = 0) { // cause the static registration to be instantiated. - force_instantiate(instance_finder::registration); + python::detail::force_instantiate(instance_finder::registration); // register all up/downcasts here register_dynamic_id(); diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 1319425f..a237d5d7 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -13,7 +13,7 @@ # include # include # include -# include +# include # include # include # include @@ -63,7 +63,7 @@ namespace detail typedef iterator_range range_; PyObject* py_self = PyTuple_GET_ITEM(args_, 0); - from_python c0(py_self); + arg_from_python c0(py_self); range_* self = c0(py_self); // Done iterating? @@ -167,9 +167,9 @@ namespace detail // Extract x from the first argument PyObject* arg0 = PyTuple_GET_ITEM(args_, 0); - from_python c0(arg0); + arg_from_python c0(arg0); if (!c0.convertible()) return 0; - typename from_python::result_type x = c0(arg0); + typename arg_from_python::result_type x = c0(arg0); // Build and convert the iterator_range<>. return cr( diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 6d0ef81c..6912da25 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -17,6 +17,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -66,19 +67,19 @@ struct pointer_holder_back_reference : instance_holder # include # endif -# define BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER_BACK_REFERENCE(nargs, ignored) \ - BOOST_PP_EXPR_IF(nargs, template <) \ - BOOST_PP_ENUM_PARAMS(nargs, class A) \ - BOOST_PP_EXPR_IF(nargs, >) \ - pointer_holder_back_reference(PyObject* p \ - BOOST_PP_COMMA_IF(nargs) \ - BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ - : m_p(new held_type( \ - p BOOST_PP_COMMA_IF(nargs) \ - BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ - )) \ - { \ - void const* x = &instance_finder::registration; (void)x; \ +# define BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER_BACK_REFERENCE(nargs, ignored) \ + BOOST_PP_EXPR_IF(nargs, template <) \ + BOOST_PP_ENUM_PARAMS(nargs, class A) \ + BOOST_PP_EXPR_IF(nargs, >) \ + pointer_holder_back_reference(PyObject* p \ + BOOST_PP_COMMA_IF(nargs) \ + BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ + : m_p(new held_type( \ + p BOOST_PP_COMMA_IF(nargs) \ + BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ + )) \ + { \ + python::detail::force_instantiate(instance_finder::registration); \ } BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER_BACK_REFERENCE,nil) diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index e722d6b6..d4469561 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -14,6 +14,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -54,19 +55,19 @@ struct value_holder_back_reference : instance_holder # include # endif -# define BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER_BACK_REFERENCE(nargs, ignored) \ - BOOST_PP_EXPR_IF(nargs, template <) \ - BOOST_PP_ENUM_PARAMS(nargs, class A) \ - BOOST_PP_EXPR_IF(nargs, >) \ - value_holder_back_reference(PyObject* p \ - BOOST_PP_COMMA_IF(nargs) \ - BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ - : m_held( \ - p BOOST_PP_COMMA_IF(nargs) \ - BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ - ) \ - { \ - void const* x = &instance_finder::registration; (void)x; \ +# define BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER_BACK_REFERENCE(nargs, ignored) \ + BOOST_PP_EXPR_IF(nargs, template <) \ + BOOST_PP_ENUM_PARAMS(nargs, class A) \ + BOOST_PP_EXPR_IF(nargs, >) \ + value_holder_back_reference(PyObject* p \ + BOOST_PP_COMMA_IF(nargs) \ + BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ + : m_held( \ + p BOOST_PP_COMMA_IF(nargs) \ + BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ + ) \ + { \ + python::detail::force_instantiate(instance_finder::registration); \ } BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER_BACK_REFERENCE,nil) diff --git a/include/boost/python/operators2.hpp b/include/boost/python/operators2.hpp index 36d5e16b..aa97071f 100755 --- a/include/boost/python/operators2.hpp +++ b/include/boost/python/operators2.hpp @@ -7,9 +7,10 @@ # define OPERATORS2_DWA2002530_HPP # include -# include +# include # include # include +# include # include # include # include @@ -26,7 +27,7 @@ namespace detail template PyObject* convert_result(T const& x) { - return converter::callback_to_python(x).get_incref(); + return converter::arg_to_python(x).get_incref(); } // Operator implementation template declarations. The nested apply diff --git a/include/boost/python/preprocessed/call.hpp b/include/boost/python/preprocessed/call.hpp index 51b9aa79..8280cd93 100644 --- a/include/boost/python/preprocessed/call.hpp +++ b/include/boost/python/preprocessed/call.hpp @@ -11,268 +11,268 @@ // (replace-string "PyEval_CallFunction(" "\nPyEval_CallFunction(\n") template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" ")"))); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" ")") - ,converter::callback_to_python(a0).get())); + ,converter::arg_to_python(a0).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get() - ,converter::callback_to_python(a10).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get() + ,converter::arg_to_python(a10).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get() - ,converter::callback_to_python(a10).get() - ,converter::callback_to_python(a11).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get() + ,converter::arg_to_python(a10).get() + ,converter::arg_to_python(a11).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get() - ,converter::callback_to_python(a10).get() - ,converter::callback_to_python(a11).get() - ,converter::callback_to_python(a12).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get() + ,converter::arg_to_python(a10).get() + ,converter::arg_to_python(a11).get() + ,converter::arg_to_python(a12).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get() - ,converter::callback_to_python(a10).get() - ,converter::callback_to_python(a11).get() - ,converter::callback_to_python(a12).get() - ,converter::callback_to_python(a13).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get() + ,converter::arg_to_python(a10).get() + ,converter::arg_to_python(a11).get() + ,converter::arg_to_python(a12).get() + ,converter::arg_to_python(a13).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallFunction( callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get() - ,converter::callback_to_python(a10).get() - ,converter::callback_to_python(a11).get() - ,converter::callback_to_python(a12).get() - ,converter::callback_to_python(a13).get() - ,converter::callback_to_python(a14).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get() + ,converter::arg_to_python(a10).get() + ,converter::arg_to_python(a11).get() + ,converter::arg_to_python(a12).get() + ,converter::arg_to_python(a13).get() + ,converter::arg_to_python(a14).get())); } #endif // CALL_PP_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/call_method.hpp b/include/boost/python/preprocessed/call_method.hpp index ea989e63..6ce1ecfb 100644 --- a/include/boost/python/preprocessed/call_method.hpp +++ b/include/boost/python/preprocessed/call_method.hpp @@ -11,267 +11,267 @@ // (replace-string "PyEval_CallMethod(" "\nPyEval_CallMethod(\n") template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" ")"))); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" ")") - ,converter::callback_to_python(a0).get())); + ,converter::arg_to_python(a0).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get() - ,converter::callback_to_python(a10).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get() + ,converter::arg_to_python(a10).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get() - ,converter::callback_to_python(a10).get() - ,converter::callback_to_python(a11).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get() + ,converter::arg_to_python(a10).get() + ,converter::arg_to_python(a11).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get() - ,converter::callback_to_python(a10).get() - ,converter::callback_to_python(a11).get() - ,converter::callback_to_python(a12).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get() + ,converter::arg_to_python(a10).get() + ,converter::arg_to_python(a11).get() + ,converter::arg_to_python(a12).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get() - ,converter::callback_to_python(a10).get() - ,converter::callback_to_python(a11).get() - ,converter::callback_to_python(a12).get() - ,converter::callback_to_python(a13).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get() + ,converter::arg_to_python(a10).get() + ,converter::arg_to_python(a11).get() + ,converter::arg_to_python(a12).get() + ,converter::arg_to_python(a13).get())); } template -typename converter::callback_from_python::result_type +typename converter::return_from_python::result_type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14,boost::type* =0) { - converter::callback_from_pythonconverter; + converter::return_from_pythonconverter; return converter( PyEval_CallMethod( self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::callback_to_python(a0).get() - ,converter::callback_to_python(a1).get() - ,converter::callback_to_python(a2).get() - ,converter::callback_to_python(a3).get() - ,converter::callback_to_python(a4).get() - ,converter::callback_to_python(a5).get() - ,converter::callback_to_python(a6).get() - ,converter::callback_to_python(a7).get() - ,converter::callback_to_python(a8).get() - ,converter::callback_to_python(a9).get() - ,converter::callback_to_python(a10).get() - ,converter::callback_to_python(a11).get() - ,converter::callback_to_python(a12).get() - ,converter::callback_to_python(a13).get() - ,converter::callback_to_python(a14).get())); + ,converter::arg_to_python(a0).get() + ,converter::arg_to_python(a1).get() + ,converter::arg_to_python(a2).get() + ,converter::arg_to_python(a3).get() + ,converter::arg_to_python(a4).get() + ,converter::arg_to_python(a5).get() + ,converter::arg_to_python(a6).get() + ,converter::arg_to_python(a7).get() + ,converter::arg_to_python(a8).get() + ,converter::arg_to_python(a9).get() + ,converter::arg_to_python(a10).get() + ,converter::arg_to_python(a11).get() + ,converter::arg_to_python(a12).get() + ,converter::arg_to_python(a13).get() + ,converter::arg_to_python(a14).get())); } #endif// CALL_METHOD_PP_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/ptr_holder_back_reference.hpp b/include/boost/python/preprocessed/ptr_holder_back_reference.hpp index 882e1788..78247790 100644 --- a/include/boost/python/preprocessed/ptr_holder_back_reference.hpp +++ b/include/boost/python/preprocessed/ptr_holder_back_reference.hpp @@ -15,8 +15,8 @@ pointer_holder_back_reference(PyObject*p) :m_p(new held_type( p)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0) @@ -24,8 +24,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0) p ,(typename unforward::type)(a0))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1) @@ -34,8 +34,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1) ,(typename unforward::type)(a0) ,(typename unforward::type)(a1))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) @@ -45,8 +45,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) ,(typename unforward::type)(a1) ,(typename unforward::type)(a2))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) @@ -57,8 +57,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) ,(typename unforward::type)(a2) ,(typename unforward::type)(a3))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) @@ -70,8 +70,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) ,(typename unforward::type)(a3) ,(typename unforward::type)(a4))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) @@ -84,8 +84,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) ,(typename unforward::type)(a4) ,(typename unforward::type)(a5))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) @@ -99,8 +99,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 ,(typename unforward::type)(a5) ,(typename unforward::type)(a6))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) @@ -115,8 +115,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 ,(typename unforward::type)(a6) ,(typename unforward::type)(a7))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) @@ -132,8 +132,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 ,(typename unforward::type)(a7) ,(typename unforward::type)(a8))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) @@ -150,8 +150,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 ,(typename unforward::type)(a8) ,(typename unforward::type)(a9))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) @@ -169,8 +169,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 ,(typename unforward::type)(a9) ,(typename unforward::type)(a10))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11) @@ -189,8 +189,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 ,(typename unforward::type)(a10) ,(typename unforward::type)(a11))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12) @@ -210,8 +210,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 ,(typename unforward::type)(a11) ,(typename unforward::type)(a12))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13) @@ -232,8 +232,8 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 ,(typename unforward::type)(a12) ,(typename unforward::type)(a13))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13,A14 a14) @@ -255,7 +255,7 @@ pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 ,(typename unforward::type)(a13) ,(typename unforward::type)(a14))) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } #endif//POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/returning_non_void.hpp b/include/boost/python/preprocessed/returning_non_void.hpp index c677a072..ebf35cdd 100644 --- a/include/boost/python/preprocessed/returning_non_void.hpp +++ b/include/boost/python/preprocessed/returning_non_void.hpp @@ -13,47 +13,47 @@ template static PyObject*call(R(A0::*pmf)(),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)()); + c0(PyTuple_GET_ITEM(args_,0))).*pmf)()); return policies->postcall(args_,result); } template static PyObject*call(R(A0::*pmf)(A1),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)))); return policies->postcall(args_,result); } template static PyObject*call(R(A0::*pmf)(A1,A2),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)))); return policies->postcall(args_,result); @@ -61,20 +61,20 @@ static PyObject*call(R(A0::*pmf)(A1,A2),PyObject*args_,PyObject*,P const*policie template static PyObject*call(R(A0::*pmf)(A1,A2,A3),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)))); @@ -83,22 +83,22 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3),PyObject*args_,PyObject*,P const*poli template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -108,24 +108,24 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4),PyObject*args_,PyObject*,P const*p template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -136,26 +136,26 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P cons template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -167,28 +167,28 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P c template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -201,30 +201,30 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*, template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -238,32 +238,32 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObjec template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -278,34 +278,34 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyOb template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -321,36 +321,36 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_, template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -367,38 +367,38 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*ar template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -416,40 +416,40 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObjec template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -468,42 +468,42 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyO template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -523,44 +523,44 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14) template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; - from_pythonc15(PyTuple_GET_ITEM(args_,15)); + arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); if(!c15.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -581,47 +581,47 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14, template static PyObject*call(R(A0::*pmf)()const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)()); + c0(PyTuple_GET_ITEM(args_,0))).*pmf)()); return policies->postcall(args_,result); } template static PyObject*call(R(A0::*pmf)(A1)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)))); return policies->postcall(args_,result); } template static PyObject*call(R(A0::*pmf)(A1,A2)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)))); return policies->postcall(args_,result); @@ -629,20 +629,20 @@ static PyObject*call(R(A0::*pmf)(A1,A2)const,PyObject*args_,PyObject*,P const*po template static PyObject*call(R(A0::*pmf)(A1,A2,A3)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)))); @@ -651,22 +651,22 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3)const,PyObject*args_,PyObject*,P const template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -676,24 +676,24 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const,PyObject*args_,PyObject*,P co template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -704,26 +704,26 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const,PyObject*args_,PyObject*,P template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -735,28 +735,28 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const,PyObject*args_,PyObject template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -769,30 +769,30 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args_,PyObj template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -806,32 +806,32 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args_,Py template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -846,34 +846,34 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args_ template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -889,36 +889,36 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,PyObject*a template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -935,38 +935,38 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,PyObje template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -984,40 +984,40 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,Py template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1036,42 +1036,42 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)cons template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1091,44 +1091,44 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14) template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; - from_pythonc15(PyTuple_GET_ITEM(args_,15)); + arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); if(!c15.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1149,47 +1149,47 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14, template static PyObject*call(R(A0::*pmf)()volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)()); + c0(PyTuple_GET_ITEM(args_,0))).*pmf)()); return policies->postcall(args_,result); } template static PyObject*call(R(A0::*pmf)(A1)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)))); return policies->postcall(args_,result); } template static PyObject*call(R(A0::*pmf)(A1,A2)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)))); return policies->postcall(args_,result); @@ -1197,20 +1197,20 @@ static PyObject*call(R(A0::*pmf)(A1,A2)volatile,PyObject*args_,PyObject*,P const template static PyObject*call(R(A0::*pmf)(A1,A2,A3)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)))); @@ -1219,22 +1219,22 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3)volatile,PyObject*args_,PyObject*,P co template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1244,24 +1244,24 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)volatile,PyObject*args_,PyObject*,P template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1272,26 +1272,26 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)volatile,PyObject*args_,PyObject template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1303,28 +1303,28 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args_,PyObj template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1337,30 +1337,30 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args_,Py template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1374,32 +1374,32 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args_ template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1414,34 +1414,34 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*ar template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1457,36 +1457,36 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,PyObjec template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1503,38 +1503,38 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,PyO template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1552,40 +1552,40 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1604,42 +1604,42 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)vola template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1659,44 +1659,44 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14) template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; - from_pythonc15(PyTuple_GET_ITEM(args_,15)); + arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); if(!c15.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1717,47 +1717,47 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14, template static PyObject*call(R(A0::*pmf)()const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)()); + c0(PyTuple_GET_ITEM(args_,0))).*pmf)()); return policies->postcall(args_,result); } template static PyObject*call(R(A0::*pmf)(A1)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)))); return policies->postcall(args_,result); } template static PyObject*call(R(A0::*pmf)(A1,A2)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)))); return policies->postcall(args_,result); @@ -1765,20 +1765,20 @@ static PyObject*call(R(A0::*pmf)(A1,A2)const volatile,PyObject*args_,PyObject*,P template static PyObject*call(R(A0::*pmf)(A1,A2,A3)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)))); @@ -1787,22 +1787,22 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3)const volatile,PyObject*args_,PyObject template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1812,24 +1812,24 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const volatile,PyObject*args_,PyObj template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1840,26 +1840,26 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const volatile,PyObject*args_,Py template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1871,28 +1871,28 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args_ template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1905,30 +1905,30 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*ar template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1942,32 +1942,32 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -1982,34 +1982,34 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObj template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -2025,36 +2025,36 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,P template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -2071,38 +2071,38 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volati template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -2120,40 +2120,40 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const vo template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -2172,42 +2172,42 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)cons template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -2227,44 +2227,44 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14) template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; - from_pythonc15(PyTuple_GET_ITEM(args_,15)); + arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); if(!c15.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; if(!cr.convertible())return 0; if(!policies->precall(args_))return 0; PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) , c2(PyTuple_GET_ITEM(args_,2)) , c3(PyTuple_GET_ITEM(args_,3)) @@ -2295,7 +2295,7 @@ static PyObject*call(R(*pf)(),PyObject*args_,PyObject*,P const*policies) template static PyObject*call(R(*pf)(A0),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2308,9 +2308,9 @@ static PyObject*call(R(*pf)(A0),PyObject*args_,PyObject*,P const*policies) template static PyObject*call(R(*pf)(A0,A1),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2324,11 +2324,11 @@ static PyObject*call(R(*pf)(A0,A1),PyObject*args_,PyObject*,P const*policies) template static PyObject*call(R(*pf)(A0,A1,A2),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2343,13 +2343,13 @@ static PyObject*call(R(*pf)(A0,A1,A2),PyObject*args_,PyObject*,P const*policies) template static PyObject*call(R(*pf)(A0,A1,A2,A3),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2365,15 +2365,15 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3),PyObject*args_,PyObject*,P const*polici template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2390,17 +2390,17 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4),PyObject*args_,PyObject*,P const*pol template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2418,19 +2418,19 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const* template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2449,21 +2449,21 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P con template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2483,23 +2483,23 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2520,25 +2520,25 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject* template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2560,27 +2560,27 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObje template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2603,29 +2603,29 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,Py template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2649,31 +2649,31 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2698,33 +2698,33 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject* template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; @@ -2750,35 +2750,35 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObj template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; typedef typename P::result_converter result_converter; typename mpl::apply1::type cr; diff --git a/include/boost/python/preprocessed/returning_void.hpp b/include/boost/python/preprocessed/returning_void.hpp index 2179c9d9..63f643f7 100644 --- a/include/boost/python/preprocessed/returning_void.hpp +++ b/include/boost/python/preprocessed/returning_void.hpp @@ -13,38 +13,38 @@ template static PyObject*call(R(A0::*pmf)(),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)(); + c0(PyTuple_GET_ITEM(args_,0))).*pmf)(); return policies->postcall(args_,detail::none()); } template static PyObject*call(R(A0::*pmf)(A1),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1))); return policies->postcall(args_,detail::none()); } template static PyObject*call(R(A0::*pmf)(A1,A2),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2))); return policies->postcall(args_,detail::none()); @@ -52,17 +52,17 @@ static PyObject*call(R(A0::*pmf)(A1,A2),PyObject*args_,PyObject*,P const*policie template static PyObject*call(R(A0::*pmf)(A1,A2,A3),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3))); @@ -71,19 +71,19 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3),PyObject*args_,PyObject*,P const*poli template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -93,21 +93,21 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4),PyObject*args_,PyObject*,P const*p template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -118,23 +118,23 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P cons template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -146,25 +146,25 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P c template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -177,27 +177,27 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*, template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -211,29 +211,29 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObjec template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -248,31 +248,31 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyOb template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -288,33 +288,33 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_, template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -331,35 +331,35 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*ar template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -377,37 +377,37 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObjec template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -426,39 +426,39 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyO template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -478,41 +478,41 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14) template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; - from_pythonc15(PyTuple_GET_ITEM(args_,15)); + arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); if(!c15.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -533,38 +533,38 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14, template static PyObject*call(R(A0::*pmf)()const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)(); + c0(PyTuple_GET_ITEM(args_,0))).*pmf)(); return policies->postcall(args_,detail::none()); } template static PyObject*call(R(A0::*pmf)(A1)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1))); return policies->postcall(args_,detail::none()); } template static PyObject*call(R(A0::*pmf)(A1,A2)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2))); return policies->postcall(args_,detail::none()); @@ -572,17 +572,17 @@ static PyObject*call(R(A0::*pmf)(A1,A2)const,PyObject*args_,PyObject*,P const*po template static PyObject*call(R(A0::*pmf)(A1,A2,A3)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3))); @@ -591,19 +591,19 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3)const,PyObject*args_,PyObject*,P const template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -613,21 +613,21 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const,PyObject*args_,PyObject*,P co template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -638,23 +638,23 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const,PyObject*args_,PyObject*,P template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -666,25 +666,25 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const,PyObject*args_,PyObject template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -697,27 +697,27 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args_,PyObj template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -731,29 +731,29 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args_,Py template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -768,31 +768,31 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args_ template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -808,33 +808,33 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,PyObject*a template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -851,35 +851,35 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,PyObje template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -897,37 +897,37 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,Py template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -946,39 +946,39 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)cons template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -998,41 +998,41 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14) template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; - from_pythonc15(PyTuple_GET_ITEM(args_,15)); + arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); if(!c15.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1053,38 +1053,38 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14, template static PyObject*call(R(A0::*pmf)()volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)(); + c0(PyTuple_GET_ITEM(args_,0))).*pmf)(); return policies->postcall(args_,detail::none()); } template static PyObject*call(R(A0::*pmf)(A1)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1))); return policies->postcall(args_,detail::none()); } template static PyObject*call(R(A0::*pmf)(A1,A2)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2))); return policies->postcall(args_,detail::none()); @@ -1092,17 +1092,17 @@ static PyObject*call(R(A0::*pmf)(A1,A2)volatile,PyObject*args_,PyObject*,P const template static PyObject*call(R(A0::*pmf)(A1,A2,A3)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3))); @@ -1111,19 +1111,19 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3)volatile,PyObject*args_,PyObject*,P co template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1133,21 +1133,21 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)volatile,PyObject*args_,PyObject*,P template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1158,23 +1158,23 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)volatile,PyObject*args_,PyObject template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1186,25 +1186,25 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args_,PyObj template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1217,27 +1217,27 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args_,Py template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1251,29 +1251,29 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args_ template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1288,31 +1288,31 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*ar template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1328,33 +1328,33 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,PyObjec template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1371,35 +1371,35 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,PyO template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1417,37 +1417,37 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1466,39 +1466,39 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)vola template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1518,41 +1518,41 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14) template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; - from_pythonc15(PyTuple_GET_ITEM(args_,15)); + arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); if(!c15.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1573,38 +1573,38 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14, template static PyObject*call(R(A0::*pmf)()const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)(); + c0(PyTuple_GET_ITEM(args_,0))).*pmf)(); return policies->postcall(args_,detail::none()); } template static PyObject*call(R(A0::*pmf)(A1)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1))); return policies->postcall(args_,detail::none()); } template static PyObject*call(R(A0::*pmf)(A1,A2)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2))); return policies->postcall(args_,detail::none()); @@ -1612,17 +1612,17 @@ static PyObject*call(R(A0::*pmf)(A1,A2)const volatile,PyObject*args_,PyObject*,P template static PyObject*call(R(A0::*pmf)(A1,A2,A3)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3))); @@ -1631,19 +1631,19 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3)const volatile,PyObject*args_,PyObject template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1653,21 +1653,21 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const volatile,PyObject*args_,PyObj template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1678,23 +1678,23 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const volatile,PyObject*args_,Py template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1706,25 +1706,25 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args_ template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1737,27 +1737,27 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*ar template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1771,29 +1771,29 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1808,31 +1808,31 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObj template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1848,33 +1848,33 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,P template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1891,35 +1891,35 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volati template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1937,37 +1937,37 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const vo template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -1986,39 +1986,39 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)cons template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -2038,41 +2038,41 @@ static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14) template static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; - from_pythonc15(PyTuple_GET_ITEM(args_,15)); + arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); if(!c15.convertible())return 0; if(!policies->precall(args_))return 0; (( - c0(PyTuple_GET_ITEM(args_,0)))->*pmf)( + c0(PyTuple_GET_ITEM(args_,0))).*pmf)( c1(PyTuple_GET_ITEM(args_,1)) ,c2(PyTuple_GET_ITEM(args_,2)) ,c3(PyTuple_GET_ITEM(args_,3)) @@ -2100,7 +2100,7 @@ static PyObject*call(R(*pf)(),PyObject*args_,PyObject*,P const*policies) template static PyObject*call(R(*pf)(A0),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2110,9 +2110,9 @@ static PyObject*call(R(*pf)(A0),PyObject*args_,PyObject*,P const*policies) template static PyObject*call(R(*pf)(A0,A1),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2123,11 +2123,11 @@ static PyObject*call(R(*pf)(A0,A1),PyObject*args_,PyObject*,P const*policies) template static PyObject*call(R(*pf)(A0,A1,A2),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2139,13 +2139,13 @@ static PyObject*call(R(*pf)(A0,A1,A2),PyObject*args_,PyObject*,P const*policies) template static PyObject*call(R(*pf)(A0,A1,A2,A3),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2158,15 +2158,15 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3),PyObject*args_,PyObject*,P const*polici template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2180,17 +2180,17 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4),PyObject*args_,PyObject*,P const*pol template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2205,19 +2205,19 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const* template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2233,21 +2233,21 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P con template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2264,23 +2264,23 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2298,25 +2298,25 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject* template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2335,27 +2335,27 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObje template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2375,29 +2375,29 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,Py template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2418,31 +2418,31 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2464,33 +2464,33 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject* template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( @@ -2513,35 +2513,35 @@ static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObj template static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) { - from_pythonc0(PyTuple_GET_ITEM(args_,0)); + arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); if(!c0.convertible())return 0; - from_pythonc1(PyTuple_GET_ITEM(args_,1)); + arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); if(!c1.convertible())return 0; - from_pythonc2(PyTuple_GET_ITEM(args_,2)); + arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); if(!c2.convertible())return 0; - from_pythonc3(PyTuple_GET_ITEM(args_,3)); + arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); if(!c3.convertible())return 0; - from_pythonc4(PyTuple_GET_ITEM(args_,4)); + arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); if(!c4.convertible())return 0; - from_pythonc5(PyTuple_GET_ITEM(args_,5)); + arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); if(!c5.convertible())return 0; - from_pythonc6(PyTuple_GET_ITEM(args_,6)); + arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); if(!c6.convertible())return 0; - from_pythonc7(PyTuple_GET_ITEM(args_,7)); + arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); if(!c7.convertible())return 0; - from_pythonc8(PyTuple_GET_ITEM(args_,8)); + arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); if(!c8.convertible())return 0; - from_pythonc9(PyTuple_GET_ITEM(args_,9)); + arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); if(!c9.convertible())return 0; - from_pythonc10(PyTuple_GET_ITEM(args_,10)); + arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); if(!c10.convertible())return 0; - from_pythonc11(PyTuple_GET_ITEM(args_,11)); + arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); if(!c11.convertible())return 0; - from_pythonc12(PyTuple_GET_ITEM(args_,12)); + arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); if(!c12.convertible())return 0; - from_pythonc13(PyTuple_GET_ITEM(args_,13)); + arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); if(!c13.convertible())return 0; - from_pythonc14(PyTuple_GET_ITEM(args_,14)); + arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); if(!c14.convertible())return 0; if(!policies->precall(args_))return 0; (*pf)( diff --git a/include/boost/python/preprocessed/value_holder_back_reference.hpp b/include/boost/python/preprocessed/value_holder_back_reference.hpp index 76fc18ed..c5b06020 100644 --- a/include/boost/python/preprocessed/value_holder_back_reference.hpp +++ b/include/boost/python/preprocessed/value_holder_back_reference.hpp @@ -13,16 +13,16 @@ value_holder_back_reference(PyObject*p) :m_held(p) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0) :m_held(p ,(typename unforward::type)(a0)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1) @@ -30,8 +30,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1) ,(typename unforward::type)(a0) ,(typename unforward::type)(a1)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) @@ -40,8 +40,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) ,(typename unforward::type)(a1) ,(typename unforward::type)(a2)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) @@ -51,8 +51,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) ,(typename unforward::type)(a2) ,(typename unforward::type)(a3)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) @@ -63,8 +63,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) ,(typename unforward::type)(a3) ,(typename unforward::type)(a4)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) @@ -76,8 +76,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) ,(typename unforward::type)(a4) ,(typename unforward::type)(a5)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) @@ -90,8 +90,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6 ,(typename unforward::type)(a5) ,(typename unforward::type)(a6)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) @@ -105,8 +105,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6 ,(typename unforward::type)(a6) ,(typename unforward::type)(a7)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) @@ -121,8 +121,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6 ,(typename unforward::type)(a7) ,(typename unforward::type)(a8)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) @@ -138,8 +138,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6 ,(typename unforward::type)(a8) ,(typename unforward::type)(a9)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) @@ -156,8 +156,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6 ,(typename unforward::type)(a9) ,(typename unforward::type)(a10)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11) @@ -175,8 +175,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6 ,(typename unforward::type)(a10) ,(typename unforward::type)(a11)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12) @@ -195,8 +195,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6 ,(typename unforward::type)(a11) ,(typename unforward::type)(a12)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13) @@ -216,8 +216,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6 ,(typename unforward::type)(a12) ,(typename unforward::type)(a13)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } template value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13,A14 a14) @@ -238,8 +238,8 @@ value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6 ,(typename unforward::type)(a13) ,(typename unforward::type)(a14)) { - void const*x=&instance_finder::registration; - (void)x; + python::detail::force_instantiate( + instance_finder::registration); } #endif // VALUE_HOLDER_BACK_REFERENCE_DWA2002411_HPP diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index 5d468c9f..480cd909 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -10,6 +10,7 @@ # include # include # include +# include # include # include diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index f0aa9b7c..c495445d 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -66,7 +66,7 @@ namespace }; // A SlotPolicy for extracting integer types from Python objects - struct int_rvalue_from_python + struct int_rvalue_from_python_base { static unaryfunc* get_slot(PyObject* obj) { @@ -84,20 +84,96 @@ namespace return &number_methods->nb_int; } - - static long extract(PyObject* intermediate) + }; + + template + struct int_rvalue_from_python : int_rvalue_from_python_base + { + static T extract(PyObject* intermediate) { - if (PyFloat_Check(intermediate)) - { - return numeric_cast(PyFloat_AS_DOUBLE(intermediate)); - } - else + return numeric_cast( + PyFloat_Check(intermediate) + ? PyFloat_AS_DOUBLE(intermediate) + : PyInt_AS_LONG(intermediate) + ); + } + }; + +#ifdef BOOST_HAS_LONG_LONG + // A SlotPolicy for extracting long long types from Python objects + struct long_long_rvalue_from_python_base + { + static unaryfunc* get_slot(PyObject* obj) + { + PyNumberMethods* number_methods = obj->ob_type->tp_as_number; + if (number_methods == 0) + return 0; + + // For floating and integer types, return the identity + // conversion slot to avoid creating a new object. We'll + // handle that in the extract function + if (PyInt_Check(obj)) + return &number_methods->nb_int; + + if (PyFloat_Check(obj)) + return &number_methods->nb_float; + + if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__long__")) + return 0; + + return &number_methods->nb_long; + } + }; + + struct long_long_rvalue_from_python : long_long_rvalue_from_python_base + { + static long long extract(PyObject* intermediate) + { + if (PyInt_Check(intermediate)) { return PyInt_AS_LONG(intermediate); } + if (PyFloat_Check(intermediate)) + { + return numeric_cast(PyFloat_AS_DOUBLE(intermediate)); + } + else + { + long long result = PyLong_AsLongLong(intermediate); + + if (PyErr_Occurred()) + throw_error_already_set(); + + return result; + } } }; + struct unsigned_long_long_rvalue_from_python : long_long_rvalue_from_python_base + { + static unsigned long long extract(PyObject* intermediate) + { + if (PyInt_Check(intermediate)) + { + return numeric_cast(PyInt_AS_LONG(intermediate)); + } + if (PyFloat_Check(intermediate)) + { + return numeric_cast(PyFloat_AS_DOUBLE(intermediate)); + } + else + { + unsigned long long result = PyLong_AsUnsignedLongLong(intermediate); + + if (PyErr_Occurred()) + throw_error_already_set(); + + return result; + } + } + }; +#endif + // identity_unaryfunc/py_object_identity -- manufacture a unaryfunc // "slot" which just returns its argument. Used for bool @@ -177,9 +253,10 @@ namespace }; - // identity_unaryfunc/non_null -- manufacture a unaryfunc "slot" - // which just returns its argument. Used for bool conversions, since - // all Python objects are directly convertible to bool + // to_complex_unaryfunc/py_object_to_complex -- manufacture a + // unaryfunc "slot" which calls its argument's __complex__ + // method. We have this because there's no type object nb_complex + // slot. extern "C" PyObject* to_complex_unaryfunc(PyObject* x) { return PyObject_CallMethod(x, "__complex__", const_cast("()")); @@ -233,22 +310,22 @@ namespace }; } -BOOST_PYTHON_DECL PyObject* do_call_to_python(char x) +BOOST_PYTHON_DECL PyObject* do_return_to_python(char x) { return PyString_FromStringAndSize(&x, 1); } -BOOST_PYTHON_DECL PyObject* do_call_to_python(char const* x) +BOOST_PYTHON_DECL PyObject* do_return_to_python(char const* x) { return x ? PyString_FromString(x) : boost::python::detail::none(); } -BOOST_PYTHON_DECL PyObject* do_call_to_python(PyObject* x) +BOOST_PYTHON_DECL PyObject* do_return_to_python(PyObject* x) { return x ? x : boost::python::detail::none(); } -BOOST_PYTHON_DECL PyObject* do_callback_to_python(PyObject* x) +BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject* x) { if (x == 0) return boost::python::detail::none(); @@ -257,7 +334,7 @@ BOOST_PYTHON_DECL PyObject* do_callback_to_python(PyObject* x) return x; } -#define REGISTER_INT_CONVERTERS(U) slot_rvalue_from_python() +#define REGISTER_INT_CONVERTERS(U) slot_rvalue_from_python >() #define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U) void initialize_builtin_converters() @@ -270,7 +347,12 @@ void initialize_builtin_converters() REGISTER_INT_CONVERTERS2(short); REGISTER_INT_CONVERTERS2(int); REGISTER_INT_CONVERTERS2(long); - + +# ifdef BOOST_HAS_LONG_LONG + slot_rvalue_from_python(); + slot_rvalue_from_python(); +# endif + // floating types slot_rvalue_from_python(); slot_rvalue_from_python(); diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index b96b57e7..bd6aa904 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -4,7 +4,7 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include #include #include #include @@ -33,9 +33,9 @@ namespace detail } } - callback_to_python_base::callback_to_python_base( + arg_to_python_base::arg_to_python_base( void const volatile* source, to_python_function_t converter) - : callback_to_python_holder(convert(source, converter)) + : arg_to_python_holder(convert(source, converter)) { } diff --git a/src/errors.cpp b/src/errors.cpp index 91ac7b99..6d0cfd90 100644 --- a/src/errors.cpp +++ b/src/errors.cpp @@ -9,6 +9,7 @@ #endif #include +#include namespace boost { namespace python { @@ -28,6 +29,10 @@ BOOST_PYTHON_DECL bool handle_exception_impl(function0 f) { PyErr_NoMemory(); } + catch(const bad_numeric_cast& x) + { + PyErr_SetString(PyExc_OverflowError, x.what()); + } catch(const std::exception& x) { PyErr_SetString(PyExc_RuntimeError, x.what()); diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 2778c7b6..4d8ead2c 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -91,6 +91,11 @@ char apply_char_char(PyObject* f, char c) return call(f, c); } +char const* apply_to_string_literal(PyObject* f) +{ + return call(f, "hello, world"); +} + int X::counter; BOOST_PYTHON_MODULE_INIT(callbacks_ext) @@ -113,6 +118,7 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) .def("apply_cstring_cstring", apply_cstring_cstring) .def("apply_cstring_pyobject", apply_cstring_pyobject) .def("apply_char_char", apply_char_char) + .def("apply_to_string_literal", apply_to_string_literal) .add( class_("X") diff --git a/test/callbacks.py b/test/callbacks.py index 71ad3fb7..9a48ec2c 100644 --- a/test/callbacks.py +++ b/test/callbacks.py @@ -11,6 +11,13 @@ >>> def identity(x): ... return x +Once we have array conversion support, this test will fail. Er, +succeed: + +>>> try: apply_to_string_literal(identity) +... except: pass # expected +... else: print 'expected an exception!' + >>> x = apply_X_X(identity, X(42)) >>> x.value() 42 diff --git a/test/newtest.py b/test/newtest.py index 59b25e74..0edd34b8 100644 --- a/test/newtest.py +++ b/test/newtest.py @@ -79,12 +79,23 @@ are a complicated constructor and member function, respectively. >>> c2.get_n() 0 + a quick regression test for a bug where None could be converted + to the target of any member function. To see it, we need to + access the __dict__ directly, to bypass the type check supplied + by the Method property which wraps the method when accessed as an + attribute. + +>>> try: A.__dict__['name'](None) +... except TypeError: pass +... else: print 'expected an exception!' + + >>> a = A() >>> b = B() >>> c = C() >>> d = D() ------- + >>> take_a(a).name() 'A' diff --git a/test/select_from_python_test.cpp b/test/select_from_python_test.cpp index b5648447..084f2e18 100644 --- a/test/select_from_python_test.cpp +++ b/test/select_from_python_test.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -28,128 +28,128 @@ int main() ASSERT_SAME( - select_from_python::type, rvalue_from_python + select_arg_from_python::type, arg_rvalue_from_python ); ASSERT_SAME( - select_from_python::type, rvalue_from_python + select_arg_from_python::type, arg_rvalue_from_python ); ASSERT_SAME( - select_from_python::type, rvalue_from_python + select_arg_from_python::type, arg_rvalue_from_python ); ASSERT_SAME( - select_from_python::type, rvalue_from_python + select_arg_from_python::type, arg_rvalue_from_python ); ASSERT_SAME( - select_from_python::type, pointer_from_python + select_arg_from_python::type, pointer_arg_from_python ); ASSERT_SAME( - select_from_python::type, pointer_from_python + select_arg_from_python::type, pointer_arg_from_python ); ASSERT_SAME( - select_from_python::type, pointer_from_python + select_arg_from_python::type, pointer_arg_from_python ); ASSERT_SAME( - select_from_python::type, pointer_from_python + select_arg_from_python::type, pointer_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, rvalue_from_python + select_arg_from_python::type, arg_rvalue_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, pointer_const_reference_from_python + select_arg_from_python::type, pointer_cref_arg_from_python ); ASSERT_SAME( - select_from_python::type, pointer_const_reference_from_python + select_arg_from_python::type, pointer_cref_arg_from_python ); ASSERT_SAME( - select_from_python::type, pointer_const_reference_from_python + select_arg_from_python::type, pointer_cref_arg_from_python ); ASSERT_SAME( - select_from_python::type, pointer_const_reference_from_python + select_arg_from_python::type, pointer_cref_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); ASSERT_SAME( - select_from_python::type, reference_from_python + select_arg_from_python::type, reference_arg_from_python ); return result; } diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp index 2066e0f8..25ad7fee 100644 --- a/test/test_builtin_converters.cpp +++ b/test/test_builtin_converters.cpp @@ -41,6 +41,10 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters) .def("rewrap_value_unsigned_short", by_value::rewrap) .def("rewrap_value_long", by_value::rewrap) .def("rewrap_value_unsigned_long", by_value::rewrap) +#ifdef BOOST_HAS_LONG_LONG + .def("rewrap_value_long_long", by_value::rewrap) + .def("rewrap_value_unsigned_long_long", by_value::rewrap) +#endif .def("rewrap_value_float", by_value::rewrap) .def("rewrap_value_double", by_value::rewrap) .def("rewrap_value_long_double", by_value::rewrap) @@ -64,6 +68,10 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters) .def("rewrap_const_reference_unsigned_short", by_const_reference::rewrap) .def("rewrap_const_reference_long", by_const_reference::rewrap) .def("rewrap_const_reference_unsigned_long", by_const_reference::rewrap) +#ifdef BOOST_HAS_LONG_LONG + .def("rewrap_const_reference_long_long", by_const_reference::rewrap) + .def("rewrap_const_reference_unsigned_long_long", by_const_reference::rewrap) +#endif .def("rewrap_const_reference_float", by_const_reference::rewrap) .def("rewrap_const_reference_double", by_const_reference::rewrap) .def("rewrap_const_reference_long_double", by_const_reference::rewrap) diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index 8f7b5e58..332c8927 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -1,5 +1,13 @@ """ >>> from builtin_converters import * + +# Synthesize idendity functions in case long long not supported +>>> if not 'rewrap_value_long_long' in dir(): +... def rewrap_value_long_long(x): return long(x) +... def rewrap_value_unsigned_long_long(x): return long(x) +... def rewrap_const_reference_long_long(x): return long(x) +... def rewrap_const_reference_unsigned_long_long(x): return long(x) + >>> rewrap_value_bool(None) 0 >>> rewrap_value_bool(0) @@ -30,6 +38,21 @@ 42 >>> rewrap_value_unsigned_long(42) 42 +>>> rewrap_value_long_long(42) +42L +>>> rewrap_value_unsigned_long_long(42) +42L + + show that we have range checking. + +>>> try: rewrap_value_unsigned_short(-42) +... except OverflowError: pass +... else: print 'expected an OverflowError!' + +>>> try: rewrap_value_int(must_be_long) +... except OverflowError: pass +... else: print 'expected an OverflowError!' + >>> abs(rewrap_value_float(4.2) - 4.2) < .000001 1 @@ -86,6 +109,11 @@ 42 >>> rewrap_const_reference_unsigned_long(42) 42 +>>> rewrap_const_reference_long_long(42) +42L +>>> rewrap_const_reference_unsigned_long_long(42) +42L + >>> abs(rewrap_const_reference_float(4.2) - 4.2) < .000001 1 @@ -153,6 +181,14 @@ Check that classic classes also work 1 """ +# compute a long value that's too big for an int +# note that some day these may be integrated, so +big_int = 1 +while (big_int << 1) > 0: + big_int <<= 1 +must_be_long = long(big_int) << 1 + + def run(args = None): import sys import doctest diff --git a/todo.txt b/todo.txt index d97eade5..3bcd16ac 100644 --- a/todo.txt +++ b/todo.txt @@ -1,426 +1,11 @@ -Check for const reference parameters in all from_python functions in py.h, including implementations. -Better python and C++ exception handling/error reporting. -long long support -use Python generic numeric coercion in from_python() for C++ numeric types -Rename PyPtr to Reference. -Report Cygwin linker memory issues -__init__ stuff - Make abstract classes non-instantiable (?) - Call default __init__ functions automatically where applicable (?) -Support for Python LONG types in Objects.h -Throw TypeError after asserting when objects from objects.cpp detect a type mismatch. -Figure out how to package everything as a shared library. -Unicode string support -Add read-only wrapper for __dict__ attribute -Objects.h support for generic objects, Sequence objects, etc. -empty() member functions for objects.hpp +Wrap enums as a subclass of Python int -Testing - Python 2.0 - object revival in __del__ - More thorough tests of objects.h/cpp classes - Better reference-count checking +Write "inside the Python type system", a survey of typeobject.c in +Python source -- may go hand-in-hand with enum wrapping -Optimizations - Remove one level of indirection on type objects (no vtbl?). - Specializations of Caller<> for commmon combinations of argument types (?) - Replace uses of XXXable classes - Don't allocate instance __dict__ unless used. - - -Documentation: +Better overload resolution - choose best match - differences between Python classes and ExtensionClasses - additional capabilities of ExtensionClasses - slice adjustment +Implement type_info streaming for GCC +(http://mail.python.org/pipermail/c++-sig/2002-June/001277.html) - Why special attributes other than __doc__ and __name__ are immutable. - An example of the problems with the built-in Python classes. - - >>> class A: - ... def __getattr__(self, name): - ... return 'A.__getattr__' - ... - >>> class B(A): pass - ... - >>> class C(B): pass - ... - >>> C().x - 'A.__getattr__' - >>> B.__bases__ = () - >>> C().x - 'A.__getattr__' - - Smart pointers - #ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE - namespace py { - #endif - - template - struct VtkConverters - { - typedef py::PyExtensionClassConverters Converters; - - friend vtk_ptr& from_python(PyObject* p, py::Type&>) - { return Converters::ptr_from_python(p, py::Type >()); } - - friend vtk_ptr& from_python(PyObject* p, py::Type >) - { return Converters::ptr_from_python(p, py::Type >()); } - - friend const vtk_ptr& from_python(PyObject* p, py::Type&>) - { return Converters::ptr_from_python(p, py::Type >()); } - - friend PyObject* to_python(vtk_ptr x) - { return Converters::ptr_to_python(x); } - }; - - #ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE - } - #endif - - template - struct VtkWrapper : py::ClassWrapper, py::VtkConverters - { - typedef py::ClassWrapper Base; - VtkWrapper(Module& module, const char* name) - : Base(module, name) {} - }; - - exception handling - - Advanced Topics: - Advanced Type Conversion - adding conversions for fundamental types - generic conversions for template types (with partial spec). - - Interacting with built-in Python objects and types from C++ - - dealing with non-const reference/pointer parameters - - extending multiple-argument support using gen_all.py - - - Fancy wrapping tricks - templates - Yes. If you look at the examples in extclass_demo.cpp you'll see that I have - exposed several template instantiations (e.g. std::pair) in Python. - Keep in mind, however, that you can only expose a template instantiation, - not a template. In other words, MyTemplate can be exposed. MyTemplate - itself cannot. - - Well, that's not strictly true. Wow, this is more complicated to explain - than I thought. - You can't make an ExtensionClass, since after all MyTemplate is - not a type. You can only expose a concrete type to Python. - - What you *can* do (if your compiler supports partial ordering of function - templates - MSVC is broken and does not) is to write appropriate - from_python() and to_python() functions for converting a whole class of - template instantiations to/from Python. That won't let you create an - instance of MyTemplate from Python, but it will let you - pass/return arbitrary MyTemplate instances to/from your - wrapped C++ functions. - - template - MyTemplate from_python(PyObject* x, py::Type >) - { - // code to convert x into a MyTemplate... that part is up to you - } - - template - PyObject* from_python(const MyTemplate&) - { - // code to convert MyTemplate into a PyObject*... that part is up to - you - } - - For example, you could use this to convert Python lists to/from - std::vector automatically. - - Pointer return values - - Case 1: - - > I am now also able to wrap the problematic TextRecordIterator for Python. - > However, one of its function compiles with this warning: - > - > d:\py_cpp/caller.h(33) : warning C4800: 'const class Record *const ' - > : forcing value to bool 'true' or 'false' (performance warning) - > d:\py_cpp/functions.h(54) : see reference to function template - > instantiation 'struct _object *__cdecl py::Caller::call(const class Record - > *const (__thiscall TextRecordIterator::*)(void),struct _object *,struct - > _object *)' being compiled - > - > If you look at the offending code, you'll see that we really do need to - > get back that pointer: - > - > const Record* const TextRecordIterator::Next() { - > if (fStatus != RecordIterator::SUCCESS) { - > return 0; - > } else { - > return &fData; - > } - > } - > - > The point of the TextRecordIterator is to hand over one reord after - > another. A bool wouldn't do us much good here :-) - > - > Do you have any suggestions for fixing this? - - In general, py_cpp doesn't automatically convert pointer return values - to_python because pointers have too many potential meanings. Is it an - iterator? A pointer to a single element? An array? Is ownership being passed - to Python or is the pointer really just a reference? If the latter, what - happens when some C++ code deletes the referent. The only exception to this - rule is const char*, since it has a generally accepted interpretation (could - be trouble with some generic code, though!) - - If you have wrapped the Record class, you could add this to namespace py: - - PyObject* to_python(const Record* p) { - return to_python(*p); - } - - Of course, this will cause the Record class to be copied. If you can't live - with that (Record would have to be /really/ heavyweight to make this - worthwhile), you can follow one of these dangerous approaches: - - 1. Use the technique I described with dangerous_array in - http://www.egroups.com/message/boost/6196. You do not have to expose Record - explicitly in this case. Instead the class you expose will be more of a - Record_proxy - - 2. Wrap Record in the usual way, then add the following to namespace py: - - PyObject* to_python(const Record* p) - { - return ExtensionClass::ptr_to_python(const_cast(p)); - } - - This will cause the Record* to be treated as though it were an owning smart - pointer, even though it's not. Be sure you don't use the reference for - anything from Python once the pointer becomes invalid, though. Don't worry - too much about the const-correctness issue: Const-correctness is completely - lost to Python anyway! - - 3. As above, but instead wrap const Record rather than plain Record. Then - you can avoid the const_cast, but you obviously can't def() any non-const - member functions of Record. - - Case 2: - - > I have yet another question. This is more a general wrapper question. - > Let me say that there is a function that returns a float* which most - > probably is an array. Similarly if I have a function that takes a - > float* as an argument, what is the best way of wrapping this? - - I think you have correctly perceived that it doesn't make sense for me to - automatically convert all pointers, since the ownership semantics are so - blurry. - - > 1) If the array is small it makes sense to convert it to either a - > tuple or list. What is the easiest way to do this?? I am looking - > for a way that makes one write the least code. :) - - How can you tell the length of the array from a single pointer? - Once you've answered that question, you can expose a wrapper function which - returns an instance of the py::Tuple or py::List class from objects.h. If - you are using a List, for example, you could write something like this: - - py::List wrap_f() - { - T* start = f(); - py::List x; - for (T* p = start; p != start + length_constant; ++p) - x.push_back(py::to_python(*p)); - return x; - } - - > 2) If the array is large it may not make sense to use a list/tuple - > esp. if the values are used for computationally intense programs. - - In this case you can do one of several somewhat dangerous things. Why - dangerous? Because python can not control the lifetime of the data, so the - data in the array may be destroyed or become invalid before the last - reference to it disappears. The basic approach is to make a small C++ class - which contains the pointer, and expose that: - - // UNTESTED - template - struct dangerous_array - { - dangerous_array(T* start, T* end) - : m_start(start), m_end(end) {} - - // exposed as "__len__" - std::size_t length() { - return m_end - m_start; - } - - // exposed as "__getitem__" - T get_item(std::size_t n) { - check_range(n); - return start[n]; - } - - // exposed as "__setitem__" if the array is mutable - void set_item(std::size_t n, const T& x) { - check_range(n); - start[n] = x; - } - private: - void check_range(std::size_t n) { - if (n >= m_end - m_start) { - PyErr_SetString(PyExc_IndexError, "array index out of range"); - throw py::ErrorAlreadySet; - } - } - T* m_start; - T* m_end; - }; - - A reasonably safe approach would be to make a wrapper function for each - function that returns a T*, and expose that instead. If you're too lazy and - you really like to live on the edge, though, you can write to_python(T*) in - terms of to_python(const dangerous_array&), and you'll automatically - convert all T* return values to a wrapped dangerous_array. - - > 3) For an arbitrary class "class_A", say, can py_cpp handle - > references to class_A &instance, or class_A *instance?? i.e. will it - > wrap function calls to such objects? This question is obviously - > related to the earlier questions. - - Yes, iff class_A has been exposed to python with a ClassWrapper. - See http://people.ne.mediaone.net/abrahams/downloads/under-the-hood.html for - a few details. - - raw C++ arrays - You could expose a function like this one to get the desired effect: - - #include - void set_len(UnitCell& x, py::Tuple tuple) - { - double len[3]; - for (std::size_t i =0; i < 3; ++i) - len[i] = py::from_python(tuple[i].get(), py::Type()); - x.set_len(len); - } - - Types that are already wrapped by other libraries - - It's not documented yet, but you should be able to use a raw PyObject* or a - py::Ptr as one parameter to your C++ function. Then you can manipulate it as - any other generic Python object. - - Alternatively, If the NTL gives you a C/C++ interface, you can also write - your own converter function: - - some_ntl_type& from_python(PyObject* p, py::Type) - { - // an Example implementation. Basically, you need - // to extract the NTL type from the PyObject*. - if (p->ob_type != NTL_long_type) { - PyErr_SetString(PyExc_TypeErr, "NTL long required"); - throw py::ArgumentError(); - } - return *static_cast(p); - } - - then the C++ functions you're wrapping can take a some_NTL_type& parameter - directly. - - "Thin converting wrappers" for constructors - - hijack some of the functionality - described in the section on Overridable Virtual Functions (even though you - don't have any virtual functions). I suggest this workaround: - - struct UnitCellWrapper : UnitCell - { - UnitCellWrapper(PyObject* self, py::Tuple x, py::Tuple y) - : UnitCell(from_python(x[1], py::Type()), - from_python(x[2], py::Type()), - from_python(x[3], py::Type()), - from_python(y[1], py::Type()), - from_python(y[2], py::Type()), - from_python(y[3], py::Type())) - {} - } - - py::ClassWrapper unit_cell_class; - unit_cell_class.def(py::Constructor()); - ... - - returning references to wrapped objects - - the importance of declaration order of ClassWrappers/ExtensionInstances - - out parameters and non-const pointers - - Calling back into Python: - // caveat: UNTESTED! - #include - #include - #include - #include - int main() - { - try { - py::Ptr module(PyImport_ImportModule("weapons")); - const int strength = 10; - const char* manufacturer = "Vordon Empire"; - py::Ptr a_blaster(py::Callback::call_method( - module.get(), "Blaster", strength, manufacturer)); - py::Callback::call_method(a_blaster.get(), "Fire"); - int old_strength = py::Callback::call_method(a_blaster.get(), "get_strength"); - py::Callback::call_method(a_blaster.get(), "set_strength", 5); - } - catch(...) - { - } - } - - Miscellaneous - About the vc6 project and the debug build - About doctest.py - -Boost remarks: - - > > One of us is completely nuts ;->. How can I move the test - > > (is_prefix(enablers[i].name + 2, name + 2)) outside the loop if it - depends - > > on the loop index, i? - > > - > name += 2; - > for() - > { - > if (is_prefix(enablers[i].name + 2, name)) - > } - - I see now. I guess I should stop pussyfooting and either go for optimization - or clarity here, eh? - - ------ - - > Re: Dict - > Why abbreviate this? Code is read 5 or 6 times for every time its - > written. The few extra characters don't affect compile time or program - > speed. It's part of my personal goal of write what you mean, name them - what - > they are. - - I completely agree. Abbrevs rub me the wrong way, 2 ;-> - - ------- - - - - -Later: - keyword and varargs? - Put explicit Type<> arguments at the beginnings of overloads, to make them look more like template instance specifications. - -Known bugs - can't handle 'const void' return values - Who returns 'const void'? I did it once, by mistake ;) From 7c312d358b76b419dc7b0ad7dcdb6314f9310e42 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 6 Jun 2002 21:57:16 +0000 Subject: [PATCH 0508/1042] work-around for mipspro linker problem. [SVN r14095] --- test/select_from_python_test.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/select_from_python_test.cpp b/test/select_from_python_test.cpp index 084f2e18..34018781 100644 --- a/test/select_from_python_test.cpp +++ b/test/select_from_python_test.cpp @@ -2,7 +2,9 @@ #include #include -#if defined(__GNUC__) && __GNUC__ < 3 // 2.95.x linker seems to demand this definition +// gcc 2.95.x and MIPSpro 7.3.1.3 linker seem to demand this definition +#if ((defined(__GNUC__) && __GNUC__ < 3)) \ + || (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238)) namespace boost { namespace python { BOOST_PYTHON_DECL bool handle_exception_impl(function0) { From 59ea6b120ccd551a8f6ead3019cf52535fdcfc4c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 7 Jun 2002 16:37:24 +0000 Subject: [PATCH 0509/1042] MIPSpro 7.3.1.3 adjustments [SVN r14102] --- include/boost/python/object/class.hpp | 1 + include/boost/python/type_id.hpp | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 466b6e44..b86f660c 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -39,6 +39,7 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable void add_property(char const* name, ref const& fget); void add_property(char const* name, ref const& fget, ref const& fset); void setattr(char const* name, ref const&); + void enable_pickle_support(); private: ref m_object; }; diff --git a/include/boost/python/type_id.hpp b/include/boost/python/type_id.hpp index 2432af00..11c15120 100755 --- a/include/boost/python/type_id.hpp +++ b/include/boost/python/type_id.hpp @@ -19,7 +19,9 @@ namespace boost { namespace python { // for this compiler at least, cross-shared-library type_info // comparisons don't work, so use typeid(x).name() instead. It's not // yet clear what the best default strategy is. -# if defined(__GNUC__) && __GNUC__ >= 3 || defined(_AIX) +# if (defined(__GNUC__) && __GNUC__ >= 3) \ + || defined(_AIX) \ + || ( defined(__sgi) && defined(__host_mips)) # define BOOST_PYTHON_TYPE_ID_NAME # endif @@ -28,7 +30,7 @@ namespace boost { namespace python { // which works across shared libraries. struct type_info : private totally_ordered { - type_info(std::type_info const& = typeid(void)); + inline type_info(std::type_info const& = typeid(void)); inline bool operator<(type_info const& rhs) const; inline bool operator==(type_info const& rhs) const; @@ -59,8 +61,8 @@ inline type_info type_id(boost::type* = 0) ); } -# if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ <= 245 -// KCC on this platform seems to mistakenly distinguish "int" from +# if defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 +// Older EDG-based compilers seems to mistakenly distinguish "int" from // "signed int", etc., but only in typeid() expressions. However // though int == signed int, the "signed" decoration is propagated // down into template instantiations. Explicit specialization stops @@ -76,6 +78,9 @@ inline type_info type_id(boost::type*) \ BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short) BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int) BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long) +# ifdef BOOST_HAS_LONG_LONG +BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long) +# endif # undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID # endif From 89930f34d7ee8c9513832870cfdad13e8926cf1e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 7 Jun 2002 17:14:13 +0000 Subject: [PATCH 0510/1042] undo accidental commit [SVN r14103] --- include/boost/python/object/class.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index b86f660c..466b6e44 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -39,7 +39,6 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable void add_property(char const* name, ref const& fget); void add_property(char const* name, ref const& fget, ref const& fset); void setattr(char const* name, ref const&); - void enable_pickle_support(); private: ref m_object; }; From 43d8c811048d02ae5bd7338386f24229681544fb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 8 Jun 2002 15:35:10 +0000 Subject: [PATCH 0511/1042] use sys.maxint [SVN r14112] --- test/test_builtin_converters.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index 332c8927..6600c6b7 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -49,7 +49,7 @@ ... except OverflowError: pass ... else: print 'expected an OverflowError!' ->>> try: rewrap_value_int(must_be_long) +>>> try: rewrap_value_int(sys.maxint * 2) ... except OverflowError: pass ... else: print 'expected an OverflowError!' @@ -181,13 +181,6 @@ Check that classic classes also work 1 """ -# compute a long value that's too big for an int -# note that some day these may be integrated, so -big_int = 1 -while (big_int << 1) > 0: - big_int <<= 1 -must_be_long = long(big_int) << 1 - def run(args = None): import sys From 1de6a21f3ab52b9db3d684b90c692860ba36ea98 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 8 Jun 2002 16:51:16 +0000 Subject: [PATCH 0512/1042] Fix transform_iterator nonconformance [SVN r14114] --- test/input_iterator.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/test/input_iterator.cpp b/test/input_iterator.cpp index 005d393d..0eb5c109 100644 --- a/test/input_iterator.cpp +++ b/test/input_iterator.cpp @@ -8,25 +8,26 @@ #include #include #include -#include -#include -#include using namespace boost::python; typedef std::list list_int; -// Prove that we can handle InputIterators which return rvalues. This -// input iterator example was stolen from the iterator_adaptors -// documentation -typedef std::binder1st > doubler; +// Prove that we can handle InputIterators which return rvalues. +struct doubler +{ + typedef int result_type; + int operator()(int x) const { return x * 2; } +}; + typedef boost::transform_iterator_generator::type doubling_iterator; typedef std::pair list_range2; + list_range2 range2(list_int& x) { return list_range2( - boost::make_transform_iterator(x.begin(), std::bind1st(std::multiplies(),2)) - , boost::make_transform_iterator(x.end(), std::bind1st(std::multiplies(),2))); + boost::make_transform_iterator(x.begin(), doubler()) + , boost::make_transform_iterator(x.end(), doubler())); } // We do this in a separate module from iterators_ext (iterators.cpp) From e331512473b8fe4dda3a72020ad6b1fcab7d361c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 11 Jun 2002 15:48:32 +0000 Subject: [PATCH 0513/1042] fix typo [SVN r14130] --- doc/v2/Apr2002.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/Apr2002.html b/doc/v2/Apr2002.html index a51e46c2..5789b3f8 100644 --- a/doc/v2/Apr2002.html +++ b/doc/v2/Apr2002.html @@ -120,7 +120,7 @@ more-sophisticated overloading mechanism than the current simple-minded "first match" approach, as I suggested last month. -

    Boost.Python V1 Mainenance

    +

    Boost.Python V1 Maintenance

    As much as I'm looking forward to retiring Boost.Python v1, a significant amount of effort has been being spent dealing with support From 14d2bae2388eba8d8840821e09f04fc7c03c3c80 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 11 Jun 2002 19:51:44 +0000 Subject: [PATCH 0514/1042] initial commit [SVN r14131] --- doc/v2/May2002.html | 309 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 doc/v2/May2002.html diff --git a/doc/v2/May2002.html b/doc/v2/May2002.html new file mode 100644 index 00000000..d94481cb --- /dev/null +++ b/doc/v2/May2002.html @@ -0,0 +1,309 @@ + + + + +Boost.Python - May 2002 Progress Report + + + + + + + +
    +

    +

    +
    +

    Boost.Python

    +

    May 2002 Progress Report

    +
    +
    +

    Contents

    +
    +
    Introduction
    +
    New Features
    +
    +
    Shared Library Support for AIX
    +
    Class Enhancements
    +
    +
    Operators
    +
    Iterators
    +
    Properties
    +
    setattr
    +
    __module__ Attribute
    +
    +
    back_reference
    +
    + +
    Documentation
    +
    Miscellaneous
    +
    +
    Converters
    +
    Checkins Mailing List
    +
    Shared Libraries
    +
    + +
    What's Next
    +
    + +

    Introduction

    + +Aside from library development, work on Boost.Python in May was +focused on reducing the support burden. In recent weeks, responding to +requests for support, espcially surrounding building the library, had +begun to impede progress on development. There was a major push to +release a stable 1.28.0 of Boost, including documentation of Boost.Build and specific +instructions for building Boost.Python +v1. The documentation for Boost.Python v2 was also updated as +described here. + +

    New Features

    + +

    Shared Library Support for AIX

    + + The Kull group required the ability to build and test Boost.Python + extensions on AIX, a platform with "creatively designed" + shared library semantics. Making this work was a multi-pronged + effort, involving changes to Boost.Build and some great research by + Martin Casado which uncovered the key mechanism required to allow + shared libraries to use functions from the Python executable. The + current solution used in Boost.Build relies on a Python + Script as part of the build process. This is not a problem for + Boost.Python, as Python will be available. However, the commands + issued by the script are so simple that a 100%-pure-Boost.Jam + solution is surely possible. Linking on AIX is sufficiently + interesting to have skewed the Boost.Python development schedule a + bit. + +

    Class Enhancements

    + +

    Operators

    + +Support for exposing C++ operators and functions as the corresponding +Python special methods was added. Thinking that the Boost.Python +v1 interface was a little too +esoteric (especially the use of +left_operand<...>/right_operand<...> for +asymmetric operands), I introduced a simple form of expression +templates which allow users to simply write the expressions that +should be wrapped, as in this example. + +

    Iterators

    + +Python iterator support as required by the Kull project resulted in a +highly flexible interface allowing: + +
    + +
    Direct exposure of a class' begin() and +end() functions: + +
    +    ...
    +    .def("__iter__", iterator<list_int>())
    +
    +
    + +
    Creation of iterators from member functions... +
    +    ...
    +    .def("__iter__"
    +         , range(&my_class::x_begin, &my_class::x_end))
    +    )
    +
    +
    + +
    ...and member data: +
    +    ...
    +    .def("__iter__"
    +         , range(&std::pair<char*,char*>::first, &std::pair<char*,char*>::second))
    +    )
    +
    +
    + +
    The ability to specify CallPolicies, e.g. to prevent copying of +heavyweight values: + +
    +    ...
    +    .def("__iter__", 
    +         , range<return_value_policy<copy_non_const_reference> >(
    +               &my_sequence<heavy>::begin
    +             , &my_sequence<heavy>::end))
    +
    +
    + +
    + +

    Properties

    + +The Kull iteration interfaces also required the ability to iterate +over a sequence specified by an instance's attribute: +
    +>>> f = field()
    +>>> for e in f.elements:
    +...     print e,
    +
    + +This forced the exposure of the property + interface used internally to implement the data member exposure + facility described in March. Properties are an + incredibly useful idiom, so it's good to be able to provide them + at little new development cost. + +

    setattr

    + +class_<> acquired a setattr member +function which allows users to easily add new Python objects as class +attributes. + +

    __module__ Attribute

    + +Ralf Grosse-Kunstleve has been working on pickling support for v2. To +make it work correctly, he had to make sure that a class' +__module__ attribute was set correctly. + +

    back_reference

    + +The new back_reference<T> template can be used as a +function parameter when the user needs access to both a T +argument and to the Python object which manages it. The function will +only match in the overload resolution process if it would match the +same function signature with T substituted for +back_reference<T>. This feature is not yet +documented. + +

    Documentation

    + +In a major effort to prepare Boost.Python v2 to replace v1, many pages +of new reference documentation were added: + +
    + +
    +
    CallPolicies.html
    +
    Dereferenceable.html
    +
    Extractor.html
    +
    HolderGenerator.html
    +
    ResultConverter.html
    +
    call_method.html
    +
    callbacks.html
    +
    data_members.html
    +
    has_back_reference.html
    +
    implicit.html
    +
    instance_holder.html
    +
    operators.html
    +
    ptr.html
    +
    type_id.html
    +
    with_custodian_and_ward.html
    +
    + +
    +Major updates were made to the following pages: + + +
    +
    +
    call.html
    updated
    +
    class.html
    +
    reference.html
    +
    +
    + + As usual, careful documentation forces one to consider the + interface again, and there were many interface changes + associated with this effort, including the elevation of the + following components from implementation detail to + first-class library citizen: + +
    +
    +
    type_id.hpp
    +
    pointee.hpp
    +
    lvalue_from_pytype.hpp
    +
    + + +

    Miscellaneous

    + +

    Converters

    + +It appears that the world of C++ <==> Python conversion rules is +an endlessly-rich area of exploration. Completing the conversions for +char and char const* types, as described at +the end of April's report, +uncovered some interesting new shades to the problem. It turns out to +be worth distinguishing mutable and immutable lvalue conversions, +because despite the fact that Python doesn't understand +const, it does understand immutability (c.f. Python +strings, which expose an immutable char pointer). It is +also worth recognizing types which represent lvalue sequences, +to prevent Python "foobar" from being silently +truncated to C++ 'f'. More details on this insight can be +found in the mailing list +archive. I don't plan to do anything about this immediately, but I +do think it's the right direction to go in the long run. + +

    Checkins Mailing List

    + +In order to better coordinate changes made by multiple developers, I +enabled syncmail +for the Boost.Python CVS trees, and established an associated mailing +list. Subscribe to this list to receive notices of each new +checkin. + +

    Shared Libraries

    + +Beyond the vagaries of dynamic linking on AIX, I have been +participating in a more-general discussion of dynamic linking for +C++. Needless to say, C++ dynamic linking is of critical importance to +Boost.Python: all extension modules are normally built as shared +libraries, and Boost.Python extension modules share a common library +as well. + +In fact, there are at least two separate conversations. One +in the C++ standard extensions mailing list concerns what can be +standardized for C++ and shared libraries; the other, mostly on the gcc mailing list, concerns the +behavior of GCC on Posix/ELF platforms. + +Some of the GCC threads are here: + +
    +http://gcc.gnu.org/ml/gcc/2002-05/msg02002.html
    +http://gcc.gnu.org/ml/gcc/2002-05/msg02945.html
    +http://gcc.gnu.org/ml/gcc/2002-05/msg01758.html +
    + +

    What's Next

    + +Development is focused on what's needed to be able to retire +Boost.Python v1. At the moment, that means deciding the user-friendly +interfaces for to_/from_python conversion, and formally exposing the +Python object smart pointers and object wrapper classes. Quite a few +questions have also been showing up recently about how to embed Python +with Boost.Python, and how to link with it statically; the solutions +to these issues will probably have to be formalized before long. + +

    Revised + + 11 June, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + From 52ba3c7f8054b67af82b7144eddc27ae1d882983 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 12 Jun 2002 20:52:53 +0000 Subject: [PATCH 0515/1042] expect_non_null optimization [SVN r14134] --- include/boost/python/errors.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp index 5b138ce4..1f83b679 100644 --- a/include/boost/python/errors.hpp +++ b/include/boost/python/errors.hpp @@ -35,17 +35,17 @@ inline void handle_exception() handle_exception(detail::rethrow); } -BOOST_PYTHON_DECL PyObject* expect_non_null_impl(PyObject* x); +BOOST_PYTHON_DECL void throw_argument_error(); +BOOST_PYTHON_DECL void throw_error_already_set(); template inline T* expect_non_null(T* x) { - return (T*)expect_non_null_impl((PyObject*)x); + if (x == 0) + throw_error_already_set(); + return x; } -BOOST_PYTHON_DECL void throw_argument_error(); -BOOST_PYTHON_DECL void throw_error_already_set(); - }} // namespace boost::python #endif // ERRORS_DWA052500_H_ From 0d58869d6ec84ff1875c6a43b2fcdf420882adb1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 12 Jun 2002 21:57:35 +0000 Subject: [PATCH 0516/1042] Fix refcounting bug [SVN r14135] --- src/objects.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/objects.cpp b/src/objects.cpp index a947542b..f446919d 100644 --- a/src/objects.cpp +++ b/src/objects.cpp @@ -250,8 +250,7 @@ const ref& dictionary_proxy::operator=(const ref& rhs) dictionary_proxy::operator ref() const { - return ref(m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get()), - ref::increment_count); + return ref(m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get())); } dictionary_proxy::dictionary_proxy(const ref& dict, const ref& key) From 366ee6d24b6c88f93fe9945eb06eba3f0bf30102 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 12 Jun 2002 21:59:17 +0000 Subject: [PATCH 0517/1042] reference<> => handle<> [SVN r14136] --- Jamfile | 2 +- include/boost/python/back_reference.hpp | 10 +- include/boost/python/cast.hpp | 96 ++++ include/boost/python/class.hpp | 28 +- .../boost/python/converter/arg_to_python.hpp | 10 +- .../python/converter/arg_to_python_base.hpp | 33 +- .../python/converter/builtin_converters.hpp | 7 +- .../converter/callback_to_python_base.hpp | 53 --- include/boost/python/detail/module_base.hpp | 15 +- include/boost/python/detail/wrap_function.hpp | 2 +- include/boost/python/from_python.hpp | 53 --- include/boost/python/handle.hpp | 223 +++++++++ include/boost/python/iterator.hpp | 12 +- include/boost/python/module.hpp | 4 +- include/boost/python/object/class.hpp | 18 +- .../boost/python/object/class_converters.hpp | 2 +- include/boost/python/object/class_wrapper.hpp | 8 +- include/boost/python/object/function.hpp | 4 +- include/boost/python/object/iterator.hpp | 20 +- include/boost/python/object/iterator_core.hpp | 4 +- include/boost/python/objects.hpp | 17 +- include/boost/python/objects2.hpp | 348 ++++++++++++++ include/boost/python/operators2.hpp | 2 +- include/boost/python/reference.hpp | 21 +- include/boost/python/to_python_indirect.hpp | 2 +- src/converter/builtin_converters.cpp | 4 +- src/converter/callback.cpp | 8 +- src/errors.cpp | 7 - src/module.cpp | 28 +- src/object/class.cpp | 52 ++- src/object/function.cpp | 6 +- src/object/iterator.cpp | 6 +- src/objects2.cpp | 426 ++++++++++++++++++ test/Jamfile | 4 + test/cltree.cpp | 3 + test/upcast.cpp | 19 + 36 files changed, 1264 insertions(+), 293 deletions(-) create mode 100755 include/boost/python/cast.hpp delete mode 100644 include/boost/python/converter/callback_to_python_base.hpp delete mode 100644 include/boost/python/from_python.hpp create mode 100755 include/boost/python/handle.hpp create mode 100755 include/boost/python/objects2.hpp create mode 100755 src/objects2.cpp create mode 100755 test/upcast.cpp diff --git a/Jamfile b/Jamfile index 19b269b0..23d82c1b 100644 --- a/Jamfile +++ b/Jamfile @@ -23,7 +23,7 @@ dll bpl src/object/life_support.cpp src/errors.cpp src/module.cpp - src/objects.cpp + src/objects2.cpp src/converter/builtin_converters.cpp src/converter/callback.cpp src/object/iterator.cpp diff --git a/include/boost/python/back_reference.hpp b/include/boost/python/back_reference.hpp index bde26dcd..fbfaff11 100644 --- a/include/boost/python/back_reference.hpp +++ b/include/boost/python/back_reference.hpp @@ -6,7 +6,7 @@ #ifndef BACK_REFERENCE_DWA2002510_HPP # define BACK_REFERENCE_DWA2002510_HPP -# include +# include namespace boost { namespace python { @@ -17,10 +17,10 @@ struct back_reference typedef T type; back_reference(PyObject*, T); - ref reference() const; + handle<> reference() const; T get() const; private: - ref m_reference; + handle<> m_reference; T m_value; }; @@ -75,13 +75,13 @@ class is_back_reference // template back_reference::back_reference(PyObject* p, T x) - : m_reference(p, ref::increment_count) + : m_reference(python::borrow(p)) , m_value(x) { } template -ref back_reference::reference() const +handle<> back_reference::reference() const { return m_reference; } diff --git a/include/boost/python/cast.hpp b/include/boost/python/cast.hpp new file mode 100755 index 00000000..9408579a --- /dev/null +++ b/include/boost/python/cast.hpp @@ -0,0 +1,96 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CAST_DWA200269_HPP +# define CAST_DWA200269_HPP + +# include +# include +# include + +namespace boost { namespace python { + +template struct base_type_traits; + +template <> +struct base_type_traits +{ + typedef PyObject type; +}; + +template <> +struct base_type_traits +{ + typedef PyObject type; +}; + +namespace detail +{ + typedef char* yes_convertible; + typedef int* no_convertible; + + typedef char* yes_python_object; + typedef int* no_python_object; + + template + struct convertible + { + static inline yes_convertible check(Target) { return 0; } + static inline no_convertible check(...) { return 0; } + }; + + template + inline Target* upcast(Target* p, yes_convertible) + { + return p; + } + + template + inline Target* upcast(Source* p, no_convertible, boost::type* = 0) + { + typedef typename base_type_traits::type base; + return detail::upcast((base*)p, convertible::check((base*)0)); + } + + + template + inline Target* downcast(Source* p, yes_convertible) + { + return static_cast(p); + } + + template + inline Target* downcast(Source* p, no_convertible, boost::type* = 0) + { + typedef typename base_type_traits::type base; + return (Target*)detail::downcast(p, convertible::check((base*)0)); + } + + template + inline void assert_castable(boost::type* = 0) + { + typedef char must_be_a_complete_type[sizeof(T)]; + } +} + +template +inline Target* upcast(Source* x, Target* = 0) +{ + detail::assert_castable(); + detail::assert_castable(); + return detail::upcast(x, detail::convertible::check(x)); +} + +template +inline Target* downcast(Source* x, Target* = 0) +{ + detail::assert_castable(); + detail::assert_castable(); + return detail::downcast(x, detail::convertible::check((Target*)0)); +} + +}} // namespace boost::python + +#endif // CAST_DWA200269_HPP diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index ec21ba8e..861d8e72 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -9,7 +9,7 @@ # include # include # include -# include +# include # include # include # include @@ -46,14 +46,14 @@ namespace detail // to the type of holder that must be created. The 3rd argument is a // reference to the Python type object to be created. template - static inline void register_copy_constructor(mpl::bool_t const&, Holder*, ref const& obj, T* = 0) + static inline void register_copy_constructor(mpl::bool_t const&, Holder*, handle<> const& obj, T* = 0) { objects::class_wrapper x(obj); } // Tag dispatched to have no effect. template - static inline void register_copy_constructor(mpl::bool_t const&, Holder*, ref const&, T* = 0) + static inline void register_copy_constructor(mpl::bool_t const&, Holder*, handle<> const&, T* = 0) { } } @@ -104,7 +104,7 @@ class class_ : public objects::class_base // appropriate. objects::function::add_to_namespace( this->object(), name, - ref(detail::wrap_function( + handle<>(detail::wrap_function( // This bit of nastiness casts F to a member function of T if possible. detail::member_function_cast::stage1(f).stage2((T*)0).stage3(f) ))); @@ -132,7 +132,7 @@ class class_ : public objects::class_base // appropriate. objects::function::add_to_namespace( this->object(), op.name(), - ref(detail::wrap_function(&op_t::template apply::execute))); + handle<>(detail::wrap_function(&op_t::template apply::execute))); return *this; } @@ -176,7 +176,7 @@ class class_ : public objects::class_base template self& def_readonly(char const* name, D T::*pm) { - ref fget(make_getter(pm)); + handle<> fget(make_getter(pm)); this->add_property(name, fget); return *this; } @@ -184,16 +184,16 @@ class class_ : public objects::class_base template self& def_readwrite(char const* name, D T::*pm) { - ref fget(make_getter(pm)); - ref fset(make_setter(pm)); + handle<> fget(make_getter(pm)); + handle<> fset(make_setter(pm)); return this->add_property(name, fget, fset); } // Property creation - self& add_property(char const* name, ref const& fget); - self& add_property(char const* name, ref const& fget, ref const& fset); + self& add_property(char const* name, handle<> const& fget); + self& add_property(char const* name, handle<> const& fget, handle<> const& fset); - self& setattr(char const* name, ref const&); + self& setattr(char const* name, handle<> const&); private: // types typedef objects::class_id class_id; @@ -258,21 +258,21 @@ inline class_::class_(char const* name) template -inline class_& class_::add_property(char const* name, ref const& fget) +inline class_& class_::add_property(char const* name, handle<> const& fget) { base::add_property(name, fget); return *this; } template -inline class_& class_::add_property(char const* name, ref const& fget, ref const& fset) +inline class_& class_::add_property(char const* name, handle<> const& fget, handle<> const& fset) { base::add_property(name, fget, fset); return *this; } template -inline class_& class_::setattr(char const* name, ref const& x) +inline class_& class_::setattr(char const* name, handle<> const& x) { base::setattr(name, x); return *this; diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index 6cd9836c..78268fd0 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -11,6 +11,8 @@ # include # include # include +// Bring in specializations +# include namespace boost { namespace python { namespace converter { @@ -19,7 +21,7 @@ namespace detail BOOST_PYTHON_DECL void throw_no_class_registered(); template - struct reference_arg_to_python : arg_to_python_holder + struct reference_arg_to_python : handle<> { reference_arg_to_python(T& x); private: @@ -41,7 +43,7 @@ namespace detail }; template - struct pointer_shallow_arg_to_python : arg_to_python_holder + struct pointer_shallow_arg_to_python : handle<> { // Throw an exception if the conversion can't succeed pointer_shallow_arg_to_python(Ptr); @@ -129,13 +131,13 @@ namespace detail template inline reference_arg_to_python::reference_arg_to_python(T& x) - : arg_to_python_holder(get_object(x)) + : handle<>(get_object(x)) { } template inline pointer_shallow_arg_to_python::pointer_shallow_arg_to_python(Ptr x) - : arg_to_python_holder(get_object(x)) + : handle<>(get_object(x)) {} template diff --git a/include/boost/python/converter/arg_to_python_base.hpp b/include/boost/python/converter/arg_to_python_base.hpp index 7573b499..1e5fe191 100755 --- a/include/boost/python/converter/arg_to_python_base.hpp +++ b/include/boost/python/converter/arg_to_python_base.hpp @@ -7,45 +7,16 @@ # define ARG_TO_PYTHON_BASE_DWA200237_HPP # include # include -# include +# include namespace boost { namespace python { namespace converter { namespace detail { - struct arg_to_python_holder - { - arg_to_python_holder(PyObject* obj); - PyObject* get() const; - PyObject* get_incref() const; - private: - ref m_held; - }; - - struct BOOST_PYTHON_DECL arg_to_python_base : arg_to_python_holder + struct BOOST_PYTHON_DECL arg_to_python_base : handle<> { arg_to_python_base(void const volatile* source, to_python_function_t); }; - - // - // implmentation - // - inline arg_to_python_holder::arg_to_python_holder(PyObject* obj) - : m_held(obj) - { - } - - inline PyObject* arg_to_python_holder::get() const - { - return m_held.get(); - } - - inline PyObject* arg_to_python_holder::get_incref() const - { - PyObject* result = m_held.get(); - Py_XINCREF(result); - return result; - } } }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index 9d072498..77a78069 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -7,8 +7,7 @@ # define BUILTIN_CONVERTERS_DWA2002124_HPP # include # include -# include -# include +# include # include # include @@ -65,10 +64,10 @@ namespace detail namespace converter \ { \ template <> struct arg_to_python< T > \ - : detail::arg_to_python_holder \ + : handle<> \ { \ arg_to_python(T const& x) \ - : detail::arg_to_python_holder(expr) {} \ + : python::handle<>(expr) {} \ }; \ } diff --git a/include/boost/python/converter/callback_to_python_base.hpp b/include/boost/python/converter/callback_to_python_base.hpp deleted file mode 100644 index d03f2f60..00000000 --- a/include/boost/python/converter/callback_to_python_base.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CALLBACK_TO_PYTHON_BASE_DWA200237_HPP -# define CALLBACK_TO_PYTHON_BASE_DWA200237_HPP -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -namespace detail -{ - struct callback_to_python_holder - { - callback_to_python_holder(PyObject* obj); - PyObject* get() const; - PyObject* get_incref() const; - private: - ref m_held; - }; - - struct BOOST_PYTHON_DECL callback_to_python_base : callback_to_python_holder - { - callback_to_python_base(void const volatile* source, to_python_function_t); - }; - - // - // implmentation - // - inline callback_to_python_holder::callback_to_python_holder(PyObject* obj) - : m_held(obj) - { - } - - inline PyObject* callback_to_python_holder::get() const - { - return m_held.get(); - } - - inline PyObject* callback_to_python_holder::get_incref() const - { - PyObject* result = m_held.get(); - Py_XINCREF(result); - return result; - } -} - -}}} // namespace boost::python::converter - -#endif // CALLBACK_TO_PYTHON_BASE_DWA200237_HPP diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp index ecd13aa4..aaa6a135 100644 --- a/include/boost/python/detail/module_base.hpp +++ b/include/boost/python/detail/module_base.hpp @@ -6,7 +6,7 @@ #ifndef MODULE_BASE_DWA2002227_HPP # define MODULE_BASE_DWA2002227_HPP # include -# include +# include namespace boost { namespace python { namespace detail { @@ -19,25 +19,24 @@ class BOOST_PYTHON_DECL module_base // Add elements to the module void setattr(const char* name, PyObject*); - void setattr(const char* name, ref const&); - void add(PyTypeObject* x); // just use the type's name - void add_type(ref); + void setattr(const char* name, handle<> const&); + void add(type_handle const&); // just use the type's name // Return a reference to the Python module object being built - inline ref object() const; + inline handle<> object() const; protected: - void add_class(ref const& class_obj); + void add_class(type_handle const& class_obj); private: - ref m_module; + handle<> m_module; static PyMethodDef initial_methods[1]; }; // // inline implementations // -inline ref module_base::object() const +inline handle<> module_base::object() const { return m_module; } diff --git a/include/boost/python/detail/wrap_function.hpp b/include/boost/python/detail/wrap_function.hpp index 57725efd..71ee967e 100644 --- a/include/boost/python/detail/wrap_function.hpp +++ b/include/boost/python/detail/wrap_function.hpp @@ -31,7 +31,7 @@ template inline PyObject* wrap_function_aux(F f, PyObject*) { return f; } template -inline PyObject* wrap_function_aux(F f, boost::python::reference x) { return x.release(); } +inline PyObject* wrap_function_aux(F f, boost::python::handle x) { return x.release(); } template inline PyObject* wrap_function_aux(F f, ...) { return make_function(f); } diff --git a/include/boost/python/from_python.hpp b/include/boost/python/from_python.hpp deleted file mode 100644 index 4219bc2d..00000000 --- a/include/boost/python/from_python.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#error obsolete -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FROM_PYTHON_DWA2002128_HPP -# define FROM_PYTHON_DWA2002128_HPP - -# include - -namespace boost { namespace python { - -template -struct from_python - : converter::select_arg_from_python::type -{ - typedef typename converter::select_from_python::type base; - from_python(PyObject*); -}; - -// specialization for PyObject* -template <> -struct from_python -{ - typedef PyObject* result_type; - - from_python(PyObject*) {} - bool convertible() const { return true; } - PyObject* operator()(PyObject* source) const { return source; } -}; - -template <> -struct from_python -{ - typedef PyObject* const& result_type; - from_python(PyObject*) {} - bool convertible() const { return true; } - PyObject*const& operator()(PyObject*const& source) const { return source; } -}; - -// -// implementations -// -template -inline from_python::from_python(PyObject* source) - : base(source) -{ -} - -}} // namespace boost::python - -#endif // FROM_PYTHON_DWA2002128_HPP diff --git a/include/boost/python/handle.hpp b/include/boost/python/handle.hpp new file mode 100755 index 00000000..912717e0 --- /dev/null +++ b/include/boost/python/handle.hpp @@ -0,0 +1,223 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef HANDLE_DWA200269_HPP +# define HANDLE_DWA200269_HPP + +# include +# include +# include + +namespace boost { namespace python { + +template +inline T* incref(T* p) +{ + Py_INCREF(python::upcast(p)); + return p; +} + +template +inline T* xincref(T* p) +{ + Py_XINCREF(python::upcast(p)); + return p; +} + +template +inline void decref(T* p) +{ + Py_DECREF(python::upcast(p)); +} + +template +inline void xdecref(T* p) +{ + Py_XDECREF(python::upcast(p)); +} + +template struct borrowed; +template struct null_ok; + +template +inline borrowed* borrow(T* p) +{ + return (borrowed*)p; +} + +template +inline null_ok* allow_null(T* p) +{ + return (null_ok*)p; +} + +namespace detail +{ + template + inline T* manage_ptr(borrowed >* p, int) + { + return python::xincref((T*)p); + } + + template + inline T* manage_ptr(null_ok >* p, int) + { + return python::xincref((T*)p); + } + + template + inline T* manage_ptr(borrowed* p, long) + { + return python::incref(expect_non_null((T*)p)); + } + + template + inline T* manage_ptr(null_ok* p, long) + { + return (T*)p; + } + + template + inline T* manage_ptr(T* p, ...) + { + return expect_non_null(p); + } + +#if 0 + template + struct handle_proxy + : handle_proxy::type> + { + typedef typename base_type_traits::type base_t; + handle_proxy(PyObject* p) + : handle_proxy(p) + {} + operator T*() const { return python::downcast(m_p); } + }; + + template <> + struct handle_proxy + { + handle_proxy(PyObject* p) : m_p(p) {} + operator PyObject*() const { return (PyObject*)m_p; } + private: + PyObject* m_p; + }; +#endif +} + +template +class handle +{ + typedef T* (handle::*bool_type); + + public: + handle(); + ~handle(); + + template + handle(Y* p) + : m_p( + python::upcast( + detail::manage_ptr(p, 0) + ) + ) + { + } + + handle& operator=(handle const& r); + +#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) + + template + handle& operator=(handle const & r) // never throws + { + python::xdecref(m_p); + m_p = python::xincref(python::upcast(r.get())); + return *this; + } + +#endif + + template + handle(handle const& r) + : m_p(python::xincref(python::upcast(r.get()))) + { + } + + handle(handle const& r) + : m_p(python::xincref(r.m_p)) + { + } + + T* operator-> () const; + T* get() const; + T* release(); + + operator bool_type() const // never throws + { + return m_p ? &handle::m_p : 0; + } + bool operator! () const; // never throws + + private: // data members + T* m_p; +}; + +typedef handle type_handle; + +// +// implementations +// +template +inline handle::handle() + : m_p(0) +{ +} + +template +inline handle::~handle() +{ + python::xdecref(m_p); +} + +template +inline handle& handle::operator=(handle const& r) +{ + python::xdecref(m_p); + m_p = python::xincref(r.m_p); + return *this; +} + +template +inline T* handle::operator->() const +{ + return m_p; +} + +template +inline T* handle::get() const +{ + return m_p; +} + +template +inline bool handle::operator!() const +{ + return m_p == 0; +} + +template +inline T* handle::release() +{ + T* result = m_p; + m_p = 0; + return result; +} + +}} // namespace boost::python + + +#endif // HANDLE_DWA200269_HPP diff --git a/include/boost/python/iterator.hpp b/include/boost/python/iterator.hpp index a31954aa..724b926a 100644 --- a/include/boost/python/iterator.hpp +++ b/include/boost/python/iterator.hpp @@ -19,7 +19,7 @@ namespace detail // objects::make_iterator(...), which allows us to pass member // function and member data pointers. template - inline ref make_iterator( + inline handle<> make_iterator( Accessor1 get_start, Accessor2 get_finish, boost::type* target = 0, NextPolicies* = 0) { return objects::make_iterator_function( @@ -68,7 +68,7 @@ struct iterators // accessors. Deduce the Target type from the accessors. The iterator // returns copies of the inderlying elements. template -ref range(Accessor1 start, Accessor2 finish) +handle<> range(Accessor1 start, Accessor2 finish) { return detail::make_iterator( start, finish @@ -78,7 +78,7 @@ ref range(Accessor1 start, Accessor2 finish) // Create an iterator-building function which uses the given accessors // and next() policies. Deduce the Target type. template -ref range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) +handle<> range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) { return detail::make_iterator(start, finish, detail::target(start)); } @@ -86,7 +86,7 @@ ref range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) // Create an iterator-building function which uses the given accessors // and next() policies, operating on the given Target type template -ref range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type* = 0) +handle<> range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type* = 0) { typedef typename add_reference::type target; return detail::make_iterator(start, finish); @@ -98,10 +98,10 @@ ref range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type -struct iterator : ref +struct iterator : handle<> { iterator() - : ref( + : handle<>( range( &iterators::begin, &iterators::end )) diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 38a80dca..23f2884e 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -27,7 +27,7 @@ class module : public detail::module_base // Add elements to the module module& setattr(const char* name, PyObject*); module& setattr(const char* name, PyTypeObject*); - module& setattr(const char* name, ref const&); + module& setattr(const char* name, handle<> const&); module& add(PyTypeObject* x); // just use the type's name template @@ -68,7 +68,7 @@ inline module& module::setattr(const char* name, PyTypeObject* x) return *this; } -inline module& module::setattr(const char* name, ref const& x) +inline module& module::setattr(const char* name, handle<> const& x) { this->base::setattr(name, x); return *this; diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 466b6e44..8cf29b23 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -10,7 +10,7 @@ # include # include # include -# include +# include # include # include @@ -35,15 +35,15 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable ); // Retrieve the underlying object - ref object() const { return m_object; } - void add_property(char const* name, ref const& fget); - void add_property(char const* name, ref const& fget, ref const& fset); - void setattr(char const* name, ref const&); + type_handle object() const { return m_object; } + void add_property(char const* name, handle<> const& fget); + void add_property(char const* name, handle<> const& fget, handle<> const& fset); + void setattr(char const* name, handle<> const&); private: - ref m_object; + type_handle m_object; }; -BOOST_PYTHON_DECL ref registered_class_object(class_id id); +BOOST_PYTHON_DECL type_handle registered_class_object(class_id id); // Each extension instance will be one of these struct instance @@ -52,8 +52,8 @@ struct instance instance_holder* objects; }; -BOOST_PYTHON_DECL ref class_metatype(); -BOOST_PYTHON_DECL ref class_type(); +BOOST_PYTHON_DECL type_handle class_metatype(); +BOOST_PYTHON_DECL type_handle class_type(); }}} // namespace boost::python::objects diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index e396dc25..14e79a9d 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -8,7 +8,7 @@ # include # include -# include +# include # include # include # include diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index 577d1012..73804fbf 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -6,7 +6,7 @@ #ifndef CLASS_WRAPPER_DWA20011221_HPP # define CLASS_WRAPPER_DWA20011221_HPP -# include +# include # include namespace boost { namespace python { namespace objects { @@ -15,7 +15,7 @@ template struct class_wrapper : to_python_converter > { - class_wrapper(ref const& type_) + class_wrapper(handle<> const& type_) : m_class_object_keeper(type_) { assert(type_->ob_type == (PyTypeObject*)class_metatype().get()); @@ -34,7 +34,7 @@ struct class_wrapper // Everything's OK; Bypass NULL checks but guard against // exceptions. - ref result(raw_result, ref::allow_null()); + handle<> result(python::allow_null(raw_result)); // Build a value_holder to contain the object using the copy // constructor @@ -48,7 +48,7 @@ struct class_wrapper } private: - ref m_class_object_keeper; + handle<> m_class_object_keeper; static PyTypeObject* m_class_object; }; diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index 37f86e7d..ef2f1251 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -8,7 +8,7 @@ # include # include -# include +# include # include namespace boost { namespace python { namespace objects { @@ -27,7 +27,7 @@ struct BOOST_PYTHON_DECL function : PyObject // a function object (this class), and an existing function is // already there, add it as an overload. static void add_to_namespace( - ref const& name_space, char const* name, ref const& attribute); + handle<> const& name_space, char const* name, handle<> const& attribute); private: // helper functions void argument_error(PyObject* args, PyObject* keywords) const; diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index a237d5d7..7e801f92 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -11,7 +11,7 @@ # include # include # include -# include +# include # include # include # include @@ -42,9 +42,9 @@ struct default_iterator_call_policies template struct iterator_range { - iterator_range(ref sequence, Iterator start, Iterator finish); + iterator_range(handle<> sequence, Iterator start, Iterator finish); - ref m_sequence; // Keeps the sequence alive while iterating. + handle<> m_sequence; // Keeps the sequence alive while iterating. Iterator m_start; Iterator m_finish; }; @@ -113,18 +113,18 @@ namespace detail // policies, creating it if neccessary. Requires: NextPolicies is // default-constructible. template - ref demand_iterator_class(char const* name, Iterator* = 0, NextPolicies const& policies = NextPolicies()) + handle<> demand_iterator_class(char const* name, Iterator* = 0, NextPolicies const& policies = NextPolicies()) { typedef iterator_range range_; // Check the registry. If one is already registered, return it. - ref result( + handle<> result( objects::registered_class_object(python::type_id())); if (result.get() == 0) { // Make a callable object which can be used as the iterator's next() function. - ref next_function( + handle<> next_function( new objects::function( objects::py_function( bind(&detail::iterator_next::execute, _1, _2, policies)) @@ -174,7 +174,7 @@ namespace detail // Build and convert the iterator_range<>. return cr( iterator_range( - ref(arg0, ref::increment_count) + handle<>(python::borrow(arg0)) , get_start(x), get_finish(x))); } }; @@ -187,13 +187,13 @@ namespace detail // iterators for the range, and an instance of NextPolicies is used as // CallPolicies for the Python iterator's next() function. template -inline ref make_iterator_function( +inline handle<> make_iterator_function( Accessor1 const& get_start, Accessor2 const& get_finish , boost::type* = 0, NextPolicies* = 0) { typedef typename Accessor1::result_type result_type; - return ref( + return handle<>( new objects::function( objects::py_function( boost::bind( @@ -210,7 +210,7 @@ inline ref make_iterator_function( // template inline iterator_range::iterator_range( - ref sequence, Iterator start, Iterator finish) + handle<> sequence, Iterator start, Iterator finish) : m_sequence(sequence), m_start(start), m_finish(finish) { } diff --git a/include/boost/python/object/iterator_core.hpp b/include/boost/python/object/iterator_core.hpp index dee87050..c3d5f6ae 100644 --- a/include/boost/python/object/iterator_core.hpp +++ b/include/boost/python/object/iterator_core.hpp @@ -6,11 +6,11 @@ #ifndef ITERATOR_CORE_DWA2002512_HPP # define ITERATOR_CORE_DWA2002512_HPP -# include +# include namespace boost { namespace python { namespace objects { -BOOST_PYTHON_DECL ref identity_function(); +BOOST_PYTHON_DECL handle<> identity_function(); BOOST_PYTHON_DECL void set_stop_iteration_error(); }}} // namespace boost::python::object diff --git a/include/boost/python/objects.hpp b/include/boost/python/objects.hpp index 8b230478..a5b87d88 100644 --- a/include/boost/python/objects.hpp +++ b/include/boost/python/objects.hpp @@ -9,11 +9,14 @@ #ifndef OBJECTS_DWA051100_H_ # define OBJECTS_DWA051100_H_ -# include -# include -# include -# include "boost/operators.hpp" -# include +# ifdef BOOST_PYTHON_V2 +# include +# else +# include +# include +# include +# include "boost/operators.hpp" +# include namespace boost { namespace python { @@ -354,8 +357,6 @@ struct BOOST_PYTHON_DECL list_slice_proxy }} // namespace boost::python -# ifndef BOOST_PYTHON_V2 - BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE BOOST_PYTHON_DECL PyObject* to_python(const boost::python::tuple&); @@ -391,5 +392,5 @@ inline boost::python::dictionary from_python(PyObject* p, boost::python::type +# include +# include +# include "boost/operators.hpp" +# include + +namespace boost { namespace python { + +class BOOST_PYTHON_DECL objects_base +{ + public: + explicit objects_base(handle<> const& p); + + // Return a reference to the held object + handle<> reference() const; + + // Return a raw pointer to the held object + PyObject* get() const; + + private: + handle<> m_p; +}; + +class tuple; + +class BOOST_PYTHON_DECL tuple_base : public objects_base +{ + public: + explicit tuple_base(std::size_t n = 0); + explicit tuple_base(handle<> p); + + static PyTypeObject* type_obj(); + static bool accepts(handle<> p); + std::size_t size() const; + handle<> operator[](std::size_t pos) const; + + void set_item(std::size_t pos, const handle<>& rhs); + + tuple slice(int low, int high) const; + + friend BOOST_PYTHON_DECL tuple operator+(const tuple&, const tuple&); + friend BOOST_PYTHON_DECL tuple& operator+=(tuple&, const tuple&); +}; + +class tuple : public tuple_base +{ + public: + explicit tuple(std::size_t n = 0) : tuple_base(n) {} + explicit tuple(handle<> p) : tuple_base(p) {} + + template + tuple(const std::pair& x) + : tuple_base(handle<>(PyTuple_New(2))) + { + set_item(0, x.first); + set_item(1, x.second); + } + + template + tuple(const First& first, const Second& second) + : tuple_base(handle<>(PyTuple_New(2))) + { + set_item(0, first); + set_item(1, second); + } + + template + tuple(const First& first, const Second& second, const Third& third) + : tuple_base(handle<>(PyTuple_New(3))) + { + set_item(0, first); + set_item(1, second); + set_item(2, third); + } + + template + tuple(const First& first, const Second& second, const Third& third, const Fourth& fourth) + : tuple_base(handle<>(PyTuple_New(4))) + { + set_item(0, first); + set_item(1, second); + set_item(2, third); + set_item(3, fourth); + } + + void set_item(std::size_t pos, const handle<>& rhs) + { + tuple_base::set_item(pos, rhs); + } +}; + +class list; + +struct BOOST_PYTHON_DECL list_proxy; +struct BOOST_PYTHON_DECL list_slice_proxy; + +class BOOST_PYTHON_DECL list_base : public objects_base +{ + protected: + typedef list_proxy proxy; + typedef list_slice_proxy slice_proxy; + public: + explicit list_base(handle<> p); + explicit list_base(std::size_t sz = 0); + static PyTypeObject* type_obj(); + static bool accepts(handle<> p); + std::size_t size() const; + handle<> operator[](std::size_t pos) const; + proxy operator[](std::size_t pos); + handle<> get_item(std::size_t pos) const; + + void set_item(std::size_t pos, const handle<>& ); + +// void set_item(std::size_t pos, const object& ); + + void insert(std::size_t index, const handle<>& item); + + void push_back(const handle<>& item); + + void append(const handle<>& item); + + list slice(int low, int high) const; + slice_proxy slice(int low, int high); + void sort(); + void reverse(); + tuple as_tuple() const; +}; + +class list : public list_base +{ + public: + explicit list(handle<> p) : list_base(p) {} + explicit list(std::size_t sz = 0) : list_base(sz) {} + template + void set_item(std::size_t pos, const T& x) + { this->set_item(pos, make_ref(x)); } + template + void insert(std::size_t index, const T& x) + { this->insert(index, make_ref(x)); } + template + void push_back(const T& item) + { this->push_back(make_ref(item)); } + template + void append(const T& item) + { this->append(make_ref(item)); } + + void set_item(std::size_t pos, const handle<>& x) { list_base::set_item(pos, x); } + void insert(std::size_t index, const handle<>& item) { list_base::insert(index, item); } + void push_back(const handle<>& item) { list_base::push_back(item); } + void append(const handle<>& item) { list_base::append(item); } +}; + +class BOOST_PYTHON_DECL string + : public objects_base, public boost::multipliable2 +{ + public: + // Construct from an owned PyObject*. + // Precondition: p must point to a python string. + explicit string(handle<> p); + explicit string(const char* s); + string(const char* s, std::size_t length); + string(const string& rhs); + + enum interned_t { interned }; + string(const char* s, interned_t); + + // Get the type object for Strings + static PyTypeObject* type_obj(); + + // Return true if the given object is a python string + static bool accepts(handle<> o); + + // Return the length of the string. + std::size_t size() const; + + // Returns a null-terminated representation of the contents of string. + // The pointer refers to the internal buffer of string, not a copy. + // The data must not be modified in any way. It must not be de-allocated. + const char* c_str() const; + + string& operator*=(unsigned int repeat_count); + string& operator+=(const string& rhs); + friend string operator+(string x, string y); + string& operator+=(const char* rhs); + friend string operator+(string x, const char* y); + friend string operator+(const char* x, string y); + + void intern(); + + friend string operator%(const string& format, const tuple& args); +}; + +class dictionary; + +struct BOOST_PYTHON_DECL dictionary_proxy; + +class BOOST_PYTHON_DECL dictionary_base : public objects_base +{ + protected: + typedef dictionary_proxy proxy; + + public: + explicit dictionary_base(handle<> p); + dictionary_base(); + void clear(); + + static PyTypeObject* type_obj(); + static bool accepts(handle<> p); + + public: + proxy operator[](handle<> key); + handle<> operator[](handle<> key) const; + handle<> get_item(const handle<>& key) const; + handle<> get_item(const handle<>& key, const handle<>& default_) const; + + void set_item(const handle<>& key, const handle<>& value); + + void erase(handle<> key); + +// proxy operator[](const object& key); +// ref operator[](const object& key) const; + +// ref get_item(const object& key, ref default_ = ref()) const; +// void set_item(const object& key, const ref& value); + +// void erase(const object& key); + + list items() const; + list keys() const; + list values() const; + + std::size_t size() const; + // TODO: iterator support +}; + +struct BOOST_PYTHON_DECL dictionary_proxy +{ + template + const handle<>& operator=(const T& rhs) + { return (*this) = make_ref(rhs); } + const handle<>& operator=(const handle<>& rhs); + + operator handle<>() const; + private: + friend class dictionary_base; + dictionary_proxy(const handle<>& dict, const handle<>& key); + + // This is needed to work around the very strange MSVC error report that the + // return type of the built-in operator= differs from that of the ones + // defined above. Couldn't hurt to make these un-assignable anyway, though. + const handle<>& operator=(const dictionary_proxy&); // Not actually implemented + private: + handle<> m_dict; + handle<> m_key; +}; + +class dictionary : public dictionary_base +{ + typedef dictionary_proxy proxy; + public: + explicit dictionary(handle<> p) : dictionary_base(p) {} + dictionary() : dictionary_base() {} + + template + proxy operator[](const Key& key) + { return this->operator[](make_ref(key)); } + proxy operator[](handle<> key) + { return dictionary_base::operator[](key); } + + template + handle<> operator[](const Key& key) const + { return this->operator[](make_ref(key)); } + handle<> operator[](handle<> key) const + { return dictionary_base::operator[](key); } + + template + handle<> get_item(const Key& key) const + { return this->get_item(make_ref(key)); } + handle<> get_item(const handle<>& key) const + { return dictionary_base::get_item(key); } + + template + handle<> get_item(const Key& key, const Default& default_) const + { return this->get_item(make_ref(key), make_ref(default_)); } + handle<> get_item(const handle<>& key, const handle<>& default_) const + { return dictionary_base::get_item(key, default_); } + + template + void set_item(const Key& key, const Value& value) + { this->set_item(make_ref(key), make_ref(value)); } + void set_item(const handle<>& key, const handle<>& value) + { dictionary_base::set_item(key, value); } + + template + void erase(const Key& key) + { this->erase(make_ref(key)); } + void erase(handle<> key) + { dictionary_base::erase(key); } +}; + +struct BOOST_PYTHON_DECL list_proxy +{ + template + const handle<>& operator=(const T& rhs) + { return (*this) = make_ref(rhs); } + const handle<>& operator=(const handle<>& rhs); + + operator handle<>() const; + + private: + friend class list_base; + list_proxy(const handle<>& list, std::size_t index); + + // This is needed to work around the very strange MSVC error report that the + // return type of the built-in operator= differs from that of the ones + // defined above. Couldn't hurt to make these un-assignable anyway, though. + const handle<>& operator=(const list_proxy&); // Not actually implemented + private: + list m_list; + std::size_t m_index; +}; + +struct BOOST_PYTHON_DECL list_slice_proxy +{ + const list& operator=(const list& rhs); + operator handle<>() const; + operator list() const; + std::size_t size() const; + handle<> operator[](std::size_t pos) const; + private: + friend class list_base; + list_slice_proxy(const handle<>& list, int low, int high); + private: + handle<> m_list; + int m_low, m_high; +}; + +}} // namespace boost::python + +#endif // OBJECTS_DWA20020611_H diff --git a/include/boost/python/operators2.hpp b/include/boost/python/operators2.hpp index aa97071f..a58b7559 100755 --- a/include/boost/python/operators2.hpp +++ b/include/boost/python/operators2.hpp @@ -27,7 +27,7 @@ namespace detail template PyObject* convert_result(T const& x) { - return converter::arg_to_python(x).get_incref(); + return converter::arg_to_python(x).release(); } // Operator implementation template declarations. The nested apply diff --git a/include/boost/python/reference.hpp b/include/boost/python/reference.hpp index 97edef99..f070f114 100644 --- a/include/boost/python/reference.hpp +++ b/include/boost/python/reference.hpp @@ -9,6 +9,12 @@ #ifndef PYPTR_DWA050400_H_ # define PYPTR_DWA050400_H_ +# ifdef BOOST_PYTHON_V2 + +# error obsolete + +# else + # include # include # include @@ -19,7 +25,6 @@ # include # include -# ifndef BOOST_PYTHON_V2 # include BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE @@ -39,19 +44,14 @@ struct py_ptr_conversions : Base }; BOOST_PYTHON_END_CONVERSION_NAMESPACE -# endif namespace boost { namespace python { -# ifndef BOOST_PYTHON_V2 BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions); -# endif template class reference -# ifndef BOOST_PYTHON_V2 : public py_ptr_conversions, T> -# endif { public: typedef T value_type; @@ -215,12 +215,7 @@ private: inline PyObject* object() const { -#ifdef BOOST_PYTHON_V2 - return (PyObject*)( - (char*)&m_p->ob_type - offsetof(PyObject,ob_type)); -#else return as_object(m_p); -#endif } T* m_p; @@ -228,14 +223,14 @@ private: typedef reference ref; -#ifndef BOOST_PYTHON_V2 template ref make_ref(const T& x) { return ref(to_python(x)); } -#endif }} // namespace boost::python +#endif // BOOST_PYTHON_V2 + #endif // PYPTR_DWA050400_H_ diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index 480cd909..6aaa2ab0 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -107,7 +107,7 @@ inline PyObject* to_python_indirect::operator()(T x) const // Everything's OK; Bypass NULL checks but guard against // exceptions. - ref result(raw_result, ref::allow_null()); + handle<> result(python::allow_null(raw_result)); // Build a value_holder to contain the object using the copy // constructor diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index c495445d..038d0ff5 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include @@ -54,7 +54,7 @@ namespace { // Get the (intermediate) source object unaryfunc creator = *static_cast(data->convertible); - ref intermediate(creator(obj)); + handle<> intermediate(creator(obj)); // Get the location in which to construct void* storage = ((rvalue_base_data*)data)->storage.bytes; diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index bd6aa904..573e38f9 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include namespace boost { namespace python { namespace converter { @@ -35,7 +35,7 @@ namespace detail arg_to_python_base::arg_to_python_base( void const volatile* source, to_python_function_t converter) - : arg_to_python_holder(convert(source, converter)) + : handle<>(convert(source, converter)) { } @@ -65,7 +65,7 @@ namespace detail PyObject* source , lvalue_from_python_registration*const& converters) { - ref holder(source); + handle<> holder(source); if (source->ob_refcnt <= 2) { PyErr_SetString( @@ -106,7 +106,7 @@ namespace detail BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_stage1_data& data, void* storage) { - ref holder(src); + handle<> holder(src); data = find(src, static_cast(data.convertible)); diff --git a/src/errors.cpp b/src/errors.cpp index 6d0cfd90..cd188cb6 100644 --- a/src/errors.cpp +++ b/src/errors.cpp @@ -54,13 +54,6 @@ void BOOST_PYTHON_DECL throw_error_already_set() throw error_already_set(); } -BOOST_PYTHON_DECL PyObject* expect_non_null_impl(PyObject* x) -{ - if (x == 0) - throw_error_already_set(); - return x; -} - namespace detail { BOOST_PYTHON_DECL void expect_complex(PyObject* p) diff --git a/src/module.cpp b/src/module.cpp index e958c6d8..e5d996cc 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -8,13 +8,14 @@ #include #include +#include namespace boost { namespace python { namespace detail { module_base::module_base(const char* name) : m_module( - Py_InitModule(const_cast(name), initial_methods) - , ref::increment_count) + borrow(Py_InitModule(const_cast(name), initial_methods)) + ) { } @@ -24,38 +25,33 @@ module_base::~module_base() void module_base::setattr(const char* name, PyObject* x) { - setattr(name, ref(x)); + setattr(name, handle<>(x)); } -void module_base::setattr(char const* name, ref const& x) +void module_base::setattr(char const* name, handle<> const& x) { // Use function::add_to_namespace to achieve overloading if // appropriate. objects::function::add_to_namespace(m_module, name, x); } -void module_base::add(PyTypeObject* x) +void module_base::add(type_handle const& x) { - this->setattr(x->tp_name, (PyObject*)x); + this->setattr(x->tp_name, x); } -void module_base::add_type(ref x) +void module_base::add_class(type_handle const& class_obj) { - assert(PyObject_TypeCheck(x.get(), &PyType_Type)); - add((PyTypeObject*)x.release()); -} - -void module_base::add_class(ref const& class_obj) -{ - this->add_type(class_obj); + this->add(class_obj); - ref module_name( + handle<> module_name( PyObject_GetAttrString( m_module.get(), const_cast("__name__")) ); int status = PyObject_SetAttrString( - class_obj.get(), const_cast("__module__"), module_name.get()); + python::upcast(class_obj.get()) + , const_cast("__module__"), module_name.get()); if (status == -1) throw_error_already_set(); diff --git a/src/object/class.cpp b/src/object/class.cpp index ea0c332b..cfea075f 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -101,16 +101,16 @@ void instance_holder::install(PyObject* self) throw() namespace objects { // Get the metatype object for all extension classes. - BOOST_PYTHON_DECL ref class_metatype() + BOOST_PYTHON_DECL type_handle class_metatype() { if (class_metatype_object.tp_dict == 0) { class_metatype_object.ob_type = &PyType_Type; class_metatype_object.tp_base = &PyType_Type; if (PyType_Ready(&class_metatype_object)) - return ref(); + return type_handle(); } - return ref((PyObject*)&class_metatype_object, ref::increment_count); + return type_handle(borrow(&class_metatype_object)); } extern "C" { @@ -172,16 +172,16 @@ namespace objects PyType_GenericNew }; - BOOST_PYTHON_DECL ref class_type() + BOOST_PYTHON_DECL type_handle class_type() { if (class_type_object.tp_dict == 0) { - class_type_object.ob_type = (PyTypeObject*)class_metatype().release(); + class_type_object.ob_type = incref(class_metatype().get()); class_type_object.tp_base = &PyBaseObject_Type; if (PyType_Ready(&class_type_object)) - return ref(); + return type_handle(); } - return ref((PyObject*)&class_type_object, ref::increment_count); + return type_handle(borrow(&class_type_object)); } BOOST_PYTHON_DECL void* @@ -206,11 +206,11 @@ namespace objects struct class_registry { public: - ref get(class_id id) const; - ref query(class_id id) const; - void set(class_id, ref class_object); + type_handle get(class_id id) const; + type_handle query(class_id id) const; + void set(class_id, type_handle class_object); private: - typedef detail::map_entry entry; + typedef detail::map_entry entry; std::vector m_impl; }; @@ -220,7 +220,7 @@ namespace objects return x; } - inline ref class_registry::query(class_id id) const + inline type_handle class_registry::query(class_id id) const { std::vector::const_iterator start = m_impl.begin(); std::vector::const_iterator finish = m_impl.end(); @@ -228,12 +228,12 @@ namespace objects std::vector::const_iterator p = boost::detail::lower_bound(start, finish, id); - return (p == finish || p->key != id) ? ref() : p->value; + return (p == finish || p->key != id) ? type_handle() : p->value; } - inline ref class_registry::get(class_id id) const + inline type_handle class_registry::get(class_id id) const { - ref result(this->query(id)); + type_handle result(this->query(id)); if (result.get() == 0) { @@ -245,7 +245,7 @@ namespace objects return result; } - inline void class_registry::set(class_id id, ref object) + inline void class_registry::set(class_id id, type_handle object) { std::vector::iterator start = m_impl.begin(); std::vector::iterator finish = m_impl.end(); @@ -276,8 +276,10 @@ namespace objects args.set_item(0, string(name).reference()); args.set_item(1, bases.reference()); args.set_item(2, dictionary().reference()); - - m_object = ref(PyObject_CallObject(class_metatype().get(), args.get())); + + PyObject* c = PyObject_CallObject(upcast(class_metatype().get()), args.get()); + assert(PyType_IsSubtype(c->ob_type, &PyType_Type)); + m_object = type_handle((PyTypeObject*)c); r.set(types[0], m_object); } @@ -287,25 +289,25 @@ namespace objects extern DL_IMPORT(PyTypeObject) PyProperty_Type; } - void class_base::add_property(char const* name, ref const& fget) + void class_base::add_property(char const* name, handle<> const& fget) { - ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.get())); + handle<> property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.get())); setattr(name, property); } - void class_base::add_property(char const* name, ref const& fget, ref const& fset) + void class_base::add_property(char const* name, handle<> const& fget, handle<> const& fset) { - ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.get(), fset.get())); + handle<> property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.get(), fset.get())); setattr(name, property); } - void class_base::setattr(char const* name, ref const& x) + void class_base::setattr(char const* name, handle<> const& x) { - if (PyObject_SetAttrString(object().get(), const_cast(name), x.get()) < 0) + if (PyObject_SetAttrString(upcast(object().get()), const_cast(name), x.get()) < 0) throw_error_already_set(); } - BOOST_PYTHON_DECL ref registered_class_object(class_id id) + BOOST_PYTHON_DECL type_handle registered_class_object(class_id id) { return registry().query(id); } diff --git a/src/object/function.cpp b/src/object/function.cpp index 0d89791c..8855ba75 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -149,14 +149,14 @@ namespace function* not_implemented_function() { static function* result = new function(py_function(¬_implemented_impl), 2, 3); - static ref keeper(result); + static handle<> keeper(result); return result; } } void function::add_to_namespace( - ref const& name_space, char const* name_, ref const& attribute) + handle<> const& name_space, char const* name_, handle<> const& attribute) { string const name(name_); PyObject* const ns = name_space.get(); @@ -175,7 +175,7 @@ void function::add_to_namespace( if (dict == 0) throw_error_already_set(); - ref existing(PyObject_GetItem(dict, name.get()), ref::null_ok); + handle<> existing( allow_null(PyObject_GetItem(dict, name.get())) ); if (existing.get()) { diff --git a/src/object/iterator.cpp b/src/object/iterator.cpp index 6a927726..8b6da346 100644 --- a/src/object/iterator.cpp +++ b/src/object/iterator.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include namespace boost { namespace python { namespace objects { @@ -18,9 +18,9 @@ static PyObject* identity(PyObject* args_, PyObject*) return x; } -BOOST_PYTHON_DECL ref identity_function() +BOOST_PYTHON_DECL handle<> identity_function() { - static ref result(new objects::function(py_function(&identity), 1)); + static handle<> result(new objects::function(py_function(&identity), 1)); return result; } diff --git a/src/objects2.cpp b/src/objects2.cpp new file mode 100755 index 00000000..5ec410ab --- /dev/null +++ b/src/objects2.cpp @@ -0,0 +1,426 @@ +// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// The author gratefully acknowleges the support of Dragon Systems, Inc., in +// producing this work. + +// TODO: Move inline implementations from objects.cpp here + +#ifndef BOOST_PYTHON_SOURCE +# define BOOST_PYTHON_SOURCE +#endif + +#include +#include + +namespace boost { namespace python { + +objects_base::objects_base(handle<> const& p) + : m_p(borrow(p.get())) // Do the null check here +{} + +// Return a reference to the held object +handle<> objects_base::reference() const +{ + return m_p; +} + +// Return a raw pointer to the held object +PyObject* objects_base::get() const +{ + return m_p.get(); +} + +}} // namespace boost::python + +namespace boost { namespace python { + +tuple_base::tuple_base(std::size_t n) + : objects_base(handle<>(PyTuple_New(n))) +{ + for (std::size_t i = 0; i < n; ++i) + PyTuple_SET_ITEM(get(), i, detail::none()); +} + +tuple_base::tuple_base(handle<> p) + : objects_base(p) +{ + assert(accepts(p)); + if (!accepts(p)) + { + PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); + throw_error_already_set(); + } +} + +PyTypeObject* tuple_base::type_obj() +{ + return &PyTuple_Type; +} + +bool tuple_base::accepts(handle<> p) +{ + return PyTuple_Check(p.get()); +} + +std::size_t tuple_base::size() const +{ + return PyTuple_Size(get()); +} + +handle<> tuple_base::operator[](std::size_t pos) const +{ + return handle<>(borrow(PyTuple_GetItem(get(), static_cast(pos)))); +} + +void tuple_base::set_item(std::size_t pos, const handle<>& rhs) +{ + int failed = PyTuple_SetItem( + get() + , static_cast(pos) + , incref(expect_non_null(rhs.get())) + ); + (void)failed; + assert(failed == 0); +} + +tuple tuple_base::slice(int low, int high) const +{ + return tuple(handle<>(PyTuple_GetSlice(get(), low, high))); +} + +BOOST_PYTHON_DECL tuple& operator+=(tuple& self, const tuple& rhs) +{ + return self = self + rhs; +} + + +// Construct from an owned PyObject*. +// Precondition: p must point to a python string. +string::string(handle<> p) + : objects_base(p) +{ + assert(accepts(p)); + if (!accepts(p)) + { + PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); + throw_error_already_set(); + } +} + +string::string(const char* s) + : objects_base(handle<>(PyString_FromString(s))) {} + +string::string(const char* s, std::size_t length) + : objects_base(handle<>(PyString_FromStringAndSize(s, length))) {} + +string::string(const char* s, interned_t) + : objects_base(handle<>(PyString_InternFromString(s))) {} + +string::string(const string& rhs) + : objects_base(rhs.reference()) {} + +// Get the type object for Strings +PyTypeObject* string::type_obj() +{ return &PyString_Type; } + +// Return true if the given object is a python string +bool string::accepts(handle<> o) +{ return PyString_Check(o.get()); } + +// Return the length of the string. +std::size_t string::size() const +{ + int size = PyString_GET_SIZE(get()); + assert(size >= 0); + return static_cast(size); +} + +// Returns a null-terminated representation of the contents of string. +// The pointer refers to the internal buffer of string, not a copy. +// The data must not be modified in any way. It must not be de-allocated. +const char* string::c_str() const +{ return PyString_AS_STRING(get()); } + +void string::intern() +{ // UNTESTED!! + *this = string(handle<>(borrow(PyString_InternFromString(c_str())))); +} + +string& string::operator*=(unsigned int repeat_count) +{ + *this = string(handle<>(PySequence_Repeat(get(), repeat_count))); + return *this; +} + +dictionary_base::dictionary_base(handle<> p) + : objects_base(p) +{ + assert(accepts(p)); + if (!accepts(p)) + { + PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); + throw_error_already_set(); + } +} + +dictionary_base::dictionary_base() + : objects_base(handle<>(PyDict_New())) {} + +PyTypeObject* dictionary_base::type_obj() +{ return &PyDict_Type; } + +bool dictionary_base::accepts(handle<> p) +{ return PyDict_Check(p.get()); } + +void dictionary_base::clear() +{ PyDict_Clear(get()); } + +const handle<>& dictionary_proxy::operator=(const handle<>& rhs) +{ + if (PyDict_SetItem(m_dict.get(), m_key.get(), rhs.get()) == -1) + throw_error_already_set(); + return rhs; +} + +dictionary_proxy::operator handle<>() const +{ + return handle<>( + m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get())); +} + +dictionary_proxy::dictionary_proxy(const handle<>& dict, const handle<>& key) + : m_dict(dict), m_key(key) {} + +dictionary_proxy dictionary_base::operator[](handle<> key) +{ return proxy(reference(), key); } + +handle<> dictionary_base::operator[](handle<> key) const { + // An odd MSVC bug causes the ".operator Ptr()" to be needed + return proxy(reference(), key).operator handle<>(); +} + + +handle<> dictionary_base::get_item(const handle<>& key) const +{ + return get_item(key, handle<>()); +} + +handle<> dictionary_base::get_item(const handle<>& key, const handle<>& default_) const +{ + PyObject* value_or_null = PyDict_GetItem(get(), key.get()); + if (value_or_null == 0 && !PyErr_Occurred()) + return default_; + else + return handle<>(borrow(value_or_null)); // Will throw if there was another error +} + +void dictionary_base::set_item(const handle<>& key, const handle<>& value) +{ + if (PyDict_SetItem(get(), key.get(), value.get()) == -1) + throw_error_already_set(); +} + +void dictionary_base::erase(handle<> key) { + if (PyDict_DelItem(get(), key.get()) == -1) + throw_error_already_set(); +} + +list dictionary_base::items() const { return list(handle<>(PyDict_Items(get()))); } +list dictionary_base::keys() const { return list(handle<>(PyDict_Keys(get()))); } +list dictionary_base::values() const { return list(handle<>(PyDict_Values(get()))); } + +std::size_t dictionary_base::size() const { return static_cast(PyDict_Size(get())); } + +string operator+(string x, string y) +{ + PyObject* io_string = incref(x.get()); + PyString_Concat(&io_string, y.get()); + return string(handle<>(io_string)); +} + +string& string::operator+=(const string& rhs) +{ + return *this = *this + rhs; +} + +string& string::operator+=(const char* y) +{ + return *this += string(y); +} + +string operator%(const string& format, const tuple& args) +{ + return string(handle<>(PyString_Format(format.get(), args.reference().get()))); +} + +string operator+(string x, const char* y) +{ + return x + string(y); +} + +string operator+(const char* x, string y) +{ + return string(x) + y; +} + +tuple operator+(const tuple& x, const tuple& y) +{ + tuple result(x.size() + y.size()); + for (std::size_t xi = 0; xi < x.size(); ++xi) + result.set_item(xi, x[xi]); + for (std::size_t yi = 0; yi < y.size(); ++yi) + result.set_item(yi + x.size(), y[yi]); + return result; +} + + +list_base::list_base(handle<> p) + : objects_base(p) +{ + assert(accepts(p)); + if (!accepts(p)) + { + PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); + throw_error_already_set(); + } +} + +list_base::list_base(std::size_t sz) + : objects_base(handle<>(PyList_New(sz))) +{ +} + +PyTypeObject* list_base::type_obj() +{ + return &PyList_Type; +} + +bool list_base::accepts(handle<> p) +{ + return PyList_Check(p.get()); +} + +std::size_t list_base::size() const +{ + return PyList_Size(get()); +} + +handle<> list_base::operator[](std::size_t pos) const +{ + return handle<>(borrow(PyList_GetItem(get(), pos))); +} + +list_proxy list_base::operator[](std::size_t pos) +{ + return proxy(reference(), pos); +} + +void list_base::insert(std::size_t index, const handle<>& item) +{ + if (PyList_Insert(get(), index, item.get()) == -1) + throw_error_already_set(); +} + +void list_base::push_back(const handle<>& item) +{ + if (PyList_Append(get(), item.get()) == -1) + throw_error_already_set(); +} + +void list_base::append(const handle<>& item) +{ + this->push_back(item); +} + +list list_base::slice(int low, int high) const +{ + return list(handle<>(PyList_GetSlice(get(), low, high))); +} + +list_slice_proxy list_base::slice(int low, int high) +{ + return list_slice_proxy(reference(), low, high); +} + +void list_base::sort() +{ + if (PyList_Sort(get()) == -1) + throw_error_already_set(); +} + +void list_base::reverse() +{ + if (PyList_Reverse(get()) == -1) + throw_error_already_set(); +} + +tuple list_base::as_tuple() const +{ + return tuple(handle<>(PyList_AsTuple(get()))); +} + +const handle<>& list_proxy::operator=(const handle<>& rhs) +{ + m_list.set_item(m_index, rhs); + return rhs; +} + +list_proxy::operator handle<>() const +{ + return handle<>(borrow(PyList_GetItem(m_list.get(), m_index))); +} + +handle<> list_base::get_item(std::size_t pos) const +{ + return handle<>(borrow(PyList_GetItem(this->get(), pos))); +} + +void list_base::set_item(std::size_t pos, const handle<>& rhs) +{ + int result = PyList_SetItem(this->get(), pos, rhs.get()); + if (result == -1) + throw_error_already_set(); + Py_INCREF(rhs.get()); +} + +list_proxy::list_proxy(const handle<>& list, std::size_t index) + : m_list(list), m_index(index) +{ +} + +const list& list_slice_proxy::operator=(const list& rhs) +{ + if (PyList_SetSlice(m_list.get(), m_low, m_high, rhs.get()) == -1) + throw_error_already_set(); + return rhs; +} + +list_slice_proxy::operator handle<>() const +{ + return handle<>(PyList_GetSlice(m_list.get(), m_low, m_high)); +} + +list_slice_proxy::operator list() const +{ + return list(this->operator handle<>()); +} + +std::size_t list_slice_proxy::size() const +{ + return this->operator list().size(); +} + +handle<> list_slice_proxy::operator[](std::size_t pos) const +{ + return this->operator list()[pos].operator handle<>(); +} + +list_slice_proxy::list_slice_proxy(const handle<>& list, int low, int high) + : m_list(list), m_low(low), m_high(high) +{ +} + +}} // namespace boost::python diff --git a/test/Jamfile b/test/Jamfile index ef6c0b7d..c0459022 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -98,6 +98,10 @@ unit-test pointee unit-test result : result.cpp : $(BOOST_ROOT) ; +unit-test upcast + : upcast.cpp + : $(BOOST_ROOT) BOOST_PYTHON_STATIC_LIB $(PYTHON_PROPERTIES) ; + unit-test select_holder : select_holder.cpp : $(BOOST_ROOT) BOOST_PYTHON_STATIC_LIB $(PYTHON_PROPERTIES) diff --git a/test/cltree.cpp b/test/cltree.cpp index a17fd659..d99a4862 100755 --- a/test/cltree.cpp +++ b/test/cltree.cpp @@ -83,3 +83,6 @@ BOOST_PYTHON_MODULE_INIT(cltree) { ) ; } + +#include "module_tail.cpp" + diff --git a/test/upcast.cpp b/test/upcast.cpp new file mode 100755 index 00000000..b02d2534 --- /dev/null +++ b/test/upcast.cpp @@ -0,0 +1,19 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include + +struct X { long x; }; +struct Y : X, PyObject {}; + +int main() +{ + PyTypeObject o; + Y y; + assert(&boost::python::upcast(&o)->ob_refcnt == &o.ob_refcnt); + assert(&boost::python::upcast(&y)->ob_refcnt == &y.ob_refcnt); + return 0; +} + From 8817b1e2af2dedbb74519faef926dd029164b459 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 13 Jun 2002 14:06:08 +0000 Subject: [PATCH 0518/1042] fixed missing template parameter [SVN r14140] --- include/boost/python/module.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 23f2884e..a4dad490 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -30,8 +30,8 @@ class module : public detail::module_base module& setattr(const char* name, handle<> const&); module& add(PyTypeObject* x); // just use the type's name - template - module& add(class_ const& c) + template + module& add(class_ const& c) { this->add_class(c.object()); return *this; From 773bb0651e77ae8726b7acd4d42470ddfaf88904 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 16 Jun 2002 20:13:38 +0000 Subject: [PATCH 0519/1042] borrow() -> borrowed() type -> boost::type [SVN r14153] --- include/boost/python/back_reference.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/python/back_reference.hpp b/include/boost/python/back_reference.hpp index fbfaff11..3ad7d240 100644 --- a/include/boost/python/back_reference.hpp +++ b/include/boost/python/back_reference.hpp @@ -55,7 +55,7 @@ namespace detail no_back_reference_t is_back_reference_test(...); template - yes_back_reference_t is_back_reference_test(type< back_reference >); + yes_back_reference_t is_back_reference_test(boost::type< back_reference >); } template @@ -64,7 +64,7 @@ class is_back_reference public: BOOST_STATIC_CONSTANT( bool, value = ( - sizeof(detail::is_back_reference_test(type())) + sizeof(detail::is_back_reference_test(boost::type())) == sizeof(detail::yes_back_reference_t))); }; @@ -75,7 +75,7 @@ class is_back_reference // template back_reference::back_reference(PyObject* p, T x) - : m_reference(python::borrow(p)) + : m_reference(python::borrowed(p)) , m_value(x) { } From 0b5937a3968a344b53fd2072ec2b71e3587e31d4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 16 Jun 2002 20:18:51 +0000 Subject: [PATCH 0520/1042] type -> boost::type [SVN r14154] --- include/boost/python/ptr.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/ptr.hpp b/include/boost/python/ptr.hpp index dfbb2153..5f8ad2d0 100644 --- a/include/boost/python/ptr.hpp +++ b/include/boost/python/ptr.hpp @@ -80,7 +80,7 @@ namespace detail no_pointer_wrapper_t is_pointer_wrapper_test(...); template - yes_pointer_wrapper_t is_pointer_wrapper_test(type< pointer_wrapper >); + yes_pointer_wrapper_t is_pointer_wrapper_test(boost::type< pointer_wrapper >); template struct pointer_unwrapper @@ -109,7 +109,7 @@ class is_pointer_wrapper public: BOOST_STATIC_CONSTANT( bool, value = ( - sizeof(detail::is_pointer_wrapper_test(type())) + sizeof(detail::is_pointer_wrapper_test(boost::type())) == sizeof(detail::yes_pointer_wrapper_t))); }; From c12ffa21dab0af0cfbcd1d948fd8a21a0f867815 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 16 Jun 2002 20:41:54 +0000 Subject: [PATCH 0521/1042] beginning of object support [SVN r14157] --- Jamfile | 1 + include/boost/python/base_type_traits.hpp | 36 +++ include/boost/python/cast.hpp | 29 +- .../boost/python/converter/arg_to_python.hpp | 82 ++++- .../python/converter/arg_to_python_base.hpp | 11 +- .../python/converter/builtin_converters.hpp | 1 - .../boost/python/converter/from_python.hpp | 1 + .../boost/python/converter/object_manager.hpp | 149 +++++++++ .../python/converter/return_from_python.hpp | 4 + include/boost/python/detail/borrowed_ptr.hpp | 56 ++++ include/boost/python/detail/convertible.hpp | 25 ++ .../boost/python/detail/indirect_traits.hpp | 4 +- include/boost/python/detail/unwind_type.hpp | 2 +- include/boost/python/handle.hpp | 175 +++++++---- include/boost/python/handle_fwd.hpp | 17 ++ include/boost/python/object.hpp | 20 ++ include/boost/python/object/forward.hpp | 4 +- include/boost/python/object/iterator.hpp | 2 +- include/boost/python/object_attributes.hpp | 81 +++++ include/boost/python/object_core.hpp | 286 ++++++++++++++++++ include/boost/python/object_items.hpp | 81 +++++ include/boost/python/object_protocol.hpp | 45 +++ include/boost/python/object_protocol_core.hpp | 20 ++ .../boost/python/preprocessed/object_call.hpp | 101 +++++++ include/boost/python/proxy.hpp | 129 ++++++++ include/boost/python/refcount.hpp | 42 +++ include/boost/python/to_python_value.hpp | 86 ++++-- src/converter/callback.cpp | 4 + src/module.cpp | 2 +- src/object/class.cpp | 4 +- src/object_protocol.cpp | 35 +++ src/objects2.cpp | 14 +- test/Jamfile | 78 ++--- test/borrowed.cpp | 33 ++ test/callbacks.cpp | 25 +- test/callbacks.py | 14 +- test/object.cpp | 149 +++++++++ test/object.py | 95 ++++++ test/object_fail1.cpp | 12 + test/object_manager.cpp | 37 +++ test/raw_pyobject_fail1.cpp | 12 + test/raw_pyobject_fail2.cpp | 14 + test/test_builtin_converters.cpp | 36 +++ test/test_builtin_converters.py | 20 ++ 44 files changed, 1895 insertions(+), 179 deletions(-) create mode 100755 include/boost/python/base_type_traits.hpp create mode 100755 include/boost/python/converter/object_manager.hpp create mode 100755 include/boost/python/detail/borrowed_ptr.hpp create mode 100755 include/boost/python/detail/convertible.hpp create mode 100755 include/boost/python/handle_fwd.hpp create mode 100755 include/boost/python/object.hpp create mode 100755 include/boost/python/object_attributes.hpp create mode 100755 include/boost/python/object_core.hpp create mode 100755 include/boost/python/object_items.hpp create mode 100755 include/boost/python/object_protocol.hpp create mode 100755 include/boost/python/object_protocol_core.hpp create mode 100755 include/boost/python/preprocessed/object_call.hpp create mode 100755 include/boost/python/proxy.hpp create mode 100755 include/boost/python/refcount.hpp create mode 100755 src/object_protocol.cpp create mode 100755 test/borrowed.cpp create mode 100755 test/object.cpp create mode 100644 test/object.py create mode 100755 test/object_fail1.cpp create mode 100755 test/object_manager.cpp create mode 100755 test/raw_pyobject_fail1.cpp create mode 100755 test/raw_pyobject_fail2.cpp diff --git a/Jamfile b/Jamfile index 23d82c1b..b0993452 100644 --- a/Jamfile +++ b/Jamfile @@ -27,6 +27,7 @@ dll bpl src/converter/builtin_converters.cpp src/converter/callback.cpp src/object/iterator.cpp + src/object_protocol.cpp : $(BOOST_PYTHON_V2_PROPERTIES) BOOST_PYTHON_SOURCE diff --git a/include/boost/python/base_type_traits.hpp b/include/boost/python/base_type_traits.hpp new file mode 100755 index 00000000..cae9ebc2 --- /dev/null +++ b/include/boost/python/base_type_traits.hpp @@ -0,0 +1,36 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BASE_TYPE_TRAITS_DWA2002614_HPP +# define BASE_TYPE_TRAITS_DWA2002614_HPP + +namespace boost { namespace python { + +namespace detail +{ + struct unspecialized {}; +} + +// Derive from unspecialized so we can detect whether traits are +// specialized +template struct base_type_traits + : detail::unspecialized +{}; + +template <> +struct base_type_traits +{ + typedef PyObject type; +}; + +template <> +struct base_type_traits +{ + typedef PyObject type; +}; + +}} // namespace boost::python + +#endif // BASE_TYPE_TRAITS_DWA2002614_HPP diff --git a/include/boost/python/cast.hpp b/include/boost/python/cast.hpp index 9408579a..1897fc60 100755 --- a/include/boost/python/cast.hpp +++ b/include/boost/python/cast.hpp @@ -9,38 +9,13 @@ # include # include # include +# include +# include namespace boost { namespace python { -template struct base_type_traits; - -template <> -struct base_type_traits -{ - typedef PyObject type; -}; - -template <> -struct base_type_traits -{ - typedef PyObject type; -}; - namespace detail { - typedef char* yes_convertible; - typedef int* no_convertible; - - typedef char* yes_python_object; - typedef int* no_python_object; - - template - struct convertible - { - static inline yes_convertible check(Target) { return 0; } - static inline no_convertible check(...) { return 0; } - }; - template inline Target* upcast(Target* p, yes_convertible) { diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index 78268fd0..e4a2bfaf 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -10,7 +10,11 @@ # include # include # include +# include # include +# include +# include +# include // Bring in specializations # include @@ -51,9 +55,27 @@ namespace detail static PyObject* get_object(Ptr p); }; + // Convert types that manage a Python object to_python + template + struct object_manager_arg_to_python + { + object_manager_arg_to_python(T const& x) : m_src(x) {} + + PyObject* get() const + { + return python::upcast(converter::get_managed_object(m_src)); + } + + private: + T const& m_src; + }; + template struct select_arg_to_python { + BOOST_STATIC_CONSTANT( + bool, manager = is_object_manager::value); + BOOST_STATIC_CONSTANT( bool, ptr = is_pointer::value); @@ -67,15 +89,19 @@ namespace detail typedef typename unwrap_pointer::type unwrapped_ptr; typedef typename mpl::select_type< - ptr - , pointer_deep_arg_to_python + manager + , object_manager_arg_to_python , typename mpl::select_type< - ptr_wrapper - , pointer_shallow_arg_to_python + ptr + , pointer_deep_arg_to_python , typename mpl::select_type< - ref_wrapper - , reference_arg_to_python - , value_arg_to_python + ptr_wrapper + , pointer_shallow_arg_to_python + , typename mpl::select_type< + ref_wrapper + , reference_arg_to_python + , value_arg_to_python + >::type >::type >::type >::type type; @@ -108,6 +134,39 @@ struct arg_to_python // namespace detail { + // reject_raw_object_ptr -- cause a compile-time error if the user + // should pass a raw Python object pointer + using python::detail::yes_convertible; + using python::detail::no_convertible; + using python::detail::unspecialized; + + template struct cannot_convert_raw_PyObject; + + template + struct reject_raw_object_helper + { + static void error(Convertibility) + { + cannot_convert_raw_PyObject::to_python_use_handle_instead(); + } + static void error(...) {} + }; + + template + inline void reject_raw_object_ptr(T*) + { + reject_raw_object_helper::error( + python::detail::convertible::check((T*)0)); + + typedef typename remove_cv::type value_type; + + reject_raw_object_helper::error( + python::detail::convertible::check( + (base_type_traits*)0 + )); + } + // --------- + template inline value_arg_to_python::value_arg_to_python(T const& x) : arg_to_python_base(&x, to_python_function::value) @@ -118,6 +177,7 @@ namespace detail inline pointer_deep_arg_to_python::pointer_deep_arg_to_python(Ptr x) : arg_to_python_base(x, pointee_to_python_function::value) { + detail::reject_raw_object_ptr((Ptr)0); } template @@ -131,14 +191,16 @@ namespace detail template inline reference_arg_to_python::reference_arg_to_python(T& x) - : handle<>(get_object(x)) + : handle<>(reference_arg_to_python::get_object(x)) { } template inline pointer_shallow_arg_to_python::pointer_shallow_arg_to_python(Ptr x) - : handle<>(get_object(x)) - {} + : handle<>(pointer_shallow_arg_to_python::get_object(x)) + { + detail::reject_raw_object_ptr((Ptr)0); + } template inline PyObject* pointer_shallow_arg_to_python::get_object(Ptr x) diff --git a/include/boost/python/converter/arg_to_python_base.hpp b/include/boost/python/converter/arg_to_python_base.hpp index 1e5fe191..a0ec7518 100755 --- a/include/boost/python/converter/arg_to_python_base.hpp +++ b/include/boost/python/converter/arg_to_python_base.hpp @@ -13,9 +13,18 @@ namespace boost { namespace python { namespace converter { namespace detail { - struct BOOST_PYTHON_DECL arg_to_python_base : handle<> + struct BOOST_PYTHON_DECL arg_to_python_base +# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140 + : handle<> +# endif { arg_to_python_base(void const volatile* source, to_python_function_t); +# if defined(BOOST_MSVC) && _MSC_FULL_VER == 13102140 + PyObject* get() const { return m_ptr.get(); } + PyObject* release() { return m_ptr.release(); } + private: + handle<> m_ptr; +# endif }; } diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index 77a78069..d8bce16b 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -105,7 +105,6 @@ BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) BOOST_PYTHON_RETURN_TO_PYTHON_BY_VALUE(PyObject*, converter::do_return_to_python(x)) -BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(PyObject*, converter::do_arg_to_python(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::complex, PyComplex_FromDoubles(x.real(), x.imag())) diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index 12740439..d2fb4db2 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -1,3 +1,4 @@ +#error obsolete // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided diff --git a/include/boost/python/converter/object_manager.hpp b/include/boost/python/converter/object_manager.hpp new file mode 100755 index 00000000..93c394e2 --- /dev/null +++ b/include/boost/python/converter/object_manager.hpp @@ -0,0 +1,149 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJECT_MANAGER_DWA2002614_HPP +# define OBJECT_MANAGER_DWA2002614_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +class object; + +}} + +namespace boost { namespace python { namespace converter { + +template +class is_object_manager +{ + BOOST_STATIC_CONSTANT(bool, hdl = is_handle::value); + BOOST_STATIC_CONSTANT(bool, borrowed = python::detail::is_borrowed_ptr::value); + public: + BOOST_STATIC_CONSTANT(bool, value = (hdl | borrowed)); +}; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct is_reference_to_object_manager +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_reference_to_object_manager + : is_object_manager +{ +}; + +template +struct is_reference_to_object_manager + : is_object_manager +{ +}; + +template +struct is_reference_to_object_manager + : is_object_manager +{ +}; + +template +struct is_reference_to_object_manager + : is_object_manager +{ +}; +# else + +namespace detail +{ + typedef char (&yes_reference_to_object_manager)[1]; + typedef char (&no_reference_to_object_manager)[2]; + + template + struct is_object_manager_help + : mpl::select_type< + is_object_manager::value + , yes_reference_to_object_manager + , no_reference_to_object_manager> + { + }; + + template + struct is_reference_to_object_manager_helper + { + template + struct apply + { + static int x; + static no_reference_to_object_manager check(...); + }; + }; + + template + typename is_object_manager_help::type + is_object_manager_helper(int*, double, double, U&); + + template + typename is_object_manager_help::type + is_object_manager_helper(int*, int*, double, U const&); + + template + typename is_object_manager_help::type + is_object_manager_helper(int*, double, int*, U volatile&); + + template + typename is_object_manager_help::type + is_object_manager_helper(int*, int*, int*, U const volatile&); + + no_reference_to_object_manager is_object_manager_helper(...); +} + +template +struct is_reference_to_object_manager +{ + typedef typename mpl::select_type< + is_reference::value, int*, double>::type r_t; + typedef typename mpl::select_type< + python::detail::is_reference_to_const::value, int*, double>::type rc_t; + typedef typename mpl::select_type< + python::detail::is_reference_to_volatile::value, int*, double>::type rv_t; + + typedef typename mpl::select_type::value, T, int>::type value_t; + + static value_t sample_object; + + BOOST_STATIC_CONSTANT( + bool, value + = (sizeof(detail::is_object_manager_helper(r_t(),rc_t(),rv_t(),sample_object)) + == sizeof(detail::yes_reference_to_object_manager) + ) + ); +}; +# endif + +template +inline T* get_managed_object(handle const& h) +{ + return h.get(); +} + +template +inline T* get_managed_object(python::detail::borrowed const volatile* p) +{ + return (T*)p; +} + +// forward declaration needed because name lookup is bound by the +// definition context. +PyObject* get_managed_object(python::object const&); + +}}} // namespace boost::python::converter + +#endif // OBJECT_MANAGER_DWA2002614_HPP diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 249bb6e3..cb16c888 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -7,6 +7,10 @@ # define RETURN_FROM_PYTHON_DWA200265_HPP # include +# include +# include +# include +# include namespace boost { namespace python { namespace converter { diff --git a/include/boost/python/detail/borrowed_ptr.hpp b/include/boost/python/detail/borrowed_ptr.hpp new file mode 100755 index 00000000..4e6d187a --- /dev/null +++ b/include/boost/python/detail/borrowed_ptr.hpp @@ -0,0 +1,56 @@ +#ifndef BORROWED_PTR_DWA20020601_HPP +# define BORROWED_PTR_DWA20020601_HPP +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +# include +#include + +namespace boost { namespace python { namespace detail { + +template class borrowed +{ + typedef T type; +}; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct is_borrowed_ptr +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +struct is_borrowed_ptr*> +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +# else // no partial specialization + +typedef char (&yes_borrowed_ptr_t)[1]; +typedef char (&no_borrowed_ptr_t)[2]; + +no_borrowed_ptr_t is_borrowed_ptr_test(...); + +template +yes_borrowed_ptr_t is_borrowed_ptr_test(boost::type< borrowed* >); + +template +class is_borrowed_ptr +{ + public: + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof(detail::is_borrowed_ptr_test(boost::type())) + == sizeof(detail::yes_borrowed_ptr_t))); +}; + +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +}}} // namespace boost::python::detail + +#endif // #ifndef BORROWED_PTR_DWA20020601_HPP diff --git a/include/boost/python/detail/convertible.hpp b/include/boost/python/detail/convertible.hpp new file mode 100755 index 00000000..2a4d5106 --- /dev/null +++ b/include/boost/python/detail/convertible.hpp @@ -0,0 +1,25 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CONVERTIBLE_DWA2002614_HPP +# define CONVERTIBLE_DWA2002614_HPP + +// Supplies a runtime is_convertible check which can be used with tag +// dispatching to work around the Metrowerks Pro7 limitation with boost::is_convertible +namespace boost { namespace python { namespace detail { + +typedef char* yes_convertible; +typedef int* no_convertible; + +template +struct convertible +{ + static inline yes_convertible check(Target) { return 0; } + static inline no_convertible check(...) { return 0; } +}; + +}}} // namespace boost::python::detail + +#endif // CONVERTIBLE_DWA2002614_HPP diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index dd4502cc..ba184a7d 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -26,7 +26,7 @@ struct is_reference_to_const BOOST_STATIC_CONSTANT(bool, value = true); }; -# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13012108 // vc7.01 alpha workaround +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround template struct is_reference_to_const { @@ -121,7 +121,7 @@ struct is_reference_to_volatile BOOST_STATIC_CONSTANT(bool, value = true); }; -# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13012108 // vc7.01 alpha workaround +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround template struct is_reference_to_volatile { diff --git a/include/boost/python/detail/unwind_type.hpp b/include/boost/python/detail/unwind_type.hpp index 7d1fe390..878b6cc1 100644 --- a/include/boost/python/detail/unwind_type.hpp +++ b/include/boost/python/detail/unwind_type.hpp @@ -133,7 +133,7 @@ struct unwind_helper2 // why bother? template inline typename Generator::result_type -unwind_type(type*p = 0, Generator* = 0) +unwind_type(boost::type*p = 0, Generator* = 0) { BOOST_STATIC_CONSTANT(int, indirection = (is_pointer::value ? pointer_ : 0) diff --git a/include/boost/python/handle.hpp b/include/boost/python/handle.hpp index 912717e0..aa1412b3 100755 --- a/include/boost/python/handle.hpp +++ b/include/boost/python/handle.hpp @@ -9,44 +9,14 @@ # include # include # include +# include +# include +# include namespace boost { namespace python { -template -inline T* incref(T* p) -{ - Py_INCREF(python::upcast(p)); - return p; -} - -template -inline T* xincref(T* p) -{ - Py_XINCREF(python::upcast(p)); - return p; -} - -template -inline void decref(T* p) -{ - Py_DECREF(python::upcast(p)); -} - -template -inline void xdecref(T* p) -{ - Py_XDECREF(python::upcast(p)); -} - -template struct borrowed; template struct null_ok; -template -inline borrowed* borrow(T* p) -{ - return (borrowed*)p; -} - template inline null_ok* allow_null(T* p) { @@ -56,19 +26,19 @@ inline null_ok* allow_null(T* p) namespace detail { template - inline T* manage_ptr(borrowed >* p, int) + inline T* manage_ptr(detail::borrowed >* p, int) { return python::xincref((T*)p); } template - inline T* manage_ptr(null_ok >* p, int) + inline T* manage_ptr(null_ok >* p, int) { return python::xincref((T*)p); } template - inline T* manage_ptr(borrowed* p, long) + inline T* manage_ptr(detail::borrowed* p, long) { return python::incref(expect_non_null((T*)p)); } @@ -84,31 +54,9 @@ namespace detail { return expect_non_null(p); } - -#if 0 - template - struct handle_proxy - : handle_proxy::type> - { - typedef typename base_type_traits::type base_t; - handle_proxy(PyObject* p) - : handle_proxy(p) - {} - operator T*() const { return python::downcast(m_p); } - }; - - template <> - struct handle_proxy - { - handle_proxy(PyObject* p) : m_p(p) {} - operator PyObject*() const { return (PyObject*)m_p; } - private: - PyObject* m_p; - }; -#endif } -template +template class handle { typedef T* (handle::*bool_type); @@ -153,6 +101,7 @@ class handle } T* operator-> () const; + T& operator* () const; T* get() const; T* release(); @@ -168,6 +117,79 @@ class handle typedef handle type_handle; +// +// Converter specializations +// +template struct arg_from_python; +template <> +struct arg_from_python > +{ + typedef handle<> result_type; + + arg_from_python(PyObject*); + bool convertible() const; + handle<> operator()(PyObject* x) const; +}; + +template <> +struct arg_from_python const&> + : arg_from_python > +{ + arg_from_python(PyObject*); +}; + +namespace converter +{ + template struct return_from_python; + + template <> + struct return_from_python > + { + typedef handle<> result_type; + result_type operator()(PyObject* x) const; + }; +} + +// +// Compile-time introspection +// +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +class is_handle +{ + public: + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +template +class is_handle > +{ + public: + BOOST_STATIC_CONSTANT(bool, value = true); +}; +# else +namespace detail +{ + typedef char (&yes_handle_t)[1]; + typedef char (&no_handle_t)[2]; + + no_handle_t is_handle_test(...); + + template + yes_handle_t is_handle_test(boost::type< handle >); +} + +template +class is_handle +{ + public: + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof(detail::is_handle_test(boost::type())) + == sizeof(detail::yes_handle_t))); +}; +# endif + // // implementations // @@ -197,6 +219,12 @@ inline T* handle::operator->() const return m_p; } +template +inline T& handle::operator*() const +{ + return *m_p; +} + template inline T* handle::get() const { @@ -217,6 +245,35 @@ inline T* handle::release() return result; } +// +// Converter specialization implementation +// +inline arg_from_python >::arg_from_python(PyObject*) +{} + +inline bool arg_from_python >::convertible() const +{ + return true; +} + +inline handle<> arg_from_python >::operator()(PyObject* x) const +{ + return handle<>(python::borrowed(python::allow_null(x))); +} + +inline arg_from_python const&>::arg_from_python(PyObject*) + : arg_from_python >(0) +{} + +namespace converter +{ + inline handle<> + return_from_python >::operator()(PyObject* x) const + { + return handle<>(x); + } +} + }} // namespace boost::python diff --git a/include/boost/python/handle_fwd.hpp b/include/boost/python/handle_fwd.hpp new file mode 100755 index 00000000..afcce163 --- /dev/null +++ b/include/boost/python/handle_fwd.hpp @@ -0,0 +1,17 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef HANDLE_FWD_DWA2002615_HPP +# define HANDLE_FWD_DWA2002615_HPP + +# include + +namespace boost { namespace python { + +template class handle; + +}} // namespace boost::python + +#endif // HANDLE_FWD_DWA2002615_HPP diff --git a/include/boost/python/object.hpp b/include/boost/python/object.hpp new file mode 100755 index 00000000..6720298c --- /dev/null +++ b/include/boost/python/object.hpp @@ -0,0 +1,20 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJECT_DWA2002612_HPP +# define OBJECT_DWA2002612_HPP + +# include +# include +# include + +namespace boost { namespace python { + +class string; +class type; + +}} // namespace boost::python + +#endif // OBJECT_DWA2002612_HPP diff --git a/include/boost/python/object/forward.hpp b/include/boost/python/object/forward.hpp index acae1173..cc23e94c 100644 --- a/include/boost/python/object/forward.hpp +++ b/include/boost/python/object/forward.hpp @@ -61,7 +61,7 @@ namespace detail no_reference_to_value_t is_reference_to_value_test(...); template - yes_reference_to_value_t is_reference_to_value_test(type< reference_to_value >); + yes_reference_to_value_t is_reference_to_value_test(boost::type< reference_to_value >); template struct unforwarder @@ -89,7 +89,7 @@ namespace detail public: BOOST_STATIC_CONSTANT( bool, value = ( - sizeof(is_reference_to_value_test(type())) + sizeof(is_reference_to_value_test(boost::type())) == sizeof(yes_reference_to_value_t))); }; } diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 7e801f92..c9434a4f 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -174,7 +174,7 @@ namespace detail // Build and convert the iterator_range<>. return cr( iterator_range( - handle<>(python::borrow(arg0)) + handle<>(python::borrowed(arg0)) , get_start(x), get_finish(x))); } }; diff --git a/include/boost/python/object_attributes.hpp b/include/boost/python/object_attributes.hpp new file mode 100755 index 00000000..a7bd6a8e --- /dev/null +++ b/include/boost/python/object_attributes.hpp @@ -0,0 +1,81 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJECT_ATTRIBUTES_DWA2002615_HPP +# define OBJECT_ATTRIBUTES_DWA2002615_HPP + +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + struct const_attribute_policies + { + static object get(object const& target, object const& key); + }; + + struct attribute_policies : const_attribute_policies + { + static object const& set(object const& target, object const& key, object const& value); + }; +} + +// +// implementation +// +inline object_attribute object::_(char const* name) +{ + return object_attribute(*this, object(name)); +} + +inline const_object_attribute object::_(char const* name) const +{ + return const_object_attribute(*this, object(name)); +} + +namespace detail +{ + inline object const_attribute_policies::get(object const& target, object const& key) + { + return python::getattr(target, key); + } + + inline object const& attribute_policies::set( + object const& target + , object const& key + , object const& value) + { + python::setattr(target, key, value); + return value; + } +} + +namespace converter +{ + // These specializations are a lie; the proxies do not directly + // manage an object. What actually happens is that the implicit + // conversion to object takes hold and its conversion to_python is + // used. That's OK in part because the object temporary *is* + // actually managing the object during the duration of the + // conversion. + template <> + struct is_object_manager + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template <> + struct is_object_manager + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; +} + +}} // namespace boost::python + +#endif // OBJECT_ATTRIBUTES_DWA2002615_HPP diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp new file mode 100755 index 00000000..80ebf2c0 --- /dev/null +++ b/include/boost/python/object_core.hpp @@ -0,0 +1,286 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJECT_CORE_DWA2002615_HPP +# define OBJECT_CORE_DWA2002615_HPP +# include +# include +# include +# include + +namespace boost { namespace python { + +// This file contains the definition of the object class and enough to +// construct/copy it, but not enough to do operations like +// attribute/item access or addition. + +template class proxy; +namespace detail +{ + struct const_attribute_policies; + struct attribute_policies; + struct const_item_policies; + struct item_policies; +} +typedef proxy const_object_attribute; +typedef proxy object_attribute; +typedef proxy const_object_item; +typedef proxy object_item; + +class object +{ +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 + typedef object const& self_cref; +# else + typedef object self_cref; +# endif + public: +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // copy constructor without NULL checking, for efficiency + object(object const&); +# endif + + // explicit conversion from any C++ object to Python + template + explicit object(T const& x) + : m_ptr( + python::borrowed( + python::allow_null( // null check is already done + converter::arg_to_python(x).get()) + ) + ) + { + } + + // capture this case explicitly to handle string + // literals. Otherwise, they get deduced as char[N]const& above + // and conversion fails at runtime. + explicit object(char const* x) + : m_ptr( + python::borrowed( + python::allow_null( // null check is already done + converter::arg_to_python(x).get()) + ) + ) + { + + } + + // Throw error_already_set() if the handle is null. + explicit object(handle<> const&); + + // Attribute access via x._("attribute_name") + const_object_attribute _(char const*) const; + object_attribute _(char const*); + + object operator()() const + { + return object(call >(m_ptr.get())); + } + +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif + +# define BOOST_PYTHON_OBJECT_CALL(nargs,ignored) \ + template \ + object operator()(BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a))) const \ + { \ + return object(call >(&**this, BOOST_PP_ENUM_PARAMS(nargs, a))); \ + } + + BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_OBJECT_CALL, ignored) + + // truth value testing + typedef handle<> (object::*bool_type); + operator bool_type() const; + bool operator!() const; // needed for vc6 + + // item access + const_object_item operator[](self_cref) const; + object_item operator[](self_cref); + + template + const_object_item operator[](T const& key) const + { + return (*this)[object(key)]; + } + + template + object_item operator[](T const& key) + { + return (*this)[object(key)]; + } + + // Underlying object access + PyObject* operator->() const; + PyObject& operator*() const; + + public: // implementation detail -- for internal use only + object(null_ok >*); + object(detail::borrowed >*); + object(detail::borrowed*); + class new_pyobject_reference; + object(new_pyobject_reference*); + + private: + handle<> m_ptr; +}; + +// +// Converter Specializations +// +template struct arg_from_python; + +template <> +struct arg_from_python +{ + typedef object result_type; + + arg_from_python(PyObject*); + bool convertible() const; + object operator()(PyObject* x) const; +}; + +template <> +struct arg_from_python + : arg_from_python +{ + arg_from_python(PyObject*); +}; + +template <> +struct arg_from_python +{ + typedef object& result_type; + + arg_from_python(PyObject*); + bool convertible() const; + object& operator()(PyObject* x) const; + private: + mutable object m_result; +}; + +namespace converter +{ + template struct is_object_manager; + + template <> + struct is_object_manager + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template struct return_from_python; + template <> + struct return_from_python + { + typedef object result_type; + result_type operator()(PyObject* x) const; + }; +} + +// +// implementation +// + +inline object::object(handle<> const& x) + : m_ptr(python::borrowed(x.get())) +{} + +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +// copy constructor without NULL checking, for efficiency +inline object::object(object const& rhs) + : m_ptr(python::allow_null(python::borrowed(&*rhs))) +{} +# endif + +inline object::object(null_ok >* p) + : m_ptr(p) +{} + +inline object::object(detail::borrowed >* p) + : m_ptr(p) +{} + +inline object::object(detail::borrowed* p) + : m_ptr(p) +{} + +inline object::object(object::new_pyobject_reference* p) + : m_ptr((PyObject*)p) +{} + +inline PyObject* object::operator->() const +{ + return m_ptr.operator->(); +} + +inline PyObject& object::operator*() const +{ + return *m_ptr; +} + +inline object::operator object::bool_type() const +{ + return PyObject_IsTrue(&**this) ? &object::m_ptr : 0; +} + +inline bool object::operator!() const +{ + return !PyObject_IsTrue(&**this); +} + +// +// Converter speciaization implementations +// +inline arg_from_python::arg_from_python(PyObject*) +{} + +inline bool arg_from_python::convertible() const +{ + return true; +} + +inline object arg_from_python::operator()(PyObject* x) const +{ + return object(python::borrowed(python::allow_null(x))); +} + +inline arg_from_python::arg_from_python(PyObject*) + : arg_from_python(0) +{} + +inline arg_from_python::arg_from_python(PyObject* x) + : m_result(python::allow_null(python::borrowed(x))) +{} + +inline bool arg_from_python::convertible() const +{ + return true; +} + +inline object& arg_from_python::operator()(PyObject* x) const +{ + return m_result; +} + +namespace converter +{ + inline object + return_from_python::operator()(PyObject* x) const + { + return object((object::new_pyobject_reference*)x); + } + + inline PyObject* get_managed_object(object const& x) + { + return &*x; + } +} + +}} // namespace boost::python + +#endif // OBJECT_CORE_DWA2002615_HPP diff --git a/include/boost/python/object_items.hpp b/include/boost/python/object_items.hpp new file mode 100755 index 00000000..27233c24 --- /dev/null +++ b/include/boost/python/object_items.hpp @@ -0,0 +1,81 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJECT_ITEMS_DWA2002615_HPP +# define OBJECT_ITEMS_DWA2002615_HPP + +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + struct const_item_policies + { + static object get(object const& target, object const& key); + }; + + struct item_policies : const_item_policies + { + static object const& set(object const& target, object const& key, object const& value); + }; +} + +// +// implementation +// +inline object_item object::operator[](object::self_cref key) +{ + return object_item(*this, key); +} + +inline const_object_item object::operator[](object::self_cref key) const +{ + return const_object_item(*this, key); +} + +namespace detail +{ + inline object const_item_policies::get(object const& target, object const& key) + { + return python::getitem(target, key); + } + + inline object const& item_policies::set( + object const& target + , object const& key + , object const& value) + { + python::setitem(target, key, value); + return value; + } +} + +namespace converter +{ + // These specializations are a lie; the proxies do not directly + // manage an object. What actually happens is that the implicit + // conversion to object takes hold and its conversion to_python is + // used. That's OK in part because the object temporary *is* + // actually managing the object during the duration of the + // conversion. + template <> + struct is_object_manager + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template <> + struct is_object_manager + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; +} + +}} // namespace boost::python + +#endif // OBJECT_ITEMS_DWA2002615_HPP diff --git a/include/boost/python/object_protocol.hpp b/include/boost/python/object_protocol.hpp new file mode 100755 index 00000000..e9b47bad --- /dev/null +++ b/include/boost/python/object_protocol.hpp @@ -0,0 +1,45 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJECT_PROTOCOL_DWA2002615_HPP +# define OBJECT_PROTOCOL_DWA2002615_HPP + +# include +# include +# include +# include + +namespace boost { namespace python { + +template +inline object getattr(Target const& target, Key const& key) +{ + return getattr(object(target), object(key)); +} + + +template +inline void setattr(object const& target, Key const& key, Value const& value) +{ + return setattr(target, object(key), object(value)); +} + +template +inline object getitem(Target const& target, Key const& key) +{ + return getitem(object(target), object(key)); +} + + +template +inline void setitem(object const& target, Key const& key, Value const& value) +{ + return setitem(target, object(key), object(value)); +} + + +}} // namespace boost::python + +#endif // OBJECT_PROTOCOL_DWA2002615_HPP diff --git a/include/boost/python/object_protocol_core.hpp b/include/boost/python/object_protocol_core.hpp new file mode 100755 index 00000000..adbd593f --- /dev/null +++ b/include/boost/python/object_protocol_core.hpp @@ -0,0 +1,20 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJECT_PROTOCOL_CORE_DWA2002615_HPP +# define OBJECT_PROTOCOL_CORE_DWA2002615_HPP + +namespace boost { namespace python { + +class object; + +BOOST_PYTHON_DECL object getattr(object const& target, object const& key); +BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value); +BOOST_PYTHON_DECL object getitem(object const& target, object const& key); +BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value); + +}} // namespace boost::python + +#endif // OBJECT_PROTOCOL_CORE_DWA2002615_HPP diff --git a/include/boost/python/preprocessed/object_call.hpp b/include/boost/python/preprocessed/object_call.hpp new file mode 100755 index 00000000..e3d605cb --- /dev/null +++ b/include/boost/python/preprocessed/object_call.hpp @@ -0,0 +1,101 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJECT_CALL_DWA2002612_HPP +# define OBJECT_CALL_DWA2002612_HPP + +template +object +operator()(A0 const&a0)const +{ + return call(&**this,a0); +} +template +object +operator()(A0 const&a0,A1 const&a1)const +{ + return call(&**this,a0,a1); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2)const +{ + return call(&**this,a0,a1,a2); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3)const +{ + return call(&**this,a0,a1,a2,a3); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4)const +{ + return call(&**this,a0,a1,a2,a3,a4); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5)const +{ + return call(&**this,a0,a1,a2,a3,a4,a5); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6)const +{ + return call(&**this,a0,a1,a2,a3,a4,a5,a6); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7)const +{ + return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8)const +{ + return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9)const +{ + return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10)const +{ + return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11)const +{ + return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12)const +{ + return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13)const +{ + return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13); +} +template +object +operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14)const +{ + return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14); +} + + +#endif // OBJECT_CALL_DWA2002612_HPP diff --git a/include/boost/python/proxy.hpp b/include/boost/python/proxy.hpp new file mode 100755 index 00000000..46476f2d --- /dev/null +++ b/include/boost/python/proxy.hpp @@ -0,0 +1,129 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef PROXY_DWA2002615_HPP +# define PROXY_DWA2002615_HPP +# include + +namespace boost { namespace python { + +class object; + +template +class proxy +{ +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 + typedef proxy const& copy_ctor_self; +# else + typedef proxy copy_ctor_self; +# endif + public: + operator object() const; + + // to support a[b] = c[d] + proxy& operator=(copy_ctor_self); + + template + inline proxy& operator=(T const& rhs) + { + Policies::set(m_target, m_key, python::object(rhs)); + return *this; + } + +# define BOOST_PYTHON_PROXY_ASSIGN_DECL(op) \ + object operator op (object const&); \ + \ + template \ + object operator op (T const& rhs) \ + { \ + return *this op python::object(rhs); \ + } + +// BOOST_PYTHON_PROXY_ASSIGN_DECL(=) + BOOST_PYTHON_PROXY_ASSIGN_DECL(+=) + BOOST_PYTHON_PROXY_ASSIGN_DECL(-=) + BOOST_PYTHON_PROXY_ASSIGN_DECL(*=) + BOOST_PYTHON_PROXY_ASSIGN_DECL(/=) + BOOST_PYTHON_PROXY_ASSIGN_DECL(%=) + BOOST_PYTHON_PROXY_ASSIGN_DECL(<<=) + BOOST_PYTHON_PROXY_ASSIGN_DECL(>>=) + BOOST_PYTHON_PROXY_ASSIGN_DECL(&=) + BOOST_PYTHON_PROXY_ASSIGN_DECL(^=) + BOOST_PYTHON_PROXY_ASSIGN_DECL(|=) +# undef BOOST_PYTHON_PROXY_ASSIGN_DECL + + // truth value testing + operator object::bool_type() const; + bool operator!() const; // needed for vc6 + + private: + friend class object; + proxy(object const& target, object const& key); + + private: + object m_target; + object m_key; +}; + +// +// implementation +// + +template +inline proxy::proxy(object const& target, object const& key) + : m_target(target), m_key(key) +{} + +template +inline proxy::operator object() const +{ + return Policies::get(m_target, m_key); +} + +// to support a[b] = c[d] +template +inline proxy& proxy::operator=(typename proxy::copy_ctor_self rhs) +{ + return *this = python::object(rhs); +} + +# define BOOST_PYTHON_PROXY_ASSIGN_DEF(op) \ +template \ +inline object proxy::operator op(object const& other) \ +{ \ + return Policies::set( \ + m_target, m_key \ + , Policies::get(m_target,m_key) op other); \ +} + +BOOST_PYTHON_PROXY_ASSIGN_DEF(+=) +BOOST_PYTHON_PROXY_ASSIGN_DEF(-=) +BOOST_PYTHON_PROXY_ASSIGN_DEF(*=) +BOOST_PYTHON_PROXY_ASSIGN_DEF(/=) +BOOST_PYTHON_PROXY_ASSIGN_DEF(%=) +BOOST_PYTHON_PROXY_ASSIGN_DEF(<<=) +BOOST_PYTHON_PROXY_ASSIGN_DEF(>>=) +BOOST_PYTHON_PROXY_ASSIGN_DEF(&=) +BOOST_PYTHON_PROXY_ASSIGN_DEF(^=) +BOOST_PYTHON_PROXY_ASSIGN_DEF(|=) + +# undef BOOST_PYTHON_PROXY_ASSIGN_DEF + + +template +inline proxy::operator object::bool_type() const +{ + return python::object(*this); +} + +template +inline bool proxy::operator!() const +{ + return !python::object(*this); +} + +}} // namespace boost::python + +#endif // PROXY_DWA2002615_HPP diff --git a/include/boost/python/refcount.hpp b/include/boost/python/refcount.hpp new file mode 100755 index 00000000..dce6b266 --- /dev/null +++ b/include/boost/python/refcount.hpp @@ -0,0 +1,42 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef REFCOUNT_DWA2002615_HPP +# define REFCOUNT_DWA2002615_HPP + +# include +# include + +namespace boost { namespace python { + +template +inline T* incref(T* p) +{ + Py_INCREF(python::upcast(p)); + return p; +} + +template +inline T* xincref(T* p) +{ + Py_XINCREF(python::upcast(p)); + return p; +} + +template +inline void decref(T* p) +{ + Py_DECREF(python::upcast(p)); +} + +template +inline void xdecref(T* p) +{ + Py_XDECREF(python::upcast(p)); +} + +}} // namespace boost::python + +#endif // REFCOUNT_DWA2002615_HPP diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp index 8f3b0e22..ea9e892e 100644 --- a/include/boost/python/to_python_value.hpp +++ b/include/boost/python/to_python_value.hpp @@ -10,34 +10,84 @@ # include # include # include +# include +# include +# include +# include namespace boost { namespace python { -template -struct to_python_value +namespace detail { - typedef typename add_reference< - typename add_const::type - >::type argument_type; + template + struct object_manager_to_python_value + { + typedef typename add_reference< + typename add_const::type + >::type argument_type; - static bool convertible(); - PyObject* operator()(argument_type) const; -}; + static bool convertible(); + PyObject* operator()(argument_type) const; + }; - -template -bool to_python_value::convertible() -{ - // if this assert fires, our static variable hasn't been set up yet. - return converter::to_python_function::value != 0; + + template + struct registry_to_python_value + { + typedef typename add_reference< + typename add_const::type + >::type argument_type; + + static bool convertible(); + PyObject* operator()(argument_type) const; + }; } template -PyObject* to_python_value::operator()(argument_type x) const +struct to_python_value + : mpl::select_type< + boost::type_traits::ice_or< + converter::is_object_manager::value + , converter::is_reference_to_object_manager::value + >::value + + , detail::object_manager_to_python_value + , detail::registry_to_python_value + >::type { - // This might be further optimized on platforms which dynamically - // link without specific imports/exports - return converter::to_python_function::value(&x); +}; + +// +// implementation +// +namespace detail +{ + template + inline bool registry_to_python_value::convertible() + { + return converter::to_python_function::value != 0; + } + + template + inline PyObject* registry_to_python_value::operator()(argument_type x) const + { + return converter::to_python_function::value(&x); + } + + template + inline bool object_manager_to_python_value::convertible() + { + return true; + } + + template + inline PyObject* object_manager_to_python_value::operator()(argument_type x) const + { + return python::upcast( + python::xincref( + converter::get_managed_object(x)) + ); + } } }} // namespace boost::python diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index 573e38f9..e07b4869 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -35,7 +35,11 @@ namespace detail arg_to_python_base::arg_to_python_base( void const volatile* source, to_python_function_t converter) +# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140 : handle<>(convert(source, converter)) +# else + : m_ptr(convert(source, converter)) +# endif { } diff --git a/src/module.cpp b/src/module.cpp index e5d996cc..f7edf39e 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -14,7 +14,7 @@ namespace boost { namespace python { namespace detail { module_base::module_base(const char* name) : m_module( - borrow(Py_InitModule(const_cast(name), initial_methods)) + python::borrowed(Py_InitModule(const_cast(name), initial_methods)) ) { } diff --git a/src/object/class.cpp b/src/object/class.cpp index cfea075f..a64b811d 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -110,7 +110,7 @@ namespace objects if (PyType_Ready(&class_metatype_object)) return type_handle(); } - return type_handle(borrow(&class_metatype_object)); + return type_handle(borrowed(&class_metatype_object)); } extern "C" { @@ -181,7 +181,7 @@ namespace objects if (PyType_Ready(&class_type_object)) return type_handle(); } - return type_handle(borrow(&class_type_object)); + return type_handle(borrowed(&class_type_object)); } BOOST_PYTHON_DECL void* diff --git a/src/object_protocol.cpp b/src/object_protocol.cpp new file mode 100755 index 00000000..c04a8da2 --- /dev/null +++ b/src/object_protocol.cpp @@ -0,0 +1,35 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include + +namespace boost { namespace python { + +object getattr(object const& target, object const& key) +{ + return object((object::new_pyobject_reference*)PyObject_GetAttr(&*target, &*key)); +} + +void setattr(object const& target, object const& key, object const& value) +{ + if (PyObject_SetAttr(&*target, &*key, &*value) == -1) + throw_error_already_set(); +} + +object getitem(object const& target, object const& key) +{ + return object((object::new_pyobject_reference*)PyObject_GetItem(&*target, &*key)); +} + +void setitem(object const& target, object const& key, object const& value) +{ + if (PyObject_SetItem(&*target, &*key, &*value) == -1) + throw_error_already_set(); +} + +}} // namespace boost::python diff --git a/src/objects2.cpp b/src/objects2.cpp index 5ec410ab..699b21df 100755 --- a/src/objects2.cpp +++ b/src/objects2.cpp @@ -18,7 +18,7 @@ namespace boost { namespace python { objects_base::objects_base(handle<> const& p) - : m_p(borrow(p.get())) // Do the null check here + : m_p(borrowed(p.get())) // Do the null check here {} // Return a reference to the held object @@ -72,7 +72,7 @@ std::size_t tuple_base::size() const handle<> tuple_base::operator[](std::size_t pos) const { - return handle<>(borrow(PyTuple_GetItem(get(), static_cast(pos)))); + return handle<>(borrowed(PyTuple_GetItem(get(), static_cast(pos)))); } void tuple_base::set_item(std::size_t pos, const handle<>& rhs) @@ -146,7 +146,7 @@ const char* string::c_str() const void string::intern() { // UNTESTED!! - *this = string(handle<>(borrow(PyString_InternFromString(c_str())))); + *this = string(handle<>(borrowed(PyString_InternFromString(c_str())))); } string& string::operator*=(unsigned int repeat_count) @@ -214,7 +214,7 @@ handle<> dictionary_base::get_item(const handle<>& key, const handle<>& default_ if (value_or_null == 0 && !PyErr_Occurred()) return default_; else - return handle<>(borrow(value_or_null)); // Will throw if there was another error + return handle<>(borrowed(value_or_null)); // Will throw if there was another error } void dictionary_base::set_item(const handle<>& key, const handle<>& value) @@ -310,7 +310,7 @@ std::size_t list_base::size() const handle<> list_base::operator[](std::size_t pos) const { - return handle<>(borrow(PyList_GetItem(get(), pos))); + return handle<>(borrowed(PyList_GetItem(get(), pos))); } list_proxy list_base::operator[](std::size_t pos) @@ -370,12 +370,12 @@ const handle<>& list_proxy::operator=(const handle<>& rhs) list_proxy::operator handle<>() const { - return handle<>(borrow(PyList_GetItem(m_list.get(), m_index))); + return handle<>(borrowed(PyList_GetItem(m_list.get(), m_index))); } handle<> list_base::get_item(std::size_t pos) const { - return handle<>(borrow(PyList_GetItem(this->get(), pos))); + return handle<>(borrowed(PyList_GetItem(this->get(), pos))); } void list_base::set_item(std::size_t pos, const handle<>& rhs) diff --git a/test/Jamfile b/test/Jamfile index c0459022..b54bb723 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -1,8 +1,11 @@ subproject libs/python/test ; # bring in the rules for python -SEARCH on python.jam = $(BOOST_BUILD_PATH) ; -include python.jam ; +SEARCH on python.jam = $(BOOST_BUILD_PATH) ; +include python.jam ; +# bring in rules for testing +SEARCH on testing.jam = $(BOOST_BUILD_PATH) ; +include testing.jam ; local PYTHON_V1_PROPERTIES = $(PYTHON_PROPERTIES) ; local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) ; @@ -58,6 +61,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 object ; bpl-test virtual_functions ; bpl-test back_reference ; bpl-test implicit ; @@ -76,44 +80,44 @@ if $(TEST_BIENSTMAN_NON_BUGS) } # --- unit tests of library components --- -unit-test indirect_traits_test - : indirect_traits_test.cpp : $(BOOST_ROOT) ; -unit-test destroy_test - : destroy_test.cpp : $(BOOST_ROOT) ; -unit-test pointer_type_id_test - : pointer_type_id_test.cpp : $(BOOST_ROOT) ; +run indirect_traits_test.cpp ; +run destroy_test.cpp ; +run pointer_type_id_test.cpp ; +run member_function_cast.cpp ; +run bases.cpp ; +run if_else.cpp ; +run pointee.cpp ; +run result.cpp ; +compile borrowed.cpp : $(PYTHON_PROPERTIES) ; +compile object_manager.cpp : $(PYTHON_PROPERTIES) ; -unit-test member_function_cast - : member_function_cast.cpp : $(BOOST_ROOT) ; +run upcast.cpp + : # command-line args + : # input files + : [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] + BOOST_PYTHON_STATIC_LIB + ; -unit-test bases - : bases.cpp : $(BOOST_ROOT) ; - -unit-test if_else - : if_else.cpp : $(BOOST_ROOT) ; - -unit-test pointee - : pointee.cpp : $(BOOST_ROOT) ; - -unit-test result - : result.cpp : $(BOOST_ROOT) ; - -unit-test upcast - : upcast.cpp - : $(BOOST_ROOT) BOOST_PYTHON_STATIC_LIB $(PYTHON_PROPERTIES) ; - -unit-test select_holder - : select_holder.cpp - : $(BOOST_ROOT) BOOST_PYTHON_STATIC_LIB $(PYTHON_PROPERTIES) -; - -unit-test select_from_python_test - : select_from_python_test.cpp - ../src/converter/type_id.cpp - - : $(BOOST_ROOT) - [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] +run select_holder.cpp + : # command-line args + : # input files + : [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] BOOST_PYTHON_STATIC_LIB ; +run select_from_python_test.cpp ../src/converter/type_id.cpp + : # command-line args + : # input files + : [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] + BOOST_PYTHON_STATIC_LIB + ; + +if $(TEST_EXPECTED_FAILURES) +{ + compile-fail ./raw_pyobject_fail1.cpp : $(PYTHON_PROPERTIES) ; + compile-fail ./raw_pyobject_fail2.cpp : $(PYTHON_PROPERTIES) ; + compile-fail ./object_fail1.cpp : $(PYTHON_PROPERTIES) ; +} + + diff --git a/test/borrowed.cpp b/test/borrowed.cpp new file mode 100755 index 00000000..b46dafb0 --- /dev/null +++ b/test/borrowed.cpp @@ -0,0 +1,33 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include + +using namespace boost::python; + +template +void assert_borrowed_ptr(T const& x) +{ + BOOST_STATIC_ASSERT(boost::python::detail::is_borrowed_ptr::value); +} + +template +void assert_not_borrowed_ptr(T const& x) +{ + BOOST_STATIC_ASSERT(!boost::python::detail::is_borrowed_ptr::value); +} + +int main() +{ + assert_borrowed_ptr(borrowed((PyObject*)0)); + assert_borrowed_ptr(borrowed((PyTypeObject*)0)); + assert_borrowed_ptr((detail::borrowed const*)0); + assert_borrowed_ptr((detail::borrowed volatile*)0); + assert_borrowed_ptr((detail::borrowed const volatile*)0); + assert_not_borrowed_ptr((PyObject*)0); + assert_not_borrowed_ptr(0); + return 0; +} diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 4d8ead2c..6be5a782 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -11,6 +11,7 @@ #include #include #include +#include using namespace boost::python; @@ -51,12 +52,12 @@ void apply_void_X_ref(PyObject* f, X& x) call(f, boost::ref(x)); } -X& apply_X_ref_pyobject(PyObject* f, PyObject* obj) +X& apply_X_ref_handle(PyObject* f, handle<> obj) { return call(f, obj); } -X* apply_X_ptr_pyobject(PyObject* f, PyObject* obj) +X* apply_X_ptr_handle_cref(PyObject* f, handle<> const& obj) { return call(f, obj); } @@ -83,7 +84,7 @@ char const* apply_cstring_cstring(PyObject* f, char const* s) char const* apply_cstring_pyobject(PyObject* f, PyObject* s) { - return call(f, s); + return call(f, borrowed(s)); } char apply_char_char(PyObject* f, char c) @@ -96,11 +97,25 @@ char const* apply_to_string_literal(PyObject* f) return call(f, "hello, world"); } +handle<> apply_to_own_type(handle<> x) +{ + // Tests that we can return handle<> from a callback and that we + // can pass arbitrary handle. + return call >(x.get(), type_handle(borrowed(x->ob_type))); +} + +object apply_object_object(PyObject* f, object x) +{ + return call(f, x); +} + int X::counter; BOOST_PYTHON_MODULE_INIT(callbacks_ext) { boost::python::module("callbacks_ext") + .def("apply_object_object", apply_object_object) + .def("apply_to_own_type", apply_to_own_type) .def("apply_int_int", apply_int_int) .def("apply_void_int", apply_void_int) .def("apply_X_X", apply_X_X) @@ -109,10 +124,10 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) .def("apply_void_X_ptr", apply_void_X_ptr) .def("apply_void_X_deep_ptr", apply_void_X_deep_ptr) - .def("apply_X_ptr_pyobject", apply_X_ptr_pyobject + .def("apply_X_ptr_handle_cref", apply_X_ptr_handle_cref , return_value_policy()) - .def("apply_X_ref_pyobject", apply_X_ref_pyobject + .def("apply_X_ref_handle", apply_X_ref_handle , return_value_policy()) .def("apply_cstring_cstring", apply_cstring_cstring) diff --git a/test/callbacks.py b/test/callbacks.py index 9a48ec2c..937961fd 100644 --- a/test/callbacks.py +++ b/test/callbacks.py @@ -74,27 +74,27 @@ succeed: >>> last_x.value() 43 ->>> y = apply_X_ref_pyobject(identity, x) +>>> y = apply_X_ref_handle(identity, x) >>> assert y.value() == x.value() >>> increment(x) >>> assert y.value() == x.value() ->>> y = apply_X_ptr_pyobject(identity, x) +>>> y = apply_X_ptr_handle_cref(identity, x) >>> assert y.value() == x.value() >>> increment(x) >>> assert y.value() == x.value() ->>> y = apply_X_ptr_pyobject(identity, None) +>>> y = apply_X_ptr_handle_cref(identity, None) >>> y >>> def new_x(ignored): ... return X(666) ... ->>> try: apply_X_ref_pyobject(new_x, 1) +>>> try: apply_X_ref_handle(new_x, 1) ... except ReferenceError: pass ... else: print 'no error' ->>> try: apply_X_ptr_pyobject(new_x, 1) +>>> try: apply_X_ptr_handle_cref(new_x, 1) ... except ReferenceError: pass ... else: print 'no error' @@ -113,6 +113,10 @@ succeed: >>> apply_char_char(identity, 'x') 'x' + +>>> assert apply_to_own_type(identity) is type(identity) + +>>> assert apply_object_object(identity, identity) is identity ''' def run(args = None): diff --git a/test/object.cpp b/test/object.cpp new file mode 100755 index 00000000..f3a31011 --- /dev/null +++ b/test/object.cpp @@ -0,0 +1,149 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include + +using namespace boost::python; + +object call_object_3(object f) +{ + return f(3); +} + +object message() +{ + return object("hello, world!"); +} + +object number() +{ + return object(42); +} + +object obj_getattr(object x, char const* name) +{ + return x._(name); +} + +object obj_const_getattr(object const& x, char const* name) +{ + return x._(name); +} + +void obj_setattr(object x, char const* name, object value) +{ + x._(name) = value; +} + +void obj_setattr42(object x, char const* name) +{ + x._(name) = 42; +} + +void obj_moveattr(object& x, char const* src, char const* dst) +{ + x._(dst) = x._(src); +} + +object obj_getitem(object x, object key) +{ + return x[key]; +} + +object obj_getitem3(object x) +{ + return x[3]; +} + +object obj_const_getitem(object const& x, object key) +{ + return x[key]; +} + +void obj_setitem(object x, object key, object value) +{ + x[key] = value; +} + +void obj_setitem42(object x, object key) +{ + x[key] = 42; +} + +void obj_moveitem(object& x, object src, object dst) +{ + x[dst] = x[src]; +} + +void obj_moveitem2(object const& x_src, object k_src, object& x_dst, object k_dst) +{ + x_dst[k_dst] = x_src[k_src]; +} + +bool test(object y) +{ + return y; +} + +bool test_not(object y) +{ + return !y; +} + +bool test_attr(object y, char* name) +{ + return y._(name); +} + +bool test_not_attr(object y, char* name) +{ + return !y._(name); +} + +bool test_item(object y, object key) +{ + return y[key]; +} + +bool test_not_item(object y, object key) +{ + return !y[key]; +} + +BOOST_PYTHON_MODULE_INIT(object_ext) +{ + module("object_ext") + .def("call_object_3", call_object_3) + .def("message", message) + .def("number", number) + + .def("obj_getattr", obj_getattr) + .def("obj_const_getattr", obj_const_getattr) + .def("obj_setattr", obj_setattr) + .def("obj_setattr42", obj_setattr42) + .def("obj_moveattr", obj_moveattr) + + + .def("obj_getitem", obj_getitem) + .def("obj_getitem3", obj_getitem) + .def("obj_const_getitem", obj_const_getitem) + .def("obj_setitem", obj_setitem) + .def("obj_setitem42", obj_setitem42) + .def("obj_moveitem", obj_moveitem) + .def("obj_moveitem2", obj_moveitem2) + + .def("test", test) + .def("test_not", test_not) + + .def("test_attr", test_attr) + .def("test_not_attr", test_not_attr) + + .def("test_item", test_item) + .def("test_not_item", test_not_item) + ; +} + +#include "module_tail.cpp" diff --git a/test/object.py b/test/object.py new file mode 100644 index 00000000..68e46fe3 --- /dev/null +++ b/test/object.py @@ -0,0 +1,95 @@ +''' +>>> from object_ext import * +>>> def print1(x): +... print x +>>> call_object_3(print1) +3 +>>> message() +'hello, world!' +>>> number() +42 + +>>> test('hi') +1 +>>> test(None) +0 +>>> test_not('hi') +0 +>>> test_not(0) +1 + + Attributes + +>>> class X: pass +... +>>> x = X() + +>>> try: obj_getattr(x, 'foo') +... except AttributeError: pass +... else: print 'expected an exception' + +>>> obj_setattr(x, 'foo', 1) +>>> x.foo +1 +>>> obj_getattr(x, 'foo') +1 +>>> obj_const_getattr(x, 'foo') +1 +>>> obj_setattr42(x, 'foo') +>>> x.foo +42 +>>> obj_moveattr(x, 'foo', 'bar') +>>> x.bar +42 +>>> test_attr(x, 'foo') +1 +>>> test_not_attr(x, 'foo') +0 +>>> x.foo = None +>>> test_attr(x, 'foo') +0 +>>> test_not_attr(x, 'foo') +1 + + Items + +>>> d = {} +>>> obj_setitem(d, 'foo', 1) +>>> d['foo'] +1 +>>> obj_getitem(d, 'foo') +1 +>>> obj_const_getitem(d, 'foo') +1 +>>> obj_setitem42(d, 'foo') +>>> d['foo'] +42 +>>> obj_moveitem(d, 'foo', 'bar') +>>> d['bar'] +42 +>>> obj_moveitem2(d, 'bar', d, 'baz') +>>> d['baz'] +42 +>>> test_item(d, 'foo') +1 +>>> test_not_item(d, 'foo') +0 +>>> d['foo'] = None +>>> test_item(d, 'foo') +0 +>>> test_not_item(d, 'foo') +1 +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) diff --git a/test/object_fail1.cpp b/test/object_fail1.cpp new file mode 100755 index 00000000..3b09e71d --- /dev/null +++ b/test/object_fail1.cpp @@ -0,0 +1,12 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include + +int f(boost::python::object const& x) +{ + x._("hello") = 1; + return 0; +} diff --git a/test/object_manager.cpp b/test/object_manager.cpp new file mode 100755 index 00000000..75c816bc --- /dev/null +++ b/test/object_manager.cpp @@ -0,0 +1,37 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include "test_class.hpp" + +using namespace boost::python; +using namespace boost::python::converter; + +template struct undefined; + +int main() +{ + BOOST_STATIC_ASSERT(is_object_manager >::value); + BOOST_STATIC_ASSERT(!is_object_manager::value); + BOOST_STATIC_ASSERT(!is_object_manager >::value); + + BOOST_STATIC_ASSERT(is_reference_to_object_manager&>::value); + BOOST_STATIC_ASSERT(is_reference_to_object_manager const&>::value); + BOOST_STATIC_ASSERT(is_reference_to_object_manager volatile&>::value); + BOOST_STATIC_ASSERT(is_reference_to_object_manager const volatile&>::value); + +// undefined >::t1> x1; +// undefined >::t2> x2; + + BOOST_STATIC_ASSERT(!is_reference_to_object_manager >::value); + BOOST_STATIC_ASSERT(!is_reference_to_object_manager >::value); + BOOST_STATIC_ASSERT(!is_reference_to_object_manager&>::value); + BOOST_STATIC_ASSERT(!is_reference_to_object_managerconst&>::value); + + return 0; +} + diff --git a/test/raw_pyobject_fail1.cpp b/test/raw_pyobject_fail1.cpp new file mode 100755 index 00000000..8fe73d68 --- /dev/null +++ b/test/raw_pyobject_fail1.cpp @@ -0,0 +1,12 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include + +int main() +{ + boost::python::converter::arg_to_python x(0); + return 0; +} diff --git a/test/raw_pyobject_fail2.cpp b/test/raw_pyobject_fail2.cpp new file mode 100755 index 00000000..7a0e79d9 --- /dev/null +++ b/test/raw_pyobject_fail2.cpp @@ -0,0 +1,14 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include + +struct X : PyObject {}; + +int main() +{ + boost::python::converter::arg_to_python x(0); + return 0; +} diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp index 25ad7fee..bf7d991e 100644 --- a/test/test_builtin_converters.cpp +++ b/test/test_builtin_converters.cpp @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include template struct by_value @@ -25,11 +28,37 @@ struct by_const_reference } }; +template +struct by_reference +{ + static T rewrap(T& x) + { + return x; + } +}; + +using boost::python::handle; +using boost::python::object; +using boost::python::borrowed; + +// Used to test that arbitrary handle<>s can be returned +handle get_type(handle<> x) +{ + return handle(borrowed(x->ob_type)); +} + +handle<> return_null_handle() +{ + return handle<>(); +} + char const* rewrap_value_mutable_cstring(char* x) { return x; } BOOST_PYTHON_MODULE_INIT(builtin_converters) { boost::python::module("builtin_converters") + .def("get_type", get_type) + .def("return_null_handle", return_null_handle) .def("rewrap_value_bool", by_value::rewrap) .def("rewrap_value_char", by_value::rewrap) @@ -53,6 +82,8 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters) .def("rewrap_value_complex_long_double", by_value >::rewrap) .def("rewrap_value_string", by_value::rewrap) .def("rewrap_value_cstring", by_value::rewrap) + .def("rewrap_value_handle", by_value >::rewrap) + .def("rewrap_value_object", by_value::rewrap) // Expose this to illustrate our failings ;-). See test_builtin_converters.py .def("rewrap_value_mutable_cstring", rewrap_value_mutable_cstring) @@ -80,6 +111,11 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters) .def("rewrap_const_reference_complex_long_double", by_const_reference >::rewrap) .def("rewrap_const_reference_string", by_const_reference::rewrap) .def("rewrap_const_reference_cstring", by_const_reference::rewrap) + .def("rewrap_const_reference_handle", by_const_reference >::rewrap) + .def("rewrap_const_reference_object", by_const_reference::rewrap) + + + .def("rewrap_reference_object", by_reference::rewrap) ; } diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index 6600c6b7..fb4725ba 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -73,6 +73,12 @@ >>> rewrap_value_string('yo, wassup?') 'yo, wassup?' +>>> rewrap_value_handle(1) +1 +>>> x = 'hi' +>>> assert rewrap_value_handle(x) is x +>>> assert rewrap_value_object(x) is x + Note that we can currently get a mutable pointer into an immutable Python string: @@ -134,6 +140,13 @@ >>> rewrap_const_reference_string('yo, wassup?') 'yo, wassup?' +>>> rewrap_const_reference_handle(1) +1 +>>> x = 'hi' +>>> assert rewrap_const_reference_handle(x) is x +>>> assert rewrap_const_reference_object(x) is x +>>> assert rewrap_reference_object(x) is x + Check that None <==> NULL @@ -180,6 +193,13 @@ Check that classic classes also work >>> abs(rewrap_value_complex_double(FortyTwo()) - (4+.2j)) < .000001 1 +# show that arbitrary handle instantiations can be returned +>>> get_type(1) is type(1) +1 + +>>> try: return_null_handle() +... except: pass +... else: print 'expectd an exception' """ def run(args = None): From 9a5b89da59b33167c7cafad9049ca6a264c92a76 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 16 Jun 2002 21:31:29 +0000 Subject: [PATCH 0522/1042] initial checkin [SVN r14159] --- include/boost/python/borrowed.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100755 include/boost/python/borrowed.hpp diff --git a/include/boost/python/borrowed.hpp b/include/boost/python/borrowed.hpp new file mode 100755 index 00000000..10b1b5d1 --- /dev/null +++ b/include/boost/python/borrowed.hpp @@ -0,0 +1,20 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BORROWED_DWA2002614_HPP +# define BORROWED_DWA2002614_HPP +# include + +namespace boost { namespace python { + +template +inline python::detail::borrowed* borrowed(T* p) +{ + return (detail::borrowed*)p; +} + +}} // namespace boost::python + +#endif // BORROWED_DWA2002614_HPP From 41132af773acd8f878b95f41b2ce98925479c4f6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 16 Jun 2002 22:59:09 +0000 Subject: [PATCH 0523/1042] Bug fix [SVN r14160] --- include/boost/python/detail/borrowed_ptr.hpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/boost/python/detail/borrowed_ptr.hpp b/include/boost/python/detail/borrowed_ptr.hpp index 4e6d187a..055c8b7c 100755 --- a/include/boost/python/detail/borrowed_ptr.hpp +++ b/include/boost/python/detail/borrowed_ptr.hpp @@ -29,6 +29,24 @@ struct is_borrowed_ptr*> BOOST_STATIC_CONSTANT(bool, value = true); }; +template +struct is_borrowed_ptr const*> +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template +struct is_borrowed_ptr volatile*> +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + +template +struct is_borrowed_ptr const volatile*> +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; + # else // no partial specialization typedef char (&yes_borrowed_ptr_t)[1]; From 954d0198954dfd98fe30f5b062e84dd63794ca2a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 17 Jun 2002 20:23:13 +0000 Subject: [PATCH 0524/1042] work around early EDG problem [SVN r14163] --- include/boost/python/object_protocol.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/object_protocol.hpp b/include/boost/python/object_protocol.hpp index e9b47bad..27461e26 100755 --- a/include/boost/python/object_protocol.hpp +++ b/include/boost/python/object_protocol.hpp @@ -14,27 +14,27 @@ namespace boost { namespace python { template -inline object getattr(Target const& target, Key const& key) +object getattr(Target const& target, Key const& key) { return getattr(object(target), object(key)); } template -inline void setattr(object const& target, Key const& key, Value const& value) +void setattr(object const& target, Key const& key, Value const& value) { return setattr(target, object(key), object(value)); } template -inline object getitem(Target const& target, Key const& key) +object getitem(Target const& target, Key const& key) { return getitem(object(target), object(key)); } template -inline void setitem(object const& target, Key const& key, Value const& value) +void setitem(object const& target, Key const& key, Value const& value) { return setitem(target, object(key), object(value)); } From 87bda9e124ff3c0bab16bff320c6000be353354d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 17 Jun 2002 22:26:17 +0000 Subject: [PATCH 0525/1042] work around early EDG problem [SVN r14164] --- include/boost/python/detail/convertible.hpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/convertible.hpp b/include/boost/python/detail/convertible.hpp index 2a4d5106..f767ebfd 100755 --- a/include/boost/python/detail/convertible.hpp +++ b/include/boost/python/detail/convertible.hpp @@ -6,6 +6,11 @@ #ifndef CONVERTIBLE_DWA2002614_HPP # define CONVERTIBLE_DWA2002614_HPP +# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 241 +# include +# include +# endif + // Supplies a runtime is_convertible check which can be used with tag // dispatching to work around the Metrowerks Pro7 limitation with boost::is_convertible namespace boost { namespace python { namespace detail { @@ -16,8 +21,17 @@ typedef int* no_convertible; template struct convertible { - static inline yes_convertible check(Target) { return 0; } +# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 241 static inline no_convertible check(...) { return 0; } + static inline yes_convertible check(Target) { return 0; } +# else + template + static inline typename mpl::select_type< + is_convertible::value + , yes_convertible + , no_convertible + >::type check(X const&) { return 0; } +# endif }; }}} // namespace boost::python::detail From 66f2cd81a859319612e0f3864f54de8c400a6566 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 18 Jun 2002 13:49:09 +0000 Subject: [PATCH 0526/1042] object operator support [SVN r14168] --- Jamfile | 1 + .../boost/python/converter/object_manager.hpp | 6 +- include/boost/python/object.hpp | 1 + include/boost/python/object_attributes.hpp | 55 +- include/boost/python/object_core.hpp | 189 ++++--- include/boost/python/object_items.hpp | 51 +- include/boost/python/object_operators.hpp | 68 +++ include/boost/python/object_protocol_core.hpp | 18 +- include/boost/python/operators2.hpp | 9 +- include/boost/python/proxy.hpp | 75 +-- src/object_operators.cpp | 51 ++ src/object_protocol.cpp | 12 +- test/doctest.py | 495 ++++++++++-------- test/object.cpp | 164 +++++- test/object.py | 8 + 15 files changed, 771 insertions(+), 432 deletions(-) create mode 100644 include/boost/python/object_operators.hpp create mode 100644 src/object_operators.cpp diff --git a/Jamfile b/Jamfile index b0993452..72e4b3ec 100644 --- a/Jamfile +++ b/Jamfile @@ -28,6 +28,7 @@ dll bpl src/converter/callback.cpp src/object/iterator.cpp src/object_protocol.cpp + src/object_operators.cpp : $(BOOST_PYTHON_V2_PROPERTIES) BOOST_PYTHON_SOURCE diff --git a/include/boost/python/converter/object_manager.hpp b/include/boost/python/converter/object_manager.hpp index 93c394e2..6ffe6b1e 100755 --- a/include/boost/python/converter/object_manager.hpp +++ b/include/boost/python/converter/object_manager.hpp @@ -12,11 +12,11 @@ # include # include -namespace boost { namespace python { +namespace boost { namespace python { namespace api { class object; -}} +}}} namespace boost { namespace python { namespace converter { @@ -142,7 +142,7 @@ inline T* get_managed_object(python::detail::borrowed const volatile* p) // forward declaration needed because name lookup is bound by the // definition context. -PyObject* get_managed_object(python::object const&); +PyObject* get_managed_object(python::api::object const&); }}} // namespace boost::python::converter diff --git a/include/boost/python/object.hpp b/include/boost/python/object.hpp index 6720298c..5186669e 100755 --- a/include/boost/python/object.hpp +++ b/include/boost/python/object.hpp @@ -9,6 +9,7 @@ # include # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/object_attributes.hpp b/include/boost/python/object_attributes.hpp index a7bd6a8e..f75f76d9 100755 --- a/include/boost/python/object_attributes.hpp +++ b/include/boost/python/object_attributes.hpp @@ -10,51 +10,48 @@ # include # include -namespace boost { namespace python { +namespace boost { namespace python { namespace api { -namespace detail +struct const_attribute_policies { - struct const_attribute_policies - { - static object get(object const& target, object const& key); - }; + static object get(object const& target, object const& key); +}; - struct attribute_policies : const_attribute_policies - { - static object const& set(object const& target, object const& key, object const& value); - }; -} +struct attribute_policies : const_attribute_policies +{ + static object const& set(object const& target, object const& key, object const& value); +}; // // implementation // -inline object_attribute object::_(char const* name) +inline object_attribute object::attr(char const* name) { return object_attribute(*this, object(name)); } -inline const_object_attribute object::_(char const* name) const +inline const_object_attribute object::attr(char const* name) const { return const_object_attribute(*this, object(name)); } -namespace detail -{ - inline object const_attribute_policies::get(object const& target, object const& key) - { - return python::getattr(target, key); - } - inline object const& attribute_policies::set( - object const& target - , object const& key - , object const& value) - { - python::setattr(target, key, value); - return value; - } +inline object const_attribute_policies::get(object const& target, object const& key) +{ + return python::getattr(target, key); } +inline object const& attribute_policies::set( + object const& target + , object const& key + , object const& value) +{ + python::setattr(target, key, value); + return value; +} + +} // namespace api + namespace converter { // These specializations are a lie; the proxies do not directly @@ -64,13 +61,13 @@ namespace converter // actually managing the object during the duration of the // conversion. template <> - struct is_object_manager + struct is_object_manager { BOOST_STATIC_CONSTANT(bool, value = true); }; template <> - struct is_object_manager + struct is_object_manager { BOOST_STATIC_CONSTANT(bool, value = true); }; diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 80ebf2c0..e243b1ee 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -12,122 +12,147 @@ namespace boost { namespace python { +// Put this in an inner namespace so that the generalized operators won't take over +namespace api +{ + // This file contains the definition of the object class and enough to // construct/copy it, but not enough to do operations like // attribute/item access or addition. -template class proxy; -namespace detail -{ + template class proxy; + struct const_attribute_policies; struct attribute_policies; struct const_item_policies; struct item_policies; -} -typedef proxy const_object_attribute; -typedef proxy object_attribute; -typedef proxy const_object_item; -typedef proxy object_item; -class object -{ + typedef proxy const_object_attribute; + typedef proxy object_attribute; + typedef proxy const_object_item; + typedef proxy object_item; + + // A way to turn a conrete type T into a type dependent on U. This + // keeps conforming compilers from complaining about returning an + // incomplete T from a template member function (which must be + // defined in the class body to keep MSVC happy). + template + struct dependent + { + typedef T type; + }; + + class object + { # if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 - typedef object const& self_cref; + typedef object const& self_cref; # else - typedef object self_cref; + typedef object self_cref; # endif - public: + public: # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING - // copy constructor without NULL checking, for efficiency - object(object const&); + // copy constructor without NULL checking, for efficiency + object(object const&); # endif - // explicit conversion from any C++ object to Python - template - explicit object(T const& x) - : m_ptr( - python::borrowed( - python::allow_null( // null check is already done - converter::arg_to_python(x).get()) - ) - ) - { - } + // explicit conversion from any C++ object to Python + template + explicit object(T const& x) + : m_ptr( + python::borrowed( + python::allow_null( // null check is already done + converter::arg_to_python(x).get()) + ) + ) + { + } - // capture this case explicitly to handle string - // literals. Otherwise, they get deduced as char[N]const& above - // and conversion fails at runtime. - explicit object(char const* x) - : m_ptr( - python::borrowed( - python::allow_null( // null check is already done - converter::arg_to_python(x).get()) - ) - ) - { + // capture this case explicitly to handle string + // literals. Otherwise, they get deduced as char[N]const& above + // and conversion fails at runtime. + explicit object(char const* x) + : m_ptr( + python::borrowed( + python::allow_null( // null check is already done + converter::arg_to_python(x).get()) + ) + ) + { - } + } - // Throw error_already_set() if the handle is null. - explicit object(handle<> const&); + // Throw error_already_set() if the handle is null. + explicit object(handle<> const&); - // Attribute access via x._("attribute_name") - const_object_attribute _(char const*) const; - object_attribute _(char const*); + // Attribute access via x.attr("attribute_name") + const_object_attribute attr(char const*) const; + object_attribute attr(char const*); - object operator()() const - { - return object(call >(m_ptr.get())); - } + object operator()() const + { + return object(call >(m_ptr.get())); + } # ifndef BOOST_PYTHON_GENERATE_CODE # include # endif # define BOOST_PYTHON_OBJECT_CALL(nargs,ignored) \ - template \ - object operator()(BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a))) const \ - { \ - return object(call >(&**this, BOOST_PP_ENUM_PARAMS(nargs, a))); \ - } + template \ + object operator()(BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a))) const \ + { \ + return object(call >(&**this, BOOST_PP_ENUM_PARAMS(nargs, a))); \ + } - BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_OBJECT_CALL, ignored) + BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_OBJECT_CALL, ignored) - // truth value testing - typedef handle<> (object::*bool_type); - operator bool_type() const; - bool operator!() const; // needed for vc6 + // truth value testing + typedef handle<> (object::*bool_type); + operator bool_type() const; + bool operator!() const; // needed for vc6 - // item access - const_object_item operator[](self_cref) const; - object_item operator[](self_cref); + // item access + const_object_item operator[](self_cref) const; + object_item operator[](self_cref); - template - const_object_item operator[](T const& key) const - { - return (*this)[object(key)]; - } + template +# if BOOST_MSVC != 1300 + typename dependent::type +# else + const_object_item +# endif + operator[](T const& key) const + { + return (*this)[object(key)]; + } - template - object_item operator[](T const& key) - { - return (*this)[object(key)]; - } + template +# if BOOST_MSVC != 1300 + typename dependent::type +# else + object_item +# endif + operator[](T const& key) + { + return (*this)[object(key)]; + } - // Underlying object access - PyObject* operator->() const; - PyObject& operator*() const; + // Underlying object access + PyObject* operator->() const; + PyObject& operator*() const; - public: // implementation detail -- for internal use only - object(null_ok >*); - object(detail::borrowed >*); - object(detail::borrowed*); - class new_pyobject_reference; - object(new_pyobject_reference*); + public: // implementation detail -- for internal use only + object(null_ok >*); + object(detail::borrowed >*); + object(detail::borrowed*); + class new_pyobject_reference; + object(new_pyobject_reference*); - private: - handle<> m_ptr; -}; + private: + handle<> m_ptr; + }; +} +using api::object; // // Converter Specializations diff --git a/include/boost/python/object_items.hpp b/include/boost/python/object_items.hpp index 27233c24..a294dff6 100755 --- a/include/boost/python/object_items.hpp +++ b/include/boost/python/object_items.hpp @@ -10,20 +10,17 @@ # include # include -namespace boost { namespace python { +namespace boost { namespace python { namespace api { -namespace detail +struct const_item_policies { - struct const_item_policies - { - static object get(object const& target, object const& key); - }; + static object get(object const& target, object const& key); +}; - struct item_policies : const_item_policies - { - static object const& set(object const& target, object const& key, object const& value); - }; -} +struct item_policies : const_item_policies +{ + static object const& set(object const& target, object const& key, object const& value); +}; // // implementation @@ -38,23 +35,23 @@ inline const_object_item object::operator[](object::self_cref key) const return const_object_item(*this, key); } -namespace detail -{ - inline object const_item_policies::get(object const& target, object const& key) - { - return python::getitem(target, key); - } - inline object const& item_policies::set( - object const& target - , object const& key - , object const& value) - { - python::setitem(target, key, value); - return value; - } +inline object const_item_policies::get(object const& target, object const& key) +{ + return python::getitem(target, key); } +inline object const& item_policies::set( + object const& target + , object const& key + , object const& value) +{ + python::setitem(target, key, value); + return value; +} + +} // namespace api + namespace converter { // These specializations are a lie; the proxies do not directly @@ -64,13 +61,13 @@ namespace converter // actually managing the object during the duration of the // conversion. template <> - struct is_object_manager + struct is_object_manager { BOOST_STATIC_CONSTANT(bool, value = true); }; template <> - struct is_object_manager + struct is_object_manager { BOOST_STATIC_CONSTANT(bool, value = true); }; diff --git a/include/boost/python/object_operators.hpp b/include/boost/python/object_operators.hpp new file mode 100644 index 00000000..c339c906 --- /dev/null +++ b/include/boost/python/object_operators.hpp @@ -0,0 +1,68 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJECT_OPERATORS_DWA2002617_HPP +# define OBJECT_OPERATORS_DWA2002617_HPP + +# include + +namespace boost { namespace python { namespace api { + +# define BOOST_PYTHON_COMPARE_OP(op, opid) \ +template \ +bool operator op(L const& l, R const& r) \ +{ \ + return PyObject_RichCompareBool(&*object(l), &*object(r), opid); \ +} +BOOST_PYTHON_COMPARE_OP(>, Py_GT) +BOOST_PYTHON_COMPARE_OP(>=, Py_GE) +BOOST_PYTHON_COMPARE_OP(<, Py_LT) +BOOST_PYTHON_COMPARE_OP(<=, Py_LE) +BOOST_PYTHON_COMPARE_OP(==, Py_EQ) +BOOST_PYTHON_COMPARE_OP(!=, Py_NE) +# undef BOOST_PYTHON_COMPARE_OP + +# define BOOST_PYTHON_BINARY_OPERATOR(op) \ +BOOST_PYTHON_DECL object operator op(object const& l, object const& r); \ +template \ +object operator op(L const& l, R const& r) \ +{ \ + return object(l) op object(r); \ +} +BOOST_PYTHON_BINARY_OPERATOR(+) +BOOST_PYTHON_BINARY_OPERATOR(-) +BOOST_PYTHON_BINARY_OPERATOR(*) +BOOST_PYTHON_BINARY_OPERATOR(/) +BOOST_PYTHON_BINARY_OPERATOR(%) +BOOST_PYTHON_BINARY_OPERATOR(<<) +BOOST_PYTHON_BINARY_OPERATOR(>>) +BOOST_PYTHON_BINARY_OPERATOR(&) +BOOST_PYTHON_BINARY_OPERATOR(^) +BOOST_PYTHON_BINARY_OPERATOR(|) +# undef BOOST_PYTHON_BINARY_OPERATOR + + +# define BOOST_PYTHON_INPLACE_OPERATOR(op) \ +BOOST_PYTHON_DECL object& operator op(object& l, object const& r); \ +template \ +object& operator op(object& l, R const& r) \ +{ \ + return l op object(r); \ +} +BOOST_PYTHON_INPLACE_OPERATOR(+=) +BOOST_PYTHON_INPLACE_OPERATOR(-=) +BOOST_PYTHON_INPLACE_OPERATOR(*=) +BOOST_PYTHON_INPLACE_OPERATOR(/=) +BOOST_PYTHON_INPLACE_OPERATOR(%=) +BOOST_PYTHON_INPLACE_OPERATOR(<<=) +BOOST_PYTHON_INPLACE_OPERATOR(>>=) +BOOST_PYTHON_INPLACE_OPERATOR(&=) +BOOST_PYTHON_INPLACE_OPERATOR(^=) +BOOST_PYTHON_INPLACE_OPERATOR(|=) +# undef BOOST_PYTHON_INPLACE_OPERATOR + +}}} // namespace boost::python + +#endif // OBJECT_OPERATORS_DWA2002617_HPP diff --git a/include/boost/python/object_protocol_core.hpp b/include/boost/python/object_protocol_core.hpp index adbd593f..9fc28415 100755 --- a/include/boost/python/object_protocol_core.hpp +++ b/include/boost/python/object_protocol_core.hpp @@ -8,12 +8,20 @@ namespace boost { namespace python { -class object; +namespace api +{ + class object; -BOOST_PYTHON_DECL object getattr(object const& target, object const& key); -BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value); -BOOST_PYTHON_DECL object getitem(object const& target, object const& key); -BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value); + BOOST_PYTHON_DECL object getattr(object const& target, object const& key); + BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value); + BOOST_PYTHON_DECL object getitem(object const& target, object const& key); + BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value); +} + +using api::getattr; +using api::setattr; +using api::getitem; +using api::setitem; }} // namespace boost::python diff --git a/include/boost/python/operators2.hpp b/include/boost/python/operators2.hpp index a58b7559..d4bffb05 100755 --- a/include/boost/python/operators2.hpp +++ b/include/boost/python/operators2.hpp @@ -196,9 +196,12 @@ BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <) BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=) BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==) BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=) - +# undef BOOST_PYTHON_BINARY_OPERATOR + // pow isn't an operator in C++; handle it specially. BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r)) +# undef BOOST_PYTHON_BINARY_OPERATION + namespace self_ns { # ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP @@ -300,6 +303,7 @@ namespace self_ns \ return detail::operator_(); \ } \ } +# undef BOOST_PYTHON_INPLACE_OPERATOR BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-) BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+) @@ -310,7 +314,8 @@ BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_) BOOST_PYTHON_UNARY_OPERATOR(float, double, float_) BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex, complex_) BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast, str) - +# undef BOOST_PYTHON_UNARY_OPERATOR + }} // namespace boost::python # ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP diff --git a/include/boost/python/proxy.hpp b/include/boost/python/proxy.hpp index 46476f2d..d7747c0d 100755 --- a/include/boost/python/proxy.hpp +++ b/include/boost/python/proxy.hpp @@ -6,10 +6,9 @@ #ifndef PROXY_DWA2002615_HPP # define PROXY_DWA2002615_HPP # include +# include -namespace boost { namespace python { - -class object; +namespace boost { namespace python { namespace api { template class proxy @@ -23,37 +22,15 @@ class proxy operator object() const; // to support a[b] = c[d] - proxy& operator=(copy_ctor_self); + proxy const& operator=(copy_ctor_self) const; template - inline proxy& operator=(T const& rhs) + inline proxy const& operator=(T const& rhs) const { Policies::set(m_target, m_key, python::object(rhs)); return *this; } -# define BOOST_PYTHON_PROXY_ASSIGN_DECL(op) \ - object operator op (object const&); \ - \ - template \ - object operator op (T const& rhs) \ - { \ - return *this op python::object(rhs); \ - } - -// BOOST_PYTHON_PROXY_ASSIGN_DECL(=) - BOOST_PYTHON_PROXY_ASSIGN_DECL(+=) - BOOST_PYTHON_PROXY_ASSIGN_DECL(-=) - BOOST_PYTHON_PROXY_ASSIGN_DECL(*=) - BOOST_PYTHON_PROXY_ASSIGN_DECL(/=) - BOOST_PYTHON_PROXY_ASSIGN_DECL(%=) - BOOST_PYTHON_PROXY_ASSIGN_DECL(<<=) - BOOST_PYTHON_PROXY_ASSIGN_DECL(>>=) - BOOST_PYTHON_PROXY_ASSIGN_DECL(&=) - BOOST_PYTHON_PROXY_ASSIGN_DECL(^=) - BOOST_PYTHON_PROXY_ASSIGN_DECL(|=) -# undef BOOST_PYTHON_PROXY_ASSIGN_DECL - // truth value testing operator object::bool_type() const; bool operator!() const; // needed for vc6 @@ -84,33 +61,29 @@ inline proxy::operator object() const // to support a[b] = c[d] template -inline proxy& proxy::operator=(typename proxy::copy_ctor_self rhs) +inline proxy const& proxy::operator=(typename proxy::copy_ctor_self rhs) const { return *this = python::object(rhs); } -# define BOOST_PYTHON_PROXY_ASSIGN_DEF(op) \ -template \ -inline object proxy::operator op(object const& other) \ -{ \ - return Policies::set( \ - m_target, m_key \ - , Policies::get(m_target,m_key) op other); \ -} - -BOOST_PYTHON_PROXY_ASSIGN_DEF(+=) -BOOST_PYTHON_PROXY_ASSIGN_DEF(-=) -BOOST_PYTHON_PROXY_ASSIGN_DEF(*=) -BOOST_PYTHON_PROXY_ASSIGN_DEF(/=) -BOOST_PYTHON_PROXY_ASSIGN_DEF(%=) -BOOST_PYTHON_PROXY_ASSIGN_DEF(<<=) -BOOST_PYTHON_PROXY_ASSIGN_DEF(>>=) -BOOST_PYTHON_PROXY_ASSIGN_DEF(&=) -BOOST_PYTHON_PROXY_ASSIGN_DEF(^=) -BOOST_PYTHON_PROXY_ASSIGN_DEF(|=) - -# undef BOOST_PYTHON_PROXY_ASSIGN_DEF - +# define BOOST_PYTHON_PROXY_INPLACE(op) \ +template \ +proxy const& operator op(proxy const& lhs, R const& other) \ +{ \ + object old(lhs); \ + return lhs = (old op other); \ +} +BOOST_PYTHON_PROXY_INPLACE(+=) +BOOST_PYTHON_PROXY_INPLACE(-=) +BOOST_PYTHON_PROXY_INPLACE(*=) +BOOST_PYTHON_PROXY_INPLACE(/=) +BOOST_PYTHON_PROXY_INPLACE(%=) +BOOST_PYTHON_PROXY_INPLACE(<<=) +BOOST_PYTHON_PROXY_INPLACE(>>=) +BOOST_PYTHON_PROXY_INPLACE(&=) +BOOST_PYTHON_PROXY_INPLACE(^=) +BOOST_PYTHON_PROXY_INPLACE(|=) +# undef BOOST_PYTHON_PROXY_INPLACE template inline proxy::operator object::bool_type() const @@ -124,6 +97,6 @@ inline bool proxy::operator!() const return !python::object(*this); } -}} // namespace boost::python +}}} // namespace boost::python::api #endif // PROXY_DWA2002615_HPP diff --git a/src/object_operators.cpp b/src/object_operators.cpp new file mode 100644 index 00000000..ed824ab6 --- /dev/null +++ b/src/object_operators.cpp @@ -0,0 +1,51 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include + +namespace boost { namespace python { namespace api { + +#define BOOST_PYTHON_BINARY_OPERATOR(op, name) \ +BOOST_PYTHON_DECL object operator op(object const& l, object const& r) \ +{ \ + return object( \ + (object::new_pyobject_reference*) \ + PyNumber_##name(&*l, &*r)); \ +} + +BOOST_PYTHON_BINARY_OPERATOR(+, Add) +BOOST_PYTHON_BINARY_OPERATOR(-, Subtract) +BOOST_PYTHON_BINARY_OPERATOR(*, Multiply) +BOOST_PYTHON_BINARY_OPERATOR(/, Divide) +BOOST_PYTHON_BINARY_OPERATOR(%, Remainder) +BOOST_PYTHON_BINARY_OPERATOR(<<, Lshift) +BOOST_PYTHON_BINARY_OPERATOR(>>, Rshift) +BOOST_PYTHON_BINARY_OPERATOR(&, And) +BOOST_PYTHON_BINARY_OPERATOR(^, Xor) +BOOST_PYTHON_BINARY_OPERATOR(|, Or) +#undef BOOST_PYTHON_BINARY_OPERATOR + +#define BOOST_PYTHON_INPLACE_OPERATOR(op, name) \ +BOOST_PYTHON_DECL object& operator op##=(object& l, object const& r) \ +{ \ + return l = object( \ + (object::new_pyobject_reference*) \ + PyNumber_InPlace##name(&*l, &*r)); \ +} + +BOOST_PYTHON_INPLACE_OPERATOR(+, Add) +BOOST_PYTHON_INPLACE_OPERATOR(-, Subtract) +BOOST_PYTHON_INPLACE_OPERATOR(*, Multiply) +BOOST_PYTHON_INPLACE_OPERATOR(/, Divide) +BOOST_PYTHON_INPLACE_OPERATOR(%, Remainder) +BOOST_PYTHON_INPLACE_OPERATOR(<<, Lshift) +BOOST_PYTHON_INPLACE_OPERATOR(>>, Rshift) +BOOST_PYTHON_INPLACE_OPERATOR(&, And) +BOOST_PYTHON_INPLACE_OPERATOR(^, Xor) +BOOST_PYTHON_INPLACE_OPERATOR(|, Or) +#undef BOOST_PYTHON_INPLACE_OPERATOR + +}}} // namespace boost::python diff --git a/src/object_protocol.cpp b/src/object_protocol.cpp index c04a8da2..8f2548ab 100755 --- a/src/object_protocol.cpp +++ b/src/object_protocol.cpp @@ -8,28 +8,28 @@ #include #include -namespace boost { namespace python { +namespace boost { namespace python { namespace api { -object getattr(object const& target, object const& key) +BOOST_PYTHON_DECL object getattr(object const& target, object const& key) { return object((object::new_pyobject_reference*)PyObject_GetAttr(&*target, &*key)); } -void setattr(object const& target, object const& key, object const& value) +BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value) { if (PyObject_SetAttr(&*target, &*key, &*value) == -1) throw_error_already_set(); } -object getitem(object const& target, object const& key) +BOOST_PYTHON_DECL object getitem(object const& target, object const& key) { return object((object::new_pyobject_reference*)PyObject_GetItem(&*target, &*key)); } -void setitem(object const& target, object const& key, object const& value) +BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value) { if (PyObject_SetItem(&*target, &*key, &*value) == -1) throw_error_already_set(); } -}} // namespace boost::python +}}} // namespace boost::python::api diff --git a/test/doctest.py b/test/doctest.py index 248da82a..2829f1e6 100644 --- a/test/doctest.py +++ b/test/doctest.py @@ -1,10 +1,10 @@ -# Module doctest version 0.9.4 -# Released to the public domain 27-Mar-1999, -# by Tim Peters (tim_one@email.msn.com). +# Module doctest. +# Released to the public domain 16-Jan-2001, +# by Tim Peters (tim.one@home.com). # Provided as-is; use at your own risk; no warranty; no promises; enjoy! -"""module_builder doctest -- a framework for running examples in docstrings. +"""Module doctest -- a framework for running examples in docstrings. NORMAL USAGE @@ -20,16 +20,16 @@ if __name__ == "__main__": Then running the module as a script will cause the examples in the docstrings to get executed and verified: -python M.python +python M.py -This won't display anything unless an example fails, in which case -the failing example(s) and the cause(s) of the failure(s) are printed -to stdout (why not stderr? because stderr is a lame hack <0.2 wink>), -and the final line of output is "Test failed.". +This won't display anything unless an example fails, in which case the +failing example(s) and the cause(s) of the failure(s) are printed to stdout +(why not stderr? because stderr is a lame hack <0.2 wink>), and the final +line of output is "Test failed.". Run it with the -v switch instead: -python M.python -v +python M.py -v and a detailed report of all examples tried is printed to stdout, along with assorted summaries at the end. @@ -48,71 +48,52 @@ WHICH DOCSTRINGS ARE EXAMINED? + M.__doc__. + f.__doc__ for all functions f in M.__dict__.values(), except those - with private names. + with private names and those defined in other modules. + C.__doc__ for all classes C in M.__dict__.values(), except those with - private names. + private names and those defined in other modules. + If M.__test__ exists and "is true", it must be a dict, and each entry maps a (string) name to a function object, class object, or - string. function and class object docstrings found from M.__test__ + string. Function and class object docstrings found from M.__test__ are searched even if the name is private, and strings are searched directly as if they were docstrings. In output, a key K in M.__test__ appears with name .__test__.K -Any classes found are recursively searched similarly, to test docstrings -in their contained methods and nested classes. Private names reached -from M's globals are skipped, but all names reached from M.__test__ are -searched. +Any classes found are recursively searched similarly, to test docstrings in +their contained methods and nested classes. Private names reached from M's +globals are skipped, but all names reached from M.__test__ are searched. By default, a name is considered to be private if it begins with an -underscore (like "_my_func") but doesn't both begin and end with (at -least) two underscores (like "__init__"). You can change the default -by passing your own "isprivate" function to testmod. +underscore (like "_my_func") but doesn't both begin and end with (at least) +two underscores (like "__init__"). You can change the default by passing +your own "isprivate" function to testmod. If you want to test docstrings in objects with private names too, stuff them into an M.__test__ dict, or see ADVANCED USAGE below (e.g., pass your own isprivate function to Tester's constructor, or call the rundoc method -of a Tester obj). - -Warning: imports can cause trouble; e.g., if you do - -from XYZ import XYZclass - -then XYZclass is a name in M.__dict__ too, and doctest has no way to -know that XYZclass wasn't *defined* in M. So it may try to execute the -examples in XYZclass's docstring, and those in turn may require a -different set of globals to work correctly. I prefer to do "import *"- -friendly imports, a la - -import XYY -_XYZclass = XYZ.XYZclass -del XYZ - -and then the leading underscore stops testmod from going nuts. You may -prefer the method in the next section. - +of a Tester instance). WHAT'S THE EXECUTION CONTEXT? -By default, each time testmod finds a docstring to test, it uses a -*copy* of M's globals (so that running tests on a module doesn't change -the module's real globals, and so that one test in M can't leave behind -crumbs that accidentally allow another test to work). This means -examples can freely use any names defined at top-level in M. It also -means that sloppy imports (see above) can cause examples in external -docstrings to use globals inappropriate for them. +By default, each time testmod finds a docstring to test, it uses a *copy* +of M's globals (so that running tests on a module doesn't change the +module's real globals, and so that one test in M can't leave behind crumbs +that accidentally allow another test to work). This means examples can +freely use any names defined at top-level in M. It also means that sloppy +imports (see above) can cause examples in external docstrings to use +globals inappropriate for them. You can force use of your own dict as the execution context by passing -"globs=your_dict" to testmod instead. Presumably this would be a copy -of M.__dict__ merged with the globals from other imported modules. +"globs=your_dict" to testmod instead. Presumably this would be a copy of +M.__dict__ merged with the globals from other imported modules. WHAT IF I WANT TO TEST A WHOLE PACKAGE? Piece o' cake, provided the modules do their testing from docstrings. -Here's the test.python I use for the world's most elaborate Rational/ +Here's the test.py I use for the world's most elaborate Rational/ floating-base-conversion pkg (which I'll distribute some day): from Rational import Cvt @@ -141,11 +122,10 @@ if __name__ == "__main__": _test() IOW, it just runs testmod on all the pkg modules. testmod remembers the -names and outcomes (# of failures, # of tries) for each item it's seen, -and passing "report=0" prevents it from printing a summary in verbose -mode. Instead, the summary is delayed until all modules have been -tested, and then "doctest.master.summarize()" forces the summary at the -end. +names and outcomes (# of failures, # of tries) for each item it's seen, and +passing "report=0" prevents it from printing a summary in verbose mode. +Instead, the summary is delayed until all modules have been tested, and +then "doctest.master.summarize()" forces the summary at the end. So this is very nice in practice: each module can be tested individually with almost no work beyond writing up docstring examples, and collections @@ -157,10 +137,10 @@ WHAT ABOUT EXCEPTIONS? No problem, as long as the only output generated by the example is the traceback itself. For example: - >>> 1/0 - Traceback (innermost last): + >>> [1, 2, 3].remove(42) + Traceback (most recent call last): File "", line 1, in ? - ZeroDivisionError: integer division or modulo + ValueError: list.remove(x): x not in list >>> Note that only the exception type and value are compared (specifically, @@ -172,22 +152,22 @@ ADVANCED USAGE doctest.testmod() captures the testing policy I find most useful most often. You may want other policies. -testmod() actually creates a local obj of class doctest.Tester, -runs appropriate methods of that class, and merges the results into -global Tester obj doctest.master. +testmod() actually creates a local instance of class doctest.Tester, runs +appropriate methods of that class, and merges the results into global +Tester instance doctest.master. -You can create your own instances of doctest.Tester, and so build your -own policies, or even run methods of doctest.master directly. See +You can create your own instances of doctest.Tester, and so build your own +policies, or even run methods of doctest.master directly. See doctest.Tester.__doc__ for details. SO WHAT DOES A DOCSTRING EXAMPLE LOOK LIKE ALREADY!? Oh ya. It's easy! In most cases a copy-and-paste of an interactive -console session works fine -- just make sure the leading whitespace -is rigidly consistent (you can mix tabs and spaces if you're too lazy -to do it right, but doctest is not in the business of guessing what -you think a tab means). +console session works fine -- just make sure the leading whitespace is +rigidly consistent (you can mix tabs and spaces if you're too lazy to do it +right, but doctest is not in the business of guessing what you think a tab +means). >>> # comments are ignored >>> x = 12 @@ -205,23 +185,22 @@ you think a tab means). NO!!! >>> -Any expected output must immediately follow the final ">>>" or "..." -line containing the code, and the expected output (if any) extends -to the next ">>>" or all-whitespace line. That's it. +Any expected output must immediately follow the final ">>>" or "..." line +containing the code, and the expected output (if any) extends to the next +">>>" or all-whitespace line. That's it. Bummers: -+ Expected output cannot contain an all-whitespace line, since such a - line is taken to signal the end of expected output. ++ Expected output cannot contain an all-whitespace line, since such a line + is taken to signal the end of expected output. + Output to stdout is captured, but not output to stderr (exception tracebacks are captured via a different means). -+ If you continue a line via backslashing in an interactive session, - or for any other reason use a backslash, you need to double the - backslash in the docstring version. This is simply because you're - in a string, and so the backslash must be escaped for it to survive - intact. Like: ++ If you continue a line via backslashing in an interactive session, or for + any other reason use a backslash, you need to double the backslash in the + docstring version. This is simply because you're in a string, and so the + backslash must be escaped for it to survive intact. Like: >>> if "yes" == \\ ... "y" + \\ @@ -243,11 +222,11 @@ If you execute this very file, the examples above will be found and executed, leading to this output in verbose mode: Running doctest.__doc__ -Trying: 1/0 +Trying: [1, 2, 3].remove(42) Expecting: -Traceback (innermost last): +Traceback (most recent call last): File "", line 1, in ? -ZeroDivisionError: integer division or modulo +ValueError: list.remove(x): x not in list ok Trying: x = 12 Expecting: nothing @@ -279,7 +258,7 @@ ok 8 tests in doctest 6 tests in doctest.Tester 10 tests in doctest.Tester.merge - 7 tests in doctest.Tester.rundict + 14 tests in doctest.Tester.rundict 3 tests in doctest.Tester.rundoc 3 tests in doctest.Tester.runstring 2 tests in doctest.__test__._TestClass @@ -288,79 +267,19 @@ ok 1 tests in doctest.__test__._TestClass.square 2 tests in doctest.__test__.string 7 tests in doctest.is_private -53 tests in 17 items. -53 passed and 0 failed. +60 tests in 17 items. +60 passed and 0 failed. Test passed. """ -# 0,0,1 06-Mar-1999 -# initial version posted -# 0,0,2 06-Mar-1999 -# loosened parsing: -# cater to stinkin' tabs -# don't insist on a blank after PS2 prefix -# so trailing "... " line from a compound stmt no longer -# breaks if the file gets whitespace-trimmed -# better error msgs for inconsistent leading whitespace -# 0,9,1 08-Mar-1999 -# exposed the Tester class and added client methods -# plus docstring examples of their use (eww - head-twisting!) -# fixed logic error in reporting total # of tests & failures -# added __test__ support to testmod (a pale reflection of Christian -# Tismer's vision ...) -# removed the "deep" argument; fiddle __test__ instead -# simplified endcase logic for extracting tests, and running them. -# before, if no output was expected but some was produced -# anyway via an eval'ed result, the discrepancy wasn't caught -# made TestClass private and used __test__ to get at it -# many doc updates -# speed _SpoofOut for long expected outputs -# 0,9,2 09-Mar-1999 -# throw out comments from examples, enabling use of the much simpler -# exec compile(... "single") ... -# for simulating the runtime; that barfs on comment-only lines -# used the traceback module to do a much better job of reporting -# exceptions -# run __doc__ values thru str(), "just in case" -# privateness of names now determined by an overridable "isprivate" -# function -# by default a name now considered to be private iff it begins with -# an underscore but doesn't both begin & end with two of 'em; so -# e.g. class_t.__init__ etc are searched now -- as they always -# should have been -# 0,9,3 18-Mar-1999 -# added .flush stub to _SpoofOut (JPython buglet diagnosed by -# Hugh Emberson) -# repaired ridiculous docs about backslashes in examples -# minor internal changes -# changed source to Unix line-end conventions -# moved __test__ logic into new Tester.run__test__ method -# 0,9,4 27-Mar-1999 -# report item name and line # in failing examples -# 0,9,5 29-Jun-1999 -# allow straightforward exceptions in examples - thanks to Mark Hammond! -# 0,9,5,1 31-Mar-2000 -# break cyclic references to functions which are defined in docstrings, -# avoiding cyclic trash -# 0,9,5,2 11-Apr-2000 -# made module argument to testmod optional; it runs testmod on the __main__ -# module in that case. +__all__ = [ + 'testmod', + 'run_docstring_examples', + 'is_private', + 'Tester', +] -__version__ = 0, 9, 5 - -import types -_FunctionType = types.FunctionType -_ClassType = types.ClassType -_ModuleType = types.ModuleType -_StringType = types.StringType -del types - -import string -_string_find = string.find -_string_join = string.join -_string_split = string.split -_string_rindex = string.rindex -del string +import __future__ import re PS1 = ">>>" @@ -371,6 +290,13 @@ _isEmpty = re.compile(r"\s*$").match _isComment = re.compile(r"\s*#").match del re +from types import StringTypes as _StringTypes + +from inspect import isclass as _isclass +from inspect import isfunction as _isfunction +from inspect import ismodule as _ismodule +from inspect import classify_class_attrs as _classify_class_attrs + # Extract interactive examples from a string. Return a list of triples, # (source, outcome, lineno). "source" is the source code, and ends # with a newline iff the source spans more than one line. "outcome" is @@ -382,7 +308,7 @@ def _extract_examples(s): isPS1, isPS2 = _isPS1, _isPS2 isEmpty, isComment = _isEmpty, _isComment examples = [] - lines = _string_split(s, "\n") + lines = s.split("\n") i, n = 0, len(lines) while i < n: line = lines[i] @@ -420,7 +346,7 @@ def _extract_examples(s): # get rid of useless null line from trailing empty "..." if source[-1] == "": del source[-1] - source = _string_join(source, "\n") + "\n" + source = "\n".join(source) + "\n" # suck up response if isPS1(line) or isEmpty(line): expect = "" @@ -435,7 +361,7 @@ def _extract_examples(s): line = lines[i] if isPS1(line) or isEmpty(line): break - expect = _string_join(expect, "\n") + "\n" + expect = "\n".join(expect) + "\n" examples.append( (source, expect, lineno) ) return examples @@ -447,9 +373,21 @@ class _SpoofOut: def write(self, s): self.buf.append(s) def get(self): - return _string_join(self.buf, "") + guts = "".join(self.buf) + # If anything at all was written, make sure there's a trailing + # newline. There's no way for the expected output to indicate + # that a trailing newline is missing. + if guts and not guts.endswith("\n"): + guts = guts + "\n" + # Prevent softspace from screwing up the next test case, in + # case they used print with a trailing comma in an example. + if hasattr(self, "softspace"): + del self.softspace + return guts def clear(self): self.buf = [] + if hasattr(self, "softspace"): + del self.softspace def flush(self): # JPython calls flush pass @@ -462,7 +400,7 @@ def _tag_out(printer, *tag_msg_pairs): printer(tag + ":") msg_has_nl = msg[-1:] == "\n" msg_has_two_nl = msg_has_nl and \ - _string_find(msg, "\n") < len(msg) - 1 + msg.find("\n") < len(msg) - 1 if len(tag) + len(msg) < 76 and not msg_has_two_nl: printer(" ") else: @@ -472,10 +410,11 @@ def _tag_out(printer, *tag_msg_pairs): printer("\n") # Run list of examples, in context globs. "out" can be used to display -# stuff to "the real" stdout, and fakeout is an obj of _SpoofOut +# stuff to "the real" stdout, and fakeout is an instance of _SpoofOut # that captures the examples' std output. Return (#failures, #tries). -def _run_examples_inner(out, fakeout, examples, globs, verbose, name): +def _run_examples_inner(out, fakeout, examples, globs, verbose, name, + compileflags): import sys, traceback OK, BOOM, FAIL = range(3) NADA = "nothing" @@ -487,17 +426,19 @@ def _run_examples_inner(out, fakeout, examples, globs, verbose, name): ("Expecting", want or NADA)) fakeout.clear() try: - exec compile(source, "", "single") in globs + exec compile(source, "", "single", + compileflags, 1) in globs got = fakeout.get() state = OK except: # See whether the exception was expected. - if _string_find(want, "Traceback (innermost last):\n") == 0: + if want.find("Traceback (innermost last):\n") == 0 or \ + want.find("Traceback (most recent call last):\n") == 0: # Only compare exception type and value - the rest of # the traceback isn't necessary. - want = _string_split(want, '\n')[-2] + '\n' - exc_type, exc_val, exc_tb = sys.exc_info() - got = traceback.format_exception_only(exc_type, exc_val)[0] + want = want.split('\n')[-2] + '\n' + exc_type, exc_val = sys.exc_info()[:2] + got = traceback.format_exception_only(exc_type, exc_val)[-1] state = OK else: # unexpected exception @@ -522,25 +463,49 @@ def _run_examples_inner(out, fakeout, examples, globs, verbose, name): else: assert state == BOOM _tag_out(out, ("Exception raised", stderr.get())) + return failures, len(examples) -# Run list of examples, in context globs. Return (#failures, #tries). +# Get the future-flags associated with the future features that have been +# imported into globs. -def _run_examples(examples, globs, verbose, name): +def _extract_future_flags(globs): + flags = 0 + for fname in __future__.all_feature_names: + feature = globs.get(fname, None) + if feature is getattr(__future__, fname): + flags |= feature.compiler_flag + return flags + +# Run list of examples, in a shallow copy of context (dict) globs. +# Return (#failures, #tries). + +def _run_examples(examples, globs, verbose, name, compileflags): import sys saveout = sys.stdout + globs = globs.copy() try: sys.stdout = fakeout = _SpoofOut() x = _run_examples_inner(saveout.write, fakeout, examples, - globs, verbose, name) + globs, verbose, name, compileflags) finally: sys.stdout = saveout + # While Python gc can clean up most cycles on its own, it doesn't + # chase frame objects. This is especially irksome when running + # generator tests that raise exceptions, because a named generator- + # iterator gets an entry in globs, and the generator-iterator + # object's frame's traceback info points back to globs. This is + # easy to break just by clearing the namespace. This can also + # help to break other kinds of cycles, and even for cycles that + # gc can break itself it's better to break them ASAP. + globs.clear() return x -def run_docstring_examples(f, globs, verbose=0, name="NoName"): +def run_docstring_examples(f, globs, verbose=0, name="NoName", + compileflags=None): """f, globs, verbose=0, name="NoName" -> run examples from f.__doc__. - Use dict globs as the globals for execution. + Use (a shallow copy of) dict globs as the globals for execution. Return (#failures, #tries). If optional arg verbose is true, print stuff even if there are no @@ -562,7 +527,9 @@ def run_docstring_examples(f, globs, verbose=0, name="NoName"): e = _extract_examples(doc) if not e: return 0, 0 - return _run_examples(e, globs, verbose, name) + if compileflags is None: + compileflags = _extract_future_flags(globs) + return _run_examples(e, globs, verbose, name, compileflags) def is_private(prefix, base): """prefix, base -> true iff name prefix + "." + base is "private". @@ -591,8 +558,17 @@ def is_private(prefix, base): return base[:1] == "_" and not base[:2] == "__" == base[-2:] +# Determine if a class of function was defined in the given module. + +def _from_module(module, object): + if _isfunction(object): + return module.__dict__ is object.func_globals + if _isclass(object): + return module.__name__ == object.__module__ + raise ValueError("object must be a class or function") + class Tester: - """class_t Tester -- runs docstring examples and accumulates stats. + """Class Tester -- runs docstring examples and accumulates stats. In normal use, function doctest.testmod() hides all this from you, so use that if you can. Create your own instances of Tester to do @@ -607,9 +583,10 @@ Methods: Search object.__doc__ for examples to run; use name (or object.__name__) for logging. Return (#failures, #tries). - rundict(d, name) + rundict(d, name, module=None) Search for examples in docstrings in all of d.values(); use name - for logging. Return (#failures, #tries). + for logging. Exclude functions and classes not defined in module + if specified. Return (#failures, #tries). run__test__(d, name) Treat dict d like module.__test__. Return (#failures, #tries). @@ -619,7 +596,7 @@ Methods: (#failures, #tries). merge(other) - Merge in the test results from Tester obj "other". + Merge in the test results from Tester instance "other". >>> from doctest import Tester >>> t = Tester(globs={'x': 42}, verbose=0) @@ -637,6 +614,7 @@ Got: 84 >>> t.runstring(">>> x = x * 2\\n>>> print x\\n84\\n", 'example2') (0, 2) >>> t.summarize() +***************************************************************** 1 items had failures: 1 of 2 in XYZ ***Test Failed*** 1 failures. @@ -644,6 +622,7 @@ Got: 84 >>> t.summarize(verbose=1) 1 items passed all tests: 2 tests in example2 +***************************************************************** 1 items had failures: 1 of 2 in XYZ 4 tests in 2 items. @@ -679,7 +658,7 @@ see its docs for details. if mod is None and globs is None: raise TypeError("Tester.__init__: must specify mod or globs") - if mod is not None and type(mod) is not _ModuleType: + if mod is not None and not _ismodule(mod): raise TypeError("Tester.__init__: mod must be a module; " + `mod`) if globs is None: @@ -697,6 +676,8 @@ see its docs for details. self.name2ft = {} # map name to (#failures, #trials) pair + self.compileflags = _extract_future_flags(globs) + def runstring(self, s, name): """ s, name -> search string s for examples to run, logging as name. @@ -728,9 +709,8 @@ see its docs for details. f = t = 0 e = _extract_examples(s) if e: - globs = self.globs.copy() - f, t = _run_examples(e, globs, self.verbose, name) - globs.clear() # DWA - break cyclic references to functions defined in docstrings + f, t = _run_examples(e, self.globs, self.verbose, name, + self.compileflags) if self.verbose: print f, "of", t, "examples failed in string", name self.__record_outcome(name, f, t) @@ -768,51 +748,133 @@ see its docs for details. "when object.__name__ doesn't exist; " + `object`) if self.verbose: print "Running", name + ".__doc__" - globs = self.globs.copy() - f, t = run_docstring_examples(object, globs, - self.verbose, name) - globs.clear() # DWA - break cyclic references to functions defined in docstrings - + f, t = run_docstring_examples(object, self.globs, self.verbose, name, + self.compileflags) if self.verbose: print f, "of", t, "examples failed in", name + ".__doc__" self.__record_outcome(name, f, t) - if type(object) is _ClassType: - f2, t2 = self.rundict(object.__dict__, name) - f = f + f2 - t = t + t2 + if _isclass(object): + # In 2.2, class and static methods complicate life. Build + # a dict "that works", by hook or by crook. + d = {} + for tag, kind, homecls, value in _classify_class_attrs(object): + + if homecls is not object: + # Only look at names defined immediately by the class. + continue + + elif self.isprivate(name, tag): + continue + + elif kind == "method": + # value is already a function + d[tag] = value + + elif kind == "static method": + # value isn't a function, but getattr reveals one + d[tag] = getattr(object, tag) + + elif kind == "class method": + # Hmm. A classmethod object doesn't seem to reveal + # enough. But getattr turns it into a bound method, + # and from there .im_func retrieves the underlying + # function. + d[tag] = getattr(object, tag).im_func + + elif kind == "property": + # The methods implementing the property have their + # own docstrings -- but the property may have one too. + if value.__doc__ is not None: + d[tag] = str(value.__doc__) + + elif kind == "data": + # Grab nested classes. + if _isclass(value): + d[tag] = value + + else: + raise ValueError("teach doctest about %r" % kind) + + f2, t2 = self.run__test__(d, name) + f += f2 + t += t2 + return f, t - def rundict(self, d, name): + def rundict(self, d, name, module=None): """ - d. name -> search for docstring examples in all of d.values(). + d, name, module=None -> search for docstring examples in d.values(). For k, v in d.items() such that v is a function or class, do self.rundoc(v, name + "." + k). Whether this includes objects with private names depends on the constructor's - "isprivate" argument. + "isprivate" argument. If module is specified, functions and + classes that are not defined in module are excluded. Return aggregate (#failures, #examples). - >>> def _f(): - ... '''>>> assert 1 == 1 - ... ''' - >>> def g(): + Build and populate two modules with sample functions to test that + exclusion of external functions and classes works. + + >>> import new + >>> m1 = new.module('_m1') + >>> m2 = new.module('_m2') + >>> test_data = \""" + ... def _f(): + ... '''>>> assert 1 == 1 + ... ''' + ... def g(): ... '''>>> assert 2 != 1 ... ''' - >>> d = {"_f": _f, "g": g} + ... class H: + ... '''>>> assert 2 > 1 + ... ''' + ... def bar(self): + ... '''>>> assert 1 < 2 + ... ''' + ... \""" + >>> exec test_data in m1.__dict__ + >>> exec test_data in m2.__dict__ + >>> m1.__dict__.update({"f2": m2._f, "g2": m2.g, "h2": m2.H}) + + Tests that objects outside m1 are excluded: + >>> t = Tester(globs={}, verbose=0) - >>> t.rundict(d, "rundict_test") # _f is skipped - (0, 1) + >>> t.rundict(m1.__dict__, "rundict_test", m1) # _f, f2 and g2 and h2 skipped + (0, 3) + + Again, but with a custom isprivate function allowing _f: + >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) - >>> t.rundict(d, "rundict_test_pvt") # both are searched - (0, 2) + >>> t.rundict(m1.__dict__, "rundict_test_pvt", m1) # Only f2, g2 and h2 skipped + (0, 4) + + And once more, not excluding stuff outside m1: + + >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) + >>> t.rundict(m1.__dict__, "rundict_test_pvt") # None are skipped. + (0, 8) + + The exclusion of objects from outside the designated module is + meant to be invoked automagically by testmod. + + >>> testmod(m1) + (0, 3) + """ if not hasattr(d, "items"): raise TypeError("Tester.rundict: d must support .items(); " + `d`) f = t = 0 - for thisname, value in d.items(): - if type(value) in (_FunctionType, _ClassType): + # Run the tests by alpha order of names, for consistency in + # verbose-mode output. + names = d.keys() + names.sort() + for thisname in names: + value = d[thisname] + if _isfunction(value) or _isclass(value): + if module and not _from_module(module, value): + continue f2, t2 = self.__runone(value, name + "." + thisname) f = f + f2 t = t + t2 @@ -830,11 +892,16 @@ see its docs for details. savepvt = self.isprivate try: self.isprivate = lambda *args: 0 - for k, v in d.items(): + # Run the tests by alpha order of names, for consistency in + # verbose-mode output. + keys = d.keys() + keys.sort() + for k in keys: + v = d[k] thisname = prefix + k - if type(v) is _StringType: + if type(v) in _StringTypes: f, t = self.runstring(v, thisname) - elif type(v) in (_FunctionType, _ClassType): + elif _isfunction(v) or _isclass(v): f, t = self.rundoc(v, thisname) else: raise TypeError("Tester.run__test__: values in " @@ -885,6 +952,7 @@ see its docs for details. for thing, count in passed: print " %3d tests in %s" % (count, thing) if failed: + print "*" * 65 print len(failed), "items had failures:" failed.sort() for thing, (f, t) in failed: @@ -900,7 +968,7 @@ see its docs for details. def merge(self, other): """ - other -> merge in test results from the other Tester obj. + other -> merge in test results from the other Tester instance. If self and other both have a test result for something with the same name, the (#failures, #tests) results are @@ -962,7 +1030,7 @@ see its docs for details. def __runone(self, target, name): if "." in name: - i = _string_rindex(name, ".") + i = name.rindex(".") prefix, base = name[:i], name[i+1:] else: prefix, base = "", base @@ -972,9 +1040,9 @@ see its docs for details. master = None -def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None, +def testmod(m, name=None, globs=None, verbose=None, isprivate=None, report=1): - """m=None, name=None, globs=None, verbose=None, isprivate=None, report=1 + """m, name=None, globs=None, verbose=None, isprivate=None, report=1 Test examples in docstrings in functions and classes reachable from module m, starting with m.__doc__. Private names are skipped. @@ -1007,10 +1075,10 @@ def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None, else prints nothing at the end. In verbose mode, the summary is detailed, else very brief (in fact, empty if all tests passed). - Advanced tomfoolery: testmod runs methods of a local obj of + Advanced tomfoolery: testmod runs methods of a local instance of class doctest.Tester, then merges the results into (or creates) - global Tester obj doctest.master. Methods of doctest.master - can be called directly too, if you want to do something unusual. + global Tester instance doctest.master. Methods of doctest.master + can be called directly too, if you want to do something unusual. Passing report=0 to testmod is especially useful then, to delay displaying a summary. Invoke doctest.master.summarize(verbose) when you're done fiddling. @@ -1018,20 +1086,13 @@ def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None, global master - if m is None: - import sys - # DWA - m will still be None if this wasn't invoked from the command - # line, in which case the following TypeError is about as good an error - # as we should expect - m = sys.modules.get('__main__') - - if type(m) is not _ModuleType: + if not _ismodule(m): raise TypeError("testmod: module required; " + `m`) if name is None: name = m.__name__ tester = Tester(m, globs=globs, verbose=verbose, isprivate=isprivate) failures, tries = tester.rundoc(m, name) - f, t = tester.rundict(m.__dict__, name) + f, t = tester.rundict(m.__dict__, name, m) failures = failures + f tries = tries + t if hasattr(m, "__test__"): diff --git a/test/object.cpp b/test/object.cpp index f3a31011..9fb847d1 100755 --- a/test/object.cpp +++ b/test/object.cpp @@ -25,27 +25,27 @@ object number() object obj_getattr(object x, char const* name) { - return x._(name); + return x.attr(name); } object obj_const_getattr(object const& x, char const* name) { - return x._(name); + return x.attr(name); } void obj_setattr(object x, char const* name, object value) { - x._(name) = value; + x.attr(name) = value; } void obj_setattr42(object x, char const* name) { - x._(name) = 42; + x.attr(name) = 42; } void obj_moveattr(object& x, char const* src, char const* dst) { - x._(dst) = x._(src); + x.attr(dst) = x.attr(src); } object obj_getitem(object x, object key) @@ -95,12 +95,12 @@ bool test_not(object y) bool test_attr(object y, char* name) { - return y._(name); + return y.attr(name); } bool test_not_attr(object y, char* name) { - return !y._(name); + return !y.attr(name); } bool test_item(object y, object key) @@ -113,20 +113,161 @@ bool test_not_item(object y, object key) return !y[key]; } +bool check_binary_operators() +{ + int y; + + object x(3); + +#define TEST_BINARY(op) \ + for (y = 1; y < 6; ++y) \ + { \ + if ((x op y) != (3 op y)) \ + return false; \ + } \ + for (y = 1; y < 6; ++y) \ + { \ + if ((y op x) != (y op 3)) \ + return false; \ + } \ + for (y = 1; y < 6; ++y) \ + { \ + object oy(y); \ + if ((oy op x) != (oy op 3)) \ + return false; \ + } + TEST_BINARY(>) + TEST_BINARY(>=) + TEST_BINARY(<) + TEST_BINARY(<=) + TEST_BINARY(==) + TEST_BINARY(!=) + + TEST_BINARY(+) + TEST_BINARY(-) + TEST_BINARY(*) + TEST_BINARY(/) + TEST_BINARY(%) + TEST_BINARY(<<) + TEST_BINARY(>>) + TEST_BINARY(&) + TEST_BINARY(^) + TEST_BINARY(|) + return true; +} + +bool check_inplace(object l, object o) +{ + int y; +#define TEST_INPLACE(op) \ + for (y = 1; y < 6; ++y) \ + { \ + object x(666); \ + x op##= y; \ + if (x != (666 op y)) \ + return false; \ + } \ + for (y = 1; y < 6; ++y) \ + { \ + object x(666); \ + x op##= object(y); \ + if (!(x == (666 op y))) \ + return false; \ + } + TEST_INPLACE(+) + TEST_INPLACE(-) + TEST_INPLACE(*) + TEST_INPLACE(/) + TEST_INPLACE(%) + TEST_INPLACE(<<) + TEST_INPLACE(>>) + TEST_INPLACE(&) + TEST_INPLACE(^) + TEST_INPLACE(|) + + l += l; + for (y = 0; y < 6; ++y) + { + if (l[y] != y % 3) + return false; + } + +#define TEST_ITEM_INPLACE(index, op, n, r1, r2) \ + l[index] op##= n; \ + if (l[index] != r1) \ + return false; \ + l[index] op##= object(n); \ + if (!(l[index] == r2)) \ + return false; + + TEST_ITEM_INPLACE(0,+,7,7,14) + TEST_ITEM_INPLACE(1,-,2,-1,-3) + TEST_ITEM_INPLACE(2,*,3,6,18) + TEST_ITEM_INPLACE(2,/,2,9,4) + TEST_ITEM_INPLACE(0,%,4,2,2) + l[0] += 1; + TEST_ITEM_INPLACE(0,<<,2,12,48) + TEST_ITEM_INPLACE(0,>>,1,24,12) + l[4] = 15; + TEST_ITEM_INPLACE(4,&,(16+4+1),5,5) + TEST_ITEM_INPLACE(0,^,1,13,12) + TEST_ITEM_INPLACE(0,|,1,13,13) + + o.attr("x0") = 0; + o.attr("x1") = 1; + o.attr("x2") = 2; + o.attr("x3") = 0; + o.attr("x4") = 1; + +#define TEST_ATTR_INPLACE(index, op, n, r1, r2) \ + o.attr("x" #index) op##= n; \ + if (o.attr("x" #index) != r1) \ + return false; \ + o.attr("x" #index) op##= object(n); \ + if (o.attr("x" #index) != r2) \ + return false; + + TEST_ATTR_INPLACE(0,+,7,7,14) + TEST_ATTR_INPLACE(1,-,2,-1,-3) + TEST_ATTR_INPLACE(2,*,3,6,18) + TEST_ATTR_INPLACE(2,/,2,9,4) + TEST_ATTR_INPLACE(0,%,4,2,2) + o.attr("x0") += 1; + TEST_ATTR_INPLACE(0,<<,2,12,48) + TEST_ATTR_INPLACE(0,>>,1,24,12) + o.attr("x4") = 15; + TEST_ATTR_INPLACE(4,&,(16+4+1),5,5) + TEST_ATTR_INPLACE(0,^,1,13,12) + TEST_ATTR_INPLACE(0,|,1,13,13) + + if (l[0] != o.attr("x0")) + return false; + if (l[1] != o.attr("x1")) + return false; + if (l[2] != o.attr("x2")) + return false; + if (l[3] != o.attr("x3")) + return false; + if (l[4] != o.attr("x4")) + return false; + + return true; +} + BOOST_PYTHON_MODULE_INIT(object_ext) { module("object_ext") .def("call_object_3", call_object_3) .def("message", message) .def("number", number) - + .def("obj_getattr", obj_getattr) .def("obj_const_getattr", obj_const_getattr) .def("obj_setattr", obj_setattr) .def("obj_setattr42", obj_setattr42) .def("obj_moveattr", obj_moveattr) - + .def("obj_getitem", obj_getitem) .def("obj_getitem3", obj_getitem) .def("obj_const_getitem", obj_const_getitem) @@ -134,7 +275,7 @@ BOOST_PYTHON_MODULE_INIT(object_ext) .def("obj_setitem42", obj_setitem42) .def("obj_moveitem", obj_moveitem) .def("obj_moveitem2", obj_moveitem2) - + .def("test", test) .def("test_not", test_not) @@ -143,6 +284,9 @@ BOOST_PYTHON_MODULE_INIT(object_ext) .def("test_item", test_item) .def("test_not_item", test_not_item) + + .def("check_binary_operators", check_binary_operators) + .def("check_inplace", check_inplace) ; } diff --git a/test/object.py b/test/object.py index 68e46fe3..e3cb9dc1 100644 --- a/test/object.py +++ b/test/object.py @@ -79,6 +79,14 @@ 0 >>> test_not_item(d, 'foo') 1 + + Operators + + +>>> assert check_binary_operators() +>>> class X: pass +... +>>> assert check_inplace(range(3), X()) ''' def run(args = None): From 8aba4862951ac4533bca2302019b5aec9cde1880 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 19 Jun 2002 02:12:14 +0000 Subject: [PATCH 0527/1042] Fix tru64cxx problems, remove operator*/-> from object [SVN r14173] --- include/boost/python/object_core.hpp | 50 +++++++------------ include/boost/python/object_items.hpp | 16 ++++++ include/boost/python/object_operators.hpp | 11 ++-- .../boost/python/preprocessed/object_call.hpp | 30 +++++------ src/object_operators.cpp | 4 +- src/object_protocol.cpp | 8 +-- 6 files changed, 60 insertions(+), 59 deletions(-) diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index e243b1ee..f3aa3907 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -32,23 +32,14 @@ namespace api typedef proxy const_object_item; typedef proxy object_item; - // A way to turn a conrete type T into a type dependent on U. This - // keeps conforming compilers from complaining about returning an - // incomplete T from a template member function (which must be - // defined in the class body to keep MSVC happy). - template - struct dependent - { - typedef T type; - }; - class object { # if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 typedef object const& self_cref; # else typedef object self_cref; -# endif +# endif + public: # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING // copy constructor without NULL checking, for efficiency @@ -78,7 +69,6 @@ namespace api ) ) { - } // Throw error_already_set() if the handle is null. @@ -116,30 +106,29 @@ namespace api object_item operator[](self_cref); template -# if BOOST_MSVC != 1300 - typename dependent::type -# else const_object_item -# endif operator[](T const& key) const +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + ; +# else { return (*this)[object(key)]; } +# endif template -# if BOOST_MSVC != 1300 - typename dependent::type -# else object_item -# endif operator[](T const& key) +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + ; +# else { return (*this)[object(key)]; } +# endif // Underlying object access - PyObject* operator->() const; - PyObject& operator*() const; + handle<> const& ptr() const; public: // implementation detail -- for internal use only object(null_ok >*); @@ -218,7 +207,7 @@ inline object::object(handle<> const& x) # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING // copy constructor without NULL checking, for efficiency inline object::object(object const& rhs) - : m_ptr(python::allow_null(python::borrowed(&*rhs))) + : m_ptr(python::allow_null(python::borrowed(rhs.m_ptr.get()))) {} # endif @@ -238,24 +227,19 @@ inline object::object(object::new_pyobject_reference* p) : m_ptr((PyObject*)p) {} -inline PyObject* object::operator->() const +inline handle<> const& object::ptr() const { - return m_ptr.operator->(); -} - -inline PyObject& object::operator*() const -{ - return *m_ptr; + return m_ptr; } inline object::operator object::bool_type() const { - return PyObject_IsTrue(&**this) ? &object::m_ptr : 0; + return PyObject_IsTrue(m_ptr.get()) ? &object::m_ptr : 0; } inline bool object::operator!() const { - return !PyObject_IsTrue(&**this); + return !PyObject_IsTrue(m_ptr.get()); } // @@ -302,7 +286,7 @@ namespace converter inline PyObject* get_managed_object(object const& x) { - return &*x; + return x.ptr().get(); } } diff --git a/include/boost/python/object_items.hpp b/include/boost/python/object_items.hpp index a294dff6..6c69ad58 100755 --- a/include/boost/python/object_items.hpp +++ b/include/boost/python/object_items.hpp @@ -35,6 +35,22 @@ inline const_object_item object::operator[](object::self_cref key) const return const_object_item(*this, key); } +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 +template +inline const_object_item +object::operator[](T const& key) const +{ + return (*this)[object(key)]; +} + +template +inline object_item +object::operator[](T const& key) +{ + return (*this)[object(key)]; +} +# endif + inline object const_item_policies::get(object const& target, object const& key) { diff --git a/include/boost/python/object_operators.hpp b/include/boost/python/object_operators.hpp index c339c906..b911905c 100644 --- a/include/boost/python/object_operators.hpp +++ b/include/boost/python/object_operators.hpp @@ -10,11 +10,12 @@ namespace boost { namespace python { namespace api { -# define BOOST_PYTHON_COMPARE_OP(op, opid) \ -template \ -bool operator op(L const& l, R const& r) \ -{ \ - return PyObject_RichCompareBool(&*object(l), &*object(r), opid); \ +# define BOOST_PYTHON_COMPARE_OP(op, opid) \ +template \ +bool operator op(L const& l, R const& r) \ +{ \ + return PyObject_RichCompareBool( \ + object(l).ptr().get(), object(r).ptr().get(), opid); \ } BOOST_PYTHON_COMPARE_OP(>, Py_GT) BOOST_PYTHON_COMPARE_OP(>=, Py_GE) diff --git a/include/boost/python/preprocessed/object_call.hpp b/include/boost/python/preprocessed/object_call.hpp index e3d605cb..7ac34373 100755 --- a/include/boost/python/preprocessed/object_call.hpp +++ b/include/boost/python/preprocessed/object_call.hpp @@ -10,91 +10,91 @@ template object operator()(A0 const&a0)const { - return call(&**this,a0); + return call(this->ptr().get(),a0); } template object operator()(A0 const&a0,A1 const&a1)const { - return call(&**this,a0,a1); + return call(this->ptr().get(),a0,a1); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2)const { - return call(&**this,a0,a1,a2); + return call(this->ptr().get(),a0,a1,a2); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3)const { - return call(&**this,a0,a1,a2,a3); + return call(this->ptr().get(),a0,a1,a2,a3); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4)const { - return call(&**this,a0,a1,a2,a3,a4); + return call(this->ptr().get(),a0,a1,a2,a3,a4); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5)const { - return call(&**this,a0,a1,a2,a3,a4,a5); + return call(this->ptr().get(),a0,a1,a2,a3,a4,a5); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6)const { - return call(&**this,a0,a1,a2,a3,a4,a5,a6); + return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7)const { - return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7); + return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8)const { - return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8); + return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9)const { - return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9); + return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10)const { - return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); + return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11)const { - return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11); + return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12)const { - return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12); + return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13)const { - return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13); + return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13); } template object operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14)const { - return call(&**this,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14); + return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14); } diff --git a/src/object_operators.cpp b/src/object_operators.cpp index ed824ab6..0aa0f1b7 100644 --- a/src/object_operators.cpp +++ b/src/object_operators.cpp @@ -13,7 +13,7 @@ BOOST_PYTHON_DECL object operator op(object const& l, object const& r) \ { \ return object( \ (object::new_pyobject_reference*) \ - PyNumber_##name(&*l, &*r)); \ + PyNumber_##name(l.ptr().get(), r.ptr().get())); \ } BOOST_PYTHON_BINARY_OPERATOR(+, Add) @@ -33,7 +33,7 @@ BOOST_PYTHON_DECL object& operator op##=(object& l, object const& r) \ { \ return l = object( \ (object::new_pyobject_reference*) \ - PyNumber_InPlace##name(&*l, &*r)); \ + PyNumber_InPlace##name(l.ptr().get(), r.ptr().get())); \ } BOOST_PYTHON_INPLACE_OPERATOR(+, Add) diff --git a/src/object_protocol.cpp b/src/object_protocol.cpp index 8f2548ab..3e9baa35 100755 --- a/src/object_protocol.cpp +++ b/src/object_protocol.cpp @@ -12,23 +12,23 @@ namespace boost { namespace python { namespace api { BOOST_PYTHON_DECL object getattr(object const& target, object const& key) { - return object((object::new_pyobject_reference*)PyObject_GetAttr(&*target, &*key)); + return object((object::new_pyobject_reference*)PyObject_GetAttr(target.ptr().get(), key.ptr().get())); } BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value) { - if (PyObject_SetAttr(&*target, &*key, &*value) == -1) + if (PyObject_SetAttr(target.ptr().get(), key.ptr().get(), value.ptr().get()) == -1) throw_error_already_set(); } BOOST_PYTHON_DECL object getitem(object const& target, object const& key) { - return object((object::new_pyobject_reference*)PyObject_GetItem(&*target, &*key)); + return object((object::new_pyobject_reference*)PyObject_GetItem(target.ptr().get(), key.ptr().get())); } BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value) { - if (PyObject_SetItem(&*target, &*key, &*value) == -1) + if (PyObject_SetItem(target.ptr().get(), key.ptr().get(), value.ptr().get()) == -1) throw_error_already_set(); } From e2d75c0b7613388c11acb8c8a5107c12bf91ca24 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 19 Jun 2002 02:45:39 +0000 Subject: [PATCH 0528/1042] Fixed is_borrowed_ptr [SVN r14174] --- include/boost/python/detail/borrowed_ptr.hpp | 37 +++++++++++++++++--- test/borrowed.cpp | 1 + 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/include/boost/python/detail/borrowed_ptr.hpp b/include/boost/python/detail/borrowed_ptr.hpp index 055c8b7c..527dfc46 100755 --- a/include/boost/python/detail/borrowed_ptr.hpp +++ b/include/boost/python/detail/borrowed_ptr.hpp @@ -7,7 +7,10 @@ // to its suitability for any purpose. # include -#include +# include +# include +# include +# include namespace boost { namespace python { namespace detail { @@ -23,6 +26,7 @@ struct is_borrowed_ptr BOOST_STATIC_CONSTANT(bool, value = false); }; +# if !defined(__MWERKS__) || __MWERKS__ > 0x3000 template struct is_borrowed_ptr*> { @@ -46,16 +50,41 @@ struct is_borrowed_ptr const volatile*> { BOOST_STATIC_CONSTANT(bool, value = true); }; +# else +template +struct is_borrowed +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; +template +struct is_borrowed > +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; +template +struct is_borrowed_ptr + : is_borrowed::type> +{ +}; +# endif # else // no partial specialization typedef char (&yes_borrowed_ptr_t)[1]; typedef char (&no_borrowed_ptr_t)[2]; - + no_borrowed_ptr_t is_borrowed_ptr_test(...); +template +typename mpl::select_type< + is_pointer::value + , T + , int + >::type +is_borrowed_ptr_test1(boost::type); + template -yes_borrowed_ptr_t is_borrowed_ptr_test(boost::type< borrowed* >); +yes_borrowed_ptr_t is_borrowed_ptr_test(borrowed const volatile*); template class is_borrowed_ptr @@ -63,7 +92,7 @@ class is_borrowed_ptr public: BOOST_STATIC_CONSTANT( bool, value = ( - sizeof(detail::is_borrowed_ptr_test(boost::type())) + sizeof(detail::is_borrowed_ptr_test(is_borrowed_ptr_test1(boost::type()))) == sizeof(detail::yes_borrowed_ptr_t))); }; diff --git a/test/borrowed.cpp b/test/borrowed.cpp index b46dafb0..0f8d3112 100755 --- a/test/borrowed.cpp +++ b/test/borrowed.cpp @@ -3,6 +3,7 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. +#include #include #include From 913d2984ce2898a65ac10123979d593895b8765c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 19 Jun 2002 16:34:26 +0000 Subject: [PATCH 0529/1042] Fixed object proxy chaining for everything bug GCC 2.9x [SVN r14183] --- include/boost/python/object_attributes.hpp | 10 +- include/boost/python/object_core.hpp | 148 ++++++++++-------- include/boost/python/object_items.hpp | 18 ++- include/boost/python/object_operators.hpp | 24 +++ .../boost/python/preprocessed/object_call.hpp | 90 +++++++---- include/boost/python/proxy.hpp | 23 +-- test/object.cpp | 8 + 7 files changed, 194 insertions(+), 127 deletions(-) diff --git a/include/boost/python/object_attributes.hpp b/include/boost/python/object_attributes.hpp index f75f76d9..1a97ae56 100755 --- a/include/boost/python/object_attributes.hpp +++ b/include/boost/python/object_attributes.hpp @@ -25,14 +25,16 @@ struct attribute_policies : const_attribute_policies // // implementation // -inline object_attribute object::attr(char const* name) +template +inline object_attribute object_operators::attr(char const* name) { - return object_attribute(*this, object(name)); + return object_attribute(*static_cast(this), object(name)); } -inline const_object_attribute object::attr(char const* name) const +template +inline const_object_attribute object_operators::attr(char const* name) const { - return const_object_attribute(*this, object(name)); + return const_object_attribute(*static_cast(this), object(name)); } diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index f3aa3907..b0463a00 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -9,6 +9,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -32,7 +33,21 @@ namespace api typedef proxy const_object_item; typedef proxy object_item; - class object + // A way to turn a conrete type T into a type dependent on U. This + // keeps conforming compilers from complaining about returning an + // incomplete T from a template member function (which must be + // defined in the class body to keep MSVC happy). + template + struct dependent + { + typedef T type; + }; + + class object; + typedef handle<> const& (object::*bool_type)() const; + + template + class object_operators { # if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 typedef object const& self_cref; @@ -40,6 +55,70 @@ namespace api typedef object self_cref; # endif + public: + // Attribute access via x.attr("attribute_name") + const_object_attribute attr(char const*) const; + object_attribute attr(char const*); + + object operator()() const; + +# ifndef BOOST_PYTHON_GENERATE_CODE +# include +# endif + +# define BOOST_PYTHON_OBJECT_CALL(nargs,ignored) \ + template \ + typename dependent::type \ + operator()(BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a))) const \ + { \ + typedef typename dependent::type obj; \ + obj const& f = *static_cast(this); \ + return call(f.ptr().get(), BOOST_PP_ENUM_PARAMS(nargs, a)); \ + } + + BOOST_PP_REPEAT_FROM_TO_2ND( + BOOST_PP_MAX(1, BOOST_PYTHON_ARITY_START), BOOST_PYTHON_ARITY_FINISH + , BOOST_PYTHON_OBJECT_CALL, ignored) + + // truth value testing + operator bool_type() const; + bool operator!() const; // needed for vc6 + + // item access + const_object_item operator[](self_cref) const; + object_item operator[](self_cref); + + template + const_object_item + operator[](T const& key) const +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + ; +# else + { + return (*this)[object(key)]; + } +# endif + + template + object_item + operator[](T const& key) +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + ; +# else + { + return (*this)[object(key)]; + } +# endif + +# if BOOST_MSVC == 1200 + // For whatever reason, VC6 generates incorrect code unless we + // define this + object_operators& operator=(object_operators const&) { return *this; } +# endif + }; + + class object : public object_operators + { public: # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING // copy constructor without NULL checking, for efficiency @@ -73,60 +152,7 @@ namespace api // Throw error_already_set() if the handle is null. explicit object(handle<> const&); - - // Attribute access via x.attr("attribute_name") - const_object_attribute attr(char const*) const; - object_attribute attr(char const*); - - object operator()() const - { - return object(call >(m_ptr.get())); - } - -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif - -# define BOOST_PYTHON_OBJECT_CALL(nargs,ignored) \ - template \ - object operator()(BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a))) const \ - { \ - return object(call >(&**this, BOOST_PP_ENUM_PARAMS(nargs, a))); \ - } - - BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_OBJECT_CALL, ignored) - - // truth value testing - typedef handle<> (object::*bool_type); - operator bool_type() const; - bool operator!() const; // needed for vc6 - - // item access - const_object_item operator[](self_cref) const; - object_item operator[](self_cref); - - template - const_object_item - operator[](T const& key) const -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - ; -# else - { - return (*this)[object(key)]; - } -# endif - - template - object_item - operator[](T const& key) -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - ; -# else - { - return (*this)[object(key)]; - } -# endif - + // Underlying object access handle<> const& ptr() const; @@ -136,7 +162,7 @@ namespace api object(detail::borrowed*); class new_pyobject_reference; object(new_pyobject_reference*); - + private: handle<> m_ptr; }; @@ -232,16 +258,6 @@ inline handle<> const& object::ptr() const return m_ptr; } -inline object::operator object::bool_type() const -{ - return PyObject_IsTrue(m_ptr.get()) ? &object::m_ptr : 0; -} - -inline bool object::operator!() const -{ - return !PyObject_IsTrue(m_ptr.get()); -} - // // Converter speciaization implementations // diff --git a/include/boost/python/object_items.hpp b/include/boost/python/object_items.hpp index 6c69ad58..6424e2a9 100755 --- a/include/boost/python/object_items.hpp +++ b/include/boost/python/object_items.hpp @@ -25,27 +25,33 @@ struct item_policies : const_item_policies // // implementation // -inline object_item object::operator[](object::self_cref key) +template +inline object_item +object_operators::operator[](self_cref key) { - return object_item(*this, key); + return object_item(*static_cast(this), key); } -inline const_object_item object::operator[](object::self_cref key) const +template +inline const_object_item +object_operators::operator[](self_cref key) const { - return const_object_item(*this, key); + return const_object_item(*static_cast(this), key); } # if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 +template template inline const_object_item -object::operator[](T const& key) const +object_operators::operator[](T const& key) const { return (*this)[object(key)]; } +template template inline object_item -object::operator[](T const& key) +object_operators::operator[](T const& key) { return (*this)[object(key)]; } diff --git a/include/boost/python/object_operators.hpp b/include/boost/python/object_operators.hpp index b911905c..266018a6 100644 --- a/include/boost/python/object_operators.hpp +++ b/include/boost/python/object_operators.hpp @@ -10,6 +10,30 @@ namespace boost { namespace python { namespace api { +template +object object_operators::operator()() const +{ + object const& f = *static_cast(this); + return call(f.ptr().get()); +} + + +template +inline +object_operators::operator bool_type() const +{ + object const& x = *static_cast(this); + return PyObject_IsTrue(x.ptr().get()) ? &object::ptr : 0; +} + +template +inline bool +object_operators::operator!() const +{ + object const& x = *static_cast(this); + return !PyObject_IsTrue(x.ptr().get()); +} + # define BOOST_PYTHON_COMPARE_OP(op, opid) \ template \ bool operator op(L const& l, R const& r) \ diff --git a/include/boost/python/preprocessed/object_call.hpp b/include/boost/python/preprocessed/object_call.hpp index 7ac34373..3c9831d4 100755 --- a/include/boost/python/preprocessed/object_call.hpp +++ b/include/boost/python/preprocessed/object_call.hpp @@ -7,94 +7,124 @@ # define OBJECT_CALL_DWA2002612_HPP template -object +typename dependent::type operator()(A0 const&a0)const { - return call(this->ptr().get(),a0); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1)const { - return call(this->ptr().get(),a0,a1); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2)const { - return call(this->ptr().get(),a0,a1,a2); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3)const { - return call(this->ptr().get(),a0,a1,a2,a3); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4)const { - return call(this->ptr().get(),a0,a1,a2,a3,a4); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3,a4); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5)const { - return call(this->ptr().get(),a0,a1,a2,a3,a4,a5); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3,a4,a5); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6)const { - return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7)const { - return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8)const { - return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9)const { - return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10)const { - return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11)const { - return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12)const { - return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13)const { - return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13); } template -object +typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14)const { - return call(this->ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14); + typedef typename dependent::type obj; + obj const&f=*static_cast(this); + return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14); } diff --git a/include/boost/python/proxy.hpp b/include/boost/python/proxy.hpp index d7747c0d..ff726cc0 100755 --- a/include/boost/python/proxy.hpp +++ b/include/boost/python/proxy.hpp @@ -11,7 +11,7 @@ namespace boost { namespace python { namespace api { template -class proxy +class proxy : public object_operators > { # if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 typedef proxy const& copy_ctor_self; @@ -19,6 +19,7 @@ class proxy typedef proxy copy_ctor_self; # endif public: + proxy(object const& target, object const& key); operator object() const; // to support a[b] = c[d] @@ -30,14 +31,6 @@ class proxy Policies::set(m_target, m_key, python::object(rhs)); return *this; } - - // truth value testing - operator object::bool_type() const; - bool operator!() const; // needed for vc6 - - private: - friend class object; - proxy(object const& target, object const& key); private: object m_target; @@ -85,18 +78,6 @@ BOOST_PYTHON_PROXY_INPLACE(^=) BOOST_PYTHON_PROXY_INPLACE(|=) # undef BOOST_PYTHON_PROXY_INPLACE -template -inline proxy::operator object::bool_type() const -{ - return python::object(*this); -} - -template -inline bool proxy::operator!() const -{ - return !python::object(*this); -} - }}} // namespace boost::python::api #endif // PROXY_DWA2002615_HPP diff --git a/test/object.cpp b/test/object.cpp index 9fb847d1..e2940e77 100755 --- a/test/object.cpp +++ b/test/object.cpp @@ -251,6 +251,14 @@ bool check_inplace(object l, object o) if (l[4] != o.attr("x4")) return false; + // set item 5 to be a list, by calling l.__class__ + l[5] = l.attr("__class__")(); + // append an element + l[5].attr("append")(2); + // Check its value + if (l[5][0] != 2) + return false; + return true; } From d07454659aeda4872ed3c6137610a2c3b357018f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 19 Jun 2002 19:18:21 +0000 Subject: [PATCH 0530/1042] Work around some gcc-2.95.x bugs Optimize code slightly by eliminating temporaries [SVN r14185] --- include/boost/python/object_attributes.hpp | 6 +- include/boost/python/object_core.hpp | 16 ++--- include/boost/python/object_items.hpp | 6 +- .../boost/python/preprocessed/object_call.hpp | 61 +++++++++---------- include/boost/python/proxy.hpp | 3 +- 5 files changed, 48 insertions(+), 44 deletions(-) diff --git a/include/boost/python/object_attributes.hpp b/include/boost/python/object_attributes.hpp index 1a97ae56..4c8458a4 100755 --- a/include/boost/python/object_attributes.hpp +++ b/include/boost/python/object_attributes.hpp @@ -28,13 +28,15 @@ struct attribute_policies : const_attribute_policies template inline object_attribute object_operators::attr(char const* name) { - return object_attribute(*static_cast(this), object(name)); + object const& x = *static_cast(this); + return object_attribute(x, object(name)); } template inline const_object_attribute object_operators::attr(char const* name) const { - return const_object_attribute(*static_cast(this), object(name)); + object const& x = *static_cast(this); + return const_object_attribute(x, object(name)); } diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index b0463a00..762bdf90 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -66,14 +66,14 @@ namespace api # include # endif -# define BOOST_PYTHON_OBJECT_CALL(nargs,ignored) \ - template \ - typename dependent::type \ - operator()(BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a))) const \ - { \ - typedef typename dependent::type obj; \ - obj const& f = *static_cast(this); \ - return call(f.ptr().get(), BOOST_PP_ENUM_PARAMS(nargs, a)); \ +# define BOOST_PYTHON_OBJECT_CALL(nargs,ignored) \ + template \ + typename dependent::type \ + operator()(BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a))) const \ + { \ + typedef typename dependent::type obj; \ + U const& self = *static_cast(this); \ + return call(converter::get_managed_object(self), BOOST_PP_ENUM_PARAMS(nargs, a)); \ } BOOST_PP_REPEAT_FROM_TO_2ND( diff --git a/include/boost/python/object_items.hpp b/include/boost/python/object_items.hpp index 6424e2a9..a91ebcd8 100755 --- a/include/boost/python/object_items.hpp +++ b/include/boost/python/object_items.hpp @@ -29,14 +29,16 @@ template inline object_item object_operators::operator[](self_cref key) { - return object_item(*static_cast(this), key); + object const& x = *static_cast(this); + return object_item(x, key); } template inline const_object_item object_operators::operator[](self_cref key) const { - return const_object_item(*static_cast(this), key); + object const& x = *static_cast(this); + return const_object_item(x, key); } # if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 diff --git a/include/boost/python/preprocessed/object_call.hpp b/include/boost/python/preprocessed/object_call.hpp index 3c9831d4..ec3ba43e 100755 --- a/include/boost/python/preprocessed/object_call.hpp +++ b/include/boost/python/preprocessed/object_call.hpp @@ -11,121 +11,120 @@ typename dependent::type operator()(A0 const&a0)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0); } template typename dependent::type operator()(A0 const&a0,A1 const&a1)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3,a4); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3,a4); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3,a4,a5); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13); } template typename dependent::type operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14)const { typedef typename dependent::type obj; - obj const&f=*static_cast(this); - return call(f.ptr().get(),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14); + U const&self=*static_cast(this); + return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14); } - #endif // OBJECT_CALL_DWA2002612_HPP diff --git a/include/boost/python/proxy.hpp b/include/boost/python/proxy.hpp index ff726cc0..d17f5871 100755 --- a/include/boost/python/proxy.hpp +++ b/include/boost/python/proxy.hpp @@ -28,7 +28,8 @@ class proxy : public object_operators > template inline proxy const& operator=(T const& rhs) const { - Policies::set(m_target, m_key, python::object(rhs)); + python::object const& x(rhs); + Policies::set(m_target, m_key, x); return *this; } From d250057a7c95ea224fa10caf94932ac645d47dbc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 19 Jun 2002 22:58:58 +0000 Subject: [PATCH 0531/1042] GCC 3 workaround [SVN r14188] --- include/boost/python/proxy.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/boost/python/proxy.hpp b/include/boost/python/proxy.hpp index d17f5871..8491f722 100755 --- a/include/boost/python/proxy.hpp +++ b/include/boost/python/proxy.hpp @@ -28,7 +28,11 @@ class proxy : public object_operators > template inline proxy const& operator=(T const& rhs) const { +# if __GNUC__ != 3 python::object const& x(rhs); +# else + python::object x(rhs); +# endif Policies::set(m_target, m_key, x); return *this; } From 7bb39ae5416e677417ab558289c1f50a3b9e5451 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 19 Jun 2002 23:00:43 +0000 Subject: [PATCH 0532/1042] IRIX CC (EDG 238) fix/workaround. [SVN r14189] --- include/boost/python/detail/convertible.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/convertible.hpp b/include/boost/python/detail/convertible.hpp index f767ebfd..4ab58d94 100755 --- a/include/boost/python/detail/convertible.hpp +++ b/include/boost/python/detail/convertible.hpp @@ -21,7 +21,7 @@ typedef int* no_convertible; template struct convertible { -# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 241 +# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 241 || __EDG_VERSION__ == 238 static inline no_convertible check(...) { return 0; } static inline yes_convertible check(Target) { return 0; } # else From bf84024d6bdca411ee234706a0f9bddc019576f9 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 20 Jun 2002 00:19:59 +0000 Subject: [PATCH 0533/1042] maybe slower but certainly conforming [SVN r14190] --- include/boost/python/proxy.hpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/include/boost/python/proxy.hpp b/include/boost/python/proxy.hpp index 8491f722..b74d155c 100755 --- a/include/boost/python/proxy.hpp +++ b/include/boost/python/proxy.hpp @@ -28,12 +28,7 @@ class proxy : public object_operators > template inline proxy const& operator=(T const& rhs) const { -# if __GNUC__ != 3 - python::object const& x(rhs); -# else - python::object x(rhs); -# endif - Policies::set(m_target, m_key, x); + Policies::set(m_target, m_key, object(rhs)); return *this; } From 220734ccac0790808bb5490d77531627540ff233 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 20 Jun 2002 02:53:25 +0000 Subject: [PATCH 0534/1042] workaround for IRIX CC (EDG238) bug; move to namespace boost::python::api [SVN r14193] --- include/boost/python/object.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/boost/python/object.hpp b/include/boost/python/object.hpp index 5186669e..c7a25b66 100755 --- a/include/boost/python/object.hpp +++ b/include/boost/python/object.hpp @@ -11,11 +11,14 @@ # include # include -namespace boost { namespace python { +namespace boost { namespace python { namespace api { class string; -class type; +class type_object; -}} // namespace boost::python +template +type_object type(T const&); + +}}} // namespace boost::python::api #endif // OBJECT_DWA2002612_HPP From 693b21188c874d5a39a53bf1d52f3945d62eae50 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 20 Jun 2002 10:33:34 +0000 Subject: [PATCH 0535/1042] previous patch breaks Visual C++ 6 & 7 compilations. Roll-back to a state that allows others to use CVS while we do more experiments. [SVN r14208] --- include/boost/python/object.hpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/include/boost/python/object.hpp b/include/boost/python/object.hpp index c7a25b66..30b007c4 100755 --- a/include/boost/python/object.hpp +++ b/include/boost/python/object.hpp @@ -11,14 +11,11 @@ # include # include -namespace boost { namespace python { namespace api { +namespace boost { namespace python { + + class type_; // XXX temporary work-around + class string; -class string; -class type_object; - -template -type_object type(T const&); - -}}} // namespace boost::python::api +}} // namespace boost::python #endif // OBJECT_DWA2002612_HPP From 55dff4d512911c4a738d786c69a475d20fc12225 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 20 Jun 2002 21:47:26 +0000 Subject: [PATCH 0536/1042] slicing [SVN r14219] --- .../boost/python/converter/object_manager.hpp | 3 +- include/boost/python/object.hpp | 1 + include/boost/python/object_attributes.hpp | 45 ++---- include/boost/python/object_core.hpp | 141 ++++++++++++++++-- include/boost/python/object_items.hpp | 36 ++--- include/boost/python/object_protocol.hpp | 33 +++- include/boost/python/object_protocol_core.hpp | 22 +++ include/boost/python/object_slices.hpp | 124 +++++++++++++++ include/boost/python/proxy.hpp | 26 +++- include/boost/python/slice_nil.hpp | 41 +++++ src/object_protocol.cpp | 133 +++++++++++++++++ test/object.cpp | 17 +++ test/object.py | 5 + 13 files changed, 549 insertions(+), 78 deletions(-) create mode 100644 include/boost/python/object_slices.hpp create mode 100644 include/boost/python/slice_nil.hpp diff --git a/include/boost/python/converter/object_manager.hpp b/include/boost/python/converter/object_manager.hpp index 6ffe6b1e..23e70a1e 100755 --- a/include/boost/python/converter/object_manager.hpp +++ b/include/boost/python/converter/object_manager.hpp @@ -21,8 +21,9 @@ class object; namespace boost { namespace python { namespace converter { template -class is_object_manager +struct is_object_manager { + private: BOOST_STATIC_CONSTANT(bool, hdl = is_handle::value); BOOST_STATIC_CONSTANT(bool, borrowed = python::detail::is_borrowed_ptr::value); public: diff --git a/include/boost/python/object.hpp b/include/boost/python/object.hpp index 30b007c4..b2e0c6b3 100755 --- a/include/boost/python/object.hpp +++ b/include/boost/python/object.hpp @@ -9,6 +9,7 @@ # include # include # include +# include # include namespace boost { namespace python { diff --git a/include/boost/python/object_attributes.hpp b/include/boost/python/object_attributes.hpp index 4c8458a4..c10608cb 100755 --- a/include/boost/python/object_attributes.hpp +++ b/include/boost/python/object_attributes.hpp @@ -14,12 +14,14 @@ namespace boost { namespace python { namespace api { struct const_attribute_policies { - static object get(object const& target, object const& key); + typedef char const* key_type; + static object get(object const& target, char const* key); }; struct attribute_policies : const_attribute_policies { - static object const& set(object const& target, object const& key, object const& value); + static object const& set(object const& target, char const* key, object const& value); + static void del(object const&target, char const* key); }; // @@ -28,55 +30,38 @@ struct attribute_policies : const_attribute_policies template inline object_attribute object_operators::attr(char const* name) { - object const& x = *static_cast(this); - return object_attribute(x, object(name)); + object_cref x = *static_cast(this); + return object_attribute(x, name); } template inline const_object_attribute object_operators::attr(char const* name) const { - object const& x = *static_cast(this); - return const_object_attribute(x, object(name)); + object_cref x = *static_cast(this); + return const_object_attribute(x, name); } - -inline object const_attribute_policies::get(object const& target, object const& key) +inline object const_attribute_policies::get(object const& target, char const* key) { return python::getattr(target, key); } inline object const& attribute_policies::set( object const& target - , object const& key + , char const* key , object const& value) { python::setattr(target, key, value); return value; } -} // namespace api - -namespace converter +inline void attribute_policies::del( + object const& target + , char const* key) { - // These specializations are a lie; the proxies do not directly - // manage an object. What actually happens is that the implicit - // conversion to object takes hold and its conversion to_python is - // used. That's OK in part because the object temporary *is* - // actually managing the object during the duration of the - // conversion. - template <> - struct is_object_manager - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template <> - struct is_object_manager - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; + python::delattr(target, key); } -}} // namespace boost::python +}}} // namespace boost::python::api #endif // OBJECT_ATTRIBUTES_DWA2002615_HPP diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 762bdf90..b0b9813f 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -10,6 +10,8 @@ # include # include # include +# include +# include namespace boost { namespace python { @@ -27,12 +29,74 @@ namespace api struct attribute_policies; struct const_item_policies; struct item_policies; + struct const_slice_policies; + struct slice_policies; typedef proxy const_object_attribute; typedef proxy object_attribute; typedef proxy const_object_item; typedef proxy object_item; + typedef proxy const_object_slice; + typedef proxy object_slice; + // + // is_proxy -- proxy type detection + // +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct is_proxy + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; + template + struct is_proxy > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; +# else + typedef char yes_proxy; + typedef char (&no_proxy)[2]; + template + yes_proxy is_proxy_helper(boost::type >*); + no_proxy is_proxy_helper(...); + template + struct is_proxy + { + BOOST_STATIC_CONSTANT( + bool, value = (sizeof(is_proxy_helper((boost::type*)0)) + == sizeof(yes_proxy))); + }; +# endif + + // + // object_handle -- get the handle to construct the object with, + // based on whether T is a proxy or not + // + template + struct object_handle + { + template + static handle<> get(T const& x) + { + return handle<>( + python::borrowed( + python::allow_null( // null check is already done + converter::arg_to_python(x).get()) + ) + ); + } + }; + + template <> + struct object_handle + { + template + static handle<> get(proxy const& x) + { + return x.operator object().ptr(); + } + }; + // A way to turn a conrete type T into a type dependent on U. This // keeps conforming compilers from complaining about returning an // incomplete T from a template member function (which must be @@ -54,12 +118,19 @@ namespace api # else typedef object self_cref; # endif + + // there appears to be a codegen bug here. We prevent the early + // destruction of a temporary in CWPro8 by binding a named + // object instead. +# if __MWERKS__ != 0x3000 + typedef object const& object_cref; +# else + typedef object const object_cref; +# endif public: - // Attribute access via x.attr("attribute_name") - const_object_attribute attr(char const*) const; - object_attribute attr(char const*); - + // function call + // object operator()() const; # ifndef BOOST_PYTHON_GENERATE_CODE @@ -81,10 +152,17 @@ namespace api , BOOST_PYTHON_OBJECT_CALL, ignored) // truth value testing + // operator bool_type() const; bool operator!() const; // needed for vc6 + // Attribute access + // + const_object_attribute attr(char const*) const; + object_attribute attr(char const*); + // item access + // const_object_item operator[](self_cref) const; object_item operator[](self_cref); @@ -110,6 +188,47 @@ namespace api } # endif + // slicing + // + const_object_slice slice(self_cref, self_cref) const; + object_slice slice(self_cref, self_cref); + + const_object_slice slice(slice_nil, self_cref) const; + object_slice slice(slice_nil, self_cref); + + const_object_slice slice(self_cref, slice_nil) const; + object_slice slice(self_cref, slice_nil); + +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + template + const_object_slice + slice(T const& start, V const& end) const; + + template + object_slice + slice(T const& start, V const& end); + +# else + template + const_object_slice + slice(T const& start, V const& end) const + { + return this->slice( + slice_bound::type(start) + , slice_bound::type(end)); + } + + template + object_slice + slice(T const& start, V const& end) + { + return this->slice( + slice_bound::type(start) + , slice_bound::type(end)); + } +# endif + + # if BOOST_MSVC == 1200 // For whatever reason, VC6 generates incorrect code unless we // define this @@ -128,12 +247,7 @@ namespace api // explicit conversion from any C++ object to Python template explicit object(T const& x) - : m_ptr( - python::borrowed( - python::allow_null( // null check is already done - converter::arg_to_python(x).get()) - ) - ) + : m_ptr(object_handle::value>::get(x)) { } @@ -141,12 +255,7 @@ namespace api // literals. Otherwise, they get deduced as char[N]const& above // and conversion fails at runtime. explicit object(char const* x) - : m_ptr( - python::borrowed( - python::allow_null( // null check is already done - converter::arg_to_python(x).get()) - ) - ) + : m_ptr(object_handle<>::get(x)) { } diff --git a/include/boost/python/object_items.hpp b/include/boost/python/object_items.hpp index a91ebcd8..e07a9e50 100755 --- a/include/boost/python/object_items.hpp +++ b/include/boost/python/object_items.hpp @@ -14,12 +14,14 @@ namespace boost { namespace python { namespace api { struct const_item_policies { + typedef object key_type; static object get(object const& target, object const& key); }; struct item_policies : const_item_policies { static object const& set(object const& target, object const& key, object const& value); + static void del(object const& target, object const& key); }; // @@ -29,7 +31,7 @@ template inline object_item object_operators::operator[](self_cref key) { - object const& x = *static_cast(this); + object_cref x = *static_cast(this); return object_item(x, key); } @@ -37,7 +39,7 @@ template inline const_object_item object_operators::operator[](self_cref key) const { - object const& x = *static_cast(this); + object_cref x = *static_cast(this); return const_object_item(x, key); } @@ -62,7 +64,7 @@ object_operators::operator[](T const& key) inline object const_item_policies::get(object const& target, object const& key) { - return python::getitem(target, key); + return getitem(target, key); } inline object const& item_policies::set( @@ -70,33 +72,17 @@ inline object const& item_policies::set( , object const& key , object const& value) { - python::setitem(target, key, value); + setitem(target, key, value); return value; } -} // namespace api - -namespace converter +inline void item_policies::del( + object const& target + , object const& key) { - // These specializations are a lie; the proxies do not directly - // manage an object. What actually happens is that the implicit - // conversion to object takes hold and its conversion to_python is - // used. That's OK in part because the object temporary *is* - // actually managing the object during the duration of the - // conversion. - template <> - struct is_object_manager - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template <> - struct is_object_manager - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; + delitem(target, key); } -}} // namespace boost::python +}}} // namespace boost::python::api #endif // OBJECT_ITEMS_DWA2002615_HPP diff --git a/include/boost/python/object_protocol.hpp b/include/boost/python/object_protocol.hpp index 27461e26..fe21be17 100755 --- a/include/boost/python/object_protocol.hpp +++ b/include/boost/python/object_protocol.hpp @@ -11,7 +11,7 @@ # include # include -namespace boost { namespace python { +namespace boost { namespace python { namespace api { template object getattr(Target const& target, Key const& key) @@ -26,6 +26,12 @@ void setattr(object const& target, Key const& key, Value const& value) return setattr(target, object(key), object(value)); } +template +void delattr(object const& target, Key const& key) +{ + delattr(target, object(key)); +} + template object getitem(Target const& target, Key const& key) { @@ -39,7 +45,30 @@ void setitem(object const& target, Key const& key, Value const& value) return setitem(target, object(key), object(value)); } +template +void delitem(object const& target, Key const& key) +{ + delitem(target, object(key)); +} -}} // namespace boost::python +template +object getslice(Target const& target, Begin const& begin, End const& end) +{ + return getslice(object(target), object(begin), object(end)); +} + +template +void setslice(object const& target, Begin const& begin, End const& end, Value const& value) +{ + return setslice(target, object(begin), object(end), object(value)); +} + +template +void delslice(object const& target, Begin const& begin, End const& end) +{ + delslice(target, object(begin), object(end)); +} + +}}} // namespace boost::python::api #endif // OBJECT_PROTOCOL_DWA2002615_HPP diff --git a/include/boost/python/object_protocol_core.hpp b/include/boost/python/object_protocol_core.hpp index 9fc28415..548f9c7a 100755 --- a/include/boost/python/object_protocol_core.hpp +++ b/include/boost/python/object_protocol_core.hpp @@ -6,6 +6,8 @@ #ifndef OBJECT_PROTOCOL_CORE_DWA2002615_HPP # define OBJECT_PROTOCOL_CORE_DWA2002615_HPP +# include + namespace boost { namespace python { namespace api @@ -14,14 +16,34 @@ namespace api BOOST_PYTHON_DECL object getattr(object const& target, object const& key); BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value); + BOOST_PYTHON_DECL void delattr(object const& target, object const& key); + + // These are defined for efficiency, since attributes are commonly + // accessed through literal strings. + BOOST_PYTHON_DECL object getattr(object const& target, char const* key); + BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value); + BOOST_PYTHON_DECL void delattr(object const& target, char const* key); + BOOST_PYTHON_DECL object getitem(object const& target, object const& key); BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value); + BOOST_PYTHON_DECL void delitem(object const& target, object const& key); + + BOOST_PYTHON_DECL object getslice(object const& target, handle<> const& begin, handle<> const& end); + BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, handle<> const& end, object const& value); + BOOST_PYTHON_DECL void delslice(object const& target, handle<> const& begin, handle<> const& end); } using api::getattr; using api::setattr; +using api::delattr; + using api::getitem; using api::setitem; +using api::delitem; + +using api::getslice; +using api::setslice; +using api::delslice; }} // namespace boost::python diff --git a/include/boost/python/object_slices.hpp b/include/boost/python/object_slices.hpp new file mode 100644 index 00000000..3e61d2da --- /dev/null +++ b/include/boost/python/object_slices.hpp @@ -0,0 +1,124 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJECT_SLICES_DWA2002615_HPP +# define OBJECT_SLICES_DWA2002615_HPP + +# include +# include +# include +# include + +namespace boost { namespace python { namespace api { + +struct const_slice_policies +{ + typedef std::pair, handle<> > key_type; + static object get(object const& target, key_type const& key); +}; + +struct slice_policies : const_slice_policies +{ + static object const& set(object const& target, key_type const& key, object const& value); + static void del(object const& target, key_type const& key); +}; + +// +// implementation +// +template +object_slice +object_operators::slice(self_cref start, self_cref finish) +{ + object_cref x = *static_cast(this); + return object_slice(x, std::make_pair(start.ptr(), finish.ptr())); +} + +template +const_object_slice +object_operators::slice(self_cref start, self_cref finish) const +{ + object_cref x = *static_cast(this); + return const_object_slice(x, std::make_pair(start.ptr(), finish.ptr())); +} + +template +object_slice +object_operators::slice(slice_nil, self_cref finish) +{ + object_cref x = *static_cast(this); + return object_slice(x, std::make_pair(handle<>(), finish.ptr())); +} + +template +const_object_slice +object_operators::slice(slice_nil, self_cref finish) const +{ + object_cref x = *static_cast(this); + return const_object_slice(x, std::make_pair(handle<>(), finish.ptr())); +} + +template +object_slice +object_operators::slice(self_cref start, slice_nil) +{ + object_cref x = *static_cast(this); + return object_slice(x, std::make_pair(start.ptr(), handle<>())); +} + +template +const_object_slice +object_operators::slice(self_cref start, slice_nil) const +{ + object_cref x = *static_cast(this); + return const_object_slice(x, std::make_pair(start.ptr(), handle<>())); +} +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 +template +template +inline const_object_slice +object_operators::slice(T const& start, V const& end) const +{ + return this->slice( + typename slice_bound::type(start) + , typename slice_bound::type(end)); +} + +template +template +inline object_slice +object_operators::slice(T const& start, V const& end) +{ + return this->slice( + typename slice_bound::type(start) + , typename slice_bound::type(end)); +} +# endif + + +inline object const_slice_policies::get(object const& target, key_type const& key) +{ + return getslice(target, key.first, key.second); +} + +inline object const& slice_policies::set( + object const& target + , key_type const& key + , object const& value) +{ + setslice(target, key.first, key.second, value); + return value; +} + +inline void slice_policies::del( + object const& target + , key_type const& key) +{ + delslice(target, key.first, key.second); +} + +}}} // namespace boost::python::api + +#endif // OBJECT_SLICES_DWA2002615_HPP diff --git a/include/boost/python/proxy.hpp b/include/boost/python/proxy.hpp index b74d155c..385d4b3d 100755 --- a/include/boost/python/proxy.hpp +++ b/include/boost/python/proxy.hpp @@ -13,13 +13,15 @@ namespace boost { namespace python { namespace api { template class proxy : public object_operators > { + typedef typename Policies::key_type key_type; + # if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 typedef proxy const& copy_ctor_self; # else typedef proxy copy_ctor_self; # endif public: - proxy(object const& target, object const& key); + proxy(object const& target, key_type const& key); operator object() const; // to support a[b] = c[d] @@ -31,18 +33,28 @@ class proxy : public object_operators > Policies::set(m_target, m_key, object(rhs)); return *this; } - + + public: // implementation detail + void del() const; + private: object m_target; - object m_key; + key_type m_key; }; + +template +inline void del(proxy const& x) +{ + x.del(); +} + // // implementation // template -inline proxy::proxy(object const& target, object const& key) +inline proxy::proxy(object const& target, key_type const& key) : m_target(target), m_key(key) {} @@ -78,6 +90,12 @@ BOOST_PYTHON_PROXY_INPLACE(^=) BOOST_PYTHON_PROXY_INPLACE(|=) # undef BOOST_PYTHON_PROXY_INPLACE +template +inline void proxy::del() const +{ + Policies::del(m_target, m_key); +} + }}} // namespace boost::python::api #endif // PROXY_DWA2002615_HPP diff --git a/include/boost/python/slice_nil.hpp b/include/boost/python/slice_nil.hpp new file mode 100644 index 00000000..cb169116 --- /dev/null +++ b/include/boost/python/slice_nil.hpp @@ -0,0 +1,41 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef SLICE_NIL_DWA2002620_HPP +# define SLICE_NIL_DWA2002620_HPP + +namespace boost { namespace python { namespace api { + +class object; + +enum slice_nil +{ +# ifndef _ // Watch out for GNU gettext users, who #define _(x) + _ +# endif +}; + +template +struct slice_bound +{ + typedef object type; +}; + +template <> +struct slice_bound +{ + typedef slice_nil type; +}; + +} + +using api::slice_nil; +# ifndef _ // Watch out for GNU gettext users, who #define _(x) +using api::_; +# endif + +}} // namespace boost::python + +#endif // SLICE_NIL_DWA2002620_HPP diff --git a/src/object_protocol.cpp b/src/object_protocol.cpp index 3e9baa35..abcb7994 100755 --- a/src/object_protocol.cpp +++ b/src/object_protocol.cpp @@ -21,6 +21,40 @@ BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object c throw_error_already_set(); } +BOOST_PYTHON_DECL void delattr(object const& target, object const& key) +{ + if (PyObject_DelAttr(target.ptr().get(), key.ptr().get()) == -1) + throw_error_already_set(); +} + +BOOST_PYTHON_DECL object getattr(object const& target, char const* key) +{ + return object( + (object::new_pyobject_reference*) + PyObject_GetAttrString(target.ptr().get(), const_cast(key)) + ); +} + +BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value) +{ + if (PyObject_SetAttrString( + target.ptr().get(), const_cast(key), value.ptr().get()) == -1 + ) + { + throw_error_already_set(); + } +} + +BOOST_PYTHON_DECL void delattr(object const& target, char const* key) +{ + if (PyObject_DelAttrString( + target.ptr().get(), const_cast(key)) == -1 + ) + { + throw_error_already_set(); + } +} + BOOST_PYTHON_DECL object getitem(object const& target, object const& key) { return object((object::new_pyobject_reference*)PyObject_GetItem(target.ptr().get(), key.ptr().get())); @@ -31,5 +65,104 @@ BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object c if (PyObject_SetItem(target.ptr().get(), key.ptr().get(), value.ptr().get()) == -1) throw_error_already_set(); } + +BOOST_PYTHON_DECL void delitem(object const& target, object const& key) +{ + if (PyObject_DelItem(target.ptr().get(), key.ptr().get()) == -1) + throw_error_already_set(); +} + +namespace // slicing code copied directly out of the Python implementation +{ + #undef ISINT + #define ISINT(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x)) + + static PyObject * + apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */ + { + PyTypeObject *tp = u->ob_type; + PySequenceMethods *sq = tp->tp_as_sequence; + + if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) { + int ilow = 0, ihigh = INT_MAX; + if (!_PyEval_SliceIndex(v, &ilow)) + return NULL; + if (!_PyEval_SliceIndex(w, &ihigh)) + return NULL; + return PySequence_GetSlice(u, ilow, ihigh); + } + else { + PyObject *slice = PySlice_New(v, w, NULL); + if (slice != NULL) { + PyObject *res = PyObject_GetItem(u, slice); + Py_DECREF(slice); + return res; + } + else + return NULL; + } + } + + static int + assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x) + /* u[v:w] = x */ + { + PyTypeObject *tp = u->ob_type; + PySequenceMethods *sq = tp->tp_as_sequence; + + if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) { + int ilow = 0, ihigh = INT_MAX; + if (!_PyEval_SliceIndex(v, &ilow)) + return -1; + if (!_PyEval_SliceIndex(w, &ihigh)) + return -1; + if (x == NULL) + return PySequence_DelSlice(u, ilow, ihigh); + else + return PySequence_SetSlice(u, ilow, ihigh, x); + } + else { + PyObject *slice = PySlice_New(v, w, NULL); + if (slice != NULL) { + int res; + if (x != NULL) + res = PyObject_SetItem(u, slice, x); + else + res = PyObject_DelItem(u, slice); + Py_DECREF(slice); + return res; + } + else + return -1; + } + } +} + +BOOST_PYTHON_DECL object getslice(object const& target, handle<> const& begin, handle<> const& end) +{ + return object( + (object::new_pyobject_reference*) + apply_slice(target.ptr().get(), begin.get(), end.get())); +} + +BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, handle<> const& end, object const& value) +{ + if (assign_slice( + target.ptr().get(), begin.get(), end.get(), value.ptr().get()) == -1 + ) + { + throw_error_already_set(); + } +} + +BOOST_PYTHON_DECL void delslice(object const& target, handle<> const& begin, handle<> const& end) +{ + if (assign_slice( + target.ptr().get(), begin.get(), end.get(), 0) == -1 + ) + { + throw_error_already_set(); + } +} }}} // namespace boost::python::api diff --git a/test/object.cpp b/test/object.cpp index e2940e77..9bcf54a4 100755 --- a/test/object.cpp +++ b/test/object.cpp @@ -113,6 +113,22 @@ bool test_not_item(object y, object key) return !y[key]; } +bool check_string_slice() +{ + object s("hello, world"); + + if (s.slice(_,-3) != "hello, wo") + return false; + + if (s.slice(-3,_) != "rld") + return false; + + if (", " != s.slice(5,7)) + return false; + + return s.slice(2,-1).slice(1,-1) == "lo, wor"; +} + bool check_binary_operators() { int y; @@ -295,6 +311,7 @@ BOOST_PYTHON_MODULE_INIT(object_ext) .def("check_binary_operators", check_binary_operators) .def("check_inplace", check_inplace) + .def("check_string_slice", check_string_slice) ; } diff --git a/test/object.py b/test/object.py index e3cb9dc1..54744809 100644 --- a/test/object.py +++ b/test/object.py @@ -80,10 +80,15 @@ >>> test_not_item(d, 'foo') 1 + Slices + +>>> assert check_string_slice() + Operators >>> assert check_binary_operators() + >>> class X: pass ... >>> assert check_inplace(range(3), X()) From d7273dee1ca8203b9cd95cfd491a7a3a398f157b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 29 Jun 2002 18:49:43 +0000 Subject: [PATCH 0537/1042] added missing 'explicit' [SVN r14260] --- include/boost/python/handle.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/handle.hpp b/include/boost/python/handle.hpp index aa1412b3..78092a3f 100755 --- a/include/boost/python/handle.hpp +++ b/include/boost/python/handle.hpp @@ -66,7 +66,7 @@ class handle ~handle(); template - handle(Y* p) + explicit handle(Y* p) : m_p( python::upcast( detail::manage_ptr(p, 0) From f30fde3a522672c4ffc947ad34cf433a6ece4961 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 29 Jun 2002 19:24:11 +0000 Subject: [PATCH 0538/1042] list implementation [SVN r14261] --- Jamfile | 1 + .../boost/python/converter/arg_to_python.hpp | 31 ++- .../converter/pytype_arg_from_python.hpp | 99 ++++++++++ include/boost/python/detail/raw_pyobject.hpp | 29 +++ .../boost/python/detail/string_literal.hpp | 77 ++++++++ include/boost/python/list.hpp | 179 ++++++++++++++++++ include/boost/python/module.hpp | 2 +- include/boost/python/object_attributes.hpp | 4 +- include/boost/python/object_core.hpp | 164 ++++++++-------- include/boost/python/object_items.hpp | 8 +- include/boost/python/object_operators.hpp | 8 +- include/boost/python/object_slices.hpp | 36 ++-- include/boost/python/objects.hpp | 1 + include/boost/python/objects2.hpp | 100 +--------- include/boost/python/proxy.hpp | 4 +- src/list.cpp | 105 ++++++++++ src/object/class.cpp | 4 +- src/object/function.cpp | 2 +- src/object_operators.cpp | 10 +- src/object_protocol.cpp | 31 +-- src/objects2.cpp | 147 -------------- test/Jamfile | 2 + test/list.cpp | 131 +++++++++++++ 23 files changed, 777 insertions(+), 398 deletions(-) create mode 100644 include/boost/python/converter/pytype_arg_from_python.hpp create mode 100644 include/boost/python/detail/raw_pyobject.hpp create mode 100644 include/boost/python/detail/string_literal.hpp create mode 100644 include/boost/python/list.hpp create mode 100644 src/list.cpp create mode 100644 test/list.cpp diff --git a/Jamfile b/Jamfile index 72e4b3ec..5ebd1f0a 100644 --- a/Jamfile +++ b/Jamfile @@ -13,6 +13,7 @@ if $(UNIX) && ( $(OS) = AIX ) dll bpl : + src/list.cpp src/aix_init_module.cpp src/converter/from_python.cpp src/converter/registry.cpp diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index e4a2bfaf..a7c845d7 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -14,6 +14,7 @@ # include # include # include +# include # include // Bring in specializations # include @@ -73,6 +74,11 @@ namespace detail template struct select_arg_to_python { + // Special handling for char const[N]; interpret them as char + // const* for the sake of conversion + BOOST_STATIC_CONSTANT( + bool, is_string = python::detail::is_string_literal::value); + BOOST_STATIC_CONSTANT( bool, manager = is_object_manager::value); @@ -89,22 +95,27 @@ namespace detail typedef typename unwrap_pointer::type unwrapped_ptr; typedef typename mpl::select_type< - manager - , object_manager_arg_to_python + is_string + , arg_to_python , typename mpl::select_type< - ptr - , pointer_deep_arg_to_python + manager + , object_manager_arg_to_python , typename mpl::select_type< - ptr_wrapper - , pointer_shallow_arg_to_python + ptr + , pointer_deep_arg_to_python , typename mpl::select_type< - ref_wrapper - , reference_arg_to_python - , value_arg_to_python + ptr_wrapper + , pointer_shallow_arg_to_python + , typename mpl::select_type< + ref_wrapper + , reference_arg_to_python + , value_arg_to_python + >::type >::type >::type >::type - >::type type; + >::type + type; }; } diff --git a/include/boost/python/converter/pytype_arg_from_python.hpp b/include/boost/python/converter/pytype_arg_from_python.hpp new file mode 100644 index 00000000..ade4fd66 --- /dev/null +++ b/include/boost/python/converter/pytype_arg_from_python.hpp @@ -0,0 +1,99 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP +# define PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP + +# include + +// +// arg_from_python converters for Python type wrappers, to be used as +// base classes for specializations. +// +namespace boost { namespace python { namespace converter { + +template +struct pytype_arg_from_python +{ + pytype_arg_from_python(PyObject*); + bool convertible() const; + private: + PyObject* m_src; +}; + +// rvalue converter base +template +struct pytype_wrapper_value_arg_from_python + : pytype_arg_from_python +{ + typedef Wrapper result_type; + + pytype_wrapper_value_arg_from_python(PyObject*); + Wrapper operator()(PyObject*) const; +}; + +// Special case for Wrapper& - must store an lvalue internally. This +// OK because the entire state of the object is actually in the Python +// object. +template +struct pytype_wrapper_ref_arg_from_python + : pytype_arg_from_python +{ + typedef Wrapper& result_type; + + pytype_wrapper_ref_arg_from_python(PyObject*); + Wrapper& operator()(PyObject*) const; + private: + mutable Wrapper m_result; +}; + +// +// implementations +// + +template +inline pytype_arg_from_python::pytype_arg_from_python(PyObject* x) + : m_src(x) +{ +} + +template +inline bool pytype_arg_from_python::convertible() const +{ + return PyObject_IsInstance(m_src, (PyObject*)python_type); +} + +template +pytype_wrapper_value_arg_from_python::pytype_wrapper_value_arg_from_python( + PyObject* p) + : pytype_arg_from_python(p) +{ +} + +template +Wrapper pytype_wrapper_value_arg_from_python::operator()( + PyObject* x) const +{ + return Wrapper(python::detail::borrowed_reference(x)); +} + +template +pytype_wrapper_ref_arg_from_python::pytype_wrapper_ref_arg_from_python( + PyObject* p) + : pytype_arg_from_python(p) + , m_result(python::detail::borrowed_reference(p)) +{ +} + +template +Wrapper& pytype_wrapper_ref_arg_from_python::operator()( + PyObject* x) const +{ + return m_result; +} + +}}} // namespace boost::python::converter + +#endif // PYTYPE_ARG_FROM_PYTHON_DWA2002628_HPP diff --git a/include/boost/python/detail/raw_pyobject.hpp b/include/boost/python/detail/raw_pyobject.hpp new file mode 100644 index 00000000..5d87da56 --- /dev/null +++ b/include/boost/python/detail/raw_pyobject.hpp @@ -0,0 +1,29 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef RAW_PYOBJECT_DWA2002628_HPP +# define RAW_PYOBJECT_DWA2002628_HPP + +namespace boost { namespace python { namespace detail { + +// +// Define some types which we can use to get around the vagaries of +// PyObject*. We will use these to initialize object instances, and +// keep them in namespace detail to make sure they stay out of the +// hands of users. That is much simpler than trying to grant +// friendship to all the appropriate parties. +// + +// New references are checked for null +struct new_reference_t; +typedef new_reference_t* new_reference; + +// Borrowed references are assumed to be non-null +struct borrowed_reference_t; +typedef borrowed_reference_t* borrowed_reference; + +}}} // namespace boost::python::detail + +#endif // RAW_PYOBJECT_DWA2002628_HPP diff --git a/include/boost/python/detail/string_literal.hpp b/include/boost/python/detail/string_literal.hpp new file mode 100644 index 00000000..d8230bb8 --- /dev/null +++ b/include/boost/python/detail/string_literal.hpp @@ -0,0 +1,77 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef STRING_LITERAL_DWA2002629_HPP +# define STRING_LITERAL_DWA2002629_HPP + +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct is_string_literal +{ + BOOST_STATIC_CONSTANT(bool, value = false); +}; + +# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 +template +struct is_string_literal +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; +# else +// CWPro7 has trouble with the array type deduction above +template +struct is_string_literal + : is_same +{ +}; +# endif +# else +template +struct string_literal_helper +{ + typedef char (&yes_string_literal)[1]; + typedef char (&no_string_literal)[2]; + + template + struct apply + { + typedef apply self; + static T x; + static yes_string_literal check(char const*); + static no_string_literal check(char*); + static no_string_literal check(void const volatile*); + + BOOST_STATIC_CONSTANT( + bool, value = sizeof(self::check(x)) == sizeof(yes_string_literal)); + }; +}; + +template <> +struct string_literal_helper +{ + template + struct apply + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; +}; + +template +struct is_string_literal + : string_literal_helper::value>::apply +{ +}; +# endif + +}}} // namespace boost::python::detail + +#endif // STRING_LITERAL_DWA2002629_HPP diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp new file mode 100644 index 00000000..30189f8e --- /dev/null +++ b/include/boost/python/list.hpp @@ -0,0 +1,179 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef LIST_DWA2002627_HPP +# define LIST_DWA2002627_HPP + +# include +# include + +namespace boost { namespace python { + +class list : public object +{ +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 + typedef object const& object_cref; +# else + typedef object object_cref; +# endif + public: + BOOST_PYTHON_DECL list(); // new list + explicit BOOST_PYTHON_DECL list(object_cref sequence); // new list initialized from sequence's items + + template + explicit list(T const& sequence) + : object(list::call(object(sequence))) + { + } + + BOOST_PYTHON_DECL void append(object_cref); // append object to end + + template + void append(T const& x) + { + this->append(object(x)); + } + + BOOST_PYTHON_DECL long count(object_cref value) const; // return number of occurrences of value + + template + long count(T const& value) const + { + return this->count(object(value)); + } + + BOOST_PYTHON_DECL void extend(object_cref sequence); // extend list by appending sequence elements + + template + void extend(T const& x) + { + this->extend(object(x)); + } + + BOOST_PYTHON_DECL long index(object_cref value) const; // return index of first occurrence of value + + template + long index(T const& x) const + { + return this->index(object(x)); + } + + BOOST_PYTHON_DECL void insert(int index, object_cref); // insert object before index + BOOST_PYTHON_DECL void insert(object const& index, object_cref); + + template + void insert(int index, T const& x) // insert object before index + { + this->insert(index, object(x)); + } + + template + void insert(object const& index, T const& x) // insert object before index + { + this->insert(index, object(x)); + } + + BOOST_PYTHON_DECL object pop(); // remove and return item at index (default last) + BOOST_PYTHON_DECL object pop(long index); + BOOST_PYTHON_DECL object pop(object const& index); + + BOOST_PYTHON_DECL void remove(object_cref value); // remove first occurrence of value + + template + void remove(T const& value) + { + this->remove(object(value)); + } + + BOOST_PYTHON_DECL void reverse(); // reverse *IN PLACE* + + BOOST_PYTHON_DECL void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1 + BOOST_PYTHON_DECL void sort(object_cref cmpfunc); + + template + void sort(T const& value) + { + this->sort(object(value)); + } + + public: // implementation detail -- for internal use only + explicit list(detail::borrowed_reference); + explicit list(detail::new_reference); + + private: + static BOOST_PYTHON_DECL detail::new_reference call(object const&); +}; + +// +// Converter Specializations +// +template struct arg_from_python; + +template <> +struct arg_from_python + : converter::pytype_wrapper_value_arg_from_python +{ + typedef converter::pytype_wrapper_value_arg_from_python base; + typedef list result_type; + + arg_from_python(PyObject* p) : base(p) {} +}; + +template <> +struct arg_from_python + : arg_from_python +{ + arg_from_python(PyObject* p) + : arg_from_python(p) {} +}; + +template <> +struct arg_from_python + : converter::pytype_wrapper_ref_arg_from_python +{ + typedef converter::pytype_wrapper_ref_arg_from_python base; + typedef list result_type; + + arg_from_python(PyObject* p) + : base(p) {} +}; + +namespace converter +{ + template struct is_object_manager; + + template <> + struct is_object_manager + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template struct return_from_python; + template <> + struct return_from_python + { + typedef list result_type; + + result_type operator()(PyObject* x) const + { + return list(python::detail::new_reference(x)); + } + }; +} + +// +// list implementation +// +inline list::list(detail::borrowed_reference p) + : object(p) +{} + +inline list::list(detail::new_reference p) + : object(p) +{} + +}} // namespace boost::python + +#endif // LIST_DWA2002627_HPP diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index a4dad490..8ee63485 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -76,7 +76,7 @@ inline module& module::setattr(const char* name, handle<> const& x) inline module& module::add(PyTypeObject* x) { - this->base::add(x); + this->base::add(handle<>(borrowed(x))); return *this; } diff --git a/include/boost/python/object_attributes.hpp b/include/boost/python/object_attributes.hpp index c10608cb..4d3c2a7d 100755 --- a/include/boost/python/object_attributes.hpp +++ b/include/boost/python/object_attributes.hpp @@ -30,14 +30,14 @@ struct attribute_policies : const_attribute_policies template inline object_attribute object_operators::attr(char const* name) { - object_cref x = *static_cast(this); + object_cref2 x = *static_cast(this); return object_attribute(x, name); } template inline const_object_attribute object_operators::attr(char const* name) const { - object_cref x = *static_cast(this); + object_cref2 x = *static_cast(this); return const_object_attribute(x, name); } diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index b0b9813f..d0228cc9 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -11,6 +11,8 @@ # include # include # include +# include +# include # include namespace boost { namespace python { @@ -68,35 +70,8 @@ namespace api }; # endif - // - // object_handle -- get the handle to construct the object with, - // based on whether T is a proxy or not - // - template - struct object_handle - { - template - static handle<> get(T const& x) - { - return handle<>( - python::borrowed( - python::allow_null( // null check is already done - converter::arg_to_python(x).get()) - ) - ); - } - }; - - template <> - struct object_handle - { - template - static handle<> get(proxy const& x) - { - return x.operator object().ptr(); - } - }; - + template struct object_initializer; + // A way to turn a conrete type T into a type dependent on U. This // keeps conforming compilers from complaining about returning an // incomplete T from a template member function (which must be @@ -108,24 +83,24 @@ namespace api }; class object; - typedef handle<> const& (object::*bool_type)() const; + typedef PyObject* (object::*bool_type)() const; template class object_operators { # if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 - typedef object const& self_cref; + typedef object const& object_cref; # else - typedef object self_cref; + typedef object object_cref; # endif - // there appears to be a codegen bug here. We prevent the early - // destruction of a temporary in CWPro8 by binding a named - // object instead. + // there is a confirmed CWPro8 codegen bug here. We prevent the + // early destruction of a temporary by binding a named object + // instead. # if __MWERKS__ != 0x3000 - typedef object const& object_cref; + typedef object const& object_cref2; # else - typedef object const object_cref; + typedef object const object_cref2; # endif public: @@ -163,8 +138,8 @@ namespace api // item access // - const_object_item operator[](self_cref) const; - object_item operator[](self_cref); + const_object_item operator[](object_cref) const; + object_item operator[](object_cref); template const_object_item @@ -190,14 +165,14 @@ namespace api // slicing // - const_object_slice slice(self_cref, self_cref) const; - object_slice slice(self_cref, self_cref); + const_object_slice slice(object_cref, object_cref) const; + object_slice slice(object_cref, object_cref); - const_object_slice slice(slice_nil, self_cref) const; - object_slice slice(slice_nil, self_cref); + const_object_slice slice(slice_nil, object_cref) const; + object_slice slice(slice_nil, object_cref); - const_object_slice slice(self_cref, slice_nil) const; - object_slice slice(self_cref, slice_nil); + const_object_slice slice(object_cref, slice_nil) const; + object_slice slice(object_cref, slice_nil); # if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 template @@ -227,53 +202,69 @@ namespace api , slice_bound::type(end)); } # endif - - -# if BOOST_MSVC == 1200 - // For whatever reason, VC6 generates incorrect code unless we - // define this - object_operators& operator=(object_operators const&) { return *this; } -# endif }; class object : public object_operators { public: # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING - // copy constructor without NULL checking, for efficiency + // copy constructor without NULL checking, for efficiency. This + // confuses VC6/7 so object_initializer also handles this case. object(object const&); # endif // explicit conversion from any C++ object to Python template explicit object(T const& x) - : m_ptr(object_handle::value>::get(x)) + : m_ptr(object_initializer::value>::get( + x, detail::convertible::check(&x))) { } - // capture this case explicitly to handle string - // literals. Otherwise, they get deduced as char[N]const& above - // and conversion fails at runtime. - explicit object(char const* x) - : m_ptr(object_handle<>::get(x)) - { - } - // Throw error_already_set() if the handle is null. explicit object(handle<> const&); - // Underlying object access - handle<> const& ptr() const; + // Underlying object access -- returns a borrowed reference + PyObject* ptr() const; public: // implementation detail -- for internal use only - object(null_ok >*); - object(detail::borrowed >*); - object(detail::borrowed*); - class new_pyobject_reference; - object(new_pyobject_reference*); + explicit object(detail::borrowed_reference); + explicit object(detail::new_reference); private: - handle<> m_ptr; + PyObject* m_ptr; + }; + + // + // object_initializer -- get the handle to construct the object with, + // based on whether T is a proxy or derived from object + // + template + struct object_initializer + { + static PyObject* + get(object const& x, detail::yes_convertible) + { + return python::incref(x.ptr()); + } + + template + static PyObject* + get(T const& x, detail::no_convertible) + { + return python::incref(converter::arg_to_python(x).get()); + } + }; + + template <> + struct object_initializer + { + template + static PyObject* + get(proxy const& x, detail::no_convertible) + { + return python::incref(x.operator object().ptr()); + } }; } using api::object; @@ -336,39 +327,32 @@ namespace converter // inline object::object(handle<> const& x) - : m_ptr(python::borrowed(x.get())) + : m_ptr(incref(expect_non_null(x.get()))) {} # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING // copy constructor without NULL checking, for efficiency inline object::object(object const& rhs) - : m_ptr(python::allow_null(python::borrowed(rhs.m_ptr.get()))) + : m_ptr(incref(rhs.m_ptr)) {} # endif -inline object::object(null_ok >* p) - : m_ptr(p) +inline object::object(detail::borrowed_reference p) + : m_ptr(incref((PyObject*)p)) {} -inline object::object(detail::borrowed >* p) - : m_ptr(p) + +inline object::object(detail::new_reference p) + : m_ptr(expect_non_null((PyObject*)p)) {} -inline object::object(detail::borrowed* p) - : m_ptr(p) -{} - -inline object::object(object::new_pyobject_reference* p) - : m_ptr((PyObject*)p) -{} - -inline handle<> const& object::ptr() const +inline PyObject* object::ptr() const { return m_ptr; } // -// Converter speciaization implementations +// Converter specialization implementations // inline arg_from_python::arg_from_python(PyObject*) {} @@ -380,7 +364,7 @@ inline bool arg_from_python::convertible() const inline object arg_from_python::operator()(PyObject* x) const { - return object(python::borrowed(python::allow_null(x))); + return object(detail::borrowed_reference(x)); } inline arg_from_python::arg_from_python(PyObject*) @@ -388,7 +372,7 @@ inline arg_from_python::arg_from_python(PyObject*) {} inline arg_from_python::arg_from_python(PyObject* x) - : m_result(python::allow_null(python::borrowed(x))) + : m_result(detail::borrowed_reference(x)) {} inline bool arg_from_python::convertible() const @@ -406,12 +390,12 @@ namespace converter inline object return_from_python::operator()(PyObject* x) const { - return object((object::new_pyobject_reference*)x); + return object(python::detail::new_reference(x)); } inline PyObject* get_managed_object(object const& x) { - return x.ptr().get(); + return x.ptr(); } } diff --git a/include/boost/python/object_items.hpp b/include/boost/python/object_items.hpp index e07a9e50..436a671f 100755 --- a/include/boost/python/object_items.hpp +++ b/include/boost/python/object_items.hpp @@ -29,17 +29,17 @@ struct item_policies : const_item_policies // template inline object_item -object_operators::operator[](self_cref key) +object_operators::operator[](object_cref key) { - object_cref x = *static_cast(this); + object_cref2 x = *static_cast(this); return object_item(x, key); } template inline const_object_item -object_operators::operator[](self_cref key) const +object_operators::operator[](object_cref key) const { - object_cref x = *static_cast(this); + object_cref2 x = *static_cast(this); return const_object_item(x, key); } diff --git a/include/boost/python/object_operators.hpp b/include/boost/python/object_operators.hpp index 266018a6..1ac6e426 100644 --- a/include/boost/python/object_operators.hpp +++ b/include/boost/python/object_operators.hpp @@ -14,7 +14,7 @@ template object object_operators::operator()() const { object const& f = *static_cast(this); - return call(f.ptr().get()); + return call(f.ptr()); } @@ -23,7 +23,7 @@ inline object_operators::operator bool_type() const { object const& x = *static_cast(this); - return PyObject_IsTrue(x.ptr().get()) ? &object::ptr : 0; + return PyObject_IsTrue(x.ptr()) ? &object::ptr : 0; } template @@ -31,7 +31,7 @@ inline bool object_operators::operator!() const { object const& x = *static_cast(this); - return !PyObject_IsTrue(x.ptr().get()); + return !PyObject_IsTrue(x.ptr()); } # define BOOST_PYTHON_COMPARE_OP(op, opid) \ @@ -39,7 +39,7 @@ template \ bool operator op(L const& l, R const& r) \ { \ return PyObject_RichCompareBool( \ - object(l).ptr().get(), object(r).ptr().get(), opid); \ + object(l).ptr(), object(r).ptr(), opid); \ } BOOST_PYTHON_COMPARE_OP(>, Py_GT) BOOST_PYTHON_COMPARE_OP(>=, Py_GE) diff --git a/include/boost/python/object_slices.hpp b/include/boost/python/object_slices.hpp index 3e61d2da..a4348efc 100644 --- a/include/boost/python/object_slices.hpp +++ b/include/boost/python/object_slices.hpp @@ -30,50 +30,50 @@ struct slice_policies : const_slice_policies // template object_slice -object_operators::slice(self_cref start, self_cref finish) +object_operators::slice(object_cref start, object_cref finish) { - object_cref x = *static_cast(this); - return object_slice(x, std::make_pair(start.ptr(), finish.ptr())); + object_cref2 x = *static_cast(this); + return object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr()))); } template const_object_slice -object_operators::slice(self_cref start, self_cref finish) const +object_operators::slice(object_cref start, object_cref finish) const { - object_cref x = *static_cast(this); - return const_object_slice(x, std::make_pair(start.ptr(), finish.ptr())); + object_cref2 x = *static_cast(this); + return const_object_slice(x, std::make_pair(borrowed(start.ptr()), borrowed(finish.ptr()))); } template object_slice -object_operators::slice(slice_nil, self_cref finish) +object_operators::slice(slice_nil, object_cref finish) { - object_cref x = *static_cast(this); - return object_slice(x, std::make_pair(handle<>(), finish.ptr())); + object_cref2 x = *static_cast(this); + return object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr()))); } template const_object_slice -object_operators::slice(slice_nil, self_cref finish) const +object_operators::slice(slice_nil, object_cref finish) const { - object_cref x = *static_cast(this); - return const_object_slice(x, std::make_pair(handle<>(), finish.ptr())); + object_cref2 x = *static_cast(this); + return const_object_slice(x, std::make_pair(allow_null((PyObject*)0), borrowed(finish.ptr()))); } template object_slice -object_operators::slice(self_cref start, slice_nil) +object_operators::slice(object_cref start, slice_nil) { - object_cref x = *static_cast(this); - return object_slice(x, std::make_pair(start.ptr(), handle<>())); + object_cref2 x = *static_cast(this); + return object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0))); } template const_object_slice -object_operators::slice(self_cref start, slice_nil) const +object_operators::slice(object_cref start, slice_nil) const { - object_cref x = *static_cast(this); - return const_object_slice(x, std::make_pair(start.ptr(), handle<>())); + object_cref2 x = *static_cast(this); + return const_object_slice(x, std::make_pair(borrowed(start.ptr()), allow_null((PyObject*)0))); } # if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 template diff --git a/include/boost/python/objects.hpp b/include/boost/python/objects.hpp index a5b87d88..cab5f720 100644 --- a/include/boost/python/objects.hpp +++ b/include/boost/python/objects.hpp @@ -11,6 +11,7 @@ # ifdef BOOST_PYTHON_V2 # include +# include # else # include # include diff --git a/include/boost/python/objects2.hpp b/include/boost/python/objects2.hpp index 62d8c09f..a66a422e 100755 --- a/include/boost/python/objects2.hpp +++ b/include/boost/python/objects2.hpp @@ -14,6 +14,8 @@ namespace boost { namespace python { +class list; + class BOOST_PYTHON_DECL objects_base { public: @@ -97,67 +99,6 @@ class tuple : public tuple_base } }; -class list; - -struct BOOST_PYTHON_DECL list_proxy; -struct BOOST_PYTHON_DECL list_slice_proxy; - -class BOOST_PYTHON_DECL list_base : public objects_base -{ - protected: - typedef list_proxy proxy; - typedef list_slice_proxy slice_proxy; - public: - explicit list_base(handle<> p); - explicit list_base(std::size_t sz = 0); - static PyTypeObject* type_obj(); - static bool accepts(handle<> p); - std::size_t size() const; - handle<> operator[](std::size_t pos) const; - proxy operator[](std::size_t pos); - handle<> get_item(std::size_t pos) const; - - void set_item(std::size_t pos, const handle<>& ); - -// void set_item(std::size_t pos, const object& ); - - void insert(std::size_t index, const handle<>& item); - - void push_back(const handle<>& item); - - void append(const handle<>& item); - - list slice(int low, int high) const; - slice_proxy slice(int low, int high); - void sort(); - void reverse(); - tuple as_tuple() const; -}; - -class list : public list_base -{ - public: - explicit list(handle<> p) : list_base(p) {} - explicit list(std::size_t sz = 0) : list_base(sz) {} - template - void set_item(std::size_t pos, const T& x) - { this->set_item(pos, make_ref(x)); } - template - void insert(std::size_t index, const T& x) - { this->insert(index, make_ref(x)); } - template - void push_back(const T& item) - { this->push_back(make_ref(item)); } - template - void append(const T& item) - { this->append(make_ref(item)); } - - void set_item(std::size_t pos, const handle<>& x) { list_base::set_item(pos, x); } - void insert(std::size_t index, const handle<>& item) { list_base::insert(index, item); } - void push_back(const handle<>& item) { list_base::push_back(item); } - void append(const handle<>& item) { list_base::append(item); } -}; - class BOOST_PYTHON_DECL string : public objects_base, public boost::multipliable2 { @@ -306,43 +247,6 @@ class dictionary : public dictionary_base { dictionary_base::erase(key); } }; -struct BOOST_PYTHON_DECL list_proxy -{ - template - const handle<>& operator=(const T& rhs) - { return (*this) = make_ref(rhs); } - const handle<>& operator=(const handle<>& rhs); - - operator handle<>() const; - - private: - friend class list_base; - list_proxy(const handle<>& list, std::size_t index); - - // This is needed to work around the very strange MSVC error report that the - // return type of the built-in operator= differs from that of the ones - // defined above. Couldn't hurt to make these un-assignable anyway, though. - const handle<>& operator=(const list_proxy&); // Not actually implemented - private: - list m_list; - std::size_t m_index; -}; - -struct BOOST_PYTHON_DECL list_slice_proxy -{ - const list& operator=(const list& rhs); - operator handle<>() const; - operator list() const; - std::size_t size() const; - handle<> operator[](std::size_t pos) const; - private: - friend class list_base; - list_slice_proxy(const handle<>& list, int low, int high); - private: - handle<> m_list; - int m_low, m_high; -}; - }} // namespace boost::python #endif // OBJECTS_DWA20020611_H diff --git a/include/boost/python/proxy.hpp b/include/boost/python/proxy.hpp index 385d4b3d..2f06eeb9 100755 --- a/include/boost/python/proxy.hpp +++ b/include/boost/python/proxy.hpp @@ -73,10 +73,10 @@ inline proxy const& proxy::operator=(typename proxy::copy_ct # define BOOST_PYTHON_PROXY_INPLACE(op) \ template \ -proxy const& operator op(proxy const& lhs, R const& other) \ +proxy const& operator op(proxy const& lhs, R const& rhs) \ { \ object old(lhs); \ - return lhs = (old op other); \ + return lhs = (old op rhs); \ } BOOST_PYTHON_PROXY_INPLACE(+=) BOOST_PYTHON_PROXY_INPLACE(-=) diff --git a/src/list.cpp b/src/list.cpp new file mode 100644 index 00000000..7931c899 --- /dev/null +++ b/src/list.cpp @@ -0,0 +1,105 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include + +namespace boost { namespace python { + +BOOST_PYTHON_DECL detail::new_reference list::call(object const& arg) +{ + return (detail::new_reference)PyObject_CallFunction( + (PyObject*)&PyList_Type, "(O)", + arg.ptr()); +} + +BOOST_PYTHON_DECL list::list() + : object(detail::new_reference(PyList_New(0))) +{} + +BOOST_PYTHON_DECL list::list(object_cref sequence) + : object(list::call(sequence)) +{} + +BOOST_PYTHON_DECL void list::append(object_cref x) +{ + if (PyList_Append(this->ptr(), x.ptr()) == -1) + throw_error_already_set(); +} + +BOOST_PYTHON_DECL long list::count(object_cref value) const +{ + object result_obj(this->attr("count")(value)); + long result = PyInt_AsLong(result_obj.ptr()); + if (result == -1) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL void list::extend(object_cref sequence) +{ + this->attr("extend")(sequence); +} + +BOOST_PYTHON_DECL long list::index(object_cref value) const +{ + object result_obj(this->attr("index")(value)); + long result = PyInt_AsLong(result_obj.ptr()); + if (result == -1) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL void list::insert(int index, object_cref item) +{ + if (PyList_Insert(this->ptr(), index, item.ptr()) == -1) + throw_error_already_set(); +} + +BOOST_PYTHON_DECL void list::insert(object const& index, object_cref x) +{ + long index_ = PyInt_AsLong(index.ptr()); + if (index_ == -1 && PyErr_Occurred()) + throw_error_already_set(); + this->insert(index_, x); +} + +BOOST_PYTHON_DECL object list::pop() +{ + return this->attr("pop")(); +} + +BOOST_PYTHON_DECL object list::pop(long index) +{ + return this->pop(object(index)); +} + +BOOST_PYTHON_DECL object list::pop(object const& index) +{ + return this->attr("pop")(index); +} + +BOOST_PYTHON_DECL void list::remove(object_cref value) +{ + this->attr("remove")(value); +} + +BOOST_PYTHON_DECL void list::reverse() +{ + if (PyList_Reverse(this->ptr()) == -1) + throw_error_already_set(); +} + +BOOST_PYTHON_DECL void list::sort() +{ + if (PyList_Sort(this->ptr()) == -1) + throw_error_already_set(); +} + +BOOST_PYTHON_DECL void list::sort(object_cref cmpfunc) +{ + this->attr("sort")(cmpfunc); +} + +}} // namespace boost::python diff --git a/src/object/class.cpp b/src/object/class.cpp index a64b811d..3f03df64 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -5,7 +5,7 @@ // to its suitability for any purpose. #include #include -#include +#include #include #include #include @@ -210,7 +210,7 @@ namespace objects type_handle query(class_id id) const; void set(class_id, type_handle class_object); private: - typedef detail::map_entry entry; + typedef python::detail::map_entry entry; std::vector m_impl; }; diff --git a/src/object/function.cpp b/src/object/function.cpp index 8855ba75..4e237e4e 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/object_operators.cpp b/src/object_operators.cpp index 0aa0f1b7..471f01ad 100644 --- a/src/object_operators.cpp +++ b/src/object_operators.cpp @@ -5,6 +5,7 @@ // to its suitability for any purpose. #include +#include namespace boost { namespace python { namespace api { @@ -12,8 +13,9 @@ namespace boost { namespace python { namespace api { BOOST_PYTHON_DECL object operator op(object const& l, object const& r) \ { \ return object( \ - (object::new_pyobject_reference*) \ - PyNumber_##name(l.ptr().get(), r.ptr().get())); \ + detail::new_reference( \ + PyNumber_##name(l.ptr(), r.ptr())) \ + ); \ } BOOST_PYTHON_BINARY_OPERATOR(+, Add) @@ -32,8 +34,8 @@ BOOST_PYTHON_BINARY_OPERATOR(|, Or) BOOST_PYTHON_DECL object& operator op##=(object& l, object const& r) \ { \ return l = object( \ - (object::new_pyobject_reference*) \ - PyNumber_InPlace##name(l.ptr().get(), r.ptr().get())); \ + (detail::new_reference) \ + PyNumber_InPlace##name(l.ptr(), r.ptr())); \ } BOOST_PYTHON_INPLACE_OPERATOR(+, Add) diff --git a/src/object_protocol.cpp b/src/object_protocol.cpp index abcb7994..cafb70f3 100755 --- a/src/object_protocol.cpp +++ b/src/object_protocol.cpp @@ -12,33 +12,33 @@ namespace boost { namespace python { namespace api { BOOST_PYTHON_DECL object getattr(object const& target, object const& key) { - return object((object::new_pyobject_reference*)PyObject_GetAttr(target.ptr().get(), key.ptr().get())); + return object(detail::new_reference(PyObject_GetAttr(target.ptr(), key.ptr()))); } BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value) { - if (PyObject_SetAttr(target.ptr().get(), key.ptr().get(), value.ptr().get()) == -1) + if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1) throw_error_already_set(); } BOOST_PYTHON_DECL void delattr(object const& target, object const& key) { - if (PyObject_DelAttr(target.ptr().get(), key.ptr().get()) == -1) + if (PyObject_DelAttr(target.ptr(), key.ptr()) == -1) throw_error_already_set(); } BOOST_PYTHON_DECL object getattr(object const& target, char const* key) { return object( - (object::new_pyobject_reference*) - PyObject_GetAttrString(target.ptr().get(), const_cast(key)) - ); + detail::new_reference( + PyObject_GetAttrString(target.ptr(), const_cast(key)) + )); } BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value) { if (PyObject_SetAttrString( - target.ptr().get(), const_cast(key), value.ptr().get()) == -1 + target.ptr(), const_cast(key), value.ptr()) == -1 ) { throw_error_already_set(); @@ -48,7 +48,7 @@ BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object con BOOST_PYTHON_DECL void delattr(object const& target, char const* key) { if (PyObject_DelAttrString( - target.ptr().get(), const_cast(key)) == -1 + target.ptr(), const_cast(key)) == -1 ) { throw_error_already_set(); @@ -57,18 +57,19 @@ BOOST_PYTHON_DECL void delattr(object const& target, char const* key) BOOST_PYTHON_DECL object getitem(object const& target, object const& key) { - return object((object::new_pyobject_reference*)PyObject_GetItem(target.ptr().get(), key.ptr().get())); + return object(detail::new_reference( + PyObject_GetItem(target.ptr(), key.ptr()))); } BOOST_PYTHON_DECL void setitem(object const& target, object const& key, object const& value) { - if (PyObject_SetItem(target.ptr().get(), key.ptr().get(), value.ptr().get()) == -1) + if (PyObject_SetItem(target.ptr(), key.ptr(), value.ptr()) == -1) throw_error_already_set(); } BOOST_PYTHON_DECL void delitem(object const& target, object const& key) { - if (PyObject_DelItem(target.ptr().get(), key.ptr().get()) == -1) + if (PyObject_DelItem(target.ptr(), key.ptr()) == -1) throw_error_already_set(); } @@ -141,14 +142,14 @@ namespace // slicing code copied directly out of the Python implementation BOOST_PYTHON_DECL object getslice(object const& target, handle<> const& begin, handle<> const& end) { return object( - (object::new_pyobject_reference*) - apply_slice(target.ptr().get(), begin.get(), end.get())); + detail::new_reference( + apply_slice(target.ptr(), begin.get(), end.get()))); } BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, handle<> const& end, object const& value) { if (assign_slice( - target.ptr().get(), begin.get(), end.get(), value.ptr().get()) == -1 + target.ptr(), begin.get(), end.get(), value.ptr()) == -1 ) { throw_error_already_set(); @@ -158,7 +159,7 @@ BOOST_PYTHON_DECL void setslice(object const& target, handle<> const& begin, han BOOST_PYTHON_DECL void delslice(object const& target, handle<> const& begin, handle<> const& end) { if (assign_slice( - target.ptr().get(), begin.get(), end.get(), 0) == -1 + target.ptr(), begin.get(), end.get(), 0) == -1 ) { throw_error_already_set(); diff --git a/src/objects2.cpp b/src/objects2.cpp index 699b21df..462535e2 100755 --- a/src/objects2.cpp +++ b/src/objects2.cpp @@ -276,151 +276,4 @@ tuple operator+(const tuple& x, const tuple& y) return result; } - -list_base::list_base(handle<> p) - : objects_base(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw_error_already_set(); - } -} - -list_base::list_base(std::size_t sz) - : objects_base(handle<>(PyList_New(sz))) -{ -} - -PyTypeObject* list_base::type_obj() -{ - return &PyList_Type; -} - -bool list_base::accepts(handle<> p) -{ - return PyList_Check(p.get()); -} - -std::size_t list_base::size() const -{ - return PyList_Size(get()); -} - -handle<> list_base::operator[](std::size_t pos) const -{ - return handle<>(borrowed(PyList_GetItem(get(), pos))); -} - -list_proxy list_base::operator[](std::size_t pos) -{ - return proxy(reference(), pos); -} - -void list_base::insert(std::size_t index, const handle<>& item) -{ - if (PyList_Insert(get(), index, item.get()) == -1) - throw_error_already_set(); -} - -void list_base::push_back(const handle<>& item) -{ - if (PyList_Append(get(), item.get()) == -1) - throw_error_already_set(); -} - -void list_base::append(const handle<>& item) -{ - this->push_back(item); -} - -list list_base::slice(int low, int high) const -{ - return list(handle<>(PyList_GetSlice(get(), low, high))); -} - -list_slice_proxy list_base::slice(int low, int high) -{ - return list_slice_proxy(reference(), low, high); -} - -void list_base::sort() -{ - if (PyList_Sort(get()) == -1) - throw_error_already_set(); -} - -void list_base::reverse() -{ - if (PyList_Reverse(get()) == -1) - throw_error_already_set(); -} - -tuple list_base::as_tuple() const -{ - return tuple(handle<>(PyList_AsTuple(get()))); -} - -const handle<>& list_proxy::operator=(const handle<>& rhs) -{ - m_list.set_item(m_index, rhs); - return rhs; -} - -list_proxy::operator handle<>() const -{ - return handle<>(borrowed(PyList_GetItem(m_list.get(), m_index))); -} - -handle<> list_base::get_item(std::size_t pos) const -{ - return handle<>(borrowed(PyList_GetItem(this->get(), pos))); -} - -void list_base::set_item(std::size_t pos, const handle<>& rhs) -{ - int result = PyList_SetItem(this->get(), pos, rhs.get()); - if (result == -1) - throw_error_already_set(); - Py_INCREF(rhs.get()); -} - -list_proxy::list_proxy(const handle<>& list, std::size_t index) - : m_list(list), m_index(index) -{ -} - -const list& list_slice_proxy::operator=(const list& rhs) -{ - if (PyList_SetSlice(m_list.get(), m_low, m_high, rhs.get()) == -1) - throw_error_already_set(); - return rhs; -} - -list_slice_proxy::operator handle<>() const -{ - return handle<>(PyList_GetSlice(m_list.get(), m_low, m_high)); -} - -list_slice_proxy::operator list() const -{ - return list(this->operator handle<>()); -} - -std::size_t list_slice_proxy::size() const -{ - return this->operator list().size(); -} - -handle<> list_slice_proxy::operator[](std::size_t pos) const -{ - return this->operator list()[pos].operator handle<>(); -} - -list_slice_proxy::list_slice_proxy(const handle<>& list, int low, int high) - : m_list(list), m_low(low), m_high(high) -{ -} - }} // namespace boost::python diff --git a/test/Jamfile b/test/Jamfile index b54bb723..6fe1fc61 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -62,6 +62,7 @@ bpl-test test_pointer_adoption ; bpl-test operators ; bpl-test callbacks ; bpl-test object ; +bpl-test list ; bpl-test virtual_functions ; bpl-test back_reference ; bpl-test implicit ; @@ -88,6 +89,7 @@ run bases.cpp ; run if_else.cpp ; run pointee.cpp ; run result.cpp ; +compile string_literal.cpp ; compile borrowed.cpp : $(PYTHON_PROPERTIES) ; compile object_manager.cpp : $(PYTHON_PROPERTIES) ; diff --git a/test/list.cpp b/test/list.cpp new file mode 100644 index 00000000..714efc7e --- /dev/null +++ b/test/list.cpp @@ -0,0 +1,131 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include +#include +#include "test_class.hpp" + +using namespace boost::python; + +object new_list() +{ + return list(); +} + +list listify(object x) +{ + return list(x); +} + +object listify_string(char const* s) +{ + return list(s); +} + +std::string x_rep(test_class<> const& x) +{ + return "X(" + boost::lexical_cast(x.value()) + ")"; +} + +object apply_object_list(object f, list x) +{ + return f(x); +} + +void append_object(list& x, object y) +{ + x.append(y); +} + +void append_list(list& x, list const& y) +{ + x.append(y); +} + +typedef test_class<> X; + +int notcmp(object const& x, object const& y) +{ + return y < x ? -1 : y > x ? 1 : 0; +} + +void exercise(list x, object y, object print) +{ + x.append(y); + x.append(5); + x.append(X(3)); + + print("after append:"); + print(x); + + print("number of", y, "instances:", x.count(y)); + + print("number of 5s:", x.count(5)); + + x.extend("xyz"); + print("after extend:"); + print(x); + print("index of", y, "is:", x.index(y)); + print("index of 'l' is:", x.index("l")); + + x.insert(4, 666); + print("after inserting 666:"); + print(x); + print("inserting with object as index:"); + x.insert(x[x.index(5)], "---"); + print(x); + + print("popping..."); + x.pop(); + print(x); + x.pop(x[x.index(5)]); + print(x); + x.pop(x.index(5)); + print(x); + + print("removing", y); + x.remove(y); + print(x); + print("removing", 666); + x.remove(666); + print(x); + + print("reversing..."); + x.reverse(); + print(x); + + print("sorted:"); + x.pop(2); // make sorting predictable + x.sort(); + print(x); + + print("reverse sorted:"); + x.sort(handle<>(make_function(notcmp))); + print(x); +} + +BOOST_PYTHON_MODULE_INIT(list_ext) +{ + module("list_ext") + .def("new_list", new_list) + .def("listify", listify) + .def("listify_string", listify_string) + .def("apply_object_list", apply_object_list) + + .def("append_object", append_object) + .def("append_list", append_list) + + .def("exercise", exercise) + + .add(class_("X") + .def_init(args()) + .def( "__repr__", x_rep)) + ; +} + From 97ecfe7e03ad139a422bd7995c8399d26374d0b8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 29 Jun 2002 19:27:42 +0000 Subject: [PATCH 0539/1042] a couple more tests [SVN r14262] --- test/list.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/list.cpp b/test/list.cpp index 714efc7e..4ad285b4 100644 --- a/test/list.cpp +++ b/test/list.cpp @@ -108,6 +108,15 @@ void exercise(list x, object y, object print) print("reverse sorted:"); x.sort(handle<>(make_function(notcmp))); print(x); + + list w; + w.append(5); + w.append(6); + w += "hi"; + assert(w[0] == 5); + assert(w[1] == 6); + assert(w[2] == 'h'); + assert(w[3] == 'i'); } BOOST_PYTHON_MODULE_INIT(list_ext) From d7df5126cef45bdbb4920c3cbcea3f4f675e39b6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 29 Jun 2002 19:51:12 +0000 Subject: [PATCH 0540/1042] list implementation [SVN r14263] --- test/list.py | 87 +++++++++++++++++++++++++++++++++++++++++ test/string_literal.cpp | 30 ++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 test/list.py create mode 100644 test/string_literal.cpp diff --git a/test/list.py b/test/list.py new file mode 100644 index 00000000..a7387e2d --- /dev/null +++ b/test/list.py @@ -0,0 +1,87 @@ +''' +>>> from list_ext import * + +>>> new_list() +[] + +>>> listify((1,2,3)) +[1, 2, 3] + +>>> letters = listify_string('hello') +>>> letters +['h', 'e', 'l', 'l', 'o'] + +>>> X(22) +X(22) + +>>> def identity(x): +... return x +>>> assert apply_object_list(identity, letters) is letters + + 5 is not convertible to a list + +>>> try: apply_object_list(identity, 5) +... except TypeError: pass +... else: print 'expected an exception' + +>>> append_object(letters, '.') +>>> letters +['h', 'e', 'l', 'l', 'o', '.'] + + tuples do not automatically convert to lists when passed as arguments + +>>> try: append_list(letters, (1,2)) +... except TypeError: pass +... else: print 'expected an exception' + +>>> append_list(letters, [1,2]) +>>> letters +['h', 'e', 'l', 'l', 'o', '.', [1, 2]] + +>>> def printer(*args): +... for x in args: print x, +... print +... + +>>> y = X(42) +>>> exercise(letters, y, printer) +after append: +['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3)] +number of X(42) instances: 1 +number of 5s: 1 +after extend: +['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z'] +index of X(42) is: 7 +index of 'l' is: 2 +after inserting 666: +['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z'] +inserting with object as index: +['h', 'e', 'l', 'l', 666, '---', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y', 'z'] +popping... +['h', 'e', 'l', 'l', 666, '---', 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y'] +['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), 5, X(3), 'x', 'y'] +['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(42), X(3), 'x', 'y'] +removing X(42) +['h', 'e', 'l', 'l', 666, 'o', '.', [1, 2], X(3), 'x', 'y'] +removing 666 +['h', 'e', 'l', 'l', 'o', '.', [1, 2], X(3), 'x', 'y'] +reversing... +['y', 'x', X(3), [1, 2], '.', 'o', 'l', 'l', 'e', 'h'] +sorted: +[[1, 2], '.', 'e', 'h', 'l', 'l', 'o', 'x', 'y'] +reverse sorted: +['y', 'x', 'o', 'l', 'l', 'h', 'e', '.', [1, 2]] +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) diff --git a/test/string_literal.cpp b/test/string_literal.cpp new file mode 100644 index 00000000..5c1a1e61 --- /dev/null +++ b/test/string_literal.cpp @@ -0,0 +1,30 @@ +//#include +#include +#include +#include + +int main() +{ + using namespace boost::python::detail; + + BOOST_STATIC_ASSERT(!is_string_literal::value); + BOOST_STATIC_ASSERT(!is_string_literal::value); + BOOST_STATIC_ASSERT(!is_string_literal::value); + BOOST_STATIC_ASSERT(!is_string_literal::value); + + BOOST_STATIC_ASSERT(!is_string_literal::value); + BOOST_STATIC_ASSERT(!is_string_literal::value); + BOOST_STATIC_ASSERT(!is_string_literal::value); + BOOST_STATIC_ASSERT(!is_string_literal::value); + BOOST_STATIC_ASSERT(!is_string_literal::value); + BOOST_STATIC_ASSERT(!is_string_literal::value); + + BOOST_STATIC_ASSERT(!is_string_literal::value); + BOOST_STATIC_ASSERT(is_string_literal::value); + BOOST_STATIC_ASSERT(is_string_literal::value); + + BOOST_STATIC_ASSERT(!is_string_literal::value); + BOOST_STATIC_ASSERT(!is_string_literal::value); + BOOST_STATIC_ASSERT(!is_string_literal::value); + return 0; +} From f02a3c5b479a7836af123058bb5a19939fc89d2c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 1 Jul 2002 21:23:10 +0000 Subject: [PATCH 0541/1042] Now inheriting object_cref from object [SVN r14270] --- include/boost/python/list.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp index 30189f8e..c732b4fd 100644 --- a/include/boost/python/list.hpp +++ b/include/boost/python/list.hpp @@ -13,11 +13,6 @@ namespace boost { namespace python { class list : public object { -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 - typedef object const& object_cref; -# else - typedef object object_cref; -# endif public: BOOST_PYTHON_DECL list(); // new list explicit BOOST_PYTHON_DECL list(object_cref sequence); // new list initialized from sequence's items From bed7a7d29c63bc3b6a0842f5f0e771cb269a072e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 1 Jul 2002 21:25:01 +0000 Subject: [PATCH 0542/1042] Python long support [SVN r14271] --- Jamfile | 1 + include/boost/python/long.hpp | 112 +++++++++++++++++++++++++++ include/boost/python/object_core.hpp | 20 ++--- src/long.cpp | 40 ++++++++++ test/Jamfile | 1 + test/long.cpp | 51 ++++++++++++ test/long.py | 26 +++++++ 7 files changed, 241 insertions(+), 10 deletions(-) create mode 100644 include/boost/python/long.hpp create mode 100644 src/long.cpp create mode 100644 test/long.cpp create mode 100644 test/long.py diff --git a/Jamfile b/Jamfile index 5ebd1f0a..b28cf262 100644 --- a/Jamfile +++ b/Jamfile @@ -14,6 +14,7 @@ if $(UNIX) && ( $(OS) = AIX ) dll bpl : src/list.cpp + src/long.cpp src/aix_init_module.cpp src/converter/from_python.cpp src/converter/registry.cpp diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp new file mode 100644 index 00000000..5d39093e --- /dev/null +++ b/include/boost/python/long.hpp @@ -0,0 +1,112 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef LONG_DWA2002627_HPP +# define LONG_DWA2002627_HPP + +# include +# include + +namespace boost { namespace python { + +class long_ : public object +{ + public: + BOOST_PYTHON_DECL long_(); // new long_ + explicit BOOST_PYTHON_DECL long_(object_cref rhs); + + template + explicit long_(T const& rhs) + : object(long_::call(object(rhs))) + { + } + + explicit BOOST_PYTHON_DECL long_(object_cref rhs, object_cref base); + + template + explicit long_(T const& rhs, U const& base) + : object(long_::call(object(rhs), object(base))) + { + } + public: // implementation detail -- for internal use only + explicit long_(detail::borrowed_reference); + explicit long_(detail::new_reference); + + private: + static BOOST_PYTHON_DECL detail::new_reference call(object const&); + static BOOST_PYTHON_DECL detail::new_reference call(object const&, object const&); +}; + +// +// Converter Specializations +// +template struct arg_from_python; + +template <> +struct arg_from_python + : converter::pytype_wrapper_value_arg_from_python +{ + typedef converter::pytype_wrapper_value_arg_from_python base; + typedef long_ result_type; + + arg_from_python(PyObject* p) : base(p) {} +}; + +template <> +struct arg_from_python + : arg_from_python +{ + arg_from_python(PyObject* p) + : arg_from_python(p) {} +}; + +template <> +struct arg_from_python + : converter::pytype_wrapper_ref_arg_from_python +{ + typedef converter::pytype_wrapper_ref_arg_from_python base; + typedef long_ result_type; + + arg_from_python(PyObject* p) + : base(p) {} +}; + +namespace converter +{ + template struct is_object_manager; + + template <> + struct is_object_manager + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template struct return_from_python; + template <> + struct return_from_python + { + typedef long_ result_type; + + result_type operator()(PyObject* x) const + { + return long_(python::detail::new_reference(x)); + } + }; +} + +// +// long_ implementation +// +inline long_::long_(detail::borrowed_reference p) + : object(p) +{} + +inline long_::long_(detail::new_reference p) + : object(p) +{} + +}} // namespace boost::python + +#endif // LONG_DWA2002627_HPP diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index d0228cc9..a465bd81 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -88,21 +88,12 @@ namespace api template class object_operators { + protected: # if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 typedef object const& object_cref; # else typedef object object_cref; # endif - - // there is a confirmed CWPro8 codegen bug here. We prevent the - // early destruction of a temporary by binding a named object - // instead. -# if __MWERKS__ != 0x3000 - typedef object const& object_cref2; -# else - typedef object const object_cref2; -# endif - public: // function call // @@ -201,6 +192,15 @@ namespace api slice_bound::type(start) , slice_bound::type(end)); } +# endif + private: + // there is a confirmed CWPro8 codegen bug here. We prevent the + // early destruction of a temporary by binding a named object + // instead. +# if __MWERKS__ != 0x3000 + typedef object const& object_cref2; +# else + typedef object const object_cref2; # endif }; diff --git a/src/long.cpp b/src/long.cpp new file mode 100644 index 00000000..46d3d7c5 --- /dev/null +++ b/src/long.cpp @@ -0,0 +1,40 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include + +namespace boost { namespace python { + +BOOST_PYTHON_DECL detail::new_reference long_::call(object const& arg) +{ + return (detail::new_reference)PyObject_CallFunction( + (PyObject*)&PyLong_Type, "(O)", + arg.ptr()); +} + +BOOST_PYTHON_DECL detail::new_reference long_::call(object const& arg, object const& base) +{ + return (detail::new_reference)PyObject_CallFunction( + (PyObject*)&PyLong_Type, "(OO)", + arg.ptr(), base.ptr()); +} + +BOOST_PYTHON_DECL long_::long_() + : object( + detail::new_reference( + PyObject_CallFunction((PyObject*)&PyLong_Type, "()")) + ) +{} + +BOOST_PYTHON_DECL long_::long_(object_cref arg) + : object(long_::call(arg)) +{} + +BOOST_PYTHON_DECL long_::long_(object_cref arg, object_cref base) + : object(long_::call(arg, base)) +{} + + +}} // namespace boost::python diff --git a/test/Jamfile b/test/Jamfile index 6fe1fc61..5d0118d3 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -63,6 +63,7 @@ bpl-test operators ; bpl-test callbacks ; bpl-test object ; bpl-test list ; +bpl-test long ; bpl-test virtual_functions ; bpl-test back_reference ; bpl-test implicit ; diff --git a/test/long.cpp b/test/long.cpp new file mode 100644 index 00000000..2a139de8 --- /dev/null +++ b/test/long.cpp @@ -0,0 +1,51 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include + +using namespace boost::python; + +object new_long() +{ + return long_(); +} + +long_ longify(object x) +{ + return long_(x); +} + +object longify_string(char const* s) +{ + return long_(s); +} + +char const* is_long1(long_& x) +{ + long_ y = x; + x += 50; + assert(x == y + 50); + return "yes"; +} + +int is_long2(char const*) +{ + return 0; +} + +BOOST_PYTHON_MODULE_INIT(long_ext) +{ + module("long_ext") + .def("new_long", new_long) + .def("longify", longify) + .def("longify_string", longify_string) + .def("is_long", is_long1) + .def("is_long", is_long2) + ; +} + diff --git a/test/long.py b/test/long.py new file mode 100644 index 00000000..7d08e9b7 --- /dev/null +++ b/test/long.py @@ -0,0 +1,26 @@ +''' +>>> from long_ext import * +>>> new_long() +0L +>>> longify(42) +42L +>>> longify_string('300') +300L +>>> is_long(20L) +'yes' +>>> is_long('20') +0 +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 279ad90a3cdde19288a08e8260ec49c711162c5e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 2 Jul 2002 23:31:40 +0000 Subject: [PATCH 0543/1042] copy_ctor_self => assignment_self [SVN r14286] --- include/boost/python/proxy.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/proxy.hpp b/include/boost/python/proxy.hpp index 2f06eeb9..1818fa27 100755 --- a/include/boost/python/proxy.hpp +++ b/include/boost/python/proxy.hpp @@ -16,16 +16,16 @@ class proxy : public object_operators > typedef typename Policies::key_type key_type; # if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 - typedef proxy const& copy_ctor_self; + typedef proxy const& assignment_self; # else - typedef proxy copy_ctor_self; + typedef proxy assignment_self; # endif public: proxy(object const& target, key_type const& key); operator object() const; // to support a[b] = c[d] - proxy const& operator=(copy_ctor_self) const; + proxy const& operator=(assignment_self) const; template inline proxy const& operator=(T const& rhs) const @@ -66,7 +66,7 @@ inline proxy::operator object() const // to support a[b] = c[d] template -inline proxy const& proxy::operator=(typename proxy::copy_ctor_self rhs) const +inline proxy const& proxy::operator=(typename proxy::assignment_self rhs) const { return *this = python::object(rhs); } From 2ae7c607802679b25e650cdfd9a345a5254257db Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 2 Jul 2002 23:34:21 +0000 Subject: [PATCH 0544/1042] Fix refcounting bugs in class object; add regression Removed flotsam [SVN r14287] --- include/boost/python/converter/callback.hpp | 277 ----------------- .../boost/python/converter/from_python.hpp | 288 ------------------ include/boost/python/object_core.hpp | 84 +++-- test/object.py | 18 ++ 4 files changed, 70 insertions(+), 597 deletions(-) delete mode 100644 include/boost/python/converter/callback.hpp delete mode 100644 include/boost/python/converter/from_python.hpp diff --git a/include/boost/python/converter/callback.hpp b/include/boost/python/converter/callback.hpp deleted file mode 100644 index ae399eed..00000000 --- a/include/boost/python/converter/callback.hpp +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CALLBACK_DWA2002228_HPP -# define CALLBACK_DWA2002228_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -namespace detail -{ - template - struct pointer_callback_from_python - { - pointer_callback_from_python(); - T operator()(PyObject*) const; - }; - - template - struct reference_callback_from_python - { - reference_callback_from_python(); - T operator()(PyObject*) const; - }; - - template - struct rvalue_callback_from_python - { - rvalue_callback_from_python(); - T const& operator()(PyObject*); - private: - rvalue_data m_data; - }; - - template - struct select_callback_from_python - { - BOOST_STATIC_CONSTANT( - bool, ptr = is_pointer::value); - - BOOST_STATIC_CONSTANT( - bool, ref = is_reference::value); - - typedef typename mpl::select_type< - ptr - , pointer_callback_from_python - , typename mpl::select_type< - ref - , reference_callback_from_python - , rvalue_callback_from_python - >::type - >::type type; - }; - - - template - struct reference_callback_to_python : callback_to_python_holder - { - reference_callback_to_python(T& x); - private: - static PyObject* get_object(T& x); - }; - - template - struct value_callback_to_python : callback_to_python_base - { - // Throw an exception if the conversion can't succeed - value_callback_to_python(T const&); - }; - - template - struct pointer_deep_callback_to_python : callback_to_python_base - { - // Throw an exception if the conversion can't succeed - pointer_deep_callback_to_python(Ptr); - }; - - template - struct pointer_shallow_callback_to_python : callback_to_python_holder - { - // Throw an exception if the conversion can't succeed - pointer_shallow_callback_to_python(Ptr); - private: - static PyObject* get_object(Ptr p); - }; - - template - struct select_callback_to_python - { - BOOST_STATIC_CONSTANT( - bool, ptr = is_pointer::value); - - BOOST_STATIC_CONSTANT( - bool, ref_wrapper = is_reference_wrapper::value); - - BOOST_STATIC_CONSTANT( - bool, ptr_wrapper = is_pointer_wrapper::value); - - typedef typename unwrap_reference::type unwrapped_referent; - typedef typename unwrap_pointer::type unwrapped_ptr; - - typedef typename mpl::select_type< - ptr - , pointer_deep_callback_to_python - , typename mpl::select_type< - ptr_wrapper - , pointer_shallow_callback_to_python - , typename mpl::select_type< - ref_wrapper - , reference_callback_to_python - , value_callback_to_python - >::type - >::type - >::type type; - }; -} - -template -struct callback_from_python - : detail::select_callback_from_python::type -{ - typedef T result_type; -}; - -struct void_result -{ - private: - void_result() {} - void operator=(void_result const&); - - // I would prefer to make this completely untouchable, but few - // compilers support template friends -# if 0 - void_result(void_result const&); -# endif - friend struct callback_from_python; -}; - -// Specialization as a convenience for call and call_method -template <> -struct callback_from_python -{ - typedef void_result result_type; - result_type operator()(PyObject* x) const - { - Py_DECREF(expect_non_null(x)); - return result_type(); - } -}; - -template -struct callback_to_python - : detail::select_callback_to_python::type -{ - typedef typename detail::select_callback_to_python::type base; - public: // member functions - // Throw an exception if the conversion can't succeed - callback_to_python(T const& x); -}; - -// Convenience macros for call<> and call_method<> code generation -# define BOOST_PYTHON_CALLBACK_TO_PYTHON_GET(index,ignored) \ - converter::callback_to_python( \ - BOOST_PP_CAT(a,index)).get() - -# define BOOST_PYTHON_ARG_STRING(nargs) \ - "(" BOOST_PP_REPEAT(nargs,BOOST_PYTHON_PROJECT_2ND,"O") ")" - -// -// Implementations -// -namespace detail -{ - template - inline rvalue_callback_from_python::rvalue_callback_from_python() - : m_data(rvalue_from_python_chain::value) - { - throw_if_not_registered(m_data.stage1); - } - - template - inline T const& rvalue_callback_from_python::operator()(PyObject* obj) - { - return *(T*)convert_rvalue(obj, m_data.stage1, m_data.storage.bytes); - } - - BOOST_PYTHON_DECL void throw_no_class_registered(); - - template - inline reference_callback_from_python::reference_callback_from_python() - { - detail::throw_if_not_registered(lvalue_from_python_chain::value); - } - - template - inline T reference_callback_from_python::operator()(PyObject* obj) const - { - return python::detail::void_ptr_to_reference( - callback_convert_reference(obj, lvalue_from_python_chain::value) - , (T(*)())0); - } - - template - inline pointer_callback_from_python::pointer_callback_from_python() - { - detail::throw_if_not_registered(lvalue_from_python_chain::value); - } - - template - inline T pointer_callback_from_python::operator()(PyObject* obj) const - { - return T(callback_convert_pointer(obj, lvalue_from_python_chain::value)); - } - - template - inline value_callback_to_python::value_callback_to_python(T const& x) - : callback_to_python_base(&x, to_python_function::value) - { - } - - template - inline pointer_deep_callback_to_python::pointer_deep_callback_to_python(Ptr x) - : callback_to_python_base(x, pointee_to_python_function::value) - { - } - - template - inline PyObject* reference_callback_to_python::get_object(T& x) - { - to_python_indirect convert; - if (!convert.convertible()) - throw_no_class_registered(); - return convert(x); - } - - template - inline reference_callback_to_python::reference_callback_to_python(T& x) - : callback_to_python_holder(get_object(x)) - { - } - - template - inline pointer_shallow_callback_to_python::pointer_shallow_callback_to_python(Ptr x) - : callback_to_python_holder(get_object(x)) - {} - - template - inline PyObject* pointer_shallow_callback_to_python::get_object(Ptr x) - { - to_python_indirect convert; - if (!convert.convertible()) - throw_no_class_registered(); - return x ? convert(x) : python::detail::none(); - } -} - -template -inline callback_to_python::callback_to_python(T const& x) - : base(x) -{} - -}}} // namespace boost::python::converter - -#endif // CALLBACK_DWA2002228_HPP diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp deleted file mode 100644 index d2fb4db2..00000000 --- a/include/boost/python/converter/from_python.hpp +++ /dev/null @@ -1,288 +0,0 @@ -#error obsolete -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FROM_PYTHON_DWA2002127_HPP -# define FROM_PYTHON_DWA2002127_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python -{ - template struct from_python; -}} - -namespace boost { namespace python { namespace converter { - -struct from_python_base -{ - public: // member functions - from_python_base(void* result); - from_python_base(PyObject*, lvalue_from_python_registration const* chain); - bool convertible() const; - - protected: // member functions - void*const& result() const; - - private: // data members - void* m_result; -}; - -// Used when T == U*const& -template -struct pointer_const_reference_from_python -{ - typedef T result_type; - - pointer_const_reference_from_python(PyObject*); - T operator()(PyObject*) const; - bool convertible() const; - - private: - typename detail::referent_storage::type m_result; -}; - -// Used when T == U* -template -struct pointer_from_python : from_python_base -{ - typedef T result_type; - - pointer_from_python(PyObject*); - T operator()(PyObject*) const; -}; - -// Used when T == U& and (T != V const& or T == W volatile&) -template -struct reference_from_python : from_python_base -{ - typedef T result_type; - - reference_from_python(PyObject*); - T operator()(PyObject*) const; -}; - -// ------- rvalue converters --------- - -// Used for the case where T is a non-pointer, non-reference type OR -// is a const non-volatile reference to a non-pointer type. -template -struct rvalue_from_python -{ - typedef typename boost::add_reference< - typename boost::add_const::type - >::type result_type; - - rvalue_from_python(PyObject*); - bool convertible() const; - - result_type operator()(PyObject*); - - private: - rvalue_data m_data; -}; - -// ------- back-reference converters -------- - -// Converts to a (PyObject*,T) bundle, for when you need a reference -// back to the Python object - -template -struct back_reference_from_python - : boost::python::from_python -{ - typedef T result_type; - - back_reference_from_python(PyObject*); - T operator()(PyObject*); - private: - typedef boost::python::from_python base; -}; - -template -struct select_from_python -{ - BOOST_STATIC_CONSTANT( - bool, ptr = is_pointer::value); - - BOOST_STATIC_CONSTANT( - bool, ptr_cref - = boost::python::detail::is_reference_to_pointer::value - && boost::python::detail::is_reference_to_const::value - && !boost::python::detail::is_reference_to_volatile::value); - - - BOOST_STATIC_CONSTANT( - bool, ref = - boost::python::detail::is_reference_to_non_const::value - || boost::python::detail::is_reference_to_volatile::value); - - BOOST_STATIC_CONSTANT( - bool, back_ref = - boost::python::is_back_reference::value); - - typedef typename mpl::select_type< - ptr - , pointer_from_python - , typename mpl::select_type< - ptr_cref - , pointer_const_reference_from_python - , typename mpl::select_type< - ref - , reference_from_python - , typename mpl::select_type< - back_ref - , back_reference_from_python - , rvalue_from_python - >::type - >::type - >::type - >::type type; -}; - -// -// implementations -// -inline from_python_base::from_python_base(void* result) - : m_result(result) -{ -} - -inline from_python_base::from_python_base( - PyObject* source - , lvalue_from_python_registration const* chain) - : m_result(find(source, chain)) -{ -} - -inline bool from_python_base::convertible() const -{ - return m_result != 0; -} - -inline void*const& from_python_base::result() const -{ - return m_result; -} - -// -------- - -namespace detail -{ - template - struct null_ptr_owner - { - static T value; - }; - template T null_ptr_owner::value = 0; - - template - inline U& null_ptr_reference(U&(*)()) - { - return null_ptr_owner::value; - } -} - -template -inline pointer_const_reference_from_python::pointer_const_reference_from_python(PyObject* p) -{ - python::detail::write_void_ptr_reference( - m_result.bytes - , p == Py_None ? p : find(p, lvalue_from_python_chain::value) - , (T(*)())0); -} - -template -inline bool pointer_const_reference_from_python::convertible() const -{ - return python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0) != 0; -} -template -inline T pointer_const_reference_from_python::operator()(PyObject* p) const -{ - return (p == Py_None) - ? detail::null_ptr_reference((T(*)())0) - : python::detail::void_ptr_to_reference(m_result.bytes, (T(*)())0); -} - -// -------- - -template -inline pointer_from_python::pointer_from_python(PyObject* p) - : from_python_base(p == Py_None ? p : find(p, lvalue_from_python_chain::value)) -{ -} - -template -inline T pointer_from_python::operator()(PyObject* p) const -{ - return (p == Py_None) ? 0 : T(result()); -} - -// -------- - -template -inline reference_from_python::reference_from_python(PyObject* p) - : from_python_base(find(p,lvalue_from_python_chain::value)) -{ -} - -template -inline T reference_from_python::operator()(PyObject*) const -{ - return python::detail::void_ptr_to_reference(result(), (T(*)())0); -} - -// ------- - -template -inline rvalue_from_python::rvalue_from_python(PyObject* obj) - : m_data(find(obj, rvalue_from_python_chain::value)) -{ -} - -template -inline bool rvalue_from_python::convertible() const -{ - return m_data.stage1.convertible != 0; -} - -template -inline typename rvalue_from_python::result_type -rvalue_from_python::operator()(PyObject* p) -{ - if (m_data.stage1.construct != 0) - m_data.stage1.construct(p, &m_data.stage1); - - return python::detail::void_ptr_to_reference(m_data.stage1.convertible, (result_type(*)())0); -} - -template -back_reference_from_python::back_reference_from_python(PyObject* x) - : base(x) -{ -} - -template -inline T -back_reference_from_python::operator()(PyObject* x) -{ - return T(x, base::operator()(x)); -} - -}}} // namespace boost::python::converter - -#endif // FROM_PYTHON_DWA2002127_HPP diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index a465bd81..4e391c5c 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -164,35 +164,32 @@ namespace api const_object_slice slice(object_cref, slice_nil) const; object_slice slice(object_cref, slice_nil); - -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - template - const_object_slice - slice(T const& start, V const& end) const; - - template - object_slice - slice(T const& start, V const& end); -# else template const_object_slice slice(T const& start, V const& end) const +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + ; +# else { return this->slice( slice_bound::type(start) , slice_bound::type(end)); } +# endif template object_slice slice(T const& start, V const& end) +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + ; +# else { return this->slice( slice_bound::type(start) , slice_bound::type(end)); } -# endif +# endif private: // there is a confirmed CWPro8 codegen bug here. We prevent the // early destruction of a temporary by binding a named object @@ -204,35 +201,42 @@ namespace api # endif }; - class object : public object_operators + // VC6 and VC7 require this base class in order to generate the + // correct copy constructor for object. We can't define it there + // explicitly or it will complain of ambiguity. + struct object_base : object_operators + { + // copy constructor without NULL checking, for efficiency. + object_base(object_base const&); + object_base(PyObject* ptr); + + object_base& operator=(object_base const& rhs); + ~object_base(); + + // Underlying object access -- returns a borrowed reference + PyObject* ptr() const; + + private: + PyObject* m_ptr; + }; + + class object : public object_base { public: -# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING - // copy constructor without NULL checking, for efficiency. This - // confuses VC6/7 so object_initializer also handles this case. - object(object const&); -# endif - // explicit conversion from any C++ object to Python template explicit object(T const& x) - : m_ptr(object_initializer::value>::get( + : object_base(object_initializer::value>::get( x, detail::convertible::check(&x))) { } // Throw error_already_set() if the handle is null. explicit object(handle<> const&); - - // Underlying object access -- returns a borrowed reference - PyObject* ptr() const; public: // implementation detail -- for internal use only explicit object(detail::borrowed_reference); explicit object(detail::new_reference); - - private: - PyObject* m_ptr; }; // @@ -327,26 +331,42 @@ namespace converter // inline object::object(handle<> const& x) - : m_ptr(incref(expect_non_null(x.get()))) + : object_base(incref(expect_non_null(x.get()))) {} -# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING // copy constructor without NULL checking, for efficiency -inline object::object(object const& rhs) +inline api::object_base::object_base(object_base const& rhs) : m_ptr(incref(rhs.m_ptr)) {} -# endif + +inline api::object_base::object_base(PyObject* p) + : m_ptr(p) +{} + +inline api::object_base& api::object_base::operator=(api::object_base const& rhs) +{ + Py_INCREF(rhs.m_ptr); + Py_DECREF(this->m_ptr); + this->m_ptr = rhs.m_ptr; + return *this; +} + + +inline api::object_base::~object_base() +{ + Py_DECREF(m_ptr); +} inline object::object(detail::borrowed_reference p) - : m_ptr(incref((PyObject*)p)) + : object_base(incref((PyObject*)p)) {} inline object::object(detail::new_reference p) - : m_ptr(expect_non_null((PyObject*)p)) + : object_base(expect_non_null((PyObject*)p)) {} -inline PyObject* object::ptr() const +inline PyObject* api::object_base::ptr() const { return m_ptr; } diff --git a/test/object.py b/test/object.py index 54744809..02da5ce8 100644 --- a/test/object.py +++ b/test/object.py @@ -62,6 +62,8 @@ >>> obj_const_getitem(d, 'foo') 1 >>> obj_setitem42(d, 'foo') +>>> obj_getitem(d, 'foo') +42 >>> d['foo'] 42 >>> obj_moveitem(d, 'foo', 'bar') @@ -92,6 +94,22 @@ >>> class X: pass ... >>> assert check_inplace(range(3), X()) + + + Now make sure that object is actually managing reference counts + +>>> import weakref +>>> class Z: pass +... +>>> z = Z() +>>> def death(r): print 'death' +... +>>> r = weakref.ref(z, death) +>>> z.foo = 1 +>>> obj_getattr(z, 'foo') +1 +>>> del z +death ''' def run(args = None): From b255796b33eca5448960f0abbaffc339b57289f6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 5 Jul 2002 15:25:40 +0000 Subject: [PATCH 0545/1042] Bug fixes [SVN r14308] --- doc/inheritance.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/inheritance.html b/doc/inheritance.html index 3cceb0d0..56e96872 100644 --- a/doc/inheritance.html +++ b/doc/inheritance.html @@ -81,10 +81,10 @@ BOOST_PYTHON_MODULE_INIT(my_module)     python::module_builder my_module("my_module");     python::class_builder<Base> base_class(my_module, "Base"); -    base_class.def(python::constructor<void>()); +    base_class.def(python::constructor<>());     python::class_builder<Derived> derived_class(my_module, "Derived"); -    derived_class.def(python::constructor<void>()); +    derived_class.def(python::constructor<>()); // Establish the inheritance relationship between Base and Derived derived_class.declare_base(base_class); @@ -137,10 +137,10 @@ struct Derived2 { int f(); };
    ...    python::class_builder<Base> base2_class(my_module, "Base2"); -   base2_class.def(python::constructor<void>()); +   base2_class.def(python::constructor<>());    python::class_builder<Derived2> derived2_class(my_module, "Derived2"); -   derived2_class.def(python::constructor<void>()); +   derived2_class.def(python::constructor<>()); derived_class.declare_base(base_class, python::without_downcast); From 8b611322e523afdbabcca2bc751f1f5404ee01b2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 8 Jul 2002 17:14:26 +0000 Subject: [PATCH 0546/1042] Use new void_return mechanism [SVN r14352] --- include/boost/python/call.hpp | 3 +- include/boost/python/call_method.hpp | 3 +- include/boost/python/detail/void_return.hpp | 41 +++++++++++++++++++ include/boost/python/preprocessed/call.hpp | 32 +++++++-------- .../boost/python/preprocessed/call_method.hpp | 32 +++++++-------- 5 files changed, 77 insertions(+), 34 deletions(-) create mode 100644 include/boost/python/detail/void_return.hpp diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp index 92661a68..e8c97038 100644 --- a/include/boost/python/call.hpp +++ b/include/boost/python/call.hpp @@ -14,6 +14,7 @@ # include # include # include +# include # include namespace boost { namespace python { @@ -27,7 +28,7 @@ template < class R \ BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM_PARAMS(nargs, class A) \ > \ -typename converter::return_from_python::result_type \ +typename detail::returnable::type \ call(PyObject* callable \ BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a)) \ , boost::type* = 0 \ diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp index 9bd07375..08e9eb68 100644 --- a/include/boost/python/call_method.hpp +++ b/include/boost/python/call_method.hpp @@ -14,6 +14,7 @@ # include # include # include +# include # include namespace boost { namespace python { @@ -27,7 +28,7 @@ template < class R \ BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM_PARAMS(nargs, class A) \ > \ -typename converter::return_from_python::result_type \ +typename detail::returnable::type \ call_method(PyObject* self, char const* name \ BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a)) \ , boost::type* = 0 \ diff --git a/include/boost/python/detail/void_return.hpp b/include/boost/python/detail/void_return.hpp new file mode 100644 index 00000000..28e919d7 --- /dev/null +++ b/include/boost/python/detail/void_return.hpp @@ -0,0 +1,41 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef VOID_RETURN_DWA200274_HPP +# define VOID_RETURN_DWA200274_HPP + +namespace boost { namespace python { namespace detail { + +struct void_return +{ + void_return() {} + private: + void operator=(void_return const&); +}; + +template +struct returnable +{ + typedef T type; +}; + +# ifdef BOOST_NO_VOID_RETURNS +template <> +struct returnable +{ + typedef void_return type; +}; + +# ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS +template <> struct returnable : returnable {}; +template <> struct returnable : returnable {}; +template <> struct returnable : returnable {}; +# endif + +# endif // BOOST_NO_VOID_RETURNS + +}}} // namespace boost::python::detail + +#endif // VOID_RETURN_DWA200274_HPP diff --git a/include/boost/python/preprocessed/call.hpp b/include/boost/python/preprocessed/call.hpp index 8280cd93..97ee70dd 100644 --- a/include/boost/python/preprocessed/call.hpp +++ b/include/boost/python/preprocessed/call.hpp @@ -11,7 +11,7 @@ // (replace-string "PyEval_CallFunction(" "\nPyEval_CallFunction(\n") template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,boost::type* =0) { converter::return_from_pythonconverter; @@ -20,7 +20,7 @@ call(PyObject*callable,boost::type* =0) callable,const_cast("(" ")"))); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,boost::type* =0) { converter::return_from_pythonconverter; @@ -30,7 +30,7 @@ call(PyObject*callable,A0 const&a0,boost::type* =0) ,converter::arg_to_python(a0).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,boost::type* =0) { converter::return_from_pythonconverter; @@ -41,7 +41,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,boost::type* =0) ,converter::arg_to_python(a1).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) { converter::return_from_pythonconverter; @@ -53,7 +53,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) ,converter::arg_to_python(a2).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::type* =0) { converter::return_from_pythonconverter; @@ -66,7 +66,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::ty ,converter::arg_to_python(a3).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,boost::type* =0) { converter::return_from_pythonconverter; @@ -80,7 +80,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const& ,converter::arg_to_python(a4).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,boost::type* =0) { converter::return_from_pythonconverter; @@ -95,7 +95,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const& ,converter::arg_to_python(a5).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,boost::type* =0) { converter::return_from_pythonconverter; @@ -111,7 +111,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const& ,converter::arg_to_python(a6).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,boost::type* =0) { converter::return_from_pythonconverter; @@ -128,7 +128,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const& ,converter::arg_to_python(a7).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,boost::type* =0) { converter::return_from_pythonconverter; @@ -146,7 +146,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const& ,converter::arg_to_python(a8).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,boost::type* =0) { converter::return_from_pythonconverter; @@ -165,7 +165,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const& ,converter::arg_to_python(a9).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,boost::type* =0) { converter::return_from_pythonconverter; @@ -185,7 +185,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const& ,converter::arg_to_python(a10).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,boost::type* =0) { converter::return_from_pythonconverter; @@ -206,7 +206,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const& ,converter::arg_to_python(a11).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,boost::type* =0) { converter::return_from_pythonconverter; @@ -228,7 +228,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const& ,converter::arg_to_python(a12).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,boost::type* =0) { converter::return_from_pythonconverter; @@ -251,7 +251,7 @@ call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const& ,converter::arg_to_python(a13).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14,boost::type* =0) { converter::return_from_pythonconverter; diff --git a/include/boost/python/preprocessed/call_method.hpp b/include/boost/python/preprocessed/call_method.hpp index 6ce1ecfb..a0783402 100644 --- a/include/boost/python/preprocessed/call_method.hpp +++ b/include/boost/python/preprocessed/call_method.hpp @@ -11,7 +11,7 @@ // (replace-string "PyEval_CallMethod(" "\nPyEval_CallMethod(\n") template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,boost::type* =0) { converter::return_from_pythonconverter; @@ -20,7 +20,7 @@ call_method(PyObject*self,char const*name,boost::type* =0) self,const_cast(name),const_cast("(" ")"))); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,boost::type* =0) { converter::return_from_pythonconverter; @@ -30,7 +30,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,boost::type* =0) ,converter::arg_to_python(a0).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,boost::type* =0) { converter::return_from_pythonconverter; @@ -41,7 +41,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,boost::type ,converter::arg_to_python(a1).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) { converter::return_from_pythonconverter; @@ -53,7 +53,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,bo ,converter::arg_to_python(a2).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::type* =0) { converter::return_from_pythonconverter; @@ -66,7 +66,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 ,converter::arg_to_python(a3).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,boost::type* =0) { converter::return_from_pythonconverter; @@ -80,7 +80,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 ,converter::arg_to_python(a4).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,boost::type* =0) { converter::return_from_pythonconverter; @@ -95,7 +95,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 ,converter::arg_to_python(a5).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,boost::type* =0) { converter::return_from_pythonconverter; @@ -111,7 +111,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 ,converter::arg_to_python(a6).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,boost::type* =0) { converter::return_from_pythonconverter; @@ -128,7 +128,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 ,converter::arg_to_python(a7).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,boost::type* =0) { converter::return_from_pythonconverter; @@ -146,7 +146,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 ,converter::arg_to_python(a8).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,boost::type* =0) { converter::return_from_pythonconverter; @@ -165,7 +165,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 ,converter::arg_to_python(a9).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,boost::type* =0) { converter::return_from_pythonconverter; @@ -185,7 +185,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 ,converter::arg_to_python(a10).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,boost::type* =0) { converter::return_from_pythonconverter; @@ -206,7 +206,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 ,converter::arg_to_python(a11).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,boost::type* =0) { converter::return_from_pythonconverter; @@ -228,7 +228,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 ,converter::arg_to_python(a12).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,boost::type* =0) { converter::return_from_pythonconverter; @@ -251,7 +251,7 @@ call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 ,converter::arg_to_python(a13).get())); } template -typename converter::return_from_python::result_type +typename detail::returnable::type call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14,boost::type* =0) { converter::return_from_pythonconverter; From 0945f79cedef1da1424138ec48945999893e4ade Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 8 Jul 2002 17:17:31 +0000 Subject: [PATCH 0547/1042] Various kinds of cleanup and code massage; preparing for rvalue from_python protocol change [SVN r14353] --- .../python/converter/arg_from_python.hpp | 5 +- .../converter/callback_from_python_base.hpp | 5 +- ..._function.hpp => constructor_function.hpp} | 14 +- .../python/converter/find_from_python.hpp | 4 +- .../python/converter/from_python_data.hpp | 129 ----------------- .../converter/from_python_stage1_data.hpp | 21 --- include/boost/python/converter/implicit.hpp | 7 +- .../converter/lvalue_from_python_chain.hpp | 4 +- .../boost/python/converter/registrations.hpp | 2 +- include/boost/python/converter/registry.hpp | 3 +- .../python/converter/return_from_python.hpp | 29 ++-- .../converter/rvalue_from_python_data.hpp | 133 ++++++++++++++++++ .../boost/python/detail/referent_storage.hpp | 55 ++++++++ 13 files changed, 225 insertions(+), 186 deletions(-) rename include/boost/python/converter/{from_python_function.hpp => constructor_function.hpp} (53%) delete mode 100644 include/boost/python/converter/from_python_data.hpp delete mode 100644 include/boost/python/converter/from_python_stage1_data.hpp create mode 100644 include/boost/python/converter/rvalue_from_python_data.hpp create mode 100644 include/boost/python/detail/referent_storage.hpp diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp index ccdb961c..fa59f1d7 100755 --- a/include/boost/python/converter/arg_from_python.hpp +++ b/include/boost/python/converter/arg_from_python.hpp @@ -11,13 +11,14 @@ # include # include # include -# include +# include # include # include # include # include # include # include +# include namespace boost { namespace python { @@ -48,7 +49,7 @@ struct pointer_cref_arg_from_python private: // storage for a U* // needed because not all compilers will let us declare U* as the // return type of operator() -- we return U*const& instead - typename detail::referent_storage::type m_result; + typename python::detail::referent_storage::type m_result; }; // Base class for pointer and reference converters diff --git a/include/boost/python/converter/callback_from_python_base.hpp b/include/boost/python/converter/callback_from_python_base.hpp index 117ba145..462857af 100644 --- a/include/boost/python/converter/callback_from_python_base.hpp +++ b/include/boost/python/converter/callback_from_python_base.hpp @@ -12,12 +12,13 @@ namespace detail { // Throw an exception - BOOST_PYTHON_DECL void throw_if_not_registered(rvalue_stage1_data const&); - BOOST_PYTHON_DECL void* convert_rvalue(PyObject*, rvalue_stage1_data& data, void* storage); + BOOST_PYTHON_DECL void throw_if_not_registered(rvalue_from_python_stage1_data const&); + BOOST_PYTHON_DECL void* convert_rvalue(PyObject*, rvalue_from_python_stage1_data&, void* storage); BOOST_PYTHON_DECL void throw_if_not_registered(lvalue_from_python_registration*const&); BOOST_PYTHON_DECL void* callback_convert_reference(PyObject*, lvalue_from_python_registration*const&); BOOST_PYTHON_DECL void* callback_convert_pointer(PyObject*, lvalue_from_python_registration*const&); + BOOST_PYTHON_DECL void absorb_result(PyObject*); } }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/from_python_function.hpp b/include/boost/python/converter/constructor_function.hpp similarity index 53% rename from include/boost/python/converter/from_python_function.hpp rename to include/boost/python/converter/constructor_function.hpp index eea96372..f3c49bd4 100644 --- a/include/boost/python/converter/from_python_function.hpp +++ b/include/boost/python/converter/constructor_function.hpp @@ -3,16 +3,16 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef FROM_PYTHON_FUNCTION_DWA2002128_HPP -# define FROM_PYTHON_FUNCTION_DWA2002128_HPP - -# include +#ifndef CONSTRUCTOR_FUNCTION_DWA200278_HPP +# define CONSTRUCTOR_FUNCTION_DWA200278_HPP namespace boost { namespace python { namespace converter { -struct rvalue_stage1_data; -typedef void (*constructor_function)(PyObject* source, rvalue_stage1_data*); +// Declares the type of functions used to construct C++ objects for +// rvalue from_python conversions. +struct rvalue_from_python_stage1_data; +typedef void (*constructor_function)(PyObject* source, rvalue_from_python_stage1_data*); }}} // namespace boost::python::converter -#endif // FROM_PYTHON_FUNCTION_DWA2002128_HPP +#endif // CONSTRUCTOR_FUNCTION_DWA200278_HPP diff --git a/include/boost/python/converter/find_from_python.hpp b/include/boost/python/converter/find_from_python.hpp index 709c5de0..659848ce 100644 --- a/include/boost/python/converter/find_from_python.hpp +++ b/include/boost/python/converter/find_from_python.hpp @@ -8,7 +8,7 @@ # include # include -# include +# include namespace boost { namespace python { namespace converter { @@ -18,7 +18,7 @@ struct rvalue_from_python_registration; BOOST_PYTHON_DECL void* find( PyObject* source, lvalue_from_python_registration const*); -BOOST_PYTHON_DECL rvalue_stage1_data find( +BOOST_PYTHON_DECL rvalue_from_python_stage1_data find( PyObject* source, rvalue_from_python_registration const*); BOOST_PYTHON_DECL rvalue_from_python_registration const* find_chain( diff --git a/include/boost/python/converter/from_python_data.hpp b/include/boost/python/converter/from_python_data.hpp deleted file mode 100644 index b0d8a49f..00000000 --- a/include/boost/python/converter/from_python_data.hpp +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FROM_PYTHON_AUX_DATA_DWA2002128_HPP -# define FROM_PYTHON_AUX_DATA_DWA2002128_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -namespace detail -{ - template struct referent_size; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - template - struct referent_size - { - BOOST_STATIC_CONSTANT( - std::size_t, value = sizeof(T)); - }; - -# else - - template struct referent_size - { - static T f(); - BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(f())); - }; - -# endif - struct alignment_dummy; - typedef void (*function_ptr)(); - typedef int (alignment_dummy::*member_ptr); - typedef int (alignment_dummy::*member_function_ptr)(); - -# define BOOST_PYTHON_ALIGNMENT_TYPES BOOST_PP_TUPLE_TO_LIST( \ - 11, ( \ - char, short, int, long, float, double, long double \ - , void*, function_ptr, member_ptr, member_function_ptr)) - -# define BOOST_PYTHON_CHOOSE_LOWER_SIZE(R,P,I,T) \ - typename mpl::select_type< \ - sizeof(T) <= target, T, char>::type BOOST_PP_CAT(t,I); - -# define BOOST_PYTHON_CHOOSE_T(R,P,I,T) T BOOST_PP_CAT(t,I); - - template - union lower_size - { - BOOST_PP_LIST_FOR_EACH_I( - BOOST_PYTHON_CHOOSE_LOWER_SIZE - , ignored, BOOST_PYTHON_ALIGNMENT_TYPES) - }; - - template - union aligned_storage - { - Align align; - char bytes[size]; - }; - - template - struct referent_storage - { - typedef lower_size::value> align_t; - typedef aligned_storage::value> type; - }; -} - -template -struct rvalue_base_data -{ - rvalue_stage1_data stage1; - - typename detail::referent_storage< - typename add_reference::type - >::type storage; -}; - -template -struct rvalue_data : rvalue_base_data -{ - rvalue_data(rvalue_stage1_data const&); - rvalue_data(void*); - ~rvalue_data(); - private: - typedef typename add_reference::type>::type ref_type; -}; - -// -// Implementataions -// -template -inline rvalue_data::rvalue_data(rvalue_stage1_data const& stage1) -{ - this->stage1 = stage1; -} - -template -inline rvalue_data::rvalue_data(void* convertible) -{ - this->stage1.convertible = convertible; -} - -template -inline rvalue_data::~rvalue_data() -{ - if (this->stage1.convertible == this->storage.bytes) - python::detail::destroy_reference(this->storage.bytes); -} - -}}} // namespace boost::python::converter - -#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP diff --git a/include/boost/python/converter/from_python_stage1_data.hpp b/include/boost/python/converter/from_python_stage1_data.hpp deleted file mode 100644 index 50fd74ad..00000000 --- a/include/boost/python/converter/from_python_stage1_data.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef FROM_PYTHON_STAGE1_DATA_DWA2002223_HPP -# define FROM_PYTHON_STAGE1_DATA_DWA2002223_HPP - -# include - -namespace boost { namespace python { namespace converter { - -struct rvalue_stage1_data -{ - void* convertible; - constructor_function construct; -}; - -}}} // namespace boost::python::converter - -#endif // FROM_PYTHON_STAGE1_DATA_DWA2002223_HPP diff --git a/include/boost/python/converter/implicit.hpp b/include/boost/python/converter/implicit.hpp index 6a22a3d6..ab78d8a1 100644 --- a/include/boost/python/converter/implicit.hpp +++ b/include/boost/python/converter/implicit.hpp @@ -5,8 +5,7 @@ // to its suitability for any purpose. #ifndef IMPLICIT_DWA2002326_HPP # define IMPLICIT_DWA2002326_HPP -# include -# include +# include # include namespace boost { namespace python { namespace converter { @@ -22,7 +21,7 @@ struct implicit find_chain(obj, rvalue_from_python_chain::value)); } - static void construct(PyObject* obj, rvalue_stage1_data* data) + static void construct(PyObject* obj, rvalue_from_python_stage1_data* data) { // This is the registration we got from the convertible step rvalue_from_python_registration const* registration @@ -36,7 +35,7 @@ struct implicit if (registration->construct != 0) registration->construct(obj, &intermediate_data.stage1); - void* storage = ((rvalue_base_data*)data)->storage.bytes; + void* storage = ((rvalue_from_python_storage*)data)->storage.bytes; # if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13012108 // vc7.01 alpha workaround new (storage) Target(*static_cast(intermediate_data.stage1.convertible)); # else diff --git a/include/boost/python/converter/lvalue_from_python_chain.hpp b/include/boost/python/converter/lvalue_from_python_chain.hpp index 387c1863..0695025c 100644 --- a/include/boost/python/converter/lvalue_from_python_chain.hpp +++ b/include/boost/python/converter/lvalue_from_python_chain.hpp @@ -17,8 +17,8 @@ namespace boost { namespace python { namespace converter { // Given T == U*cv&, T == U*, or T == U&, lvalue_from_python_chain // declares a "templated global reference" to the lvalue from_python // converter chain for U. The optional bool second argument is_return, -// when true, removes special treatment for T == U*cv& so that the -// converter for U* is found. +// when true, removes the usual special treatment which causes the +// converter for U* to bve used when T == U*cv& namespace detail { template diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp index 8a27741c..636e8fa0 100644 --- a/include/boost/python/converter/registrations.hpp +++ b/include/boost/python/converter/registrations.hpp @@ -6,7 +6,7 @@ #ifndef REGISTRATIONS_DWA2002223_HPP # define REGISTRATIONS_DWA2002223_HPP -# include +# include namespace boost { namespace python { namespace converter { diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index cf5daa5e..2cf97d98 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -9,7 +9,8 @@ # include # include # include -# include +# include +# include namespace boost { namespace python { namespace converter { diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index cb16c888..2272f94b 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -7,10 +7,12 @@ # define RETURN_FROM_PYTHON_DWA200265_HPP # include -# include +# include # include # include # include +# include +# include namespace boost { namespace python { namespace converter { @@ -19,6 +21,7 @@ namespace detail template struct return_pointer_from_python { + typedef T result_type; return_pointer_from_python(); T operator()(PyObject*) const; }; @@ -26,6 +29,7 @@ namespace detail template struct return_reference_from_python { + typedef T result_type; return_reference_from_python(); T operator()(PyObject*) const; }; @@ -33,8 +37,9 @@ namespace detail template struct return_rvalue_from_python { + typedef call_traits::param_type result_type; return_rvalue_from_python(); - T const& operator()(PyObject*); + result_type operator()(PyObject*); private: rvalue_data m_data; }; @@ -64,27 +69,20 @@ template struct return_from_python : detail::select_return_from_python::type { - typedef T result_type; -}; - -struct void_result -{ - private: - void_result() {} - void operator=(void_result const&); - - friend struct return_from_python; }; // Specialization as a convenience for call and call_method template <> struct return_from_python { - typedef void_result result_type; + typedef python::detail::returnable::type result_type; + result_type operator()(PyObject* x) const { - Py_DECREF(expect_non_null(x)); + converter::detail::absorb_result(x); +# ifdef BOOST_NO_VOID_RETURNS return result_type(); +# endif } }; @@ -101,7 +99,8 @@ namespace detail } template - inline T const& return_rvalue_from_python::operator()(PyObject* obj) + inline typename return_rvalue_from_python::result_type + return_rvalue_from_python::operator()(PyObject* obj) { return *(T*)convert_rvalue(obj, m_data.stage1, m_data.storage.bytes); } diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp new file mode 100644 index 00000000..db4103c1 --- /dev/null +++ b/include/boost/python/converter/rvalue_from_python_data.hpp @@ -0,0 +1,133 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FROM_PYTHON_AUX_DATA_DWA2002128_HPP +# define FROM_PYTHON_AUX_DATA_DWA2002128_HPP + +# include +# include +# include +# include +# include + +// Data management for potential rvalue conversions from Python to C++ +// types. When a client requests a conversion to T* or T&, we +// generally require that an object of type T exists in the source +// Python object, and the code here does not apply**. This implements +// conversions which may create new temporaries of type T. The classic +// example is a conversion which converts a Python tuple to a +// std::vector. Since no std::vector lvalue exists in the Python +// object -- it must be created "on-the-fly" by the converter, and +// which must manage the lifetime of the created object. +// +// Note that the client is not precluded from using a registered +// lvalue conversion to T in this case. In other words, we will +// happily accept a Python object which /does/ contain a std::vector +// lvalue, provided an appropriate converter is registered. So, while +// this is an rvalue conversion from the client's point-of-view, the +// converter registry may serve up lvalue or rvalue conversions for +// the target type. +// +// ** C++ argument from_python conversions to T const& are an +// exception to the rule for references: since in C++, const +// references can bind to temporary rvalues, we allow rvalue +// converters to be chosen when the target type is T const& for some +// T. +namespace boost { namespace python { namespace converter { + +// Conversions begin by filling in and returning a copy of this +// structure. The process looks up a converter in the rvalue converter +// registry for the target type. It calls the convertible() function +// of each registered converter, passing the source PyObject* as an +// argument, until a non-null result is returned. This result goes in +// the convertible field, and the converter's construct() function is +// stored in the construct field. +// +// If no appropriate converter is found, conversion fails and the +// convertible field is null. This step is expected not to throw an +// exception, and when used in argument conversion for wrapped C++ +// functions, it causes overload resolution to reject the current +// function but not to fail completely. If +// +// If an lvalue converter is matched, its convertible() function is +// expected to return a pointer to the stored T object; its +// construct() function will be NULL. The convertible() function of +// rvalue converters may return any non-singular pointer; the actual +// target object will only be available once the converter's +// construct() function is called. +struct rvalue_from_python_stage1_data +{ + void* convertible; + constructor_function construct; +}; + +// Augments rvalue_from_python_stage1_data by adding storage for +// constructing an object of remove_reference::type. The +// construct() function of rvalue converters (stored in m_construct +// above) will cast the rvalue_from_python_stage1_data to an +// appropriate instantiation of this template in order to access that +// storage. +template +struct rvalue_from_python_storage +{ + rvalue_from_python_stage1_data stage1; + + // Storage for the result, in case an rvalue must be constructed + typename python::detail::referent_storage< + typename add_reference::type + >::type storage; +}; + +// Augments rvalue_from_python_storage with a destructor. If +// stage1.convertible == storage.bytes, it indicates that an object of +// remove_reference::type has been constructed in storage and +// should will be destroyed in ~rvalue_data(). It is crucial that +// successful rvalue conversions establish this equality and that +// unsuccessful ones do not. +template +struct rvalue_data : rvalue_from_python_storage +{ + // This must always be a POD struct with m_data its first member. + BOOST_STATIC_ASSERT(offsetof(rvalue_from_python_storage,stage1) == 0); + + // The usual constructor + rvalue_data(rvalue_from_python_stage1_data const&); + + // This constructor just sets m_convertible -- used by + // implicitly_convertible<> to perform the final step of the + // conversion, where the construct() function is already known. + rvalue_data(void* convertible); + + // Destroys any object constructed in the storage. + ~rvalue_data(); + private: + typedef typename add_reference::type>::type ref_type; +}; + +// +// Implementataions +// +template +inline rvalue_data::rvalue_data(rvalue_from_python_stage1_data const& stage1) +{ + this->stage1 = stage1; +} + +template +inline rvalue_data::rvalue_data(void* convertible) +{ + this->stage1.convertible = convertible; +} + +template +inline rvalue_data::~rvalue_data() +{ + if (this->stage1.convertible == this->storage.bytes) + python::detail::destroy_reference(this->storage.bytes); +} + +}}} // namespace boost::python::converter + +#endif // FROM_PYTHON_AUX_DATA_DWA2002128_HPP diff --git a/include/boost/python/detail/referent_storage.hpp b/include/boost/python/detail/referent_storage.hpp new file mode 100644 index 00000000..81ab33ea --- /dev/null +++ b/include/boost/python/detail/referent_storage.hpp @@ -0,0 +1,55 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef REFERENT_STORAGE_DWA200278_HPP +# define REFERENT_STORAGE_DWA200278_HPP +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +struct alignment_dummy; +typedef void (*function_ptr)(); +typedef int (alignment_dummy::*member_ptr); +typedef int (alignment_dummy::*member_function_ptr)(); + +# define BOOST_PYTHON_ALIGNER(T, n) \ + typename mpl::select_type< \ + sizeof(T) <= size, T, char>::type t##n + +// Storage for size bytes, aligned to all fundamental types no larger than size +template +union aligned_storage +{ + BOOST_PYTHON_ALIGNER(char, 0); + BOOST_PYTHON_ALIGNER(short, 1); + BOOST_PYTHON_ALIGNER(int, 2); + BOOST_PYTHON_ALIGNER(long, 3); + BOOST_PYTHON_ALIGNER(float, 4); + BOOST_PYTHON_ALIGNER(double, 5); + BOOST_PYTHON_ALIGNER(long double, 6); + BOOST_PYTHON_ALIGNER(void*, 7); + BOOST_PYTHON_ALIGNER(function_ptr, 8); + BOOST_PYTHON_ALIGNER(member_ptr, 9); + BOOST_PYTHON_ALIGNER(member_function_ptr, 10); + char bytes[size]; +}; + +# undef BOOST_PYTHON_ALIGNER + +// A metafunction returning a POD type which can store U, where T == +// U&. If T is not a reference type, returns a POD which can store T. +template +struct referent_storage +{ + typedef aligned_storage type; +}; + +}}} // namespace boost::python::detail + +#endif // REFERENT_STORAGE_DWA200278_HPP From 182b6755f59b79ee87be0969a2c137a59f999670 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 8 Jul 2002 19:17:00 +0000 Subject: [PATCH 0548/1042] rvalue_data -> rvalue_from_python_data [SVN r14355] --- .../python/converter/arg_from_python.hpp | 2 +- include/boost/python/converter/implicit.hpp | 2 +- .../python/converter/return_from_python.hpp | 2 +- .../converter/rvalue_from_python_data.hpp | 20 +++++++++---------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp index fa59f1d7..cf9e15ae 100755 --- a/include/boost/python/converter/arg_from_python.hpp +++ b/include/boost/python/converter/arg_from_python.hpp @@ -111,7 +111,7 @@ struct arg_rvalue_from_python result_type operator()(PyObject*); private: - rvalue_data m_data; + rvalue_from_python_data m_data; }; diff --git a/include/boost/python/converter/implicit.hpp b/include/boost/python/converter/implicit.hpp index ab78d8a1..48d680aa 100644 --- a/include/boost/python/converter/implicit.hpp +++ b/include/boost/python/converter/implicit.hpp @@ -28,7 +28,7 @@ struct implicit = static_cast(data->convertible); // Call the convertible function again - rvalue_data intermediate_data(registration->convertible(obj)); + rvalue_from_python_data intermediate_data(registration->convertible(obj)); // Use the result to construct the source type if the first // converter was an rvalue converter. diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 2272f94b..85fd3671 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -41,7 +41,7 @@ namespace detail return_rvalue_from_python(); result_type operator()(PyObject*); private: - rvalue_data m_data; + rvalue_from_python_data m_data; }; template diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp index db4103c1..90d5009c 100644 --- a/include/boost/python/converter/rvalue_from_python_data.hpp +++ b/include/boost/python/converter/rvalue_from_python_data.hpp @@ -83,25 +83,25 @@ struct rvalue_from_python_storage // Augments rvalue_from_python_storage with a destructor. If // stage1.convertible == storage.bytes, it indicates that an object of // remove_reference::type has been constructed in storage and -// should will be destroyed in ~rvalue_data(). It is crucial that -// successful rvalue conversions establish this equality and that -// unsuccessful ones do not. +// should will be destroyed in ~rvalue_from_python_data(). It is +// crucial that successful rvalue conversions establish this equality +// and that unsuccessful ones do not. template -struct rvalue_data : rvalue_from_python_storage +struct rvalue_from_python_data : rvalue_from_python_storage { // This must always be a POD struct with m_data its first member. BOOST_STATIC_ASSERT(offsetof(rvalue_from_python_storage,stage1) == 0); // The usual constructor - rvalue_data(rvalue_from_python_stage1_data const&); + rvalue_from_python_data(rvalue_from_python_stage1_data const&); // This constructor just sets m_convertible -- used by // implicitly_convertible<> to perform the final step of the // conversion, where the construct() function is already known. - rvalue_data(void* convertible); + rvalue_from_python_data(void* convertible); // Destroys any object constructed in the storage. - ~rvalue_data(); + ~rvalue_from_python_data(); private: typedef typename add_reference::type>::type ref_type; }; @@ -110,19 +110,19 @@ struct rvalue_data : rvalue_from_python_storage // Implementataions // template -inline rvalue_data::rvalue_data(rvalue_from_python_stage1_data const& stage1) +inline rvalue_from_python_data::rvalue_from_python_data(rvalue_from_python_stage1_data const& stage1) { this->stage1 = stage1; } template -inline rvalue_data::rvalue_data(void* convertible) +inline rvalue_from_python_data::rvalue_from_python_data(void* convertible) { this->stage1.convertible = convertible; } template -inline rvalue_data::~rvalue_data() +inline rvalue_from_python_data::~rvalue_from_python_data() { if (this->stage1.convertible == this->storage.bytes) python::detail::destroy_reference(this->storage.bytes); From 7d3227128c9c9d201d1a5dcca687ab0d3e294fac Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 8 Jul 2002 21:35:18 +0000 Subject: [PATCH 0549/1042] rvalue_data -> rvalue_from_python_data [SVN r14357] --- src/converter/builtin_converters.cpp | 6 +++--- src/converter/callback.cpp | 15 ++++++++++----- src/converter/from_python.cpp | 8 +++++--- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index 038d0ff5..96c8b2c5 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -50,14 +50,14 @@ namespace return slot && *slot ? slot : 0; } - static void construct(PyObject* obj, rvalue_stage1_data* data) + static void construct(PyObject* obj, rvalue_from_python_stage1_data* data) { // Get the (intermediate) source object unaryfunc creator = *static_cast(data->convertible); handle<> intermediate(creator(obj)); // Get the location in which to construct - void* storage = ((rvalue_base_data*)data)->storage.bytes; + void* storage = ((rvalue_from_python_storage*)data)->storage.bytes; new (storage) T(SlotPolicy::extract(intermediate.get())); // record successful construction diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index e07b4869..bf72e9e6 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -17,7 +17,7 @@ namespace detail namespace { - inline PyObject* convert(void const volatile* source, to_python_function_t converter) + inline PyObject* convert_to_python(void const volatile* source, to_python_function_t converter) { if (converter == 0) { @@ -36,14 +36,14 @@ namespace detail arg_to_python_base::arg_to_python_base( void const volatile* source, to_python_function_t converter) # if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140 - : handle<>(convert(source, converter)) + : handle<>(convert_to_python(source, converter)) # else - : m_ptr(convert(source, converter)) + : m_ptr(convert_to_python(source, converter)) # endif { } - BOOST_PYTHON_DECL void throw_if_not_registered(rvalue_stage1_data const& data) + BOOST_PYTHON_DECL void throw_if_not_registered(rvalue_from_python_stage1_data const& data) { if (!data.convertible) { @@ -108,7 +108,7 @@ namespace detail throw_error_already_set(); } - BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_stage1_data& data, void* storage) + BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_from_python_stage1_data& data, void* storage) { handle<> holder(src); @@ -126,6 +126,11 @@ namespace detail return data.convertible; } + + BOOST_PYTHON_DECL void absorb_result(PyObject* o) + { + Py_DECREF(expect_non_null(o)); + } } }}} // namespace boost::python::converter diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 805902a5..826f453c 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -6,17 +6,19 @@ #include #include -#include +#include +#include +#include #include #include namespace boost { namespace python { namespace converter { -BOOST_PYTHON_DECL rvalue_stage1_data find( +BOOST_PYTHON_DECL rvalue_from_python_stage1_data find( PyObject* source , rvalue_from_python_registration const* chain) { - rvalue_stage1_data data; + rvalue_from_python_stage1_data data; data.convertible = 0; for (;chain != 0; chain = chain->next) { From c1f8ae662f07038ffc156f657a7e99707a350b8f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Jul 2002 10:27:18 +0000 Subject: [PATCH 0550/1042] Added missing typename [SVN r14367] --- include/boost/python/converter/return_from_python.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 85fd3671..9bfca7ec 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -37,7 +37,7 @@ namespace detail template struct return_rvalue_from_python { - typedef call_traits::param_type result_type; + typedef typename call_traits::param_type result_type; return_rvalue_from_python(); result_type operator()(PyObject*); private: From c7225a059f538f02acec13d2c1803b8e6e7db784 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Jul 2002 15:20:18 +0000 Subject: [PATCH 0551/1042] workaround for CWPro7.2 [SVN r14372] --- include/boost/python/converter/rvalue_from_python_data.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp index 90d5009c..8b0c6091 100644 --- a/include/boost/python/converter/rvalue_from_python_data.hpp +++ b/include/boost/python/converter/rvalue_from_python_data.hpp @@ -89,8 +89,10 @@ struct rvalue_from_python_storage template struct rvalue_from_python_data : rvalue_from_python_storage { +# if !defined(__MWERKS__) || __MWERKS__ >= 0x3000 // This must always be a POD struct with m_data its first member. BOOST_STATIC_ASSERT(offsetof(rvalue_from_python_storage,stage1) == 0); +# endif // The usual constructor rvalue_from_python_data(rvalue_from_python_stage1_data const&); From ea74e34446e58083b92847c468ce268cf7a47ab4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Jul 2002 18:38:02 +0000 Subject: [PATCH 0552/1042] CWPro8 bug workarounds [SVN r14377] --- include/boost/python/object_operators.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/python/object_operators.hpp b/include/boost/python/object_operators.hpp index 1ac6e426..801218e6 100644 --- a/include/boost/python/object_operators.hpp +++ b/include/boost/python/object_operators.hpp @@ -13,7 +13,7 @@ namespace boost { namespace python { namespace api { template object object_operators::operator()() const { - object const& f = *static_cast(this); + object_cref2 f = *static_cast(this); return call(f.ptr()); } @@ -22,7 +22,7 @@ template inline object_operators::operator bool_type() const { - object const& x = *static_cast(this); + object_cref2 x = *static_cast(this); return PyObject_IsTrue(x.ptr()) ? &object::ptr : 0; } @@ -30,7 +30,7 @@ template inline bool object_operators::operator!() const { - object const& x = *static_cast(this); + object_cref2 x = *static_cast(this); return !PyObject_IsTrue(x.ptr()); } From 128c0ed5a1e104a66a55250e5e2f6c9fb0a852b5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Jul 2002 18:43:00 +0000 Subject: [PATCH 0553/1042] Fixes for MSVC [SVN r14378] --- .../boost/python/detail/indirect_traits.hpp | 92 +++++++++++++++---- 1 file changed, 75 insertions(+), 17 deletions(-) diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index ba184a7d..f22c270b 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -257,43 +257,101 @@ struct is_pointer_to_function = sizeof(::boost::detail::is_function_tester(t)) == sizeof(::boost::type_traits::yes_type)); }; +struct false_helper1 +{ + template + struct apply + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; +}; + template typename is_const_help::type reference_to_const_helper(V&); outer_no_type reference_to_const_helper(...); +template +struct is_reference_to_const_helper1 +{ + template + struct apply + { + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); + }; +}; + +template <> +struct is_reference_to_const_helper1 : false_helper1 +{ +}; + + template struct is_reference_to_const + : is_reference_to_const_helper1::value>::template apply { - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = (is_reference::value - && sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type))); }; + + +template +struct is_reference_to_non_const_helper1 +{ + template + struct apply + { + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)); + }; +}; + +template <> +struct is_reference_to_non_const_helper1 : false_helper1 +{ +}; + + template struct is_reference_to_non_const + : is_reference_to_non_const_helper1::value>::template apply { - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = (is_reference::value - && sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type))); }; + template -typename is_volatile_help::type reference_to_volatile_helper(V&); -outer_no_type reference_to_volatile_helper(...); +typename is_volatile_help::type reference_to_volatile_helper(V&); +outer_no_type +reference_to_volatile_helper(...); + +template +struct is_reference_to_volatile_helper1 +{ + template + struct apply + { + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)); + }; +}; + +template <> +struct is_reference_to_volatile_helper1 : false_helper1 +{ +}; + template struct is_reference_to_volatile + : is_reference_to_volatile_helper1::value>::template apply { - static T t; - BOOST_STATIC_CONSTANT( - bool, value - = (is_reference::value - && sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type))); }; From 222396759b88462e551543e3964bc1ffdf1faac3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Jul 2002 18:49:09 +0000 Subject: [PATCH 0554/1042] MWERKS bug workaround [SVN r14379] --- .../boost/python/detail/referent_storage.hpp | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/include/boost/python/detail/referent_storage.hpp b/include/boost/python/detail/referent_storage.hpp index 81ab33ea..aebacf64 100644 --- a/include/boost/python/detail/referent_storage.hpp +++ b/include/boost/python/detail/referent_storage.hpp @@ -6,9 +6,6 @@ #ifndef REFERENT_STORAGE_DWA200278_HPP # define REFERENT_STORAGE_DWA200278_HPP # include -# include -# include -# include # include namespace boost { namespace python { namespace detail { @@ -42,12 +39,35 @@ union aligned_storage # undef BOOST_PYTHON_ALIGNER + // Compute the size of T's referent. We wouldn't need this at all, + // but sizeof() is broken in CodeWarriors <= 8.0 + template struct referent_size; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + template + struct referent_size + { + BOOST_STATIC_CONSTANT( + std::size_t, value = sizeof(T)); + }; + +# else + + template struct referent_size + { + static T f(); + BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(f())); + }; + +# endif + // A metafunction returning a POD type which can store U, where T == // U&. If T is not a reference type, returns a POD which can store T. template struct referent_storage { - typedef aligned_storage type; + typedef aligned_storage::value> type; }; }}} // namespace boost::python::detail From 5a0d84f185be46620f8dc243eb084824a382bb81 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Jul 2002 18:57:53 +0000 Subject: [PATCH 0555/1042] Smarter range checking [SVN r14380] --- src/converter/builtin_converters.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index 96c8b2c5..daff89d3 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -91,11 +91,10 @@ namespace { static T extract(PyObject* intermediate) { - return numeric_cast( - PyFloat_Check(intermediate) - ? PyFloat_AS_DOUBLE(intermediate) - : PyInt_AS_LONG(intermediate) - ); + return PyFloat_Check(intermediate) + ? numeric_cast(PyFloat_AS_DOUBLE(intermediate)) + : numeric_cast(PyInt_AS_LONG(intermediate)) + ; } }; From 54a551e488324c448659ff53ef21b4d57f93a657 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Jul 2002 18:58:45 +0000 Subject: [PATCH 0556/1042] Add missing prototype [SVN r14381] --- src/object/class.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/object/class.cpp b/src/object/class.cpp index 3f03df64..7056ff1e 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -5,6 +5,7 @@ // to its suitability for any purpose. #include #include +#include #include #include #include From 6cb4fbb1c4660fbb0bde805c51a16f8f9cf26f5d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Jul 2002 19:21:52 +0000 Subject: [PATCH 0557/1042] Use Paul M's preprocessor iteration [SVN r14383] --- .../python/preprocessed/arg_tuple_size.hpp | 583 ---- include/boost/python/preprocessed/args.hpp | 169 - include/boost/python/preprocessed/call.hpp | 278 -- .../boost/python/preprocessed/call_method.hpp | 277 -- include/boost/python/preprocessed/caller.hpp | 413 --- .../boost/python/preprocessed/make_holder.hpp | 507 --- .../preprocessed/member_function_cast.hpp | 396 --- .../boost/python/preprocessed/object_call.hpp | 130 - .../python/preprocessed/pointer_holder.hpp | 230 -- .../ptr_holder_back_reference.hpp | 261 -- include/boost/python/preprocessed/result.hpp | 412 --- .../preprocessed/returning_non_void.hpp | 2805 ----------------- .../python/preprocessed/returning_void.hpp | 2565 --------------- include/boost/python/preprocessed/target.hpp | 402 --- .../python/preprocessed/value_holder.hpp | 228 -- .../value_holder_back_reference.hpp | 245 -- 16 files changed, 9901 deletions(-) delete mode 100644 include/boost/python/preprocessed/arg_tuple_size.hpp delete mode 100644 include/boost/python/preprocessed/args.hpp delete mode 100644 include/boost/python/preprocessed/call.hpp delete mode 100644 include/boost/python/preprocessed/call_method.hpp delete mode 100644 include/boost/python/preprocessed/caller.hpp delete mode 100644 include/boost/python/preprocessed/make_holder.hpp delete mode 100644 include/boost/python/preprocessed/member_function_cast.hpp delete mode 100755 include/boost/python/preprocessed/object_call.hpp delete mode 100644 include/boost/python/preprocessed/pointer_holder.hpp delete mode 100644 include/boost/python/preprocessed/ptr_holder_back_reference.hpp delete mode 100755 include/boost/python/preprocessed/result.hpp delete mode 100644 include/boost/python/preprocessed/returning_non_void.hpp delete mode 100644 include/boost/python/preprocessed/returning_void.hpp delete mode 100755 include/boost/python/preprocessed/target.hpp delete mode 100644 include/boost/python/preprocessed/value_holder.hpp delete mode 100644 include/boost/python/preprocessed/value_holder_back_reference.hpp diff --git a/include/boost/python/preprocessed/arg_tuple_size.hpp b/include/boost/python/preprocessed/arg_tuple_size.hpp deleted file mode 100644 index cc85236a..00000000 --- a/include/boost/python/preprocessed/arg_tuple_size.hpp +++ /dev/null @@ -1,583 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ARG_TUPLE_SIZE_DWA2002410_HPP -# define ARG_TUPLE_SIZE_DWA2002410_HPP - -# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=0); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=1); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=2); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=3); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=4); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=5); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=6); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=7); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=8); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=9); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=10); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=11); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=12); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=13); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=14); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=15); -}; - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=1); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=2); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=3); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=4); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=5); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=6); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=7); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=8); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=9); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=10); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=11); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=12); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=13); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=14); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=15); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=16); -}; - -// Metrowerks thinks this creates ambiguities -# if !defined(__MWERKS__) || __MWERKS__ > 0x2407 -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=1); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=2); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=3); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=4); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=5); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=6); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=7); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=8); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=9); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=10); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=11); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=12); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=13); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=14); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=15); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=16); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=1); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=2); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=3); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=4); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=5); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=6); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=7); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=8); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=9); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=10); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=11); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=12); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=13); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=14); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=15); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=16); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=1); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=2); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=3); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=4); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=5); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=6); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=7); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=8); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=9); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=10); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=11); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=12); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=13); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=14); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=15); -}; -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t,value=16); -}; -# endif -# else - -templatechar_array<0> -arg_tuple_size_helper(R(*)()); -templatechar_array<1> -arg_tuple_size_helper(R(*)(A0)); -templatechar_array<2> -arg_tuple_size_helper(R(*)(A0,A1)); -templatechar_array<3> -arg_tuple_size_helper(R(*)(A0,A1,A2)); -templatechar_array<4> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3)); -templatechar_array<5> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4)); -templatechar_array<6> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5)); -templatechar_array<7> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6)); -templatechar_array<8> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7)); -templatechar_array<9> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8)); -templatechar_array<10> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9)); -templatechar_array<11> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)); -templatechar_array<12> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)); -templatechar_array<13> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)); -templatechar_array<14> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)); -templatechar_array<15> -arg_tuple_size_helper(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)); - - -templatechar_array<1> -arg_tuple_size_helper(R(A0::*)()); -templatechar_array<2> -arg_tuple_size_helper(R(A0::*)(A1)); -templatechar_array<3> -arg_tuple_size_helper(R(A0::*)(A1,A2)); -templatechar_array<4> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3)); -templatechar_array<5> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)); -templatechar_array<6> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)); -templatechar_array<7> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)); -templatechar_array<8> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)); -templatechar_array<9> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)); -templatechar_array<10> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)); -templatechar_array<11> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)); -templatechar_array<12> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)); -templatechar_array<13> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)); -templatechar_array<14> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)); -templatechar_array<15> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)); -templatechar_array<16> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)); -templatechar_array<1> -arg_tuple_size_helper(R(A0::*)()const); -templatechar_array<2> -arg_tuple_size_helper(R(A0::*)(A1)const); -templatechar_array<3> -arg_tuple_size_helper(R(A0::*)(A1,A2)const); -templatechar_array<4> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3)const); -templatechar_array<5> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)const); -templatechar_array<6> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)const); -templatechar_array<7> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)const); -templatechar_array<8> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const); -templatechar_array<9> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const); -templatechar_array<10> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const); -templatechar_array<11> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const); -templatechar_array<12> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const); -templatechar_array<13> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const); -templatechar_array<14> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const); -templatechar_array<15> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const); -templatechar_array<16> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const); -templatechar_array<1> -arg_tuple_size_helper(R(A0::*)()volatile); -templatechar_array<2> -arg_tuple_size_helper(R(A0::*)(A1)volatile); -templatechar_array<3> -arg_tuple_size_helper(R(A0::*)(A1,A2)volatile); -templatechar_array<4> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3)volatile); -templatechar_array<5> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)volatile); -templatechar_array<6> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)volatile); -templatechar_array<7> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)volatile); -templatechar_array<8> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)volatile); -templatechar_array<9> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile); -templatechar_array<10> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile); -templatechar_array<11> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile); -templatechar_array<12> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile); -templatechar_array<13> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile); -templatechar_array<14> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile); -templatechar_array<15> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile); -templatechar_array<16> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile); -templatechar_array<1> -arg_tuple_size_helper(R(A0::*)()const volatile); -templatechar_array<2> -arg_tuple_size_helper(R(A0::*)(A1)const volatile); -templatechar_array<3> -arg_tuple_size_helper(R(A0::*)(A1,A2)const volatile); -templatechar_array<4> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3)const volatile); -templatechar_array<5> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4)const volatile); -templatechar_array<6> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5)const volatile); -templatechar_array<7> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6)const volatile); -templatechar_array<8> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const volatile); -templatechar_array<9> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile); -templatechar_array<10> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile); -templatechar_array<11> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile); -templatechar_array<12> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile); -templatechar_array<13> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile); -templatechar_array<14> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile); -templatechar_array<15> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile); -templatechar_array<16> -arg_tuple_size_helper(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile); - -# endif - -#endif // ARG_TUPLE_SIZE_DWA2002410_HPP diff --git a/include/boost/python/preprocessed/args.hpp b/include/boost/python/preprocessed/args.hpp deleted file mode 100644 index e33f4c52..00000000 --- a/include/boost/python/preprocessed/args.hpp +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ARGS_DWA2002417_HPP -# define ARGS_DWA2002417_HPP - -template<> -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=0); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=1); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=2); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=3); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=4); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=5); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=6); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=7); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=8); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=9); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=10); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=11); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=12); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=13); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=14); -}; -template -struct size > -{ - BOOST_STATIC_CONSTANT(long,value=15); -}; - - - - -template -struct at<0,boost::python::args > -{ - typedef A0 type; -}; -template -struct at<1,boost::python::args > -{ - typedef A1 type; -}; -template -struct at<2,boost::python::args > -{ - typedef A2 type; -}; -template -struct at<3,boost::python::args > -{ - typedef A3 type; -}; -template -struct at<4,boost::python::args > -{ - typedef A4 type; -}; -template -struct at<5,boost::python::args > -{ - typedef A5 type; -}; -template -struct at<6,boost::python::args > -{ - typedef A6 type; -}; -template -struct at<7,boost::python::args > -{ - typedef A7 type; -}; -template -struct at<8,boost::python::args > -{ - typedef A8 type; -}; -template -struct at<9,boost::python::args > -{ - typedef A9 type; -}; -template -struct at<10,boost::python::args > -{ - typedef A10 type; -}; -template -struct at<11,boost::python::args > -{ - typedef A11 type; -}; -template -struct at<12,boost::python::args > -{ - typedef A12 type; -}; -template -struct at<13,boost::python::args > -{ - typedef A13 type; -}; -template -struct at<14,boost::python::args > -{ - typedef A14 type; -}; - -#endif // ARGS_DWA2002417_HPP diff --git a/include/boost/python/preprocessed/call.hpp b/include/boost/python/preprocessed/call.hpp deleted file mode 100644 index 97ee70dd..00000000 --- a/include/boost/python/preprocessed/call.hpp +++ /dev/null @@ -1,278 +0,0 @@ -//Copyright David Abrahams 2002.Permission to copy,use, -//modify,sell and distribute this software is granted provided this -//copyright notice appears in all copies.This software is provided -//"as is" without express or implied warranty,and with no claim as -//to its suitability for any purpose. -#ifndef CALL_PP_DWA2002411_HPP -# define CALL_PP_DWA2002411_HPP - -// emacs commands used to pre-clean preprocessor output: -// (replace-regexp ", *converter" "\n, converter") -// (replace-string "PyEval_CallFunction(" "\nPyEval_CallFunction(\n") - -template -typename detail::returnable::type -call(PyObject*callable,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" ")"))); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" ")") - ,converter::arg_to_python(a0).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get() - ,converter::arg_to_python(a10).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get() - ,converter::arg_to_python(a10).get() - ,converter::arg_to_python(a11).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get() - ,converter::arg_to_python(a10).get() - ,converter::arg_to_python(a11).get() - ,converter::arg_to_python(a12).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get() - ,converter::arg_to_python(a10).get() - ,converter::arg_to_python(a11).get() - ,converter::arg_to_python(a12).get() - ,converter::arg_to_python(a13).get())); -} -template -typename detail::returnable::type -call(PyObject*callable,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallFunction( - callable,const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get() - ,converter::arg_to_python(a10).get() - ,converter::arg_to_python(a11).get() - ,converter::arg_to_python(a12).get() - ,converter::arg_to_python(a13).get() - ,converter::arg_to_python(a14).get())); -} - -#endif // CALL_PP_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/call_method.hpp b/include/boost/python/preprocessed/call_method.hpp deleted file mode 100644 index a0783402..00000000 --- a/include/boost/python/preprocessed/call_method.hpp +++ /dev/null @@ -1,277 +0,0 @@ -//Copyright David Abrahams 2002.Permission to copy,use, -//modify,sell and distribute this software is granted provided this -//copyright notice appears in all copies.This software is provided -//"as is" without express or implied warranty,and with no claim as -//to its suitability for any purpose. -#ifndef CALL_METHOD_PP_DWA2002411_HPP -# define CALL_METHOD_PP_DWA2002411_HPP - -// emacs commands used to pre-clean preprocessor output: -// (replace-regexp ", *converter" "\n, converter") -// (replace-string "PyEval_CallMethod(" "\nPyEval_CallMethod(\n") - -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" ")"))); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" ")") - ,converter::arg_to_python(a0).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get() - ,converter::arg_to_python(a10).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get() - ,converter::arg_to_python(a10).get() - ,converter::arg_to_python(a11).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get() - ,converter::arg_to_python(a10).get() - ,converter::arg_to_python(a11).get() - ,converter::arg_to_python(a12).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get() - ,converter::arg_to_python(a10).get() - ,converter::arg_to_python(a11).get() - ,converter::arg_to_python(a12).get() - ,converter::arg_to_python(a13).get())); -} -template -typename detail::returnable::type -call_method(PyObject*self,char const*name,A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14,boost::type* =0) -{ - converter::return_from_pythonconverter; - return converter( - PyEval_CallMethod( - self,const_cast(name),const_cast("(" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" "O" ")") - ,converter::arg_to_python(a0).get() - ,converter::arg_to_python(a1).get() - ,converter::arg_to_python(a2).get() - ,converter::arg_to_python(a3).get() - ,converter::arg_to_python(a4).get() - ,converter::arg_to_python(a5).get() - ,converter::arg_to_python(a6).get() - ,converter::arg_to_python(a7).get() - ,converter::arg_to_python(a8).get() - ,converter::arg_to_python(a9).get() - ,converter::arg_to_python(a10).get() - ,converter::arg_to_python(a11).get() - ,converter::arg_to_python(a12).get() - ,converter::arg_to_python(a13).get() - ,converter::arg_to_python(a14).get())); -} -#endif// CALL_METHOD_PP_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/caller.hpp b/include/boost/python/preprocessed/caller.hpp deleted file mode 100644 index dfbe40fc..00000000 --- a/include/boost/python/preprocessed/caller.hpp +++ /dev/null @@ -1,413 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CALLER_DWA2002410_HPP -# define CALLER_DWA2002410_HPP - -template -PyObject*operator()(R(*f)(),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(*f)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} - - - - -template -PyObject*operator()(R(A0::*f)(),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)()const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)()volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)()const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -template -PyObject*operator()(R(A0::*f)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,PyObject*args,PyObject*keywords,P const&policies)const -{ - return returning::call(f,args,keywords,&policies); -} -#endif // CALLER_DWA2002410_HPP diff --git a/include/boost/python/preprocessed/make_holder.hpp b/include/boost/python/preprocessed/make_holder.hpp deleted file mode 100644 index dd226a89..00000000 --- a/include/boost/python/preprocessed/make_holder.hpp +++ /dev/null @@ -1,507 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MAKE_HOLDER_DWA2002416_HPP -# define MAKE_HOLDER_DWA2002416_HPP - -template<> -struct make_holder<0> -{ - template - struct apply - { - static void - execute(PyObject*p) - { - (new - Holder(p))->install(p); - } - - }; - -}; -template<> -struct make_holder<1> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - static void - execute(PyObject*p,t0 a0) - { - (new - Holder(p,f0(a0)))->install(p); - } - - }; - -}; -template<> -struct make_holder<2> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - static void - execute(PyObject*p,t0 a0,t1 a1) - { - (new - Holder(p,f0(a0),f1(a1)))->install(p); - } - - }; - -}; -template<> -struct make_holder<3> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2)))->install(p); - } - - }; - -}; -template<> -struct make_holder<4> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3)))->install(p); - } - - }; - -}; -template<> -struct make_holder<5> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4)))->install(p); - } - - }; - -}; -template<> -struct make_holder<6> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; - typedef typename forward::type f5; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5)))->install(p); - } - - }; - -}; -template<> -struct make_holder<7> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; - typedef typename forward::type f5; - typedef typename mpl::at<6,ArgList>::type t6; - typedef typename forward::type f6; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6)))->install(p); - } - - }; - -}; -template<> -struct make_holder<8> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; - typedef typename forward::type f5; - typedef typename mpl::at<6,ArgList>::type t6; - typedef typename forward::type f6; - typedef typename mpl::at<7,ArgList>::type t7; - typedef typename forward::type f7; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7)))->install(p); - } - - }; - -}; -template<> -struct make_holder<9> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; - typedef typename forward::type f5; - typedef typename mpl::at<6,ArgList>::type t6; - typedef typename forward::type f6; - typedef typename mpl::at<7,ArgList>::type t7; - typedef typename forward::type f7; - typedef typename mpl::at<8,ArgList>::type t8; - typedef typename forward::type f8; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8)))->install(p); - } - - }; - -}; -template<> -struct make_holder<10> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; - typedef typename forward::type f5; - typedef typename mpl::at<6,ArgList>::type t6; - typedef typename forward::type f6; - typedef typename mpl::at<7,ArgList>::type t7; - typedef typename forward::type f7; - typedef typename mpl::at<8,ArgList>::type t8; - typedef typename forward::type f8; - typedef typename mpl::at<9,ArgList>::type t9; - typedef typename forward::type f9; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9)))->install(p); - } - - }; - -}; -template<> -struct make_holder<11> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; - typedef typename forward::type f5; - typedef typename mpl::at<6,ArgList>::type t6; - typedef typename forward::type f6; - typedef typename mpl::at<7,ArgList>::type t7; - typedef typename forward::type f7; - typedef typename mpl::at<8,ArgList>::type t8; - typedef typename forward::type f8; - typedef typename mpl::at<9,ArgList>::type t9; - typedef typename forward::type f9; - typedef typename mpl::at<10,ArgList>::type t10; - typedef typename forward::type f10; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9),f10(a10)))->install(p); - } - - }; - -}; -template<> -struct make_holder<12> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; - typedef typename forward::type f5; - typedef typename mpl::at<6,ArgList>::type t6; - typedef typename forward::type f6; - typedef typename mpl::at<7,ArgList>::type t7; - typedef typename forward::type f7; - typedef typename mpl::at<8,ArgList>::type t8; - typedef typename forward::type f8; - typedef typename mpl::at<9,ArgList>::type t9; - typedef typename forward::type f9; - typedef typename mpl::at<10,ArgList>::type t10; - typedef typename forward::type f10; - typedef typename mpl::at<11,ArgList>::type t11; - typedef typename forward::type f11; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9),f10(a10),f11(a11)))->install(p); - } - - }; - -}; -template<> -struct make_holder<13> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; - typedef typename forward::type f5; - typedef typename mpl::at<6,ArgList>::type t6; - typedef typename forward::type f6; - typedef typename mpl::at<7,ArgList>::type t7; - typedef typename forward::type f7; - typedef typename mpl::at<8,ArgList>::type t8; - typedef typename forward::type f8; - typedef typename mpl::at<9,ArgList>::type t9; - typedef typename forward::type f9; - typedef typename mpl::at<10,ArgList>::type t10; - typedef typename forward::type f10; - typedef typename mpl::at<11,ArgList>::type t11; - typedef typename forward::type f11; - typedef typename mpl::at<12,ArgList>::type t12; - typedef typename forward::type f12; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9),f10(a10),f11(a11),f12(a12)))->install(p); - } - - }; - -}; -template<> -struct make_holder<14> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; - typedef typename forward::type f5; - typedef typename mpl::at<6,ArgList>::type t6; - typedef typename forward::type f6; - typedef typename mpl::at<7,ArgList>::type t7; - typedef typename forward::type f7; - typedef typename mpl::at<8,ArgList>::type t8; - typedef typename forward::type f8; - typedef typename mpl::at<9,ArgList>::type t9; - typedef typename forward::type f9; - typedef typename mpl::at<10,ArgList>::type t10; - typedef typename forward::type f10; - typedef typename mpl::at<11,ArgList>::type t11; - typedef typename forward::type f11; - typedef typename mpl::at<12,ArgList>::type t12; - typedef typename forward::type f12; - typedef typename mpl::at<13,ArgList>::type t13; - typedef typename forward::type f13; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12,t13 a13) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9),f10(a10),f11(a11),f12(a12),f13(a13)))->install(p); - } - - }; - -}; -template<> -struct make_holder<15> -{ - template - struct apply - { - typedef typename mpl::at<0,ArgList>::type t0; - typedef typename forward::type f0; - typedef typename mpl::at<1,ArgList>::type t1; - typedef typename forward::type f1; - typedef typename mpl::at<2,ArgList>::type t2; - typedef typename forward::type f2; - typedef typename mpl::at<3,ArgList>::type t3; - typedef typename forward::type f3; - typedef typename mpl::at<4,ArgList>::type t4; - typedef typename forward::type f4; - typedef typename mpl::at<5,ArgList>::type t5; - typedef typename forward::type f5; - typedef typename mpl::at<6,ArgList>::type t6; - typedef typename forward::type f6; - typedef typename mpl::at<7,ArgList>::type t7; - typedef typename forward::type f7; - typedef typename mpl::at<8,ArgList>::type t8; - typedef typename forward::type f8; - typedef typename mpl::at<9,ArgList>::type t9; - typedef typename forward::type f9; - typedef typename mpl::at<10,ArgList>::type t10; - typedef typename forward::type f10; - typedef typename mpl::at<11,ArgList>::type t11; - typedef typename forward::type f11; - typedef typename mpl::at<12,ArgList>::type t12; - typedef typename forward::type f12; - typedef typename mpl::at<13,ArgList>::type t13; - typedef typename forward::type f13; - typedef typename mpl::at<14,ArgList>::type t14; - typedef typename forward::type f14; - static void - execute(PyObject*p,t0 a0,t1 a1,t2 a2,t3 a3,t4 a4,t5 a5,t6 a6,t7 a7,t8 a8,t9 a9,t10 a10,t11 a11,t12 a12,t13 a13,t14 a14) - { - (new - Holder(p,f0(a0),f1(a1),f2(a2),f3(a3),f4(a4),f5(a5),f6(a6),f7(a7),f8(a8),f9(a9),f10(a10),f11(a11),f12(a12),f13(a13),f14(a14)))->install(p); - } - - }; - -}; -#endif // MAKE_HOLDER_DWA2002416_HPP - - diff --git a/include/boost/python/preprocessed/member_function_cast.hpp b/include/boost/python/preprocessed/member_function_cast.hpp deleted file mode 100644 index d8a6a54e..00000000 --- a/include/boost/python/preprocessed/member_function_cast.hpp +++ /dev/null @@ -1,396 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MEMBER_FUNCTION_CAST_DWA2002410_HPP -# define MEMBER_FUNCTION_CAST_DWA2002410_HPP - -// emacs commands used to pre-clean preprocessor output -// (replace-regexp "> *stage1(" ">\nstage1(") - -template -static cast_helper -stage1(R(S::*)()) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)()const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)()volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)()const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile) -{ - return cast_helper(); -} -template -static cast_helper -stage1(R(S::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile) -{ - return cast_helper(); -} -#endif // MEMBER_FUNCTION_CAST_DWA2002410_HPP diff --git a/include/boost/python/preprocessed/object_call.hpp b/include/boost/python/preprocessed/object_call.hpp deleted file mode 100755 index ec3ba43e..00000000 --- a/include/boost/python/preprocessed/object_call.hpp +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OBJECT_CALL_DWA2002612_HPP -# define OBJECT_CALL_DWA2002612_HPP - -template -typename dependent::type -operator()(A0 const&a0)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3,a4); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13); -} -template -typename dependent::type -operator()(A0 const&a0,A1 const&a1,A2 const&a2,A3 const&a3,A4 const&a4,A5 const&a5,A6 const&a6,A7 const&a7,A8 const&a8,A9 const&a9,A10 const&a10,A11 const&a11,A12 const&a12,A13 const&a13,A14 const&a14)const -{ - typedef typename dependent::type obj; - U const&self=*static_cast(this); - return call(converter::get_managed_object(self),a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14); -} - -#endif // OBJECT_CALL_DWA2002612_HPP diff --git a/include/boost/python/preprocessed/pointer_holder.hpp b/include/boost/python/preprocessed/pointer_holder.hpp deleted file mode 100644 index bce4d80c..00000000 --- a/include/boost/python/preprocessed/pointer_holder.hpp +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef POINTER_HOLDER_DWA2002411_HPP -# define POINTER_HOLDER_DWA2002411_HPP - -// emacs commands used to pre-clean preprocessor output: -// (replace-regexp ": *m_p *(" "\n: m_p(") -// (replace-regexp "Value(" "Value(\n") -// (replace-regexp ", *(" "\n, (") - -pointer_holder(PyObject*) - :m_p(new Value( - )) -{ - -} -template -pointer_holder(PyObject*,A0 a0) - :m_p(new Value( - (typename unforward::type)(a0))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12) - ,(typename unforward::type)(a13))) -{ - -} -template -pointer_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13,A14 a14) - :m_p(new Value( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12) - ,(typename unforward::type)(a13) - ,(typename unforward::type)(a14))) -{ - -} -#endif // POINTER_HOLDER_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/ptr_holder_back_reference.hpp b/include/boost/python/preprocessed/ptr_holder_back_reference.hpp deleted file mode 100644 index 78247790..00000000 --- a/include/boost/python/preprocessed/ptr_holder_back_reference.hpp +++ /dev/null @@ -1,261 +0,0 @@ -//Copyright David Abrahams 2002.Permission to copy,use, -//modify,sell and distribute this software is granted provided this -//copyright notice appears in all copies.This software is provided -//"as is" without express or implied warranty,and with no claim as -//to its suitability for any purpose. -#ifndef POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP -#define POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP - -// emacs commands used to pre-clean preprocessor output: -// (replace-regexp ": *m_p *(" "\n: m_p(") -// (replace-regexp "held_type(" "held_type(\n") -// (replace-regexp ", *(" "\n, (") - -pointer_holder_back_reference(PyObject*p) - :m_p(new held_type( - p)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0) - :m_p(new held_type( - p - ,(typename unforward::type)(a0))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12) - ,(typename unforward::type)(a13))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -pointer_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13,A14 a14) - :m_p(new held_type( - p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12) - ,(typename unforward::type)(a13) - ,(typename unforward::type)(a14))) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -#endif//POINTER_HOLDER_BACK_REFERENCE_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/result.hpp b/include/boost/python/preprocessed/result.hpp deleted file mode 100755 index 10180c99..00000000 --- a/include/boost/python/preprocessed/result.hpp +++ /dev/null @@ -1,412 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef RESULT2_DWA2002521_HPP -# define RESULT2_DWA2002521_HPP - -template -boost::type*result(R(*)(),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3,A4),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),int=0) -{ - return 0; -} -template -boost::type*result(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),int=0) -{ - return 0; -} - -template -boost::type*result(R(A0::*)(),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)()const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)()volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)()const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,int=0) -{ - return 0; -} -template -boost::type*result(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,int=0) -{ - return 0; -} - - -#endif // RESULT2_DWA2002521_HPP diff --git a/include/boost/python/preprocessed/returning_non_void.hpp b/include/boost/python/preprocessed/returning_non_void.hpp deleted file mode 100644 index ebf35cdd..00000000 --- a/include/boost/python/preprocessed/returning_non_void.hpp +++ /dev/null @@ -1,2805 +0,0 @@ -//Copyright David Abrahams 2002.Permission to copy,use, -//modify,sell and distribute this software is granted provided this -//copyright notice appears in all copies.This software is provided -//"as is" without express or implied warranty,and with no claim as -//to its suitability for any purpose. -#ifndef RETURNING_NON_VOID_DWA2002410_HPP -#define RETURNING_NON_VOID_DWA2002410_HPP - -// emacs commands used to pre-clean preprocessor output: -// (replace-regexp ", *\\(c[0-9]\\)" "\n, \\1") -// (replace-regexp "( *\\(c[0-9]\\)" "(\n\\1") - -template -static PyObject*call(R(A0::*pmf)(),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)()); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)) - , c14(PyTuple_GET_ITEM(args_,14)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); - if(!c15.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)) - , c14(PyTuple_GET_ITEM(args_,14)) - , c15(PyTuple_GET_ITEM(args_,15)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)()const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)()); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)) - , c14(PyTuple_GET_ITEM(args_,14)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); - if(!c15.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)) - , c14(PyTuple_GET_ITEM(args_,14)) - , c15(PyTuple_GET_ITEM(args_,15)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)()volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)()); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)) - , c14(PyTuple_GET_ITEM(args_,14)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); - if(!c15.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)) - , c14(PyTuple_GET_ITEM(args_,14)) - , c15(PyTuple_GET_ITEM(args_,15)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)()const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)()); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)) - , c14(PyTuple_GET_ITEM(args_,14)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); - if(!c15.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)) - , c14(PyTuple_GET_ITEM(args_,14)) - , c15(PyTuple_GET_ITEM(args_,15)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(),PyObject*args_,PyObject*,P const*policies) -{ - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)()); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)))); - return policies->postcall(args_,result); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if(!cr.convertible())return 0; - if(!policies->precall(args_))return 0; - PyObject*result=cr((*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - , c1(PyTuple_GET_ITEM(args_,1)) - , c2(PyTuple_GET_ITEM(args_,2)) - , c3(PyTuple_GET_ITEM(args_,3)) - , c4(PyTuple_GET_ITEM(args_,4)) - , c5(PyTuple_GET_ITEM(args_,5)) - , c6(PyTuple_GET_ITEM(args_,6)) - , c7(PyTuple_GET_ITEM(args_,7)) - , c8(PyTuple_GET_ITEM(args_,8)) - , c9(PyTuple_GET_ITEM(args_,9)) - , c10(PyTuple_GET_ITEM(args_,10)) - , c11(PyTuple_GET_ITEM(args_,11)) - , c12(PyTuple_GET_ITEM(args_,12)) - , c13(PyTuple_GET_ITEM(args_,13)) - , c14(PyTuple_GET_ITEM(args_,14)))); - return policies->postcall(args_,result); -} -#endif // RETURNING_NON_VOID_DWA2002410_HPP diff --git a/include/boost/python/preprocessed/returning_void.hpp b/include/boost/python/preprocessed/returning_void.hpp deleted file mode 100644 index 63f643f7..00000000 --- a/include/boost/python/preprocessed/returning_void.hpp +++ /dev/null @@ -1,2565 +0,0 @@ -//Copyright David Abrahams 2002.Permission to copy,use, -//modify,sell and distribute this software is granted provided this -//copyright notice appears in all copies.This software is provided -//"as is" without express or implied warranty,and with no claim as -//to its suitability for any purpose. -#ifndef RETURNING_VOID_DWA2002410_HPP -# define RETURNING_VOID_DWA2002410_HPP - -// emacs commands used to pre-clean preprocessor output: -// (replace-regexp ", *\\(c[0-9]\\)" "\n, \\1") -// (replace-regexp "( *\\(c[0-9]\\)" "(\n\\1") - -template -static PyObject*call(R(A0::*pmf)(),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)(); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13)) - ,c14(PyTuple_GET_ITEM(args_,14))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); - if(!c15.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13)) - ,c14(PyTuple_GET_ITEM(args_,14)) - ,c15(PyTuple_GET_ITEM(args_,15))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)()const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)(); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13)) - ,c14(PyTuple_GET_ITEM(args_,14))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); - if(!c15.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13)) - ,c14(PyTuple_GET_ITEM(args_,14)) - ,c15(PyTuple_GET_ITEM(args_,15))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)()volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)(); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13)) - ,c14(PyTuple_GET_ITEM(args_,14))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); - if(!c15.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13)) - ,c14(PyTuple_GET_ITEM(args_,14)) - ,c15(PyTuple_GET_ITEM(args_,15))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)()const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)(); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13)) - ,c14(PyTuple_GET_ITEM(args_,14))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(A0::*pmf)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile,PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - arg_from_pythonc15(PyTuple_GET_ITEM(args_,15)); - if(!c15.convertible())return 0; - if(!policies->precall(args_))return 0; - (( - c0(PyTuple_GET_ITEM(args_,0))).*pmf)( - c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13)) - ,c14(PyTuple_GET_ITEM(args_,14)) - ,c15(PyTuple_GET_ITEM(args_,15))); - return policies->postcall(args_,detail::none()); -} - -template -static PyObject*call(R(*pf)(),PyObject*args_,PyObject*,P const*policies) -{ - (*pf)(); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13))); - return policies->postcall(args_,detail::none()); -} -template -static PyObject*call(R(*pf)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14),PyObject*args_,PyObject*,P const*policies) -{ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); - if(!c0.convertible())return 0; - arg_from_pythonc1(PyTuple_GET_ITEM(args_,1)); - if(!c1.convertible())return 0; - arg_from_pythonc2(PyTuple_GET_ITEM(args_,2)); - if(!c2.convertible())return 0; - arg_from_pythonc3(PyTuple_GET_ITEM(args_,3)); - if(!c3.convertible())return 0; - arg_from_pythonc4(PyTuple_GET_ITEM(args_,4)); - if(!c4.convertible())return 0; - arg_from_pythonc5(PyTuple_GET_ITEM(args_,5)); - if(!c5.convertible())return 0; - arg_from_pythonc6(PyTuple_GET_ITEM(args_,6)); - if(!c6.convertible())return 0; - arg_from_pythonc7(PyTuple_GET_ITEM(args_,7)); - if(!c7.convertible())return 0; - arg_from_pythonc8(PyTuple_GET_ITEM(args_,8)); - if(!c8.convertible())return 0; - arg_from_pythonc9(PyTuple_GET_ITEM(args_,9)); - if(!c9.convertible())return 0; - arg_from_pythonc10(PyTuple_GET_ITEM(args_,10)); - if(!c10.convertible())return 0; - arg_from_pythonc11(PyTuple_GET_ITEM(args_,11)); - if(!c11.convertible())return 0; - arg_from_pythonc12(PyTuple_GET_ITEM(args_,12)); - if(!c12.convertible())return 0; - arg_from_pythonc13(PyTuple_GET_ITEM(args_,13)); - if(!c13.convertible())return 0; - arg_from_pythonc14(PyTuple_GET_ITEM(args_,14)); - if(!c14.convertible())return 0; - if(!policies->precall(args_))return 0; - (*pf)( - c0(PyTuple_GET_ITEM(args_,0)) - ,c1(PyTuple_GET_ITEM(args_,1)) - ,c2(PyTuple_GET_ITEM(args_,2)) - ,c3(PyTuple_GET_ITEM(args_,3)) - ,c4(PyTuple_GET_ITEM(args_,4)) - ,c5(PyTuple_GET_ITEM(args_,5)) - ,c6(PyTuple_GET_ITEM(args_,6)) - ,c7(PyTuple_GET_ITEM(args_,7)) - ,c8(PyTuple_GET_ITEM(args_,8)) - ,c9(PyTuple_GET_ITEM(args_,9)) - ,c10(PyTuple_GET_ITEM(args_,10)) - ,c11(PyTuple_GET_ITEM(args_,11)) - ,c12(PyTuple_GET_ITEM(args_,12)) - ,c13(PyTuple_GET_ITEM(args_,13)) - ,c14(PyTuple_GET_ITEM(args_,14))); - return policies->postcall(args_,detail::none()); -} -#endif // RETURNING_VOID_DWA2002410_HPP diff --git a/include/boost/python/preprocessed/target.hpp b/include/boost/python/preprocessed/target.hpp deleted file mode 100755 index f2a23cee..00000000 --- a/include/boost/python/preprocessed/target.hpp +++ /dev/null @@ -1,402 +0,0 @@ -template -boost::type*target(R(*)()) -{ - return 0; -} -template -boost::type*target(R(*)(A0)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3,A4)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3,A4,A5)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)) -{ - return 0; -} -template -boost::type*target(R(*)(A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)) -{ - return 0; -} - -template -boost::type*target(R(A0::*)()) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)) -{ - return 0; -} -template -boost::type*target(R(A0::*)()const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const) -{ - return 0; -} -template -boost::type*target(R(A0::*)()volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)()const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14)const volatile) -{ - return 0; -} -template -boost::type*target(R(A0::*)(A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15)const volatile) -{ - return 0; -} - diff --git a/include/boost/python/preprocessed/value_holder.hpp b/include/boost/python/preprocessed/value_holder.hpp deleted file mode 100644 index 20437d8b..00000000 --- a/include/boost/python/preprocessed/value_holder.hpp +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef VALUE_HOLDER_DWA2002411_HPP -# define VALUE_HOLDER_DWA2002411_HPP - -// emacs commands used to pre-clean preprocessor output: -// (replace-regexp ": *m_held *(" "\n: m_held(") -// (replace-regexp ", *(" "\n, (") - -value_holder(PyObject*) - :m_held() -{ - -} -template -value_holder(PyObject*,A0 a0) - :m_held( - (typename unforward::type)(a0)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12) - ,(typename unforward::type)(a13)) -{ - -} -template -value_holder(PyObject*,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13,A14 a14) - :m_held( - (typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12) - ,(typename unforward::type)(a13) - ,(typename unforward::type)(a14)) -{ - -} -#endif // VALUE_HOLDER_DWA2002411_HPP diff --git a/include/boost/python/preprocessed/value_holder_back_reference.hpp b/include/boost/python/preprocessed/value_holder_back_reference.hpp deleted file mode 100644 index c5b06020..00000000 --- a/include/boost/python/preprocessed/value_holder_back_reference.hpp +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef VALUE_HOLDER_BACK_REFERENCE_DWA2002411_HPP -# define VALUE_HOLDER_BACK_REFERENCE_DWA2002411_HPP - -// emacs commands used to pre-clean preprocessor output: -// (replace-regexp ": *m_held *(" "\n: m_held(") -// (replace-regexp ", *(" "\n, (") - -value_holder_back_reference(PyObject*p) - :m_held(p) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0) - :m_held(p - ,(typename unforward::type)(a0)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12) - ,(typename unforward::type)(a13)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} -template -value_holder_back_reference(PyObject*p,A0 a0,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9,A10 a10,A11 a11,A12 a12,A13 a13,A14 a14) - :m_held(p - ,(typename unforward::type)(a0) - ,(typename unforward::type)(a1) - ,(typename unforward::type)(a2) - ,(typename unforward::type)(a3) - ,(typename unforward::type)(a4) - ,(typename unforward::type)(a5) - ,(typename unforward::type)(a6) - ,(typename unforward::type)(a7) - ,(typename unforward::type)(a8) - ,(typename unforward::type)(a9) - ,(typename unforward::type)(a10) - ,(typename unforward::type)(a11) - ,(typename unforward::type)(a12) - ,(typename unforward::type)(a13) - ,(typename unforward::type)(a14)) -{ - python::detail::force_instantiate( - instance_finder::registration); -} - -#endif // VALUE_HOLDER_BACK_REFERENCE_DWA2002411_HPP From 931aab22bb7538f08b2578d575a703adb95db162 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 9 Jul 2002 19:35:48 +0000 Subject: [PATCH 0558/1042] Use Paul M's preprocessor iteration [SVN r14384] --- include/boost/python/args.hpp | 103 +++--- include/boost/python/call.hpp | 88 ++--- include/boost/python/call_method.hpp | 89 ++--- .../python/converter/convertible_function.hpp | 15 + .../boost/python/converter/registrations.hpp | 5 +- include/boost/python/converter/registry.hpp | 5 +- .../boost/python/detail/arg_tuple_size.hpp | 120 ++++--- include/boost/python/detail/caller.hpp | 138 +++++--- .../python/detail/member_function_cast.hpp | 77 +++-- include/boost/python/detail/preprocessor.hpp | 123 +++---- include/boost/python/detail/result.hpp | 87 +++-- include/boost/python/detail/returning.hpp | 323 ++++++++++-------- include/boost/python/detail/target.hpp | 78 +++-- .../python/object/auto_ptr_generator.hpp | 23 -- include/boost/python/object/make_holder.hpp | 94 ++--- .../boost/python/object/pointer_holder.hpp | 130 ++++--- include/boost/python/object/value_holder.hpp | 124 ++++--- include/boost/python/object_call.hpp | 22 ++ include/boost/python/object_core.hpp | 28 +- 19 files changed, 963 insertions(+), 709 deletions(-) create mode 100644 include/boost/python/converter/convertible_function.hpp delete mode 100644 include/boost/python/object/auto_ptr_generator.hpp create mode 100644 include/boost/python/object_call.hpp diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index 1656fe1e..c99daafc 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -1,3 +1,5 @@ +#if !defined(BOOST_PP_IS_ITERATING) + // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided @@ -5,33 +7,35 @@ // to its suitability for any purpose. #ifndef ARGS_DWA2002323_HPP # define ARGS_DWA2002323_HPP -# include -# include -# include -# include -# include -# include +# include -# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245 -namespace boost { namespace python { +# include +# include + +# include +# include + +# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245 + +namespace boost { namespace python { // A type list for specifying arguments -template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename A, boost::mpl::null_argument) > -struct args : boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(A) >::type +template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, boost::mpl::null_argument) > +struct args : boost::mpl::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A) >::type {}; }} // namespace boost::python -# else // slow template instantiators need this other version with - // explicit specializations of mpl::size<> and - // mpl::at<>. Eventually, however, inheritance from mpl::list - // *should* be eliminated and the two versions unified, just in - // order to get true arity independence +# else // slow template instantiators need this other version with + // explicit specializations of mpl::size<> and + // mpl::at<>. Eventually, however, inheritance from mpl::list + // *should* be eliminated and the two versions unified, just in + // order to get true arity independence -namespace boost { namespace python { +namespace boost { namespace python { -template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_MAX_ARITY, class A, boost::mpl::null_argument) > +template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, boost::mpl::null_argument) > struct args {}; @@ -42,32 +46,45 @@ namespace boost { namespace mpl { template struct size; template struct at; -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif +# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY, , 1) +# include BOOST_PP_ITERATE() -# define BOOST_PYTHON_ARGS_SIZE(index,ignored) \ -template \ -struct size > \ -{ \ - BOOST_STATIC_CONSTANT(long, value = index); \ -}; \ +# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY - 1, , 2) +# include BOOST_PP_ITERATE() -BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_ARGS_SIZE, nil) - -# define BOOST_PYTHON_ARGS_AT(index,ignored) \ -template < \ - BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_PYTHON_ARITY_FINISH), class A)> \ -struct at > \ -{ \ - typedef BOOST_PP_CAT(A,index) type; \ -}; \ -BOOST_PP_REPEAT_FROM_TO_2ND( - BOOST_PP_DEC(BOOST_PYTHON_ARITY_START), BOOST_PP_DEC(BOOST_PYTHON_ARITY_FINISH) - , BOOST_PYTHON_ARGS_AT, data) - -}} -# endif -#endif // ARGS_DWA2002323_HPP +}} // namespace boost::mpl + +# endif // __EDG_VERSION__ + +# endif // ARGS_DWA2002323_HPP + +/* ---------- size ---------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1 +# line BOOST_PP_LINE(__LINE__, args.hpp(size)) + +# define N BOOST_PP_ITERATION() + +template +struct size > +{ + BOOST_STATIC_CONSTANT(long, value = N); +}; + +# undef N + +/* ---------- at ---------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2 +# line BOOST_PP_LINE(__LINE__, args.hpp(at)) + +# define N BOOST_PP_ITERATION() + +template +struct at > +{ + typedef BOOST_PP_CAT(A, N) type; +}; + +# undef N + +#endif diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp index e8c97038..82c07b6f 100644 --- a/include/boost/python/call.hpp +++ b/include/boost/python/call.hpp @@ -1,51 +1,63 @@ +#if !defined(BOOST_PP_IS_ITERATING) + // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef CALL_DWA2002411_HPP -# define CALL_DWA2002411_HPP -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +# ifndef CALL_DWA2002411_HPP +# define CALL_DWA2002411_HPP -namespace boost { namespace python { +# include -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif +# include +# include +# include +# include -# define BOOST_PYTHON_CALL_FUNCTION(nargs,ignored) \ -template < \ - class R \ - BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM_PARAMS(nargs, class A) \ - > \ -typename detail::returnable::type \ -call(PyObject* callable \ - BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a)) \ - , boost::type* = 0 \ - ) \ -{ \ - converter::return_from_python converter; \ - return converter( \ - PyEval_CallFunction( \ - callable \ - , const_cast(BOOST_PYTHON_ARG_STRING(nargs)) \ - BOOST_PP_COMMA_IF(nargs) \ - BOOST_PP_ENUM(nargs,BOOST_PYTHON_ARG_TO_PYTHON_GET,nil) \ - )); \ -} +# include +# include +# include -BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CALL_FUNCTION,data) +namespace boost { namespace python { + +# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(n, _) \ + , converter::arg_to_python(a##n).get() + +# define BOOST_PP_ITERATION_PARAMS_1 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET }} // namespace boost::python -#endif // CALL_DWA2002411_HPP +# endif // CALL_DWA2002411_HPP + +#elif BOOST_PP_ITERATION_DEPTH() == 1 +# line BOOST_PP_LINE(__LINE__, call.hpp) + +# define N BOOST_PP_ITERATION() + +template < + class R + BOOST_PP_COMMA_IF(N) BOOST_PYTHON_UNARY_ENUM(N, class A) + > +typename detail::returnable::type +call(PyObject* callable + BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, const& a) + , boost::type* = 0 + ) +{ + converter::return_from_python converter; + return converter( + PyEval_CallFunction( + callable + , const_cast("(" BOOST_PP_REPEAT(N, BOOST_PYTHON_FIXED, "O") ")") + BOOST_PP_REPEAT(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) + )); +} + +# undef N + +#endif diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp index 08e9eb68..c0ced783 100644 --- a/include/boost/python/call_method.hpp +++ b/include/boost/python/call_method.hpp @@ -1,52 +1,63 @@ +#if !defined(BOOST_PP_IS_ITERATING) + // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef CALL_METHOD_DWA2002411_HPP -# define CALL_METHOD_DWA2002411_HPP +# ifndef CALL_METHOD_DWA2002411_HPP +# define CALL_METHOD_DWA2002411_HPP -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +# include -namespace boost { namespace python { +# include +# include +# include +# include -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif +# include +# include +# include -# define BOOST_PYTHON_CALL_METHOD_FUNCTION(nargs,ignored) \ -template < \ - class R \ - BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM_PARAMS(nargs, class A) \ - > \ -typename detail::returnable::type \ -call_method(PyObject* self, char const* name \ - BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a)) \ - , boost::type* = 0 \ - ) \ -{ \ - converter::return_from_python converter; \ - return converter( \ - PyEval_CallMethod( \ - self \ - , const_cast(name) \ - , const_cast(BOOST_PYTHON_ARG_STRING(nargs)) \ - BOOST_PP_COMMA_IF(nargs) \ - BOOST_PP_ENUM(nargs,BOOST_PYTHON_ARG_TO_PYTHON_GET,nil) \ - )); \ -} +namespace boost { namespace python { -BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CALL_METHOD_FUNCTION,data) +# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(n, _) \ + , converter::arg_to_python(a##n).get() + +# define BOOST_PP_ITERATION_PARAMS_1 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET }} // namespace boost::python -#endif // CALL_METHOD_DWA2002411_HPP +# endif // CALL_METHOD_DWA2002411_HPP + +#elif BOOST_PP_ITERATION_DEPTH() == 1 +# line BOOST_PP_LINE(__LINE__, call_method.hpp) + +# define N BOOST_PP_ITERATION() + +template < + class R + BOOST_PP_COMMA_IF(N) BOOST_PYTHON_UNARY_ENUM(N, class A) + > +typename detail::returnable::type +call_method(PyObject* self, char const* name + BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, const& a) + , boost::type* = 0 + ) +{ + converter::return_from_python converter; + return converter( + PyEval_CallMethod( + self + , const_cast(name) + , const_cast("(" BOOST_PP_REPEAT(N, BOOST_PYTHON_FIXED, "O") ")") + BOOST_PP_REPEAT(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) + )); +} + +# undef N + +#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/converter/convertible_function.hpp b/include/boost/python/converter/convertible_function.hpp new file mode 100644 index 00000000..98db1cfb --- /dev/null +++ b/include/boost/python/converter/convertible_function.hpp @@ -0,0 +1,15 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CONVERTIBLE_FUNCTION_DWA200278_HPP +# define CONVERTIBLE_FUNCTION_DWA200278_HPP + +namespace boost { namespace python { namespace converter { + +typedef void* (*convertible_function)(PyObject*); + +}}} // namespace boost::python::converter + +#endif // CONVERTIBLE_FUNCTION_DWA200278_HPP diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp index 636e8fa0..eed1768a 100644 --- a/include/boost/python/converter/registrations.hpp +++ b/include/boost/python/converter/registrations.hpp @@ -6,19 +6,20 @@ #ifndef REGISTRATIONS_DWA2002223_HPP # define REGISTRATIONS_DWA2002223_HPP +# include # include namespace boost { namespace python { namespace converter { struct lvalue_from_python_registration { - void* (*convert)(PyObject* source); + convertible_function convert; lvalue_from_python_registration* next; }; struct rvalue_from_python_registration { - void* (*convertible)(PyObject*); + convertible_function convertible; constructor_function construct; rvalue_from_python_registration* next; }; diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index 2cf97d98..a686205c 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -11,6 +11,7 @@ # include # include # include +# include namespace boost { namespace python { namespace converter { @@ -33,7 +34,7 @@ namespace registry // Insert an rvalue from_python converter BOOST_PYTHON_DECL void insert( - void* (*convertible)(PyObject*) + convertible_function , constructor_function , type_info ); @@ -41,7 +42,7 @@ namespace registry // Insert an rvalue from_python converter at the tail of the // chain. Used for implicit conversions BOOST_PYTHON_DECL void push_back( - void* (*convertible)(PyObject*) + convertible_function , constructor_function , type_info ); diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index e958c1c0..24abae89 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -1,3 +1,5 @@ +#if !defined(BOOST_PP_IS_ITERATING) + // (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and // distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied @@ -9,13 +11,15 @@ // functions by gen_arg_tuple_size.python #ifndef ARG_TUPLE_SIZE_DWA20011201_HPP -# define ARG_TUPLE_SIZE_DWA20011201_HPP +# define ARG_TUPLE_SIZE_DWA20011201_HPP # include + # include # include -# include + # include +# include namespace boost { namespace python { namespace detail { @@ -24,31 +28,6 @@ namespace boost { namespace python { namespace detail { // (member) function of the given type. template struct arg_tuple_size; -// Include the pre-expanded version of the code -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif - -# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - -// Specializations for function pointers -# define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \ -template \ -struct arg_tuple_size \ -{ \ - BOOST_STATIC_CONSTANT(std::size_t, value = args); \ -}; - -// Specializations for member function pointers -# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF(args, cv) \ -template \ -struct arg_tuple_size \ -{ \ - BOOST_STATIC_CONSTANT(std::size_t, value = args); \ -}; - -# else - // We will use the "sizeof() trick" to work around the lack of // partial specialization in MSVC6 and its broken-ness in borland. // See http://opensource.adobe.com or @@ -60,31 +39,88 @@ struct arg_tuple_size \ // their return value is used to discriminate between various free // and member function pointers at compile-time. -# define BOOST_PYTHON_ARG_TUPLE_SIZE_PF(args, ignored) \ -template \ -char_array arg_tuple_size_helper(BOOST_PYTHON_FN(*,0,args)); +// Specializations for function pointers +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER) +# include BOOST_PP_ITERATE() -# define BOOST_PYTHON_ARG_TUPLE_SIZE_PMF(args, cv) \ -template \ -char_array arg_tuple_size_helper(BOOST_PYTHON_FN(A0::*,1,args)cv()); - -# endif +// Specializations for member function pointers +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER) +# include BOOST_PP_ITERATE() + +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) -BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_ARG_TUPLE_SIZE_PF, nil) - -// Generate a series for each cv-qualification -BOOST_PYTHON_REPEAT_MF_CV_2ND(BOOST_PYTHON_ARG_TUPLE_SIZE_PMF) - -# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(__BORLANDC__) template struct arg_tuple_size { // The sizeof() magic happens here BOOST_STATIC_CONSTANT(std::size_t, value - = sizeof(arg_tuple_size_helper(F(0)).elements) - 1); + = sizeof(arg_tuple_size_helper(F(0)).elements) - 1); }; + # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + }}} // namespace boost::python::detail #endif // ARG_TUPLE_SIZE_DWA20011201_HPP +// --------------- function pointers --------------- // +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER +# line BOOST_PP_LINE(__LINE__, arg_tuple_size.hpp(function pointers)) + +# define N BOOST_PP_ITERATION() + +# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = N); +}; + +# else + +template +char_array arg_tuple_size_helper( + R (*)(BOOST_PYTHON_UNARY_ENUM(N, A))); + +# endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +# undef N + +// --------------- pointers-to-members --------------- // +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER +// Outer iteration over cv-qualifications + +# define BOOST_PP_ITERATION_PARAMS_2 \ + 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# include BOOST_PP_ITERATE() + +#elif BOOST_PP_ITERATION_DEPTH() == 2 && BOOST_PP_RELATIVE_FLAGS(1) == BOOST_PYTHON_POINTER_TO_MEMBER +# line BOOST_PP_LINE(__LINE__, arg_tuple_size.hpp(pointers-to-members)) +// Inner iteration over arities + +# define N BOOST_PP_ITERATION() +# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) + +# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template +struct arg_tuple_size +{ + BOOST_STATIC_CONSTANT(std::size_t, value = N + 1U); +}; + +# else + +template +char_array arg_tuple_size_helper( + R (T::*)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q); + +# endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +# undef Q +# undef N + +#endif // !defined(BOOST_PP_IS_ITERATING) diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index 87ea5405..d8871cd1 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -1,23 +1,34 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CALLER_DWA20011214_HPP -# define CALLER_DWA20011214_HPP +#if !defined(BOOST_PP_IS_ITERATING) -# include -# include -# include -# include -# include -# include -# include -# include +// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and +// distribute this software is granted provided this copyright notice appears +// in all copies. This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// The author gratefully acknowleges the support of Dragon Systems, Inc., in +// producing this work. +// +// This file generated for 10-argument member functions and 11-argument free +// functions by gen_caller.python + +# ifndef CALLER_DWA20011214_HPP +# define CALLER_DWA20011214_HPP + +# include +# include +# include + +# include +# include + +# // temp: include + +# include +# include namespace boost { namespace python { - template struct to_python; + template struct to_python; }} namespace boost { namespace python { namespace detail { @@ -25,44 +36,71 @@ namespace boost { namespace python { namespace detail { struct caller { typedef PyObject* result_type; - -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif -# define BOOST_PYTHON_CALLER_PF(args_, ignored) \ -template < \ - class P \ - , class R \ - BOOST_PP_COMMA_IF(args_) BOOST_MPL_TEMPLATE_PARAMETERS(0, args_, class A) \ - > \ -PyObject* operator()( \ - BOOST_PYTHON_FN(*f,0,args_) \ - , PyObject* args, PyObject* keywords \ - , P const& policies \ - ) const \ -{ \ - return returning::call(f, args, keywords,&policies); \ -} + // function pointers +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER) +# include BOOST_PP_ITERATE() -BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CALLER_PF, nil) + // pointers-to-members +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, 3, , BOOST_PYTHON_POINTER_TO_MEMBER) +# include BOOST_PP_ITERATE() -// Member functions -# define BOOST_PYTHON_CALLER_PMF(args_, cv) \ -template \ -PyObject* operator()( \ - BOOST_PYTHON_FN(A0::*f,1,args_)cv() \ - , PyObject* args, PyObject* keywords \ - , P const& policies \ - ) const \ -{ \ - return returning::call(f, args, keywords,&policies); \ -} - -BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_CALLER_PMF) - }; }}} // namespace boost::python::detail -#endif // CALLER_DWA20011214_HPP +# endif // CALLER_DWA20011214_HPP + +/* ---------- function pointers --------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER +# line BOOST_PP_LINE(__LINE__, detail/caller.hpp(function pointers)) + +# define N BOOST_PP_ITERATION() + +template < + class P, class R + BOOST_PP_COMMA_IF(N) BOOST_PYTHON_UNARY_ENUM(N, class A) + > +PyObject* operator()( + R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)) + , PyObject* args + , PyObject* keywords + , P const& policies) const +{ + return returning::call(pf, args, keywords, &policies); +} + +# undef N + +/* ---------- pointers-to-members ---------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER +// outer over cv-qualifiers + +# define BOOST_PP_ITERATION_PARAMS_2 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# include BOOST_PP_ITERATE() + +#elif BOOST_PP_ITERATION_DEPTH() == 2 +// inner over arities + +#define N BOOST_PP_ITERATION() +#define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) + +template < + class P, class R, class T + BOOST_PP_COMMA_IF(N) BOOST_PYTHON_UNARY_ENUM(N, class A) + > +PyObject* operator()( + R (T::*pmf)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q + , PyObject* args, PyObject* keywords + , P const& policies + ) const +{ + return returning::call(pmf, args, keywords, &policies); +} + +#undef N +#undef Q + +#endif diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp index f31c1aed..c8c3fc2b 100644 --- a/include/boost/python/detail/member_function_cast.hpp +++ b/include/boost/python/detail/member_function_cast.hpp @@ -1,16 +1,21 @@ +#if !defined(BOOST_PP_IS_ITERATING) + // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef MEMBER_FUNCTION_CAST_DWA2002311_HPP -# define MEMBER_FUNCTION_CAST_DWA2002311_HPP -# include -# include -# include -# include -# include -# include + +# ifndef MEMBER_FUNCTION_CAST_DWA2002311_HPP +# define MEMBER_FUNCTION_CAST_DWA2002311_HPP + +# include + +# include +# include + +# include +# include namespace boost { namespace python { namespace detail { @@ -47,35 +52,19 @@ struct non_member_function_cast_impl template struct member_function_cast_impl { -# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING template static non_member_function_cast_impl stage1(U) { return non_member_function_cast_impl(); } -# endif - +# endif + // Member functions -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif - -# define BOOST_PYTHON_MEMBER_FUNCTION_CAST_STAGE1(args, cv) \ -template < \ - class S \ - , class R \ - BOOST_PP_COMMA_IF(BOOST_PP_DEC(args)) BOOST_MPL_TEMPLATE_PARAMETERS(1, args, class A) \ - > \ -static cast_helper \ -stage1(BOOST_PYTHON_FN(S::*,1,args)cv()) \ -{ \ - return cast_helper(); \ -} - -BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_MEMBER_FUNCTION_CAST_STAGE1) +# define BOOST_PP_ITERATION_PARAMS_1 3, (0, 3, ) +# include BOOST_PP_ITERATE() }; - template struct member_function_cast # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING @@ -92,4 +81,32 @@ struct member_function_cast }}} // namespace boost::python::detail -#endif // MEMBER_FUNCTION_CAST_DWA2002311_HPP +# endif // MEMBER_FUNCTION_CAST_DWA2002311_HPP + +#elif BOOST_PP_ITERATION_DEPTH() == 1 +// outer over cv-qualifiers + +# define BOOST_PP_ITERATION_PARAMS_2 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# include BOOST_PP_ITERATE() + +#elif BOOST_PP_ITERATION_DEPTH() == 2 +# line BOOST_PP_LINE(__LINE__, member_function_cast.hpp) +// inner over arities + +# define N BOOST_PP_ITERATION() +# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) + + template < + class S, class R + BOOST_PP_COMMA_IF(N) BOOST_PYTHON_UNARY_ENUM(N, class A) + > + static cast_helper + stage1(R (S::*)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q) + { + return cast_helper(); + } + +# undef N +# undef Q + +#endif diff --git a/include/boost/python/detail/preprocessor.hpp b/include/boost/python/detail/preprocessor.hpp index fc492155..d55d44e6 100644 --- a/include/boost/python/detail/preprocessor.hpp +++ b/include/boost/python/detail/preprocessor.hpp @@ -6,105 +6,58 @@ #ifndef PREPROCESSOR_DWA200247_HPP # define PREPROCESSOR_DWA200247_HPP -# include -# include +# include +# include +# include # include -# include -# include -# include -# include -# include -# include -namespace boost { namespace python { namespace detail { +// stuff that should be in the preprocessor library -# define BOOST_PYTHON_CONST() const -# define BOOST_PYTHON_VOLATILE() volatile -# define BOOST_PYTHON_CONST_VOLATILE() const volatile +# define BOOST_PYTHON_APPLY(x) BOOST_PP_CAT(BOOST_PYTHON_APPLY_, x) -# define BOOST_PYTHON_ALL_CV \ - BOOST_PP_TUPLE_TO_LIST(4, (BOOST_PP_EMPTY \ - , BOOST_PYTHON_CONST \ - , BOOST_PYTHON_VOLATILE \ - , BOOST_PYTHON_CONST_VOLATILE)) +# define BOOST_PYTHON_APPLY_BOOST_PYTHON_ITEM(v) v +# define BOOST_PYTHON_APPLY_BOOST_PYTHON_NIL + +// cv-qualifiers # if !defined(__MWERKS__) || __MWERKS__ > 0x2407 -# define BOOST_PYTHON_MEMBER_FUNCTION_CV BOOST_PYTHON_ALL_CV +# define BOOST_PYTHON_CV_COUNT 4 # else -# define BOOST_PYTHON_MEMBER_FUNCTION_CV BOOST_PP_TUPLE_TO_LIST(1, (BOOST_PP_EMPTY)) -# endif +# define BOOST_PYTHON_CV_COUNT 1 +# endif -#ifndef BOOST_PYTHON_DEBUGGABLE_ARITY -# define BOOST_PYTHON_DEBUGGABLE_ARITY 15 -#endif +# ifndef BOOST_PYTHON_MAX_ARITY +# define BOOST_PYTHON_MAX_ARITY 15 +# endif -#ifndef BOOST_PYTHON_MAX_ARITY -# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245 -// Generate at least two more arguments just to test the syntax -# define BOOST_PYTHON_MAX_ARITY 17 -# else -// Current EDG compilers have a really slow preprocessor which makes -// it important not to generate new functions with it unless -// absolutely neccessary -# define BOOST_PYTHON_MAX_ARITY BOOST_PYTHON_DEBUGGABLE_ARITY -# endif -#endif +# define BOOST_PYTHON_CV_QUALIFIER(i) \ + BOOST_PYTHON_APPLY( \ + BOOST_PP_TUPLE_ELEM(4, i, BOOST_PYTHON_CV_QUALIFIER_I) \ + ) -#ifdef BOOST_PYTHON_GENERATE_CODE -# undef BOOST_STATIC_CONSTANT -# define BOOST_PYTHON_ARITY_START 0 -# define BOOST_PYTHON_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY) -# define BOOST_PYTHON_MF_ARITY_START 1 -# define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY)) -#else -# define BOOST_PYTHON_ARITY_START BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY) -# define BOOST_PYTHON_ARITY_FINISH BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY) -# define BOOST_PYTHON_MF_ARITY_START BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_DEBUGGABLE_ARITY)) -# define BOOST_PYTHON_MF_ARITY_FINISH BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY)) -#endif +# define BOOST_PYTHON_CV_QUALIFIER_I \ + ( \ + BOOST_PYTHON_NIL, \ + BOOST_PYTHON_ITEM(const), \ + BOOST_PYTHON_ITEM(volatile), \ + BOOST_PYTHON_ITEM(const volatile) \ + ) -#if BOOST_PYTHON_MAX_ARITY > BOOST_PYTHON_DEBUGGABLE_ARITY +// enumerators +# define BOOST_PYTHON_UNARY_ENUM(c, text) BOOST_PP_REPEAT(c, BOOST_PYTHON_UNARY_ENUM_I, text) +# define BOOST_PYTHON_UNARY_ENUM_I(n, text) BOOST_PP_COMMA_IF(n) text ## n -# define BOOST_PYTHON_FN(inner,start,count) \ - R(inner)(BOOST_MPL_TEMPLATE_PARAMETERS(start,count,A)) +# define BOOST_PYTHON_BINARY_ENUM(c, a, b) BOOST_PP_REPEAT(c, BOOST_PYTHON_BINARY_ENUM_I, (a, b)) +# define BOOST_PYTHON_BINARY_ENUM_I(n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, _), n) -# define BOOST_PYTHON_REPEAT_ARITY_2ND(function,data) \ - BOOST_PP_REPEAT_FROM_TO_2ND( \ - BOOST_PYTHON_ARITY_START, BOOST_PYTHON_ARITY_FINISH \ - , function, data) +# define BOOST_PYTHON_ENUM_WITH_DEFAULT(c, text, def) BOOST_PP_REPEAT(c, BOOST_PYTHON_ENUM_WITH_DEFAULT_I, (text, def)) +# define BOOST_PYTHON_ENUM_WITH_DEFAULT_I(n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) = BOOST_PP_TUPLE_ELEM(2, 1, _) -# define BOOST_PYTHON_REPEAT_MF_ARITY_2ND(function,data) \ - BOOST_PP_REPEAT_FROM_TO_2ND( \ - BOOST_PYTHON_MF_ARITY_START, BOOST_PYTHON_MF_ARITY_FINISH \ - , function, data) +// fixed text (no commas) +# define BOOST_PYTHON_FIXED(n, text) text -# define BOOST_PYTHON_REPEAT_PMF_CV(index, function, cv) \ - BOOST_PYTHON_REPEAT_MF_ARITY_2ND(function,cv) - -# define BOOST_PYTHON_REPEAT_MF_CV_2ND(function) \ - BOOST_PP_LIST_FOR_EACH(BOOST_PYTHON_REPEAT_PMF_CV,function,BOOST_PYTHON_MEMBER_FUNCTION_CV) - -# define BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(function) \ - BOOST_PP_LIST_FOR_EACH(BOOST_PYTHON_REPEAT_PMF_CV,function,BOOST_PYTHON_ALL_CV) - -#define BOOST_PYTHON_NUMBER_PAIR(Index, Pair) \ - BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,0,Pair),Index) \ - BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2,1,Pair),Index) - -#define BOOST_PYTHON_ENUM_PARAMS2(N, Pair) BOOST_PP_ENUM(N, BOOST_PYTHON_NUMBER_PAIR, Pair) - -# define BOOST_PYTHON_PROJECT_1ST(a1,a2) a1 -# define BOOST_PYTHON_PROJECT_2ND(a1,a2) a2 -#else - -# define BOOST_PYTHON_REPEAT_ARITY_2ND(function,data) -# define BOOST_PYTHON_REPEAT_MF_ARITY_2ND(function,data) -# define BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(function) -# define BOOST_PYTHON_REPEAT_MF_CV_2ND(function) -# define BOOST_PYTHON_REPEAT_PMF_CV(index, function, cv) - -#endif - -}}} // namespace boost::python::detail +// flags +# define BOOST_PYTHON_FUNCTION_POINTER 0x0001 +# define BOOST_PYTHON_POINTER_TO_MEMBER 0x0002 #endif // PREPROCESSOR_DWA200247_HPP diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp index b00fd23f..2244671e 100755 --- a/include/boost/python/detail/result.hpp +++ b/include/boost/python/detail/result.hpp @@ -1,20 +1,25 @@ +#if !defined(BOOST_PP_IS_ITERATING) + // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef RESULT_DWA2002521_HPP -# define RESULT_DWA2002521_HPP -# include -# include -# include -# include -# include -# include -# include +# ifndef RESULT_DWA2002521_HPP +# define RESULT_DWA2002521_HPP -namespace boost { namespace python { namespace detail { +# include + +# include + +# include +# include + +# include +# include + +namespace boost { namespace python { namespace detail { // Defines a family of overloaded function which, given x, a function // pointer, member [function] pointer, or an AdaptableFunction object, @@ -25,20 +30,13 @@ namespace boost { namespace python { namespace detail { // an AdaptableFunction object, you must pass OL as a second argument // to get this to work portably. -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER) +# include BOOST_PP_ITERATE() -# define BOOST_PYTHON_FIRST_ARGUMENT_PF(args, ignored) \ -template \ -boost::type* result(BOOST_PYTHON_FN(*,0,args), int = 0) { return 0; } - -# define BOOST_PYTHON_FIRST_ARGUMENT_PMF(args, cv) \ -template \ -boost::type* result(BOOST_PYTHON_FN(A0::*,1,args)cv(), int = 0) { return 0; } - -BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_FIRST_ARGUMENT_PF, nil) -BOOST_PYTHON_REPEAT_MF_CV_2ND(BOOST_PYTHON_FIRST_ARGUMENT_PMF) +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER) +# include BOOST_PP_ITERATE() template boost::type* result(R (T::*), int = 0) { return 0; } @@ -79,8 +77,47 @@ template boost::type* result(X const&, short = 0) { return 0; } -# endif +# endif }}} // namespace boost::python::detail -#endif // RESULT_DWA2002521_HPP +# endif // RESULT_DWA2002521_HPP + +/* --------------- function pointers --------------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER +# line BOOST_PP_LINE(__LINE__, result.hpp(function pointers)) + +# define N BOOST_PP_ITERATION() + +template +boost::type* result(R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)), int = 0) +{ + return 0; +} + +# undef N + +/* --------------- pointers-to-members --------------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER +// Outer over cv-qualifiers + +# define BOOST_PP_ITERATION_PARAMS_2 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# include BOOST_PP_ITERATE() + +#elif BOOST_PP_ITERATION_DEPTH() == 2 +# line BOOST_PP_LINE(__LINE__, result.hpp(pointers-to-members)) +// Inner over arities + +# define N BOOST_PP_ITERATION() +# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) + +template +boost::type* result(R (T::*pmf)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q, int = 0) +{ + return 0; +} + +# undef N +# undef Q + +#endif diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 441460ea..498cc824 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -1,3 +1,5 @@ +#if !defined(BOOST_PP_IS_ITERATING) + // (C) Copyright David Abrahams 2001,2002. Permission to copy, use, modify, sell // and distribute this software is granted provided this copyright notice appears // in all copies. This software is provided "as is" without express or implied @@ -8,164 +10,205 @@ // This file generated for 5-argument member functions and 6-argument free // functions by gen_returning.py -#ifndef RETURNING_DWA20011201_HPP -# define RETURNING_DWA20011201_HPP +# ifndef RETURNING_DWA20011201_HPP +# define RETURNING_DWA20011201_HPP -# include -# include -# include -# include -# include +# include -# include -# include -# include -# include -# include -# include -# include +# include +# include +# include +# include + +# include +# include +# include +# include + +# include namespace boost { namespace python { namespace detail { +# define BOOST_PYTHON_RETURNING_NON_VOID 0x0004 +# define BOOST_PYTHON_RETURNING_VOID 0x0008 -// Calling C++ from Python template struct returning { - -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif + // Specializations for function pointers +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, BOOST_PYTHON_MAX_ARITY, , \ + BOOST_PYTHON_FUNCTION_POINTER | BOOST_PYTHON_RETURNING_NON_VOID) +# include BOOST_PP_ITERATE() -# define BOOST_PYTHON_ARG_CONVERTIBLE(index,ignored) \ - arg_from_python \ - BOOST_PP_CAT(c,index)(PyTuple_GET_ITEM(args_, index)); \ - if (!BOOST_PP_CAT(c,index).convertible()) return 0; - -# define BOOST_PYTHON_GET_ARG(index,ignored) \ - BOOST_PP_CAT(c,index)(PyTuple_GET_ITEM(args_, index)) - -# define BOOST_PYTHON_RETURNING_NON_VOID_MF(args,cv) \ - template \ - static PyObject* call( \ - BOOST_PYTHON_FN(A0::*pmf,1,args) cv() \ - , PyObject* args_, PyObject* \ - , P const* policies) \ - { \ - /* check that each of the arguments is convertible */ \ - /* self argument is special */ \ - arg_from_python c0(PyTuple_GET_ITEM(args_, 0)); \ - if (!c0.convertible()) return 0; \ - \ - /* Unroll a loop for the rest of them */ \ - BOOST_PP_REPEAT_FROM_TO(1,args,BOOST_PYTHON_ARG_CONVERTIBLE,nil) \ - \ - /* find the result converter */ \ - typedef typename P::result_converter result_converter; \ - typename mpl::apply1::type cr; \ - if (!cr.convertible()) return 0; \ - \ - if (!policies->precall(args_)) return 0; \ - \ - PyObject* result = cr( \ - ((BOOST_PYTHON_GET_ARG(0,nil)).*pmf)( \ - BOOST_PP_ENUM_SHIFTED(args,BOOST_PYTHON_GET_ARG,nil)) \ - ); \ - \ - return policies->postcall(args_, result); \ - } - -// Generate a series for each cv-qualification -BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_RETURNING_NON_VOID_MF) - -# define BOOST_PYTHON_RETURNING_NON_VOID_FN(args,ignored) \ - template \ - static PyObject* call( \ - BOOST_PYTHON_FN(*pf,0,args) \ - , PyObject* args_ \ - , PyObject* \ - , P const* policies) \ - { \ - /* check that each of the arguments is convertible */ \ - BOOST_PP_REPEAT(args,BOOST_PYTHON_ARG_CONVERTIBLE,nil) \ - \ - /* find the result converter */ \ - typedef typename P::result_converter result_converter; \ - typename mpl::apply1::type cr; \ - if (!cr.convertible()) return 0; \ - \ - if (!policies->precall(args_)) return 0; \ - \ - PyObject* result = cr( \ - (*pf)(BOOST_PP_ENUM(args,BOOST_PYTHON_GET_ARG,nil)) \ - ); \ - \ - return policies->postcall(args_, result); \ - } - -BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_RETURNING_NON_VOID_FN, nil) + // Specializations for member function pointers +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, 3, , \ + BOOST_PYTHON_POINTER_TO_MEMBER | BOOST_PYTHON_RETURNING_NON_VOID) +# include BOOST_PP_ITERATE() }; - + template <> struct returning { typedef void R; + // Specializations for function pointers +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, BOOST_PYTHON_MAX_ARITY, , \ + BOOST_PYTHON_FUNCTION_POINTER | BOOST_PYTHON_RETURNING_VOID) +# include BOOST_PP_ITERATE() -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif - -#define BOOST_PYTHON_RETURNING_VOID_MF(args,cv) \ -template \ -static PyObject*call( \ - BOOST_PYTHON_FN(A0::*pmf,1,args) cv() \ - , PyObject*args_ \ - , PyObject* \ - , P const* policies) \ -{ \ - /* check that each of the arguments is convertible */ \ - /* self argument is special */ \ - arg_from_pythonc0(PyTuple_GET_ITEM(args_,0)); \ - if (!c0.convertible()) return 0; \ - \ - /* Unroll a loop for the rest of them */ \ - BOOST_PP_REPEAT_FROM_TO(1,args,BOOST_PYTHON_ARG_CONVERTIBLE,nil) \ - \ - if (!policies->precall(args_)) return 0; \ - \ - ((c0(PyTuple_GET_ITEM(args_,0))).*pmf)( \ - BOOST_PP_ENUM_SHIFTED(args,BOOST_PYTHON_GET_ARG,nil) \ - ); \ - \ - return policies->postcall(args_,detail::none()); \ -} - -//Generate a series for each cv-qualification -BOOST_PYTHON_REPEAT_MF_ALL_CV_2ND(BOOST_PYTHON_RETURNING_VOID_MF) - -#define BOOST_PYTHON_RETURNING_VOID_FN(args,ignored) \ -template \ -static PyObject*call( \ - BOOST_PYTHON_FN(*pf,0,args) \ - , PyObject*args_ \ - , PyObject* \ - , P const* policies) \ -{ \ - /*check that each of the arguments is convertible*/ \ - BOOST_PP_REPEAT(args,BOOST_PYTHON_ARG_CONVERTIBLE,nil) \ - \ - BOOST_PP_EXPR_IF(args,if (!policies->precall(args_)) return 0;) \ - \ - (*pf)(BOOST_PP_ENUM(args,BOOST_PYTHON_GET_ARG,nil)); \ - \ - return policies->postcall(args_,detail::none()); \ -} - -BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_RETURNING_VOID_FN,nil) - + // Specializations for member function pointers +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, 3, , \ + BOOST_PYTHON_POINTER_TO_MEMBER | BOOST_PYTHON_RETURNING_VOID) +# include BOOST_PP_ITERATE() }; }}} // namespace boost::python::detail -#endif//RETURNING_DWA20011201_HPP +# undef BOOST_PYTHON_RETURNING_NON_VOID +# undef BOOST_PYTHON_RETURNING_VOID +# endif // RETURNING_DWA20011201_HPP + +// --------------- function pointers --------------- // +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_FUNCTION_POINTER +# line BOOST_PP_LINE(__LINE__, returning.hpp(function pointers)) + +# define N BOOST_PP_ITERATION() + +# define BOOST_PYTHON_CALL_ARGS(n, _) \ + BOOST_PP_COMMA_IF(n) c##n(PyTuple_GET_ITEM(args_, n)) + +# define BOOST_PYTHON_CHECK_CONVERSION(n, _) \ + arg_from_python c##n(PyTuple_GET_ITEM(args_, n)); \ + if (!c##n.convertible()) \ + return 0; + +# if (BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_RETURNING_NON_VOID) + + template + static PyObject* call( + R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)) + , PyObject* args_ + , PyObject*, P const* policies) + { + // check that each of the arguments is convertible + BOOST_PP_REPEAT(N, BOOST_PYTHON_CHECK_CONVERSION, nil) + + // find the result converter + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible() || !policies->precall(args_)) + return 0; + PyObject* result = cr( + (*pf)(BOOST_PP_REPEAT(N, BOOST_PYTHON_CALL_ARGS, nil)) + ); + return policies->postcall(args_, result); + } +# elif (BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_RETURNING_VOID) + + template + static PyObject* call( + R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)) + , PyObject* args_ + , PyObject*, P const* policies) + { + // check that each of the arguments is convertible + BOOST_PP_REPEAT(N, BOOST_PYTHON_CHECK_CONVERSION, nil) + + if (!policies->precall(args_)) + return 0; + (*pf)(BOOST_PP_REPEAT(N, BOOST_PYTHON_CALL_ARGS, nil)); + return policies->postcall(args_, detail::none()); + } +# endif // returning void / non-void + +# undef N +# undef BOOST_PYTHON_CALL_ARGS +# undef BOOST_PYTHON_CHECK_CONVERSION + +// --------------- pointers to members --------------- // +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_POINTER_TO_MEMBER + + // Outer iteration over cv-qualifications +# define BOOST_PP_ITERATION_PARAMS_2 \ + 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# include BOOST_PP_ITERATE() + +#elif BOOST_PP_ITERATION_DEPTH() == 2 && BOOST_PP_RELATIVE_FLAGS(1) & BOOST_PYTHON_POINTER_TO_MEMBER +# line BOOST_PP_LINE(__LINE__, returning.hpp(pointers-to-members)) + + // Inner iteration over arities +# define N BOOST_PP_ITERATION() +# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) + +# define BOOST_PYTHON_CALL_ARGS(n, _) \ + BOOST_PP_COMMA_IF(n) c##n(PyTuple_GET_ITEM(args_, BOOST_PP_INC(n))) + +# define BOOST_PYTHON_CHECK_CONVERSION(n, _) \ + arg_from_python c##n(PyTuple_GET_ITEM(args_, BOOST_PP_INC(n))); \ + if (!c##n.convertible()) \ + return 0; + +# if (BOOST_PP_RELATIVE_FLAGS(1) & BOOST_PYTHON_RETURNING_NON_VOID) + + template + static PyObject* call( + R (T::*pmf)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q + , PyObject* args_ + , PyObject*, P const* policies) + { + // check that each of the arguments is convertible + // self is special + arg_from_python ct(PyTuple_GET_ITEM(args_, 0)); + if (!ct.convertible()) + return 0; + + // unroll a loop for the rest of them + BOOST_PP_REPEAT(N, BOOST_PYTHON_CHECK_CONVERSION, nil) + + // find the result converter + typedef typename P::result_converter result_converter; + typename mpl::apply1::type cr; + if (!cr.convertible() || !policies->precall(args_)) + return 0; + PyObject* result = cr( + ((ct(PyTuple_GET_ITEM(args_, 0))).*pmf)( + BOOST_PP_REPEAT(N, BOOST_PYTHON_CALL_ARGS, nil)) + ); + return policies->postcall(args_, result); + } +# elif (BOOST_PP_RELATIVE_FLAGS(1) & BOOST_PYTHON_RETURNING_VOID) + + template + static PyObject* call( + R (T::*pmf)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q + , PyObject* args_ + , PyObject*, P const* policies) + { + // check that each of the arguments is convertible + // self is special + arg_from_python ct(PyTuple_GET_ITEM(args_, 0)); + if (!ct.convertible()) + return 0; + + // unroll a loop for the rest of them + BOOST_PP_REPEAT(N, BOOST_PYTHON_CHECK_CONVERSION, nil) + + if (!policies->precall(args_)) + return 0; + + ((ct(PyTuple_GET_ITEM(args_, 0))).*pmf)( + BOOST_PP_REPEAT(N, BOOST_PYTHON_CALL_ARGS, nil)); + return policies->postcall(args_, detail::none()); + } +# endif + +# undef N +# undef Q +# undef BOOST_PYTHON_CALL_ARGS +# undef BOOST_PYTHON_CHECK_CONVERSION + +#endif diff --git a/include/boost/python/detail/target.hpp b/include/boost/python/detail/target.hpp index e6869140..d8033a8c 100644 --- a/include/boost/python/detail/target.hpp +++ b/include/boost/python/detail/target.hpp @@ -1,38 +1,74 @@ +#if !defined(BOOST_PP_IS_ITERATING) + // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef TARGET_DWA2002521_HPP -# define TARGET_DWA2002521_HPP -# include -# include -# include -# include -# include -# include +# ifndef TARGET_DWA2002521_HPP +# define TARGET_DWA2002521_HPP -namespace boost { namespace python { namespace detail { +# include -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif +# include -# define BOOST_PYTHON_FIRST_ARGUMENT_PF(args, ignored) \ -template \ -boost::type* target(BOOST_PYTHON_FN(*,0,args)) { return 0; } +# include +# include +# include -# define BOOST_PYTHON_FIRST_ARGUMENT_PMF(args, cv) \ -template \ -boost::type* target(BOOST_PYTHON_FN(A0::*,1,args)cv()) { return 0; } +namespace boost { namespace python { namespace detail { -BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_FIRST_ARGUMENT_PF, nil) -BOOST_PYTHON_REPEAT_MF_CV_2ND(BOOST_PYTHON_FIRST_ARGUMENT_PMF) +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER) +# include BOOST_PP_ITERATE() + +# define BOOST_PP_ITERATION_PARAMS_1 \ + 4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER) +# include BOOST_PP_ITERATE() template boost::type* target(R (T::*)) { return 0; } }}} // namespace boost::python::detail -#endif // TARGET_DWA2002521_HPP +# endif // TARGET_DWA2002521_HPP + +/* --------------- function pointers --------------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER +# line BOOST_PP_LINE(__LINE__, target.hpp(function_pointers)) + +# define N BOOST_PP_ITERATION() + +template +boost::type* target(R (*)(BOOST_PYTHON_UNARY_ENUM(N, A))) +{ + return 0; +} + +# undef N + +/* --------------- pointers-to-members --------------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER +// Outer over cv-qualifiers + +# define BOOST_PP_ITERATION_PARAMS_2 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# include BOOST_PP_ITERATE() + +#elif BOOST_PP_ITERATION_DEPTH() == 2 +# line BOOST_PP_LINE(__LINE__, target.hpp(pointers-to-members)) +// Inner over arities + +# define N BOOST_PP_ITERATION() +# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) + +template +boost::type* target(R (T::*)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q) +{ + return 0; +} + +# undef N +# undef Q + +#endif diff --git a/include/boost/python/object/auto_ptr_generator.hpp b/include/boost/python/object/auto_ptr_generator.hpp deleted file mode 100644 index 9c13e436..00000000 --- a/include/boost/python/object/auto_ptr_generator.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef AUTO_PTR_GENERATOR_DWA2002123_HPP -# define AUTO_PTR_GENERATOR_DWA2002123_HPP -# include - -namespace boost { namespace python { namespace object { - -struct auto_ptr_generator -{ - template - struct apply - { - typedef std::auto_ptr type; - }; -}; - -}}} // namespace boost::python::object - -#endif // AUTO_PTR_GENERATOR_DWA2002123_HPP diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 1d55512c..fa6614eb 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -1,58 +1,68 @@ +#if !defined(BOOST_PP_IS_ITERATING) + // Copyright David Abrahams 2001. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef MAKE_HOLDER_DWA20011215_HPP -# define MAKE_HOLDER_DWA20011215_HPP -# include -# include -# include -# include -# include -# include -# include +# ifndef MAKE_HOLDER_DWA20011215_HPP +# define MAKE_HOLDER_DWA20011215_HPP -namespace boost { namespace python { namespace objects { +# include +# include +# include +# include + +# include + +# include +# include +# include + +namespace boost { namespace python { namespace objects { template struct make_holder; -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif +# define BOOST_PYTHON_FORWARD_ARG(index, _) \ + typedef typename mpl::at::type t##index; \ + typedef typename forward::type f##index; +# define BOOST_PYTHON_DO_FORWARD_ARG(index, _) , f##index(a##index) -# define BOOST_PYTHON_FORWARD_ARG(index, ignored) \ - typedef typename mpl::at::type BOOST_PP_CAT(t,index); \ - typedef typename forward::type BOOST_PP_CAT(f,index); +// specializations... +# define BOOST_PP_ITERATION_PARAMS_1 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# include BOOST_PP_ITERATE() -# define BOOST_PYTHON_DO_FORWARD_ARG(index, ignored) \ - BOOST_PP_CAT(f,index)(BOOST_PP_CAT(a, index)) - -# define BOOST_PYTHON_MAKE_HOLDER(nargs,ignored) \ -template <> \ -struct make_holder \ -{ \ - template \ - struct apply \ - { \ - BOOST_PP_REPEAT(nargs, BOOST_PYTHON_FORWARD_ARG, nil) \ - \ - static void execute( \ - PyObject* p \ - BOOST_PP_COMMA_IF(nargs) BOOST_PYTHON_ENUM_PARAMS2(nargs, (t,a)) ) \ - { \ - (new Holder( \ - p \ - BOOST_PP_COMMA_IF(nargs) BOOST_PP_ENUM( \ - nargs,BOOST_PYTHON_DO_FORWARD_ARG,nil)))->install(p); \ - } \ - }; \ -}; - -BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_MAKE_HOLDER,nil) +# undef BOOST_PYTHON_FORWARD_ARG +# undef BOOST_PYTHON_DO_FORWARD_ARG }}} // namespace boost::python::objects -#endif // MAKE_HOLDER_DWA20011215_HPP +# endif // MAKE_HOLDER_DWA20011215_HPP + +#elif BOOST_PP_ITERATION_DEPTH() == 1 +# line BOOST_PP_LINE(__LINE__, make_holder.hpp) + +# define N BOOST_PP_ITERATION() + +template <> +struct make_holder +{ + template + struct apply + { + BOOST_PP_REPEAT(N, BOOST_PYTHON_FORWARD_ARG, nil) + static void execute( + PyObject* p + BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, t, a)) + { + (new Holder( + p BOOST_PP_REPEAT(N, BOOST_PYTHON_DO_FORWARD_ARG, nil)))->install(p); + } + }; +}; + +# undef N + +#endif diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 6912da25..3f495250 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -1,25 +1,35 @@ +#if !defined(BOOST_PP_IS_ITERATING) + // Copyright David Abrahams 2001. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef POINTER_HOLDER_DWA20011215_HPP -# define POINTER_HOLDER_DWA20011215_HPP -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +# ifndef POINTER_HOLDER_DWA20011215_HPP +# define POINTER_HOLDER_DWA20011215_HPP -namespace boost { namespace python { namespace objects { +# include + +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include + +# include +# include +# include + +namespace boost { namespace python { namespace objects { + +# define BOOST_PYTHON_UNFORWARD_LOCAL(n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) template struct pointer_holder : instance_holder @@ -27,25 +37,10 @@ struct pointer_holder : instance_holder pointer_holder(Pointer); // Forward construction to the held object -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif +# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY, , 1) +# include BOOST_PP_ITERATE() -# define BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER(nargs, ignored) \ - BOOST_PP_EXPR_IF(nargs, template <) \ - BOOST_PP_ENUM_PARAMS(nargs, class A) \ - BOOST_PP_EXPR_IF(nargs, >) \ - pointer_holder(PyObject* \ - BOOST_PP_COMMA_IF(nargs) \ - BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ - : m_p(new Value( \ - BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ - )) \ - {} - - BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER,nil) - private: // required holder implementation void* holds(type_info); @@ -59,30 +54,12 @@ struct pointer_holder_back_reference : instance_holder private: typedef typename python::pointee::type held_type; public: - - pointer_holder_back_reference(Pointer); - - // Forward construction to the held object -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif - -# define BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER_BACK_REFERENCE(nargs, ignored) \ - BOOST_PP_EXPR_IF(nargs, template <) \ - BOOST_PP_ENUM_PARAMS(nargs, class A) \ - BOOST_PP_EXPR_IF(nargs, >) \ - pointer_holder_back_reference(PyObject* p \ - BOOST_PP_COMMA_IF(nargs) \ - BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ - : m_p(new held_type( \ - p BOOST_PP_COMMA_IF(nargs) \ - BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ - )) \ - { \ - python::detail::force_instantiate(instance_finder::registration); \ - } - BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_POINTER_HOLDER_BACK_REFERENCE,nil) + pointer_holder_back_reference(Pointer); + + // Forward construction to the held object +# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY, , 2) +# include BOOST_PP_ITERATE() private: // required holder implementation void* holds(type_info); @@ -91,6 +68,8 @@ struct pointer_holder_back_reference : instance_holder Pointer m_p; }; +# undef BOOST_PYTHON_UNFORWARD_LOCAL + template inline pointer_holder::pointer_holder(Pointer p) : m_p(p) @@ -130,4 +109,43 @@ void* pointer_holder_back_reference::holds(type_info dst_t) }}} // namespace boost::python::objects -#endif // POINTER_HOLDER_DWA20011215_HPP +# endif // POINTER_HOLDER_DWA20011215_HPP + +/* --------------- pointer_holder --------------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1 +# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp) + +# define N BOOST_PP_ITERATION() + +# if (N != 0) + template< BOOST_PYTHON_UNARY_ENUM(N, class A) > +# endif + pointer_holder(PyObject* BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) + : m_p(new Value( + BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) + )) + {} + +# undef N + +/* --------------- pointer_holder_back_reference --------------- */ +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2 +# line BOOST_PP_LINE(__LINE__, pointer_holder.hpp(pointer_holder_back_reference)) + +# define N BOOST_PP_ITERATION() + +# if (N != 0) + template < BOOST_PYTHON_UNARY_ENUM(N, class A) > +# endif + pointer_holder_back_reference( + PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) + : m_p(new held_type( + p BOOST_PP_COMMA_IF(N) BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) + )) + { + python::detail::force_instantiate(instance_finder::registration); + } + +# undef N + +#endif diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index d4469561..ac42f561 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -1,44 +1,37 @@ +#if !defined(BOOST_PP_IS_ITERATING) + // Copyright David Abrahams 2001. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef VALUE_HOLDER_DWA20011215_HPP -# define VALUE_HOLDER_DWA20011215_HPP -# include -# include -# include -# include -# include -# include -# include -# include -# include +# ifndef VALUE_HOLDER_DWA20011215_HPP +# define VALUE_HOLDER_DWA20011215_HPP + +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include +# include namespace boost { namespace python { namespace objects { +# define BOOST_PYTHON_UNFORWARD_LOCAL(n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) + template struct value_holder : instance_holder { - // Forward construction to the held object -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif - -# define BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER(nargs, ignored) \ - BOOST_PP_EXPR_IF(nargs, template <) \ - BOOST_PP_ENUM_PARAMS(nargs, class A) \ - BOOST_PP_EXPR_IF(nargs, >) \ - value_holder(PyObject* \ - BOOST_PP_COMMA_IF(nargs) \ - BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ - : m_held( \ - BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ - ) \ - {} - - BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER,nil) + // Forward construction to the held object +# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY, , 1) +# include BOOST_PP_ITERATE() private: // required holder implementation void* holds(type_info); @@ -51,34 +44,18 @@ template struct value_holder_back_reference : instance_holder { // Forward construction to the held object -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif - -# define BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER_BACK_REFERENCE(nargs, ignored) \ - BOOST_PP_EXPR_IF(nargs, template <) \ - BOOST_PP_ENUM_PARAMS(nargs, class A) \ - BOOST_PP_EXPR_IF(nargs, >) \ - value_holder_back_reference(PyObject* p \ - BOOST_PP_COMMA_IF(nargs) \ - BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,a))) \ - : m_held( \ - p BOOST_PP_COMMA_IF(nargs) \ - BOOST_PP_ENUM(nargs, BOOST_PYTHON_UNFORWARD, nil) \ - ) \ - { \ - python::detail::force_instantiate(instance_finder::registration); \ - } +# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY, , 2) +# include BOOST_PP_ITERATE() - BOOST_PYTHON_REPEAT_ARITY_2ND(BOOST_PYTHON_CONSTRUCT_VALUE_HOLDER_BACK_REFERENCE,nil) - - private: // required holder implementation +private: // required holder implementation void* holds(type_info); private: // data members BackReferenceType m_held; }; +# undef BOOST_PYTHON_UNFORWARD_LOCAL + template void* value_holder::holds(type_info dst_t) { @@ -104,4 +81,49 @@ void* value_holder_back_reference::holds( }}} // namespace boost::python::objects -#endif // VALUE_HOLDER_DWA20011215_HPP +# endif // VALUE_HOLDER_DWA20011215_HPP + +// --------------- value_holder --------------- + +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1 +# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder)) + +# define N BOOST_PP_ITERATION() + +# if (N != 0) + template +# endif + value_holder(PyObject* + BOOST_PP_COMMA_IF(N) + BOOST_PYTHON_BINARY_ENUM(N, A, a)) + : m_held( + BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) + ) + {} + +# undef N + +// --------------- value_holder_back_reference --------------- + +#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2 +# line BOOST_PP_LINE(__LINE__, value_holder.hpp(value_holder_back_reference)) + +# define N BOOST_PP_ITERATION() + +# if (N != 0) + template +# endif + value_holder_back_reference(PyObject* p + BOOST_PP_COMMA_IF(N) + BOOST_PYTHON_BINARY_ENUM(N, A, a)) + : m_held( + p BOOST_PP_COMMA_IF(N) + BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) + ) + { + python::detail::force_instantiate(instance_finder::registration); + } + +# undef N + +#endif diff --git a/include/boost/python/object_call.hpp b/include/boost/python/object_call.hpp new file mode 100644 index 00000000..4e9c569e --- /dev/null +++ b/include/boost/python/object_call.hpp @@ -0,0 +1,22 @@ +# // Copyright David Abrahams 2002. Permission to copy, use, +# // modify, sell and distribute this software is granted provided this +# // copyright notice appears in all copies. This software is provided +# // "as is" without express or implied warranty, and with no claim as +# // to its suitability for any purpose. + +#if !defined(BOOST_PP_IS_ITERATING) +# error Boost.Python - do not include this file! +#endif + +#define N BOOST_PP_ITERATION() + + template + typename dependent::type + operator()(BOOST_PYTHON_BINARY_ENUM(N, A, const& a)) const + { + typedef typename dependent::type obj; + U const& self = *static_cast(this); + return call(converter::get_managed_object(self), BOOST_PYTHON_UNARY_ENUM(N, a)); + } + +#undef N diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 4e391c5c..2fd1804f 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -5,15 +5,18 @@ // to its suitability for any purpose. #ifndef OBJECT_CORE_DWA2002615_HPP # define OBJECT_CORE_DWA2002615_HPP + +# include + # include # include -# include # include -# include # include # include # include -# include +# include + +# include namespace boost { namespace python { @@ -99,23 +102,8 @@ namespace api // object operator()() const; -# ifndef BOOST_PYTHON_GENERATE_CODE -# include -# endif - -# define BOOST_PYTHON_OBJECT_CALL(nargs,ignored) \ - template \ - typename dependent::type \ - operator()(BOOST_PYTHON_ENUM_PARAMS2(nargs, (A,const& a))) const \ - { \ - typedef typename dependent::type obj; \ - U const& self = *static_cast(this); \ - return call(converter::get_managed_object(self), BOOST_PP_ENUM_PARAMS(nargs, a)); \ - } - - BOOST_PP_REPEAT_FROM_TO_2ND( - BOOST_PP_MAX(1, BOOST_PYTHON_ARITY_START), BOOST_PYTHON_ARITY_FINISH - , BOOST_PYTHON_OBJECT_CALL, ignored) +# define BOOST_PP_ITERATION_PARAMS_1 3, (1, BOOST_PYTHON_MAX_ARITY, ) +# include BOOST_PP_ITERATE() // truth value testing // From 88170f6dc4f4f52dae73050e68f849ae974a5ba9 Mon Sep 17 00:00:00 2001 From: Paul Mensonides Date: Wed, 10 Jul 2002 06:32:00 +0000 Subject: [PATCH 0559/1042] updated to new iteration interface [SVN r14388] --- include/boost/python/args.hpp | 4 +-- include/boost/python/call.hpp | 2 +- include/boost/python/call_method.hpp | 2 +- .../boost/python/detail/arg_tuple_size.hpp | 6 ++-- include/boost/python/detail/caller.hpp | 6 ++-- .../python/detail/member_function_cast.hpp | 4 +-- include/boost/python/detail/result.hpp | 6 ++-- include/boost/python/detail/returning.hpp | 28 +++++++++---------- include/boost/python/detail/target.hpp | 6 ++-- include/boost/python/object/make_holder.hpp | 2 +- .../boost/python/object/pointer_holder.hpp | 4 +-- include/boost/python/object/value_holder.hpp | 4 +-- include/boost/python/object_core.hpp | 2 +- 13 files changed, 38 insertions(+), 38 deletions(-) diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index c99daafc..d3b7c5d9 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -46,10 +46,10 @@ namespace boost { namespace mpl { template struct size; template struct at; -# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY, , 1) +# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) # include BOOST_PP_ITERATE() -# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY - 1, , 2) +# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY - 1, , 2)) # include BOOST_PP_ITERATE() diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp index 82c07b6f..45ab7712 100644 --- a/include/boost/python/call.hpp +++ b/include/boost/python/call.hpp @@ -25,7 +25,7 @@ namespace boost { namespace python { # define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(n, _) \ , converter::arg_to_python(a##n).get() -# define BOOST_PP_ITERATION_PARAMS_1 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() # undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp index c0ced783..26b295d9 100644 --- a/include/boost/python/call_method.hpp +++ b/include/boost/python/call_method.hpp @@ -24,7 +24,7 @@ namespace boost { namespace python { # define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(n, _) \ , converter::arg_to_python(a##n).get() -# define BOOST_PP_ITERATION_PARAMS_1 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() # undef BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index 24abae89..bd1933fa 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -41,12 +41,12 @@ template struct arg_tuple_size; // Specializations for function pointers # define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER) + (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) # include BOOST_PP_ITERATE() // Specializations for member function pointers # define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER) + (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) # include BOOST_PP_ITERATE() # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) @@ -94,7 +94,7 @@ char_array arg_tuple_size_helper( // Outer iteration over cv-qualifications # define BOOST_PP_ITERATION_PARAMS_2 \ - 3, (0, BOOST_PYTHON_MAX_ARITY, ) + (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() #elif BOOST_PP_ITERATION_DEPTH() == 2 && BOOST_PP_RELATIVE_FLAGS(1) == BOOST_PYTHON_POINTER_TO_MEMBER diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index d8871cd1..43366464 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -39,12 +39,12 @@ struct caller // function pointers # define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER) + (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) # include BOOST_PP_ITERATE() // pointers-to-members # define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, 3, , BOOST_PYTHON_POINTER_TO_MEMBER) + (4, (0, 3, , BOOST_PYTHON_POINTER_TO_MEMBER)) # include BOOST_PP_ITERATE() }; @@ -78,7 +78,7 @@ PyObject* operator()( #elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER // outer over cv-qualifiers -# define BOOST_PP_ITERATION_PARAMS_2 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() #elif BOOST_PP_ITERATION_DEPTH() == 2 diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp index c8c3fc2b..c7ac4fa8 100644 --- a/include/boost/python/detail/member_function_cast.hpp +++ b/include/boost/python/detail/member_function_cast.hpp @@ -61,7 +61,7 @@ struct member_function_cast_impl # endif // Member functions -# define BOOST_PP_ITERATION_PARAMS_1 3, (0, 3, ) +# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 3, )) # include BOOST_PP_ITERATE() }; @@ -86,7 +86,7 @@ struct member_function_cast #elif BOOST_PP_ITERATION_DEPTH() == 1 // outer over cv-qualifiers -# define BOOST_PP_ITERATION_PARAMS_2 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() #elif BOOST_PP_ITERATION_DEPTH() == 2 diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp index 2244671e..742195de 100755 --- a/include/boost/python/detail/result.hpp +++ b/include/boost/python/detail/result.hpp @@ -31,11 +31,11 @@ namespace boost { namespace python { namespace detail { // to get this to work portably. # define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER) + (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) # include BOOST_PP_ITERATE() # define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER) + (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) # include BOOST_PP_ITERATE() template @@ -101,7 +101,7 @@ boost::type* result(R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)), int = 0) #elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER // Outer over cv-qualifiers -# define BOOST_PP_ITERATION_PARAMS_2 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() #elif BOOST_PP_ITERATION_DEPTH() == 2 diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 498cc824..84609493 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -36,15 +36,15 @@ template struct returning { // Specializations for function pointers -# define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, BOOST_PYTHON_MAX_ARITY, , \ - BOOST_PYTHON_FUNCTION_POINTER | BOOST_PYTHON_RETURNING_NON_VOID) +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, BOOST_PYTHON_MAX_ARITY, , \ + BOOST_PYTHON_FUNCTION_POINTER | BOOST_PYTHON_RETURNING_NON_VOID)) # include BOOST_PP_ITERATE() // Specializations for member function pointers -# define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, 3, , \ - BOOST_PYTHON_POINTER_TO_MEMBER | BOOST_PYTHON_RETURNING_NON_VOID) +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, 3, , \ + BOOST_PYTHON_POINTER_TO_MEMBER | BOOST_PYTHON_RETURNING_NON_VOID)) # include BOOST_PP_ITERATE() }; @@ -53,15 +53,15 @@ struct returning { typedef void R; // Specializations for function pointers -# define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, BOOST_PYTHON_MAX_ARITY, , \ - BOOST_PYTHON_FUNCTION_POINTER | BOOST_PYTHON_RETURNING_VOID) +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, BOOST_PYTHON_MAX_ARITY, , \ + BOOST_PYTHON_FUNCTION_POINTER | BOOST_PYTHON_RETURNING_VOID)) # include BOOST_PP_ITERATE() // Specializations for member function pointers -# define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, 3, , \ - BOOST_PYTHON_POINTER_TO_MEMBER | BOOST_PYTHON_RETURNING_VOID) +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, 3, , \ + BOOST_PYTHON_POINTER_TO_MEMBER | BOOST_PYTHON_RETURNING_VOID)) # include BOOST_PP_ITERATE() }; @@ -133,8 +133,8 @@ struct returning #elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_POINTER_TO_MEMBER // Outer iteration over cv-qualifications -# define BOOST_PP_ITERATION_PARAMS_2 \ - 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# define BOOST_PP_ITERATION_PARAMS_2 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() #elif BOOST_PP_ITERATION_DEPTH() == 2 && BOOST_PP_RELATIVE_FLAGS(1) & BOOST_PYTHON_POINTER_TO_MEMBER diff --git a/include/boost/python/detail/target.hpp b/include/boost/python/detail/target.hpp index d8033a8c..d8eb7d68 100644 --- a/include/boost/python/detail/target.hpp +++ b/include/boost/python/detail/target.hpp @@ -20,11 +20,11 @@ namespace boost { namespace python { namespace detail { # define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER) + (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) # include BOOST_PP_ITERATE() # define BOOST_PP_ITERATION_PARAMS_1 \ - 4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER) + (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) # include BOOST_PP_ITERATE() template @@ -52,7 +52,7 @@ boost::type* target(R (*)(BOOST_PYTHON_UNARY_ENUM(N, A #elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER // Outer over cv-qualifiers -# define BOOST_PP_ITERATION_PARAMS_2 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() #elif BOOST_PP_ITERATION_DEPTH() == 2 diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index fa6614eb..58a185b0 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -31,7 +31,7 @@ template struct make_holder; # define BOOST_PYTHON_DO_FORWARD_ARG(index, _) , f##index(a##index) // specializations... -# define BOOST_PP_ITERATION_PARAMS_1 3, (0, BOOST_PYTHON_MAX_ARITY, ) +# define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() # undef BOOST_PYTHON_FORWARD_ARG diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 3f495250..72cecdfc 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -38,7 +38,7 @@ struct pointer_holder : instance_holder // Forward construction to the held object -# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY, , 1) +# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) # include BOOST_PP_ITERATE() private: // required holder implementation @@ -58,7 +58,7 @@ struct pointer_holder_back_reference : instance_holder pointer_holder_back_reference(Pointer); // Forward construction to the held object -# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY, , 2) +# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 2)) # include BOOST_PP_ITERATE() private: // required holder implementation diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index ac42f561..353cd929 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -30,7 +30,7 @@ template struct value_holder : instance_holder { // Forward construction to the held object -# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY, , 1) +# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) # include BOOST_PP_ITERATE() private: // required holder implementation @@ -44,7 +44,7 @@ template struct value_holder_back_reference : instance_holder { // Forward construction to the held object -# define BOOST_PP_ITERATION_PARAMS_1 4, (0, BOOST_PYTHON_MAX_ARITY, , 2) +# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 2)) # include BOOST_PP_ITERATE() private: // required holder implementation diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 2fd1804f..35817f21 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -102,7 +102,7 @@ namespace api // object operator()() const; -# define BOOST_PP_ITERATION_PARAMS_1 3, (1, BOOST_PYTHON_MAX_ARITY, ) +# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() // truth value testing From 28011bbf55c850a038d98cce8ec3f2f968e58b4c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 10 Jul 2002 21:41:11 +0000 Subject: [PATCH 0560/1042] Remove tuple/string dependencies for Achim [SVN r14402] --- src/object/class.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index 7056ff1e..43a6ef46 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -6,8 +6,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -238,9 +238,9 @@ namespace objects if (result.get() == 0) { - string report("extension class wrapper for base class "); - (report += id.name()) += " has not been created yet"; - PyErr_SetObject(PyExc_RuntimeError, report.get()); + object report("extension class wrapper for base class "); + report = report + id.name() + " has not been created yet"; + PyErr_SetObject(PyExc_RuntimeError, report.ptr()); throw_error_already_set(); } return result; @@ -262,21 +262,26 @@ namespace objects { class_registry& r = registry(); assert(num_types >= 1); - tuple bases(std::max(num_types - 1, static_cast(1))); + + handle<> bases( + PyTuple_New(std::max(num_types - 1, static_cast(1))) + ); + if (num_types > 1) { for (std::size_t i = 1; i < num_types; ++i) - bases.set_item(i - 1, r.get(types[i])); + PyTuple_SET_ITEM(bases.get(), i - 1, upcast(r.get(types[i]).release())); } else { - bases.set_item(0, class_type()); + PyTuple_SET_ITEM(bases.get(), 0, upcast(class_type().release())); } - tuple args(3); - args.set_item(0, string(name).reference()); - args.set_item(1, bases.reference()); - args.set_item(2, dictionary().reference()); + handle<> args(PyTuple_New(3)); + PyTuple_SET_ITEM(args.get(), 0, incref(python::object(name).ptr())); + PyTuple_SET_ITEM(args.get(), 1, bases.release()); + handle<> d(PyDict_New()); + PyTuple_SET_ITEM(args.get(), 2, d.release()); PyObject* c = PyObject_CallObject(upcast(class_metatype().get()), args.get()); assert(PyType_IsSubtype(c->ob_type, &PyType_Type)); From 83719a6f48b548d67a1831fd82b1344ca5ad8145 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 11 Jul 2002 20:44:22 +0000 Subject: [PATCH 0561/1042] Attempted fix for long long handling [SVN r14410] --- .../python/converter/builtin_converters.hpp | 10 ++++--- include/boost/python/type_id.hpp | 5 +++- src/converter/builtin_converters.cpp | 26 +++++++++++-------- test/Jamfile | 18 ++++++------- test/test_builtin_converters.cpp | 17 +++++++----- 5 files changed, 45 insertions(+), 31 deletions(-) diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index d8bce16b..aebfd459 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -90,10 +90,12 @@ BOOST_PYTHON_TO_INT(char) BOOST_PYTHON_TO_INT(short) BOOST_PYTHON_TO_INT(int) BOOST_PYTHON_TO_INT(long) - -# ifdef BOOST_HAS_LONG_LONG -BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed long long, PyLong_FromLongLong(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned long long, PyLong_FromUnsignedLongLong(x)) + +// using Python's macro instead of Boost's - we don't seem to get the +// config right all the time. +# ifdef HAVE_LONG_LONG +BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed LONG_LONG, PyLong_FromLongLong(x)) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned LONG_LONG, PyLong_FromUnsignedLongLong(x)) # endif # undef BOOST_TO_PYTHON_INT diff --git a/include/boost/python/type_id.hpp b/include/boost/python/type_id.hpp index 11c15120..cf818fe3 100755 --- a/include/boost/python/type_id.hpp +++ b/include/boost/python/type_id.hpp @@ -6,6 +6,7 @@ #ifndef TYPE_ID_DWA2002517_HPP # define TYPE_ID_DWA2002517_HPP +# include # include # include # include @@ -78,7 +79,9 @@ inline type_info type_id(boost::type*) \ BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(short) BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(int) BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long) -# ifdef BOOST_HAS_LONG_LONG +// using Python's macro instead of Boost's - we don't seem to get the +// config right all the time. +# ifdef HAVE_LONG_LONG BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID(long long) # endif # undef BOOST_PYTHON_SIGNED_INTEGRAL_TYPE_ID diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index daff89d3..1d8efa29 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -98,7 +98,9 @@ namespace } }; -#ifdef BOOST_HAS_LONG_LONG +// using Python's macro instead of Boost's - we don't seem to get the +// config right all the time. +#ifdef HAVE_LONG_LONG // A SlotPolicy for extracting long long types from Python objects struct long_long_rvalue_from_python_base { @@ -126,7 +128,7 @@ namespace struct long_long_rvalue_from_python : long_long_rvalue_from_python_base { - static long long extract(PyObject* intermediate) + static LONG_LONG extract(PyObject* intermediate) { if (PyInt_Check(intermediate)) { @@ -134,11 +136,11 @@ namespace } if (PyFloat_Check(intermediate)) { - return numeric_cast(PyFloat_AS_DOUBLE(intermediate)); + return numeric_cast(PyFloat_AS_DOUBLE(intermediate)); } else { - long long result = PyLong_AsLongLong(intermediate); + LONG_LONG result = PyLong_AsLongLong(intermediate); if (PyErr_Occurred()) throw_error_already_set(); @@ -150,19 +152,19 @@ namespace struct unsigned_long_long_rvalue_from_python : long_long_rvalue_from_python_base { - static unsigned long long extract(PyObject* intermediate) + static unsigned LONG_LONG extract(PyObject* intermediate) { if (PyInt_Check(intermediate)) { - return numeric_cast(PyInt_AS_LONG(intermediate)); + return numeric_cast(PyInt_AS_LONG(intermediate)); } if (PyFloat_Check(intermediate)) { - return numeric_cast(PyFloat_AS_DOUBLE(intermediate)); + return numeric_cast(PyFloat_AS_DOUBLE(intermediate)); } else { - unsigned long long result = PyLong_AsUnsignedLongLong(intermediate); + unsigned LONG_LONG result = PyLong_AsUnsignedLongLong(intermediate); if (PyErr_Occurred()) throw_error_already_set(); @@ -347,9 +349,11 @@ void initialize_builtin_converters() REGISTER_INT_CONVERTERS2(int); REGISTER_INT_CONVERTERS2(long); -# ifdef BOOST_HAS_LONG_LONG - slot_rvalue_from_python(); - slot_rvalue_from_python(); +// using Python's macro instead of Boost's - we don't seem to get the +// config right all the time. +# ifdef HAVE_LONG_LONG + slot_rvalue_from_python(); + slot_rvalue_from_python(); # endif // floating types diff --git a/test/Jamfile b/test/Jamfile index 5d0118d3..e4cba386 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -82,38 +82,38 @@ if $(TEST_BIENSTMAN_NON_BUGS) } # --- unit tests of library components --- + +local UNIT_TEST_PROPERTIES = [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] BOOST_PYTHON_STATIC_LIB ; + run indirect_traits_test.cpp ; run destroy_test.cpp ; -run pointer_type_id_test.cpp ; +run pointer_type_id_test.cpp : : : $(UNIT_TEST_PROPERTIES) ; run member_function_cast.cpp ; run bases.cpp ; run if_else.cpp ; run pointee.cpp ; run result.cpp ; compile string_literal.cpp ; -compile borrowed.cpp : $(PYTHON_PROPERTIES) ; -compile object_manager.cpp : $(PYTHON_PROPERTIES) ; +compile borrowed.cpp : $(UNIT_TEST_PROPERTIES) ; +compile object_manager.cpp : $(UNIT_TEST_PROPERTIES) ; run upcast.cpp : # command-line args : # input files - : [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] - BOOST_PYTHON_STATIC_LIB + : $(UNIT_TEST_PROPERTIES) ; run select_holder.cpp : # command-line args : # input files - : [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] - BOOST_PYTHON_STATIC_LIB + : $(UNIT_TEST_PROPERTIES) ; run select_from_python_test.cpp ../src/converter/type_id.cpp : # command-line args : # input files - : [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] - BOOST_PYTHON_STATIC_LIB + : $(UNIT_TEST_PROPERTIES) ; if $(TEST_EXPECTED_FAILURES) diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp index bf7d991e..63b71669 100644 --- a/test/test_builtin_converters.cpp +++ b/test/test_builtin_converters.cpp @@ -9,6 +9,7 @@ #include #include #include +#include template struct by_value @@ -70,9 +71,11 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters) .def("rewrap_value_unsigned_short", by_value::rewrap) .def("rewrap_value_long", by_value::rewrap) .def("rewrap_value_unsigned_long", by_value::rewrap) -#ifdef BOOST_HAS_LONG_LONG - .def("rewrap_value_long_long", by_value::rewrap) - .def("rewrap_value_unsigned_long_long", by_value::rewrap) +// using Python's macro instead of Boost's - we don't seem to get the +// config right all the time. +#ifdef HAVE_LONG_LONG + .def("rewrap_value_long_long", by_value::rewrap) + .def("rewrap_value_unsigned_long_long", by_value::rewrap) #endif .def("rewrap_value_float", by_value::rewrap) .def("rewrap_value_double", by_value::rewrap) @@ -99,9 +102,11 @@ BOOST_PYTHON_MODULE_INIT(builtin_converters) .def("rewrap_const_reference_unsigned_short", by_const_reference::rewrap) .def("rewrap_const_reference_long", by_const_reference::rewrap) .def("rewrap_const_reference_unsigned_long", by_const_reference::rewrap) -#ifdef BOOST_HAS_LONG_LONG - .def("rewrap_const_reference_long_long", by_const_reference::rewrap) - .def("rewrap_const_reference_unsigned_long_long", by_const_reference::rewrap) +// using Python's macro instead of Boost's - we don't seem to get the +// config right all the time. +#ifdef HAVE_LONG_LONG + .def("rewrap_const_reference_long_long", by_const_reference::rewrap) + .def("rewrap_const_reference_unsigned_long_long", by_const_reference::rewrap) #endif .def("rewrap_const_reference_float", by_const_reference::rewrap) .def("rewrap_const_reference_double", by_const_reference::rewrap) From c0ecde90bcd2543362540c25fe7e36ece54e3d66 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 11 Jul 2002 21:03:30 +0000 Subject: [PATCH 0562/1042] Test a few different lvalue conversions [SVN r14411] --- test/m1.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/m1.cpp b/test/m1.cpp index fe5ef68d..ada4707e 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -187,9 +187,9 @@ struct D : B, C }; A take_a(A const& a) { return a; } -B take_b(B const& b) { return b; } -C take_c(C const& c) { return c; } -D take_d(D const& d) { return d; } +B take_b(B& b) { return b; } +C take_c(C* c) { return *c; } +D take_d(D* const& d) { return *d; } BOOST_PYTHON_MODULE_INIT(m1) { From b8aaf7d7b1c32045abe229f6e9e6b45eb51febc7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 11 Jul 2002 21:04:33 +0000 Subject: [PATCH 0563/1042] Rationalized conversion registry Better error reporting [SVN r14412] --- .../python/converter/arg_from_python.hpp | 12 +-- .../converter/callback_from_python_base.hpp | 12 ++- .../python/converter/find_from_python.hpp | 16 ++-- ..._from_python_chain.hpp => from_python.hpp} | 39 ++++++---- include/boost/python/converter/implicit.hpp | 12 +-- .../converter/lvalue_from_python_chain.hpp | 72 ------------------ .../python/converter/pointee_from_python.hpp | 63 ++++++++++++++++ .../boost/python/converter/registrations.hpp | 27 ++++++- include/boost/python/converter/registry.hpp | 6 +- .../python/converter/return_from_python.hpp | 28 ++----- src/converter/callback.cpp | 47 +++++------- src/converter/from_python.cpp | 67 +++++++++++------ src/converter/registry.cpp | 73 +++++++++---------- 13 files changed, 241 insertions(+), 233 deletions(-) rename include/boost/python/converter/{rvalue_from_python_chain.hpp => from_python.hpp} (52%) delete mode 100644 include/boost/python/converter/lvalue_from_python_chain.hpp create mode 100644 include/boost/python/converter/pointee_from_python.hpp diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp index cf9e15ae..efd60652 100755 --- a/include/boost/python/converter/arg_from_python.hpp +++ b/include/boost/python/converter/arg_from_python.hpp @@ -14,8 +14,8 @@ # include # include # include -# include -# include +# include +# include # include # include # include @@ -229,7 +229,7 @@ inline pointer_cref_arg_from_python::pointer_cref_arg_from_python(PyObject* p // a U object. python::detail::write_void_ptr_reference( m_result.bytes - , p == Py_None ? p : find(p, lvalue_from_python_chain::value) + , p == Py_None ? p : converter::get_lvalue_from_python(p, pointee_from_python::converters) , (T(*)())0); } @@ -252,7 +252,7 @@ inline T pointer_cref_arg_from_python::operator()(PyObject* p) const template inline pointer_arg_from_python::pointer_arg_from_python(PyObject* p) : arg_lvalue_from_python_base( - p == Py_None ? p : find(p, lvalue_from_python_chain::value)) + p == Py_None ? p : converter::get_lvalue_from_python(p, pointee_from_python::converters)) { } @@ -266,7 +266,7 @@ inline T pointer_arg_from_python::operator()(PyObject* p) const // template inline reference_arg_from_python::reference_arg_from_python(PyObject* p) - : arg_lvalue_from_python_base(find(p,lvalue_from_python_chain::value)) + : arg_lvalue_from_python_base(converter::get_lvalue_from_python(p,from_python::converters)) { } @@ -281,7 +281,7 @@ inline T reference_arg_from_python::operator()(PyObject*) const // template inline arg_rvalue_from_python::arg_rvalue_from_python(PyObject* obj) - : m_data(find(obj, rvalue_from_python_chain::value)) + : m_data(converter::rvalue_from_python_stage1(obj, from_python::converters)) { } diff --git a/include/boost/python/converter/callback_from_python_base.hpp b/include/boost/python/converter/callback_from_python_base.hpp index 462857af..63d078af 100644 --- a/include/boost/python/converter/callback_from_python_base.hpp +++ b/include/boost/python/converter/callback_from_python_base.hpp @@ -8,16 +8,14 @@ namespace boost { namespace python { namespace converter { +struct rvalue_from_python_stage1_data; +struct from_python_registration; + namespace detail { - - // Throw an exception - BOOST_PYTHON_DECL void throw_if_not_registered(rvalue_from_python_stage1_data const&); BOOST_PYTHON_DECL void* convert_rvalue(PyObject*, rvalue_from_python_stage1_data&, void* storage); - - BOOST_PYTHON_DECL void throw_if_not_registered(lvalue_from_python_registration*const&); - BOOST_PYTHON_DECL void* callback_convert_reference(PyObject*, lvalue_from_python_registration*const&); - BOOST_PYTHON_DECL void* callback_convert_pointer(PyObject*, lvalue_from_python_registration*const&); + BOOST_PYTHON_DECL void* callback_convert_reference(PyObject*, from_python_registration const&); + BOOST_PYTHON_DECL void* callback_convert_pointer(PyObject*, from_python_registration const&); BOOST_PYTHON_DECL void absorb_result(PyObject*); } diff --git a/include/boost/python/converter/find_from_python.hpp b/include/boost/python/converter/find_from_python.hpp index 659848ce..8a3421ee 100644 --- a/include/boost/python/converter/find_from_python.hpp +++ b/include/boost/python/converter/find_from_python.hpp @@ -12,17 +12,17 @@ namespace boost { namespace python { namespace converter { -struct lvalue_from_python_registration; -struct rvalue_from_python_registration; +struct from_python_registration; +struct rvalue_from_python_chain; -BOOST_PYTHON_DECL void* find( - PyObject* source, lvalue_from_python_registration const*); +BOOST_PYTHON_DECL void* get_lvalue_from_python( + PyObject* source, from_python_registration const&); -BOOST_PYTHON_DECL rvalue_from_python_stage1_data find( - PyObject* source, rvalue_from_python_registration const*); +BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( + PyObject* source, from_python_registration const&); -BOOST_PYTHON_DECL rvalue_from_python_registration const* find_chain( - PyObject* source, rvalue_from_python_registration const*); +BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( + PyObject* source, from_python_registration const&); }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/rvalue_from_python_chain.hpp b/include/boost/python/converter/from_python.hpp similarity index 52% rename from include/boost/python/converter/rvalue_from_python_chain.hpp rename to include/boost/python/converter/from_python.hpp index 4576e7fc..e712c7fa 100644 --- a/include/boost/python/converter/rvalue_from_python_chain.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -3,8 +3,8 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef RVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP -# define RVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP +#ifndef FROM_PYTHON_DWA2002710_HPP +# define FROM_PYTHON_DWA2002710_HPP # include # include # include @@ -12,29 +12,42 @@ namespace boost { namespace python { namespace converter { +struct from_python_registration; + namespace detail { template - struct rvalue_from_python_chain_impl + struct from_python_base { - static rvalue_from_python_registration*const& value; + static from_python_registration const& converters; }; - - template - rvalue_from_python_registration*const& rvalue_from_python_chain_impl::value - = registry::rvalue_converters(type_id()); } template -struct rvalue_from_python_chain - : detail::rvalue_from_python_chain_impl< +struct from_python + : detail::from_python_base< typename add_reference< - typename add_cv::type + typename add_cv::type >::type - > + > { }; +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +// collapses a few more types to the same static instance +template +struct from_python : from_python {}; +# endif + +// +// implementations +// +namespace detail +{ + template + from_python_registration const& from_python_base::converters + = registry::from_python_converters(type_id()); +} }}} // namespace boost::python::converter -#endif // RVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP +#endif // FROM_PYTHON_DWA2002710_HPP diff --git a/include/boost/python/converter/implicit.hpp b/include/boost/python/converter/implicit.hpp index 48d680aa..e5675e5d 100644 --- a/include/boost/python/converter/implicit.hpp +++ b/include/boost/python/converter/implicit.hpp @@ -16,16 +16,18 @@ struct implicit static void* convertible(PyObject* obj) { // Find a converter registration which can produce a Source - // instance from obj - return const_cast( - find_chain(obj, rvalue_from_python_chain::value)); + // instance from obj. The user has told us that Source can be + // converted to Target, and instantiating construct() below, + // ensures that at compile-time. + return const_cast( + converter::implicit_conversion_chain(obj, from_python::converters)); } static void construct(PyObject* obj, rvalue_from_python_stage1_data* data) { // This is the registration we got from the convertible step - rvalue_from_python_registration const* registration - = static_cast(data->convertible); + rvalue_from_python_chain const* registration + = static_cast(data->convertible); // Call the convertible function again rvalue_from_python_data intermediate_data(registration->convertible(obj)); diff --git a/include/boost/python/converter/lvalue_from_python_chain.hpp b/include/boost/python/converter/lvalue_from_python_chain.hpp deleted file mode 100644 index 0695025c..00000000 --- a/include/boost/python/converter/lvalue_from_python_chain.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP -# define LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -// Given T == U*cv&, T == U*, or T == U&, lvalue_from_python_chain -// declares a "templated global reference" to the lvalue from_python -// converter chain for U. The optional bool second argument is_return, -// when true, removes the usual special treatment which causes the -// converter for U* to bve used when T == U*cv& -namespace detail -{ - template - struct ptr_or_ptr_ref_lvalue_from_python_chain - { - static lvalue_from_python_registration*const& value; - }; - - template - lvalue_from_python_registration*const& - ptr_or_ptr_ref_lvalue_from_python_chain::value - = registry::lvalue_converters(pointer_type_id()); - - template - struct ref_lvalue_from_python_chain - { - static lvalue_from_python_registration*const& value; - }; - - template - lvalue_from_python_registration*const& - ref_lvalue_from_python_chain::value - = registry::lvalue_converters(type_id()); - - template - struct select_lvalue_from_python_chain - { - BOOST_STATIC_CONSTANT( - bool, ptr - = !is_return && boost::python::detail::is_reference_to_pointer::value - || is_pointer::value); - - typedef typename add_reference::type>::type normalized; - - typedef typename mpl::select_type< - ptr - , ptr_or_ptr_ref_lvalue_from_python_chain - , ref_lvalue_from_python_chain - >::type type; - }; -} - -template -struct lvalue_from_python_chain - : detail::select_lvalue_from_python_chain::type -{ -}; - -}}} // namespace boost::python::converter - -#endif // LVALUE_FROM_PYTHON_CHAIN_DWA200237_HPP diff --git a/include/boost/python/converter/pointee_from_python.hpp b/include/boost/python/converter/pointee_from_python.hpp new file mode 100644 index 00000000..1274f237 --- /dev/null +++ b/include/boost/python/converter/pointee_from_python.hpp @@ -0,0 +1,63 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef POINTEE_FROM_PYTHON_DWA2002710_HPP +# define POINTEE_FROM_PYTHON_DWA2002710_HPP +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +struct from_python_registration; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct pointee_from_python + : from_python< + typename remove_pointer< + typename remove_cv< + typename remove_reference::type + >::type + >::type + > +{ +}; +# else +namespace detail +{ + template + struct pointee_from_python_base + { + static from_python_registration const& converters; + }; +} + +template +struct pointee_from_python + : detail::pointee_from_python_base< + typename add_reference< + typename add_cv::type + >::type + > +{ +}; + +// +// implementations +// +namespace detail +{ + template + from_python_registration const& pointee_from_python_base::converters + = registry::from_python_converters(pointer_type_id()); +} + +# endif +}}} // namespace boost::python::converter + +#endif // POINTEE_FROM_PYTHON_DWA2002710_HPP diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp index eed1768a..fd1e4385 100644 --- a/include/boost/python/converter/registrations.hpp +++ b/include/boost/python/converter/registrations.hpp @@ -8,22 +8,41 @@ # include # include +# include namespace boost { namespace python { namespace converter { -struct lvalue_from_python_registration +struct lvalue_from_python_chain { convertible_function convert; - lvalue_from_python_registration* next; + lvalue_from_python_chain* next; }; -struct rvalue_from_python_registration +struct rvalue_from_python_chain { convertible_function convertible; constructor_function construct; - rvalue_from_python_registration* next; + rvalue_from_python_chain* next; }; +struct from_python_registration +{ + explicit from_python_registration(type_info); + + const python::type_info target_type; + lvalue_from_python_chain* lvalue_chain; + rvalue_from_python_chain* rvalue_chain; +}; + +// +// implementations +// +inline from_python_registration::from_python_registration(type_info target_type) + : target_type(target_type) + , lvalue_chain(0) + , rvalue_chain(0) +{} + }}} // namespace boost::python::converter #endif // REGISTRATIONS_DWA2002223_HPP diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index a686205c..07058bcb 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -15,14 +15,12 @@ namespace boost { namespace python { namespace converter { -struct lvalue_from_python_registration; -struct rvalue_from_python_registration; +struct from_python_registration; // This namespace acts as a sort of singleton namespace registry { - BOOST_PYTHON_DECL lvalue_from_python_registration*& lvalue_converters(type_info); - BOOST_PYTHON_DECL rvalue_from_python_registration*& rvalue_converters(type_info); + BOOST_PYTHON_DECL from_python_registration const& from_python_converters(type_info); BOOST_PYTHON_DECL to_python_function_t const& get_to_python_function(type_info); diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 9bfca7ec..077405f7 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -8,11 +8,12 @@ # include # include -# include -# include +# include # include # include # include +# include +# include namespace boost { namespace python { namespace converter { @@ -22,7 +23,6 @@ namespace detail struct return_pointer_from_python { typedef T result_type; - return_pointer_from_python(); T operator()(PyObject*) const; }; @@ -30,7 +30,6 @@ namespace detail struct return_reference_from_python { typedef T result_type; - return_reference_from_python(); T operator()(PyObject*) const; }; @@ -93,9 +92,10 @@ namespace detail { template inline return_rvalue_from_python::return_rvalue_from_python() - : m_data(rvalue_from_python_chain::value) + : m_data( + const_cast(&from_python::converters) + ) { - throw_if_not_registered(m_data.stage1); } template @@ -105,30 +105,18 @@ namespace detail return *(T*)convert_rvalue(obj, m_data.stage1, m_data.storage.bytes); } - template - inline return_reference_from_python::return_reference_from_python() - { - detail::throw_if_not_registered(lvalue_from_python_chain::value); - } - template inline T return_reference_from_python::operator()(PyObject* obj) const { return python::detail::void_ptr_to_reference( - callback_convert_reference(obj, lvalue_from_python_chain::value) + callback_convert_reference(obj, from_python::converters) , (T(*)())0); } - template - inline return_pointer_from_python::return_pointer_from_python() - { - detail::throw_if_not_registered(lvalue_from_python_chain::value); - } - template inline T return_pointer_from_python::operator()(PyObject* obj) const { - return T(callback_convert_pointer(obj, lvalue_from_python_chain::value)); + return T(callback_convert_pointer(obj, pointee_from_python::converters)); } } diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index bf72e9e6..04ad5606 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include namespace boost { namespace python { namespace converter { @@ -43,46 +45,30 @@ namespace detail { } - BOOST_PYTHON_DECL void throw_if_not_registered(rvalue_from_python_stage1_data const& data) - { - if (!data.convertible) - { - PyErr_SetString( - PyExc_TypeError - , const_cast("no from_python rvalue or lvalue converters found for type")); - throw_error_already_set(); - } - } - - BOOST_PYTHON_DECL void throw_if_not_registered(lvalue_from_python_registration*const& x) - { - if (!x) - { - PyErr_SetString( - PyExc_TypeError - , const_cast("no from_python lvalue converters found for type")); - throw_error_already_set(); - } - } - BOOST_PYTHON_DECL void* callback_convert_reference( PyObject* source - , lvalue_from_python_registration*const& converters) + , from_python_registration const& converters) { handle<> holder(source); if (source->ob_refcnt <= 2) { - PyErr_SetString( + PyErr_SetObject( PyExc_ReferenceError - , const_cast("Attempt to return dangling internal reference")); + , (object("Attempt to return dangling pointer/reference to object of type ") + + converters.target_type.name()).ptr() + ); throw_error_already_set(); } - void* result = find(source, converters); + void* result = get_lvalue_from_python(source, converters); if (!result) { - PyErr_SetString( + handle<> repr(PyObject_Repr(source)); + PyErr_SetObject( PyExc_TypeError - , const_cast("no registered from_python lvalue converter was able to convert object")); + , (object("no registered converter was able to convert ") + + repr + " to a C++ lvalue of type " + + converters.target_type.name()).ptr() + ); throw_error_already_set(); } return result; @@ -90,7 +76,7 @@ namespace detail BOOST_PYTHON_DECL void* callback_convert_pointer( PyObject* source - , lvalue_from_python_registration*const& converters) + , from_python_registration const& converters) { if (source == Py_None) { @@ -112,7 +98,8 @@ namespace detail { handle<> holder(src); - data = find(src, static_cast(data.convertible)); + data = rvalue_from_python_stage1( + src, *static_cast(data.convertible)); if (!data.convertible) { diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 826f453c..da7bde38 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -14,10 +14,12 @@ namespace boost { namespace python { namespace converter { -BOOST_PYTHON_DECL rvalue_from_python_stage1_data find( +BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( PyObject* source - , rvalue_from_python_registration const* chain) + , from_python_registration const& converters) { + rvalue_from_python_chain const* chain = converters.rvalue_chain; + rvalue_from_python_stage1_data data; data.convertible = 0; for (;chain != 0; chain = chain->next) @@ -33,23 +35,54 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data find( return data; } +BOOST_PYTHON_DECL void* get_lvalue_from_python( + PyObject* source + , from_python_registration const& converters) +{ + lvalue_from_python_chain const* chain = converters.lvalue_chain; + + for (;chain != 0; chain = chain->next) + { + void* r = chain->convert(source); + if (r != 0) + return r; + } + return 0; +} + namespace { // Prevent looping in implicit conversions. This could/should be // much more efficient, but will work for now. - typedef std::vector visited_t; + typedef std::vector visited_t; static visited_t visited; + + inline bool visit(rvalue_from_python_chain const* chain) + { + visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain); + if (p != visited.end() && *p == chain) + return false; + visited.insert(p, chain); + return true; + } + + void unvisit(rvalue_from_python_chain const* chain) + { + visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain); + assert(p != visited.end()); + visited.erase(p); + } } -BOOST_PYTHON_DECL rvalue_from_python_registration const* find_chain( +BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( PyObject* source - , rvalue_from_python_registration const* chain) + , from_python_registration const& converters) { - visited_t::iterator p = std::lower_bound(visited.begin(), visited.end(), chain); - if (p != visited.end() && *p == chain) + rvalue_from_python_chain const* chain = converters.rvalue_chain; + + if (!visit(chain)) return 0; - visited.insert(p, chain); try { for (;chain != 0; chain = chain->next) @@ -60,25 +93,11 @@ BOOST_PYTHON_DECL rvalue_from_python_registration const* find_chain( } catch(...) { - visited.erase(p); + unvisit(chain); throw; } - p = std::lower_bound(visited.begin(), visited.end(), chain); - visited.erase(p); + unvisit(chain); return chain; } -BOOST_PYTHON_DECL void* find( - PyObject* source - , lvalue_from_python_registration const* chain) -{ - for (;chain != 0; chain = chain->next) - { - void* r = chain->convert(source); - if (r != 0) - return r; - } - return 0; -} - }}} // namespace boost::python::converter diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index d1ba57df..05256ded 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include namespace boost { namespace python { namespace converter { @@ -16,21 +16,23 @@ namespace // // These are the elements stored in the registry struct entry { - entry(); + entry(type_info target); + + from_python_registration m_from_python; // The unique to_python converter for the associated C++ type. to_python_function_t m_to_python_converter; - // The collection of from_python converters for the associated - // C++ type. - lvalue_from_python_registration* m_lvalue_from_python; - rvalue_from_python_registration* m_rvalue_from_python; - // The class object associated with this type PyTypeObject* m_class_object; }; + + inline bool operator<(entry const& lhs, entry const& rhs) + { + return lhs.m_from_python.target_type < rhs.m_from_python.target_type; + } - typedef std::map registry_t; + typedef std::set registry_t; registry_t& entries() { @@ -50,19 +52,16 @@ namespace // return registry; } - entry* find(type_info type) + entry* get(type_info type) { - registry_t& assoc = entries(); - registry_t::iterator p = assoc.find(type); - return p != assoc.end() - ? &p->second - : &assoc[type]; + return const_cast( + &*entries().insert(entry(type)).first + ); } - entry::entry() - : m_to_python_converter(0) - , m_lvalue_from_python(0) - , m_rvalue_from_python(0) + entry::entry(type_info target) + : m_from_python(target) + , m_to_python_converter(0) , m_class_object(0) { } @@ -73,12 +72,12 @@ namespace registry to_python_function_t const& get_to_python_function( type_info key) { - return find(key)->m_to_python_converter; + return get(key)->m_to_python_converter; } void insert(to_python_function_t f, type_info source_t) { - to_python_function_t& slot = find(source_t)->m_to_python_converter; + to_python_function_t& slot = get(source_t)->m_to_python_converter; assert(slot == 0); // we have a problem otherwise if (slot != 0) { @@ -89,13 +88,13 @@ namespace registry } // Insert an lvalue from_python converter - void insert(void* (*convert)(PyObject*), type_info key) + void insert(convertible_function convert, type_info key) { - entry* found = find(key); - lvalue_from_python_registration *registration = new lvalue_from_python_registration; + entry* found = get(key); + lvalue_from_python_chain *registration = new lvalue_from_python_chain; registration->convert = convert; - registration->next = found->m_lvalue_from_python; - found->m_lvalue_from_python = registration; + registration->next = found->m_from_python.lvalue_chain; + found->m_from_python.lvalue_chain = registration; insert(convert, 0, key); } @@ -105,12 +104,12 @@ namespace registry , constructor_function construct , type_info key) { - entry* found = find(key); - rvalue_from_python_registration *registration = new rvalue_from_python_registration; + entry* found = get(key); + rvalue_from_python_chain *registration = new rvalue_from_python_chain; registration->convertible = convertible; registration->construct = construct; - registration->next = found->m_rvalue_from_python; - found->m_rvalue_from_python = registration; + registration->next = found->m_from_python.rvalue_chain; + found->m_from_python.rvalue_chain = registration; } // Insert an rvalue from_python converter @@ -118,11 +117,11 @@ namespace registry , constructor_function construct , type_info key) { - rvalue_from_python_registration** found = &find(key)->m_rvalue_from_python; + rvalue_from_python_chain** found = &get(key)->m_from_python.rvalue_chain; while (*found != 0) found = &(*found)->next; - rvalue_from_python_registration *registration = new rvalue_from_python_registration; + rvalue_from_python_chain *registration = new rvalue_from_python_chain; registration->convertible = convertible; registration->construct = construct; registration->next = 0; @@ -131,19 +130,13 @@ namespace registry PyTypeObject*& class_object(type_info key) { - return find(key)->m_class_object; + return get(key)->m_class_object; } - lvalue_from_python_registration*& lvalue_converters(type_info key) + from_python_registration const& from_python_converters(type_info key) { - return find(key)->m_lvalue_from_python; + return get(key)->m_from_python; } - - rvalue_from_python_registration*& rvalue_converters(type_info key) - { - return find(key)->m_rvalue_from_python; - } - } // namespace registry }}} // namespace boost::python::converter From 9ff90c98cd97afbedb828efc668b099be366230a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 11 Jul 2002 21:32:39 +0000 Subject: [PATCH 0564/1042] Merged registry tracing [SVN r14414] --- src/converter/registry.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index 05256ded..f0c7f74a 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -9,6 +9,10 @@ #include #include +#ifdef BOOST_PYTHON_TRACE_REGISTRY +# include +#endif + namespace boost { namespace python { namespace converter { namespace // @@ -48,12 +52,24 @@ namespace // initialize_builtin_converters(); } +# ifdef BOOST_PYTHON_TRACE_REGISTRY + std::cout << "registry: "; + for (registry_t::iterator p = registry.begin(); p != registry.end(); ++p) + { + std::cout << p->m_from_python.target_type << "; "; + } + std::cout << '\n'; +# endif # endif return registry; } entry* get(type_info type) { +# ifdef BOOST_PYTHON_TRACE_REGISTRY + std::cout << "looking up " << type + << (entries().find(entry(type)) == entries().end() ? ": not found\n" : ": found\n"); +# endif return const_cast( &*entries().insert(entry(type)).first ); @@ -77,7 +93,11 @@ namespace registry void insert(to_python_function_t f, type_info source_t) { +# ifdef BOOST_PYTHON_TRACE_REGISTRY + std::cout << "inserting to_python " << source_t << "\n"; +# endif to_python_function_t& slot = get(source_t)->m_to_python_converter; + assert(slot == 0); // we have a problem otherwise if (slot != 0) { @@ -90,6 +110,9 @@ namespace registry // Insert an lvalue from_python converter void insert(convertible_function convert, type_info key) { +# ifdef BOOST_PYTHON_TRACE_REGISTRY + std::cout << "inserting lvalue from_python " << key << "\n"; +# endif entry* found = get(key); lvalue_from_python_chain *registration = new lvalue_from_python_chain; registration->convert = convert; @@ -104,6 +127,9 @@ namespace registry , constructor_function construct , type_info key) { +# ifdef BOOST_PYTHON_TRACE_REGISTRY + std::cout << "inserting rvalue from_python " << key << "\n"; +# endif entry* found = get(key); rvalue_from_python_chain *registration = new rvalue_from_python_chain; registration->convertible = convertible; @@ -117,6 +143,9 @@ namespace registry , constructor_function construct , type_info key) { +# ifdef BOOST_PYTHON_TRACE_REGISTRY + std::cout << "push_back rvalue from_python " << key << "\n"; +# endif rvalue_from_python_chain** found = &get(key)->m_from_python.rvalue_chain; while (*found != 0) found = &(*found)->next; From d3bbc0eaa55eedcfd7f390e7f422b59c733982fb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 11 Jul 2002 21:41:12 +0000 Subject: [PATCH 0565/1042] Work around older EDG bug [SVN r14415] --- include/boost/python/converter/rvalue_from_python_data.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp index 8b0c6091..9736c2c3 100644 --- a/include/boost/python/converter/rvalue_from_python_data.hpp +++ b/include/boost/python/converter/rvalue_from_python_data.hpp @@ -89,7 +89,7 @@ struct rvalue_from_python_storage template struct rvalue_from_python_data : rvalue_from_python_storage { -# if !defined(__MWERKS__) || __MWERKS__ >= 0x3000 +# if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) // This must always be a POD struct with m_data its first member. BOOST_STATIC_ASSERT(offsetof(rvalue_from_python_storage,stage1) == 0); # endif From a4d651ce9ad98408c7e070a90a4e7b74bad166a1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 12 Jul 2002 11:36:15 +0000 Subject: [PATCH 0566/1042] Kill tru64cxx warnings [SVN r14419] --- include/boost/python/list.hpp | 4 ++-- include/boost/python/object_core.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp index c732b4fd..3de6dedd 100644 --- a/include/boost/python/list.hpp +++ b/include/boost/python/list.hpp @@ -94,8 +94,8 @@ class list : public object } public: // implementation detail -- for internal use only - explicit list(detail::borrowed_reference); - explicit list(detail::new_reference); + inline explicit list(detail::borrowed_reference); + inline explicit list(detail::new_reference); private: static BOOST_PYTHON_DECL detail::new_reference call(object const&); diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 35817f21..e82ff47e 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -195,8 +195,8 @@ namespace api struct object_base : object_operators { // copy constructor without NULL checking, for efficiency. - object_base(object_base const&); - object_base(PyObject* ptr); + inline object_base(object_base const&); + inline object_base(PyObject* ptr); object_base& operator=(object_base const& rhs); ~object_base(); From 3ac4cfb9a7f15f3943535622cbf6d78ce2edb4a5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 12 Jul 2002 11:37:31 +0000 Subject: [PATCH 0567/1042] Fix mistaken cast [SVN r14420] --- src/converter/callback.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index 04ad5606..5a376256 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -97,9 +97,10 @@ namespace detail BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_from_python_stage1_data& data, void* storage) { handle<> holder(src); - + + void const* registration = data.convertible; data = rvalue_from_python_stage1( - src, *static_cast(data.convertible)); + src, *static_cast(registration)); if (!data.convertible) { From 559b5647149c6af3f47bc69315b9dcb7ef4e9f40 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 12 Jul 2002 14:32:20 +0000 Subject: [PATCH 0568/1042] tru64cxx6.5 fixes [SVN r14421] --- .../converter/rvalue_from_python_data.hpp | 4 ++- include/boost/python/detail/wrap_python.hpp | 26 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp index 9736c2c3..f30ceadb 100644 --- a/include/boost/python/converter/rvalue_from_python_data.hpp +++ b/include/boost/python/converter/rvalue_from_python_data.hpp @@ -89,7 +89,9 @@ struct rvalue_from_python_storage template struct rvalue_from_python_data : rvalue_from_python_storage { -# if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) +# if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \ + && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \ + && (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) // This must always be a POD struct with m_data its first member. BOOST_STATIC_ASSERT(offsetof(rvalue_from_python_storage,stage1) == 0); # endif diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index 9c9bc2e4..7bafb9fe 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -20,6 +20,17 @@ // 04 Mar 01 Rolled in some changes from the Dragon fork (Dave Abrahams) // 01 Mar 01 define PyObject_INIT() for Python 1.x (Dave Abrahams) +// Python's LongObject.h helpfully #defines these for us, which confuses Boost's config +#include +#ifndef ULONG_MAX +# define BOOST_PYTHON_ULONG_MAX_UNDEFINED +#endif +#ifndef LONGLONG_MAX +# define BOOST_PYTHON_LONGLONG_MAX_UNDEFINED +#endif +#ifndef ULONGLONG_MAX +# define BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED +#endif #include @@ -104,6 +115,21 @@ typedef int pid_t; #include +#ifdef BOOST_PYTHON_ULONG_MAX_UNDEFINED +# undef ULONG_MAX +# undef BOOST_PYTHON_ULONG_MAX_UNDEFINED +#endif + +#ifdef BOOST_PYTHON_LONGLONG_MAX_UNDEFINED +# undef LONGLONG_MAX +# undef BOOST_PYTHON_LONGLONG_MAX_UNDEFINED +#endif + +#ifdef BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED +# undef ULONGLONG_MAX +# undef BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED +#endif + #ifdef PY_MSC_VER_DEFINED_FROM_WRAP_PYTHON_H # undef _MSC_VER #endif From 3375cdbb49b400906f04f3a717e61f9a1c150f80 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 13 Jul 2002 12:11:06 +0000 Subject: [PATCH 0569/1042] Fixed for VC7.1 [SVN r14433] --- include/boost/python/converter/arg_to_python_base.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/converter/arg_to_python_base.hpp b/include/boost/python/converter/arg_to_python_base.hpp index a0ec7518..bc4dc801 100755 --- a/include/boost/python/converter/arg_to_python_base.hpp +++ b/include/boost/python/converter/arg_to_python_base.hpp @@ -14,12 +14,12 @@ namespace boost { namespace python { namespace converter { namespace detail { struct BOOST_PYTHON_DECL arg_to_python_base -# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140 +# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102171 : handle<> # endif { arg_to_python_base(void const volatile* source, to_python_function_t); -# if defined(BOOST_MSVC) && _MSC_FULL_VER == 13102140 +# if defined(BOOST_MSVC) && BOOST_MSVC > 1300 && _MSC_FULL_VER <= 13102171 PyObject* get() const { return m_ptr.get(); } PyObject* release() { return m_ptr.release(); } private: From c15812add2425ba0b2fc454f0f61303ddd0fb0c1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 13 Jul 2002 12:11:53 +0000 Subject: [PATCH 0570/1042] long long fixes [SVN r14434] --- include/boost/python/detail/wrap_python.hpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index 7bafb9fe..e2392bc5 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -20,7 +20,10 @@ // 04 Mar 01 Rolled in some changes from the Dragon fork (Dave Abrahams) // 01 Mar 01 define PyObject_INIT() for Python 1.x (Dave Abrahams) -// Python's LongObject.h helpfully #defines these for us, which confuses Boost's config +// +// Python's LongObject.h helpfully #defines ULONGLONG_MAX for us, +// which confuses Boost's config +// #include #ifndef ULONG_MAX # define BOOST_PYTHON_ULONG_MAX_UNDEFINED @@ -32,6 +35,9 @@ # define BOOST_PYTHON_ULONGLONG_MAX_UNDEFINED #endif +// +// Get ahold of Python's version number +// #include #ifdef _DEBUG @@ -105,10 +111,6 @@ typedef int pid_t; # endif # undef HAVE_HYPOT # define HAVE_HYPOT 1 -# elif defined(_MSC_VER) -# ifdef __cplusplus -# include // prevents Python.h from defining LONGLONG_MAX, LONGLONG_MIN, and ULONGLONG_MAX -# endif # endif #endif // _WIN32 From e431318dc0ac0bd5338275155aeb124d97e95411 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 13 Jul 2002 15:16:50 +0000 Subject: [PATCH 0571/1042] Added some more tests [SVN r14437] --- test/Jamfile | 6 +++ test/callbacks.cpp | 1 + test/select_arg_to_python_test.cpp | 65 ++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 test/select_arg_to_python_test.cpp diff --git a/test/Jamfile b/test/Jamfile index e4cba386..77ff5c7c 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -116,6 +116,12 @@ run select_from_python_test.cpp ../src/converter/type_id.cpp : $(UNIT_TEST_PROPERTIES) ; +run select_arg_to_python_test.cpp ../src/converter/type_id.cpp + : # command-line args + : # input files + : $(UNIT_TEST_PROPERTIES) + ; + if $(TEST_EXPECTED_FAILURES) { compile-fail ./raw_pyobject_fail1.cpp : $(PYTHON_PROPERTIES) ; diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 6be5a782..6e916367 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -14,6 +14,7 @@ #include using namespace boost::python; +BOOST_STATIC_ASSERT(converter::is_object_manager >::value); int apply_int_int(PyObject* f, int x) { diff --git a/test/select_arg_to_python_test.cpp b/test/select_arg_to_python_test.cpp new file mode 100644 index 00000000..df925a54 --- /dev/null +++ b/test/select_arg_to_python_test.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include + +// gcc 2.95.x and MIPSpro 7.3.1.3 linker seem to demand this definition +#if ((defined(__GNUC__) && __GNUC__ < 3)) \ + || (defined(__sgi) && defined(__EDG_VERSION__) && (__EDG_VERSION__ == 238)) +namespace boost { namespace python { +BOOST_PYTHON_DECL bool handle_exception_impl(function0) +{ + return true; +} +}} +#endif + +int result; + +#define ASSERT_SAME(T1,T2) \ + if (!is_same< T1, T2 >::value) { \ + std::cout << "*********************\n"; \ + std::cout << python::type_id< T1 >() << " != " << python::type_id< T2 >() << "\n"; \ + std::cout << "*********************\n"; \ + result = 1; \ + } + +int main() +{ + using namespace boost::python::converter::detail; + using namespace boost::python::converter; + using namespace boost::python; + using namespace boost; + + + ASSERT_SAME( + select_arg_to_python::type, value_arg_to_python + ); + + ASSERT_SAME( + select_arg_to_python >::type, reference_arg_to_python + ); + + ASSERT_SAME( + select_arg_to_python >::type, pointer_shallow_arg_to_python + ); + + ASSERT_SAME( + select_arg_to_python::type, pointer_deep_arg_to_python + ); + + ASSERT_SAME( + select_arg_to_python >::type, object_manager_arg_to_python > + ); + + ASSERT_SAME( + select_arg_to_python::type, object_manager_arg_to_python + ); + + ASSERT_SAME( + select_arg_to_python::type, arg_to_python + ); + + return result; +} From 093aae1f46cb959d63d5dcac897f5bfbcba6a948 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 13 Jul 2002 18:44:51 +0000 Subject: [PATCH 0572/1042] Further rationalized conversion registry [SVN r14441] --- .../python/converter/arg_from_python.hpp | 12 ++--- .../boost/python/converter/arg_to_python.hpp | 8 +-- .../converter/callback_from_python_base.hpp | 6 +-- .../python/converter/find_from_python.hpp | 8 +-- include/boost/python/converter/implicit.hpp | 21 ++++---- .../converter/pointee_to_python_function.hpp | 50 ------------------ .../{from_python.hpp => registered.hpp} | 23 ++++---- ...from_python.hpp => registered_pointee.hpp} | 26 +++++----- .../boost/python/converter/registrations.hpp | 25 +++++++-- include/boost/python/converter/registry.hpp | 7 +-- .../python/converter/return_from_python.hpp | 11 ++-- .../python/converter/to_python_function.hpp | 50 ------------------ include/boost/python/to_python_converter.hpp | 2 +- include/boost/python/to_python_value.hpp | 6 +-- src/converter/callback.cpp | 8 +-- src/converter/from_python.cpp | 6 +-- src/converter/registry.cpp | 52 ++++--------------- 17 files changed, 104 insertions(+), 217 deletions(-) delete mode 100644 include/boost/python/converter/pointee_to_python_function.hpp rename include/boost/python/converter/{from_python.hpp => registered.hpp} (68%) rename include/boost/python/converter/{pointee_from_python.hpp => registered_pointee.hpp} (66%) delete mode 100644 include/boost/python/converter/to_python_function.hpp diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp index efd60652..351e8a2e 100755 --- a/include/boost/python/converter/arg_from_python.hpp +++ b/include/boost/python/converter/arg_from_python.hpp @@ -14,8 +14,8 @@ # include # include # include -# include -# include +# include +# include # include # include # include @@ -229,7 +229,7 @@ inline pointer_cref_arg_from_python::pointer_cref_arg_from_python(PyObject* p // a U object. python::detail::write_void_ptr_reference( m_result.bytes - , p == Py_None ? p : converter::get_lvalue_from_python(p, pointee_from_python::converters) + , p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee::converters) , (T(*)())0); } @@ -252,7 +252,7 @@ inline T pointer_cref_arg_from_python::operator()(PyObject* p) const template inline pointer_arg_from_python::pointer_arg_from_python(PyObject* p) : arg_lvalue_from_python_base( - p == Py_None ? p : converter::get_lvalue_from_python(p, pointee_from_python::converters)) + p == Py_None ? p : converter::get_lvalue_from_python(p, registered_pointee::converters)) { } @@ -266,7 +266,7 @@ inline T pointer_arg_from_python::operator()(PyObject* p) const // template inline reference_arg_from_python::reference_arg_from_python(PyObject* p) - : arg_lvalue_from_python_base(converter::get_lvalue_from_python(p,from_python::converters)) + : arg_lvalue_from_python_base(converter::get_lvalue_from_python(p,registered::converters)) { } @@ -281,7 +281,7 @@ inline T reference_arg_from_python::operator()(PyObject*) const // template inline arg_rvalue_from_python::arg_rvalue_from_python(PyObject* obj) - : m_data(converter::rvalue_from_python_stage1(obj, from_python::converters)) + : m_data(converter::rvalue_from_python_stage1(obj, registered::converters)) { } diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index a7c845d7..5f512400 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -7,8 +7,8 @@ # define ARG_TO_PYTHON_DWA200265_HPP # include -# include -# include +# include +# include # include # include # include @@ -180,13 +180,13 @@ namespace detail template inline value_arg_to_python::value_arg_to_python(T const& x) - : arg_to_python_base(&x, to_python_function::value) + : arg_to_python_base(&x, registered::converters.to_python) { } template inline pointer_deep_arg_to_python::pointer_deep_arg_to_python(Ptr x) - : arg_to_python_base(x, pointee_to_python_function::value) + : arg_to_python_base(x, registered_pointee::converters.to_python) { detail::reject_raw_object_ptr((Ptr)0); } diff --git a/include/boost/python/converter/callback_from_python_base.hpp b/include/boost/python/converter/callback_from_python_base.hpp index 63d078af..95bd2187 100644 --- a/include/boost/python/converter/callback_from_python_base.hpp +++ b/include/boost/python/converter/callback_from_python_base.hpp @@ -9,13 +9,13 @@ namespace boost { namespace python { namespace converter { struct rvalue_from_python_stage1_data; -struct from_python_registration; +struct registration; namespace detail { BOOST_PYTHON_DECL void* convert_rvalue(PyObject*, rvalue_from_python_stage1_data&, void* storage); - BOOST_PYTHON_DECL void* callback_convert_reference(PyObject*, from_python_registration const&); - BOOST_PYTHON_DECL void* callback_convert_pointer(PyObject*, from_python_registration const&); + BOOST_PYTHON_DECL void* callback_convert_reference(PyObject*, registration const&); + BOOST_PYTHON_DECL void* callback_convert_pointer(PyObject*, registration const&); BOOST_PYTHON_DECL void absorb_result(PyObject*); } diff --git a/include/boost/python/converter/find_from_python.hpp b/include/boost/python/converter/find_from_python.hpp index 8a3421ee..629eec92 100644 --- a/include/boost/python/converter/find_from_python.hpp +++ b/include/boost/python/converter/find_from_python.hpp @@ -12,17 +12,17 @@ namespace boost { namespace python { namespace converter { -struct from_python_registration; +struct registration; struct rvalue_from_python_chain; BOOST_PYTHON_DECL void* get_lvalue_from_python( - PyObject* source, from_python_registration const&); + PyObject* source, registration const&); BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( - PyObject* source, from_python_registration const&); + PyObject* source, registration const&); BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( - PyObject* source, from_python_registration const&); + PyObject* source, registration const&); }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/implicit.hpp b/include/boost/python/converter/implicit.hpp index e5675e5d..79a398aa 100644 --- a/include/boost/python/converter/implicit.hpp +++ b/include/boost/python/converter/implicit.hpp @@ -7,6 +7,7 @@ # define IMPLICIT_DWA2002326_HPP # include # include +# include namespace boost { namespace python { namespace converter { @@ -15,27 +16,27 @@ struct implicit { static void* convertible(PyObject* obj) { - // Find a converter registration which can produce a Source - // instance from obj. The user has told us that Source can be - // converted to Target, and instantiating construct() below, - // ensures that at compile-time. + // Find a converter chain which can produce a Source instance + // from obj. The user has told us that Source can be converted + // to Target, and instantiating construct() below, ensures + // that at compile-time. return const_cast( - converter::implicit_conversion_chain(obj, from_python::converters)); + converter::implicit_conversion_chain(obj, registered::converters)); } static void construct(PyObject* obj, rvalue_from_python_stage1_data* data) { - // This is the registration we got from the convertible step - rvalue_from_python_chain const* registration + // This is the chain we got from the convertible step + rvalue_from_python_chain const* chain = static_cast(data->convertible); // Call the convertible function again - rvalue_from_python_data intermediate_data(registration->convertible(obj)); + rvalue_from_python_data intermediate_data(chain->convertible(obj)); // Use the result to construct the source type if the first // converter was an rvalue converter. - if (registration->construct != 0) - registration->construct(obj, &intermediate_data.stage1); + if (chain->construct != 0) + chain->construct(obj, &intermediate_data.stage1); void* storage = ((rvalue_from_python_storage*)data)->storage.bytes; # if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13012108 // vc7.01 alpha workaround diff --git a/include/boost/python/converter/pointee_to_python_function.hpp b/include/boost/python/converter/pointee_to_python_function.hpp deleted file mode 100644 index 039914a9..00000000 --- a/include/boost/python/converter/pointee_to_python_function.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP -# define POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -// pointee_to_python_function -- -// -// essentially a "templated global reference" which holds the -// converter for converting a type to Python by-value. We "normalize" -// T by adding "const volatile&" so that fewer global variables and -// associated static initializations are generated. -namespace detail -{ - template - struct pointee_to_python_function_base - { - static to_python_function_t const& value; - }; - - template - to_python_function_t const& - pointee_to_python_function_base::value - = converter::registry::get_to_python_function(pointer_type_id()); -} - -template -struct pointee_to_python_function - : detail::pointee_to_python_function_base< - typename add_reference< - typename add_cv::type - >::type - > -{ -}; - -}}} // namespace boost::python::converter - -#endif // POINTEE_TO_PYTHON_FUNCTION_DWA2002128_HPP diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/registered.hpp similarity index 68% rename from include/boost/python/converter/from_python.hpp rename to include/boost/python/converter/registered.hpp index e712c7fa..2d3daa99 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/registered.hpp @@ -3,29 +3,30 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef FROM_PYTHON_DWA2002710_HPP -# define FROM_PYTHON_DWA2002710_HPP +#ifndef REGISTERED_DWA2002710_HPP +# define REGISTERED_DWA2002710_HPP # include # include +# include # include # include namespace boost { namespace python { namespace converter { -struct from_python_registration; +struct registration; namespace detail { template - struct from_python_base + struct registered_base { - static from_python_registration const& converters; + static registration const& converters; }; } template -struct from_python - : detail::from_python_base< +struct registered + : detail::registered_base< typename add_reference< typename add_cv::type >::type @@ -36,7 +37,7 @@ struct from_python # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // collapses a few more types to the same static instance template -struct from_python : from_python {}; +struct registered : registered {}; # endif // @@ -45,9 +46,9 @@ struct from_python : from_python {}; namespace detail { template - from_python_registration const& from_python_base::converters - = registry::from_python_converters(type_id()); + registration const& registered_base::converters + = registry::lookup(type_id()); } }}} // namespace boost::python::converter -#endif // FROM_PYTHON_DWA2002710_HPP +#endif // REGISTERED_DWA2002710_HPP diff --git a/include/boost/python/converter/pointee_from_python.hpp b/include/boost/python/converter/registered_pointee.hpp similarity index 66% rename from include/boost/python/converter/pointee_from_python.hpp rename to include/boost/python/converter/registered_pointee.hpp index 1274f237..861cf724 100644 --- a/include/boost/python/converter/pointee_from_python.hpp +++ b/include/boost/python/converter/registered_pointee.hpp @@ -3,9 +3,9 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef POINTEE_FROM_PYTHON_DWA2002710_HPP -# define POINTEE_FROM_PYTHON_DWA2002710_HPP -# include +#ifndef REGISTERED_POINTEE_DWA2002710_HPP +# define REGISTERED_POINTEE_DWA2002710_HPP +# include # include # include # include @@ -13,12 +13,12 @@ namespace boost { namespace python { namespace converter { -struct from_python_registration; +struct registration; # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template -struct pointee_from_python - : from_python< +struct registered_pointee + : registered< typename remove_pointer< typename remove_cv< typename remove_reference::type @@ -31,15 +31,15 @@ struct pointee_from_python namespace detail { template - struct pointee_from_python_base + struct registered_pointee_base { - static from_python_registration const& converters; + static registration const& converters; }; } template -struct pointee_from_python - : detail::pointee_from_python_base< +struct registered_pointee + : detail::registered_pointee_base< typename add_reference< typename add_cv::type >::type @@ -53,11 +53,11 @@ struct pointee_from_python namespace detail { template - from_python_registration const& pointee_from_python_base::converters - = registry::from_python_converters(pointer_type_id()); + registration const& registered_pointee_base::converters + = registry::lookup(pointer_type_id()); } # endif }}} // namespace boost::python::converter -#endif // POINTEE_FROM_PYTHON_DWA2002710_HPP +#endif // REGISTERED_POINTEE_DWA2002710_HPP diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp index fd1e4385..af2dd510 100644 --- a/include/boost/python/converter/registrations.hpp +++ b/include/boost/python/converter/registrations.hpp @@ -6,8 +6,10 @@ #ifndef REGISTRATIONS_DWA2002223_HPP # define REGISTRATIONS_DWA2002223_HPP +# include # include # include +# include # include namespace boost { namespace python { namespace converter { @@ -25,24 +27,41 @@ struct rvalue_from_python_chain rvalue_from_python_chain* next; }; -struct from_python_registration +struct registration { - explicit from_python_registration(type_info); + explicit registration(type_info); const python::type_info target_type; + + // The chain of eligible from_python converters when an lvalue is required lvalue_from_python_chain* lvalue_chain; + + // The chain of eligible from_python converters when an rvalue is acceptable rvalue_from_python_chain* rvalue_chain; + + // The unique to_python converter for the associated C++ type. + to_python_function_t to_python; + + // The class object associated with this type + PyTypeObject* class_object; }; // // implementations // -inline from_python_registration::from_python_registration(type_info target_type) +inline registration::registration(type_info target_type) : target_type(target_type) , lvalue_chain(0) , rvalue_chain(0) + , to_python(0) + , class_object(0) {} +inline bool operator<(registration const& lhs, registration const& rhs) +{ + return lhs.target_type < rhs.target_type; +} + }}} // namespace boost::python::converter #endif // REGISTRATIONS_DWA2002223_HPP diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index 07058bcb..e7e9f739 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -15,15 +15,12 @@ namespace boost { namespace python { namespace converter { -struct from_python_registration; +struct registration; // This namespace acts as a sort of singleton namespace registry { - BOOST_PYTHON_DECL from_python_registration const& from_python_converters(type_info); - - BOOST_PYTHON_DECL to_python_function_t const& - get_to_python_function(type_info); + BOOST_PYTHON_DECL registration const& lookup(type_info); BOOST_PYTHON_DECL void insert(to_python_function_t, type_info); diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 077405f7..8f9f31b3 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -8,12 +8,11 @@ # include # include -# include +# include +# include # include # include # include -# include -# include namespace boost { namespace python { namespace converter { @@ -93,7 +92,7 @@ namespace detail template inline return_rvalue_from_python::return_rvalue_from_python() : m_data( - const_cast(&from_python::converters) + const_cast(®istered::converters) ) { } @@ -109,14 +108,14 @@ namespace detail inline T return_reference_from_python::operator()(PyObject* obj) const { return python::detail::void_ptr_to_reference( - callback_convert_reference(obj, from_python::converters) + callback_convert_reference(obj, registered::converters) , (T(*)())0); } template inline T return_pointer_from_python::operator()(PyObject* obj) const { - return T(callback_convert_pointer(obj, pointee_from_python::converters)); + return T(callback_convert_pointer(obj, registered_pointee::converters)); } } diff --git a/include/boost/python/converter/to_python_function.hpp b/include/boost/python/converter/to_python_function.hpp deleted file mode 100644 index 0112463e..00000000 --- a/include/boost/python/converter/to_python_function.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TO_PYTHON_FUNCTION_DWA2002128_HPP -# define TO_PYTHON_FUNCTION_DWA2002128_HPP - -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace converter { - -// to_python_function -- -// -// essentially a "templated global reference" which holds the -// converter for converting a type to Python by-value. We "normalize" -// T by adding "const volatile&" so that fewer global variables and -// associated static initializations are generated. -namespace detail -{ - template - struct to_python_function_base - { - static to_python_function_t const& value; - }; - - template - to_python_function_t const& - to_python_function_base::value - = converter::registry::get_to_python_function(type_id()); -} - -template -struct to_python_function - : detail::to_python_function_base< - typename add_reference< - typename add_cv::type - >::type - > -{ -}; - -}}} // namespace boost::python::converter - -#endif // TO_PYTHON_FUNCTION_DWA2002128_HPP diff --git a/include/boost/python/to_python_converter.hpp b/include/boost/python/to_python_converter.hpp index f5155e58..814b9ba7 100644 --- a/include/boost/python/to_python_converter.hpp +++ b/include/boost/python/to_python_converter.hpp @@ -7,7 +7,7 @@ # define TO_PYTHON_CONVERTER_DWA200221_HPP # include -# include +# include # include namespace boost { namespace python { diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp index ea9e892e..7363fbf7 100644 --- a/include/boost/python/to_python_value.hpp +++ b/include/boost/python/to_python_value.hpp @@ -8,7 +8,7 @@ # include # include -# include +# include # include # include # include @@ -65,13 +65,13 @@ namespace detail template inline bool registry_to_python_value::convertible() { - return converter::to_python_function::value != 0; + return converter::registered::converters.to_python != 0; } template inline PyObject* registry_to_python_value::operator()(argument_type x) const { - return converter::to_python_function::value(&x); + return converter::registered::converters.to_python(&x); } template diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index 5a376256..3b229f3c 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -47,7 +47,7 @@ namespace detail BOOST_PYTHON_DECL void* callback_convert_reference( PyObject* source - , from_python_registration const& converters) + , registration const& converters) { handle<> holder(source); if (source->ob_refcnt <= 2) @@ -76,7 +76,7 @@ namespace detail BOOST_PYTHON_DECL void* callback_convert_pointer( PyObject* source - , from_python_registration const& converters) + , registration const& converters) { if (source == Py_None) { @@ -98,9 +98,9 @@ namespace detail { handle<> holder(src); - void const* registration = data.convertible; + void const* converters = data.convertible; data = rvalue_from_python_stage1( - src, *static_cast(registration)); + src, *static_cast(converters)); if (!data.convertible) { diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index da7bde38..f68bf0fa 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -16,7 +16,7 @@ namespace boost { namespace python { namespace converter { BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( PyObject* source - , from_python_registration const& converters) + , registration const& converters) { rvalue_from_python_chain const* chain = converters.rvalue_chain; @@ -37,7 +37,7 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( BOOST_PYTHON_DECL void* get_lvalue_from_python( PyObject* source - , from_python_registration const& converters) + , registration const& converters) { lvalue_from_python_chain const* chain = converters.lvalue_chain; @@ -76,7 +76,7 @@ namespace BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( PyObject* source - , from_python_registration const& converters) + , registration const& converters) { rvalue_from_python_chain const* chain = converters.rvalue_chain; diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index f0c7f74a..b74f8bd8 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -17,24 +17,7 @@ namespace boost { namespace python { namespace converter { namespace // { - // These are the elements stored in the registry - struct entry - { - entry(type_info target); - - from_python_registration m_from_python; - - // The unique to_python converter for the associated C++ type. - to_python_function_t m_to_python_converter; - - // The class object associated with this type - PyTypeObject* m_class_object; - }; - - inline bool operator<(entry const& lhs, entry const& rhs) - { - return lhs.m_from_python.target_type < rhs.m_from_python.target_type; - } + typedef registration entry; typedef std::set registry_t; @@ -56,7 +39,7 @@ namespace // std::cout << "registry: "; for (registry_t::iterator p = registry.begin(); p != registry.end(); ++p) { - std::cout << p->m_from_python.target_type << "; "; + std::cout << p->target_type << "; "; } std::cout << '\n'; # endif @@ -74,29 +57,16 @@ namespace // &*entries().insert(entry(type)).first ); } - - entry::entry(type_info target) - : m_from_python(target) - , m_to_python_converter(0) - , m_class_object(0) - { - } } // namespace namespace registry { - to_python_function_t const& get_to_python_function( - type_info key) - { - return get(key)->m_to_python_converter; - } - void insert(to_python_function_t f, type_info source_t) { # ifdef BOOST_PYTHON_TRACE_REGISTRY std::cout << "inserting to_python " << source_t << "\n"; # endif - to_python_function_t& slot = get(source_t)->m_to_python_converter; + to_python_function_t& slot = get(source_t)->to_python; assert(slot == 0); // we have a problem otherwise if (slot != 0) @@ -116,8 +86,8 @@ namespace registry entry* found = get(key); lvalue_from_python_chain *registration = new lvalue_from_python_chain; registration->convert = convert; - registration->next = found->m_from_python.lvalue_chain; - found->m_from_python.lvalue_chain = registration; + registration->next = found->lvalue_chain; + found->lvalue_chain = registration; insert(convert, 0, key); } @@ -134,8 +104,8 @@ namespace registry rvalue_from_python_chain *registration = new rvalue_from_python_chain; registration->convertible = convertible; registration->construct = construct; - registration->next = found->m_from_python.rvalue_chain; - found->m_from_python.rvalue_chain = registration; + registration->next = found->rvalue_chain; + found->rvalue_chain = registration; } // Insert an rvalue from_python converter @@ -146,7 +116,7 @@ namespace registry # ifdef BOOST_PYTHON_TRACE_REGISTRY std::cout << "push_back rvalue from_python " << key << "\n"; # endif - rvalue_from_python_chain** found = &get(key)->m_from_python.rvalue_chain; + rvalue_from_python_chain** found = &get(key)->rvalue_chain; while (*found != 0) found = &(*found)->next; @@ -159,12 +129,12 @@ namespace registry PyTypeObject*& class_object(type_info key) { - return get(key)->m_class_object; + return get(key)->class_object; } - from_python_registration const& from_python_converters(type_info key) + registration const& lookup(type_info key) { - return get(key)->m_from_python; + return *get(key); } } // namespace registry From 9a0118d9915f61b5deab828696aa4ca55ccc8aa2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 13 Jul 2002 21:36:57 +0000 Subject: [PATCH 0573/1042] untabify [SVN r14444] --- include/boost/python/detail/result.hpp | 8 ++--- include/boost/python/detail/target.hpp | 8 ++--- include/boost/python/object/value_holder.hpp | 38 ++++++++++---------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp index 742195de..aaad4b86 100755 --- a/include/boost/python/detail/result.hpp +++ b/include/boost/python/detail/result.hpp @@ -30,12 +30,12 @@ namespace boost { namespace python { namespace detail { // an AdaptableFunction object, you must pass OL as a second argument // to get this to work portably. -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) # include BOOST_PP_ITERATE() -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) # include BOOST_PP_ITERATE() template diff --git a/include/boost/python/detail/target.hpp b/include/boost/python/detail/target.hpp index d8eb7d68..ffda614b 100644 --- a/include/boost/python/detail/target.hpp +++ b/include/boost/python/detail/target.hpp @@ -19,12 +19,12 @@ namespace boost { namespace python { namespace detail { -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) # include BOOST_PP_ITERATE() -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) +# define BOOST_PP_ITERATION_PARAMS_1 \ + (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) # include BOOST_PP_ITERATE() template diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 353cd929..6eb0c4ed 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -29,7 +29,7 @@ namespace boost { namespace python { namespace objects { template struct value_holder : instance_holder { - // Forward construction to the held object + // Forward construction to the held object # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) # include BOOST_PP_ITERATE() @@ -91,15 +91,14 @@ void* value_holder_back_reference::holds( # define N BOOST_PP_ITERATION() # if (N != 0) - template + template # endif - value_holder(PyObject* - BOOST_PP_COMMA_IF(N) - BOOST_PYTHON_BINARY_ENUM(N, A, a)) - : m_held( - BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) - ) - {} + value_holder( + PyObject* BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) + : m_held( + BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) + ) + {} # undef N @@ -111,18 +110,17 @@ void* value_holder_back_reference::holds( # define N BOOST_PP_ITERATION() # if (N != 0) - template + template # endif - value_holder_back_reference(PyObject* p - BOOST_PP_COMMA_IF(N) - BOOST_PYTHON_BINARY_ENUM(N, A, a)) - : m_held( - p BOOST_PP_COMMA_IF(N) - BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) - ) - { - python::detail::force_instantiate(instance_finder::registration); - } + value_holder_back_reference( + PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) + : m_held( + p BOOST_PP_COMMA_IF(N) + BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) + ) + { + python::detail::force_instantiate(instance_finder::registration); + } # undef N From 5b803f00e13f5805f67bfbad013afc1f1a122fdf Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 14 Jul 2002 12:38:41 +0000 Subject: [PATCH 0574/1042] VC6 workarounds [SVN r14447] --- test/object_manager.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/test/object_manager.cpp b/test/object_manager.cpp index 75c816bc..0f1851c5 100755 --- a/test/object_manager.cpp +++ b/test/object_manager.cpp @@ -6,31 +6,27 @@ #include #include #include -#include "test_class.hpp" using namespace boost::python; using namespace boost::python::converter; -template struct undefined; +struct X {}; int main() { BOOST_STATIC_ASSERT(is_object_manager >::value); BOOST_STATIC_ASSERT(!is_object_manager::value); - BOOST_STATIC_ASSERT(!is_object_manager >::value); + BOOST_STATIC_ASSERT(!is_object_manager::value); BOOST_STATIC_ASSERT(is_reference_to_object_manager&>::value); BOOST_STATIC_ASSERT(is_reference_to_object_manager const&>::value); BOOST_STATIC_ASSERT(is_reference_to_object_manager volatile&>::value); BOOST_STATIC_ASSERT(is_reference_to_object_manager const volatile&>::value); -// undefined >::t1> x1; -// undefined >::t2> x2; - BOOST_STATIC_ASSERT(!is_reference_to_object_manager >::value); - BOOST_STATIC_ASSERT(!is_reference_to_object_manager >::value); - BOOST_STATIC_ASSERT(!is_reference_to_object_manager&>::value); - BOOST_STATIC_ASSERT(!is_reference_to_object_managerconst&>::value); + BOOST_STATIC_ASSERT(!is_reference_to_object_manager::value); + BOOST_STATIC_ASSERT(!is_reference_to_object_manager::value); + BOOST_STATIC_ASSERT(!is_reference_to_object_manager::value); return 0; } From 3ebe4c47ba098a59417f4afa6e15f256bbbd5261 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 14 Jul 2002 13:04:27 +0000 Subject: [PATCH 0575/1042] Better error reporting [SVN r14448] --- .../boost/python/converter/arg_to_python.hpp | 4 ++-- .../python/converter/arg_to_python_base.hpp | 4 +++- src/converter/callback.cpp | 20 +++++++++++-------- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index 5f512400..9b6f4b31 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -180,13 +180,13 @@ namespace detail template inline value_arg_to_python::value_arg_to_python(T const& x) - : arg_to_python_base(&x, registered::converters.to_python) + : arg_to_python_base(&x, registered::converters) { } template inline pointer_deep_arg_to_python::pointer_deep_arg_to_python(Ptr x) - : arg_to_python_base(x, registered_pointee::converters.to_python) + : arg_to_python_base(x, registered_pointee::converters) { detail::reject_raw_object_ptr((Ptr)0); } diff --git a/include/boost/python/converter/arg_to_python_base.hpp b/include/boost/python/converter/arg_to_python_base.hpp index bc4dc801..59f68b6d 100755 --- a/include/boost/python/converter/arg_to_python_base.hpp +++ b/include/boost/python/converter/arg_to_python_base.hpp @@ -11,6 +11,8 @@ namespace boost { namespace python { namespace converter { +struct registration; + namespace detail { struct BOOST_PYTHON_DECL arg_to_python_base @@ -18,7 +20,7 @@ namespace detail : handle<> # endif { - arg_to_python_base(void const volatile* source, to_python_function_t); + arg_to_python_base(void const volatile* source, registration const&); # if defined(BOOST_MSVC) && BOOST_MSVC > 1300 && _MSC_FULL_VER <= 13102171 PyObject* get() const { return m_ptr.get(); } PyObject* release() { return m_ptr.release(); } diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index 3b229f3c..0685a591 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -19,28 +19,32 @@ namespace detail namespace { - inline PyObject* convert_to_python(void const volatile* source, to_python_function_t converter) + inline PyObject* convert_to_python(void const volatile* source, registration const& converters) { - if (converter == 0) + if (converters.to_python == 0) { - PyErr_SetString( + + PyErr_SetObject( PyExc_TypeError - , const_cast("no to_python (by-value) converter found for type")); + , (object("no to_python (by-value) converter found for C++ type: ") + + converters.target_type.name()).ptr() + ); + throw_error_already_set(); } return source == 0 ? python::detail::none() - : converter(const_cast(source)); + : converters.to_python(const_cast(source)); } } arg_to_python_base::arg_to_python_base( - void const volatile* source, to_python_function_t converter) + void const volatile* source, registration const& converters) # if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140 - : handle<>(convert_to_python(source, converter)) + : handle<>(convert_to_python(source, converters)) # else - : m_ptr(convert_to_python(source, converter)) + : m_ptr(convert_to_python(source, converters)) # endif { } From 32c6906750b732d5368882c514bd3e50aa6e7669 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 14 Jul 2002 14:37:20 +0000 Subject: [PATCH 0576/1042] Remove circular dependency on working converters [SVN r14449] --- src/converter/callback.cpp | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index 0685a591..f6bdcbd1 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -23,12 +23,12 @@ namespace detail { if (converters.to_python == 0) { + handle<> msg( + ::PyString_FromFormat( + "No to_python (by-value) converter found for C++ type: %s" + , converters.target_type.name())); - PyErr_SetObject( - PyExc_TypeError - , (object("no to_python (by-value) converter found for C++ type: ") - + converters.target_type.name()).ptr() - ); + PyErr_SetObject(PyExc_TypeError, msg.get()); throw_error_already_set(); } @@ -56,23 +56,27 @@ namespace detail handle<> holder(source); if (source->ob_refcnt <= 2) { - PyErr_SetObject( - PyExc_ReferenceError - , (object("Attempt to return dangling pointer/reference to object of type ") - + converters.target_type.name()).ptr() - ); + handle<> msg( + ::PyString_FromFormat( + "Attempt to return dangling pointer/reference to object of type: %s" + , converters.target_type.name())); + + PyErr_SetObject(PyExc_ReferenceError, msg.get()); + throw_error_already_set(); } void* result = get_lvalue_from_python(source, converters); if (!result) { handle<> repr(PyObject_Repr(source)); - PyErr_SetObject( - PyExc_TypeError - , (object("no registered converter was able to convert ") - + repr + " to a C++ lvalue of type " - + converters.target_type.name()).ptr() - ); + handle<> msg( + ::PyString_FromFormat( + "No registered converter was able to convert %s to a C++ lvalue of type %s" + , PyString_AS_STRING(repr.get()) + , converters.target_type.name())); + + PyErr_SetObject(PyExc_TypeError, msg.get()); + throw_error_already_set(); } return result; From 3e07ba1012a83cbe8813e825f06deadcbdab814b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 14 Jul 2002 16:07:39 +0000 Subject: [PATCH 0577/1042] tru64cxx6.5 workarounds [SVN r14450] --- include/boost/python/detail/string_literal.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/boost/python/detail/string_literal.hpp b/include/boost/python/detail/string_literal.hpp index d8230bb8..ddafa401 100644 --- a/include/boost/python/detail/string_literal.hpp +++ b/include/boost/python/detail/string_literal.hpp @@ -26,7 +26,19 @@ struct is_string_literal { BOOST_STATIC_CONSTANT(bool, value = true); }; + +# if defined(__DECCXX_VER) && __DECCXX_VER <= 60590014 +// This compiler mistakenly gets the type of string literals as char* +// instead of char[NN]. +template <> +struct is_string_literal +{ + BOOST_STATIC_CONSTANT(bool, value = true); +}; +# endif + # else + // CWPro7 has trouble with the array type deduction above template struct is_string_literal From df7b4d81c7c274b718902dd78b3302116027eb61 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 14 Jul 2002 16:09:46 +0000 Subject: [PATCH 0578/1042] Tests for Tru64 CXX regression [SVN r14451] --- test/string_literal.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/string_literal.cpp b/test/string_literal.cpp index 5c1a1e61..882fbd4e 100644 --- a/test/string_literal.cpp +++ b/test/string_literal.cpp @@ -3,10 +3,18 @@ #include #include +using namespace boost::python::detail; + + +template +void expect_string_literal(T const&) +{ + BOOST_STATIC_ASSERT(is_string_literal::value); +} + int main() { - using namespace boost::python::detail; - + expect_string_literal("hello"); BOOST_STATIC_ASSERT(!is_string_literal::value); BOOST_STATIC_ASSERT(!is_string_literal::value); BOOST_STATIC_ASSERT(!is_string_literal::value); From 815edf1ba58bf54aecc64bd282df3af7d7467aeb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 14 Jul 2002 16:26:10 +0000 Subject: [PATCH 0579/1042] Apply VC6 workaround and None default constructor patch from Dave Hawkes. [SVN r14452] --- include/boost/python/object_core.hpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index e82ff47e..7684e044 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -211,11 +211,13 @@ namespace api class object : public object_base { public: + // default constructor creates a None object + object(); // explicit conversion from any C++ object to Python template explicit object(T const& x) : object_base(object_initializer::value>::get( - x, detail::convertible::check(&x))) + &x, detail::convertible::check(&x))) { } @@ -235,16 +237,16 @@ namespace api struct object_initializer { static PyObject* - get(object const& x, detail::yes_convertible) + get(object const* x, detail::yes_convertible) { - return python::incref(x.ptr()); + return python::incref(x->ptr()); } template static PyObject* - get(T const& x, detail::no_convertible) + get(T const* x, detail::no_convertible) { - return python::incref(converter::arg_to_python(x).get()); + return python::incref(converter::arg_to_python(*x).get()); } }; @@ -253,9 +255,9 @@ namespace api { template static PyObject* - get(proxy const& x, detail::no_convertible) + get(proxy const* x, detail::no_convertible) { - return python::incref(x.operator object().ptr()); + return python::incref(x->operator object().ptr()); } }; } @@ -319,12 +321,16 @@ namespace converter // inline object::object(handle<> const& x) - : object_base(incref(expect_non_null(x.get()))) + : object_base(python::incref(python::expect_non_null(x.get()))) +{} + +inline object::object() + : object_base(python::incref(Py_None)) {} // copy constructor without NULL checking, for efficiency inline api::object_base::object_base(object_base const& rhs) - : m_ptr(incref(rhs.m_ptr)) + : m_ptr(python::incref(rhs.m_ptr)) {} inline api::object_base::object_base(PyObject* p) @@ -346,7 +352,7 @@ inline api::object_base::~object_base() } inline object::object(detail::borrowed_reference p) - : object_base(incref((PyObject*)p)) + : object_base(python::incref((PyObject*)p)) {} From 93b4c6291a57e9102e856ceb39646362c2ac17db Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 14 Jul 2002 18:42:43 +0000 Subject: [PATCH 0580/1042] Removed flotsam [SVN r14455] --- include/boost/python/converter/arg_to_python.hpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index 9b6f4b31..9e214686 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -129,17 +129,6 @@ struct arg_to_python arg_to_python(T const& x); }; -// -// Convenience macros for call<> and call_method<> code generation -// -# define BOOST_PYTHON_ARG_TO_PYTHON_GET(index,ignored) \ - converter::arg_to_python( \ - BOOST_PP_CAT(a,index)).get() - -# define BOOST_PYTHON_ARG_STRING(nargs) \ - "(" BOOST_PP_REPEAT(nargs,BOOST_PYTHON_PROJECT_2ND,"O") ")" - - // // implementations // From baccdba75cb95174f6ca791ba7177beb7208a6f1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 14 Jul 2002 18:44:28 +0000 Subject: [PATCH 0581/1042] Better error reporting [SVN r14456] --- src/converter/callback.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp index f6bdcbd1..827d1e07 100644 --- a/src/converter/callback.cpp +++ b/src/converter/callback.cpp @@ -68,12 +68,12 @@ namespace detail void* result = get_lvalue_from_python(source, converters); if (!result) { - handle<> repr(PyObject_Repr(source)); handle<> msg( ::PyString_FromFormat( - "No registered converter was able to convert %s to a C++ lvalue of type %s" - , PyString_AS_STRING(repr.get()) - , converters.target_type.name())); + "No registered converter was able to extract a a C++ lvalue of type %s from this Python object of type %s" + , converters.target_type.name() + , source->ob_type->tp_name + )); PyErr_SetObject(PyExc_TypeError, msg.get()); @@ -106,20 +106,29 @@ namespace detail { handle<> holder(src); - void const* converters = data.convertible; - data = rvalue_from_python_stage1( - src, *static_cast(converters)); + void const* converters_ = data.convertible; + registration const& converters = *static_cast(converters_); + data = rvalue_from_python_stage1(src, converters); if (!data.convertible) { - PyErr_SetString( - PyExc_TypeError - , const_cast("no registered from_python lvalue or rvalue converter was able to convert object")); + handle<> msg( + ::PyString_FromFormat( + "No registered converter was able to produce a C++ lvalue of type %s from this Python object of type %s" + , converters.target_type.name() + , src->ob_type->tp_name + )); + + PyErr_SetObject(PyExc_TypeError, msg.get()); throw_error_already_set(); } + + // If a construct function was registered (i.e. we found an + // rvalue conversion), call it now. if (data.construct != 0) data.construct(src, &data); - + + // Return the address of the resulting C++ object return data.convertible; } From 9795a27482b6d9005a84097b41cc40c24f7dc754 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 14 Jul 2002 20:36:54 +0000 Subject: [PATCH 0582/1042] Even further rationalized conversion registry [SVN r14458] --- include/boost/python/converter/registry.hpp | 6 +- include/boost/python/object/class_object.hpp | 26 ------ include/boost/python/to_python_indirect.hpp | 4 +- src/converter/registry.cpp | 21 +++-- src/object/class.cpp | 95 +++++++++----------- 5 files changed, 64 insertions(+), 88 deletions(-) delete mode 100644 include/boost/python/object/class_object.hpp diff --git a/include/boost/python/converter/registry.hpp b/include/boost/python/converter/registry.hpp index e7e9f739..b71c949a 100644 --- a/include/boost/python/converter/registry.hpp +++ b/include/boost/python/converter/registry.hpp @@ -20,7 +20,11 @@ struct registration; // This namespace acts as a sort of singleton namespace registry { + // Get the registration corresponding to the type, creating it if neccessary BOOST_PYTHON_DECL registration const& lookup(type_info); + + // Return a pointer to the corresponding registration, if one exists + BOOST_PYTHON_DECL registration const* query(type_info); BOOST_PYTHON_DECL void insert(to_python_function_t, type_info); @@ -41,8 +45,6 @@ namespace registry , constructor_function , type_info ); - - BOOST_PYTHON_DECL PyTypeObject*& class_object(type_info key); } }}} // namespace boost::python::converter diff --git a/include/boost/python/object/class_object.hpp b/include/boost/python/object/class_object.hpp deleted file mode 100644 index 57a8ee5d..00000000 --- a/include/boost/python/object/class_object.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CLASS_OBJECT_DWA200222_HPP -# define CLASS_OBJECT_DWA200222_HPP - -# include -# include - -namespace boost { namespace python { namespace objects { - -template -struct class_object -{ - static PyTypeObject*& reference; -}; - -template -PyTypeObject*& class_object::reference - = converter::registry::class_object(python::type_id()); - -}}} // namespace boost::python::objects - -#endif // CLASS_OBJECT_DWA200222_HPP diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index 6aaa2ab0..60b861b1 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -8,7 +8,7 @@ # include # include -# include +# include # include # include # include @@ -65,7 +65,7 @@ namespace detail static result_type execute(T* p) { BOOST_STATIC_ASSERT(is_class::value); - return python::objects::class_object::reference; + return converter::registered::converters.class_object; } }; diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index b74f8bd8..60db3bb8 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -50,8 +50,11 @@ namespace // entry* get(type_info type) { # ifdef BOOST_PYTHON_TRACE_REGISTRY + registry_t::iterator p = entries().find(entry(type)); + std::cout << "looking up " << type - << (entries().find(entry(type)) == entries().end() ? ": not found\n" : ": found\n"); + << (p == entries().end() || p->target_type != type + ? "...NOT found\n" : "...found\n"); # endif return const_cast( &*entries().insert(entry(type)).first @@ -127,15 +130,21 @@ namespace registry *found = registration; } - PyTypeObject*& class_object(type_info key) - { - return get(key)->class_object; - } - registration const& lookup(type_info key) { return *get(key); } + + registration const* query(type_info type) + { + registry_t::iterator p = entries().find(entry(type)); +# ifdef BOOST_PYTHON_TRACE_REGISTRY + std::cout << "querying " << type + << (p == entries().end() || p->target_type != type + ? "...NOT found\n" : "...found\n"); +# endif + return (p == entries().end() || p->target_type != type) ? 0 : &*p; + } } // namespace registry }}} // namespace boost::python::converter diff --git a/src/object/class.cpp b/src/object/class.cpp index 43a6ef46..e49df96f 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -204,37 +204,22 @@ namespace objects namespace { - struct class_registry + // Find a registered class object corresponding to id. Return a + // null handle if no such class is registered. + inline type_handle query_class(class_id id) { - public: - type_handle get(class_id id) const; - type_handle query(class_id id) const; - void set(class_id, type_handle class_object); - private: - typedef python::detail::map_entry entry; - std::vector m_impl; - }; - - class_registry& registry() - { - static class_registry x; - return x; + converter::registration const* p = converter::registry::query(id); + return type_handle( + python::borrowed( + python::allow_null(p ? p->class_object : 0)) + ); } - inline type_handle class_registry::query(class_id id) const + // Find a registered class corresponding to id. If not found, + // throw an appropriate exception. + type_handle get_class(class_id id) { - std::vector::const_iterator start = m_impl.begin(); - std::vector::const_iterator finish = m_impl.end(); - - std::vector::const_iterator p - = boost::detail::lower_bound(start, finish, id); - - return (p == finish || p->key != id) ? type_handle() : p->value; - } - - inline type_handle class_registry::get(class_id id) const - { - type_handle result(this->query(id)); + type_handle result(query_class(id)); if (result.get() == 0) { @@ -245,48 +230,54 @@ namespace objects } return result; } - - inline void class_registry::set(class_id id, type_handle object) - { - std::vector::iterator start = m_impl.begin(); - std::vector::iterator finish = m_impl.end(); - m_impl.insert( - boost::detail::lower_bound(start, finish, id) - , entry(id, object)); - converter::registry::class_object(id) = (PyTypeObject*)object.get(); - } } + // class_base constructor + // + // name - the name of the new Python class + // + // num_types - one more than the number of declared bases + // + // types - array of python::type_info, the first item + // corresponding to the class being created, and the + // rest corresponding to its declared bases. + // class_base::class_base( char const* name, std::size_t num_types, class_id const* const types) { - class_registry& r = registry(); assert(num_types >= 1); - handle<> bases( - PyTuple_New(std::max(num_types - 1, static_cast(1))) - ); - - if (num_types > 1) + // Build a tuple of the base Python type objects. If no bases + // were declared, we'll use our class_type() as the single base + // class. + std::size_t const num_bases = std::max(num_types - 1, static_cast(1)); + handle<> bases(PyTuple_New(num_bases)); + + for (std::size_t i = 1; i <= num_bases; ++i) { - for (std::size_t i = 1; i < num_types; ++i) - PyTuple_SET_ITEM(bases.get(), i - 1, upcast(r.get(types[i]).release())); + type_handle c = (i >= num_types) ? class_type() : get_class(types[i]); + // PyTuple_SET_ITEM steals this reference + PyTuple_SET_ITEM(bases.get(), i - 1, upcast(c.release())); } - else - { - PyTuple_SET_ITEM(bases.get(), 0, upcast(class_type().release())); - } - + + // Build the (name, bases, dict) tuple for creating the new class handle<> args(PyTuple_New(3)); PyTuple_SET_ITEM(args.get(), 0, incref(python::object(name).ptr())); PyTuple_SET_ITEM(args.get(), 1, bases.release()); handle<> d(PyDict_New()); PyTuple_SET_ITEM(args.get(), 2, d.release()); + // Call the class metatype to create a new class PyObject* c = PyObject_CallObject(upcast(class_metatype().get()), args.get()); assert(PyType_IsSubtype(c->ob_type, &PyType_Type)); m_object = type_handle((PyTypeObject*)c); - r.set(types[0], m_object); + + // Insert the new class object in the registry + converter::registration& converters = const_cast( + converter::registry::lookup(types[0])); + + // Class object is leaked, for now + converters.class_object = (PyTypeObject*)incref(m_object.get()); } extern "C" @@ -315,7 +306,7 @@ namespace objects BOOST_PYTHON_DECL type_handle registered_class_object(class_id id) { - return registry().query(id); + return objects::query_class(id); } } // namespace objects From 149c60bd2e28e740766a10eeecfee85309f80fc9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 14 Jul 2002 23:25:56 +0000 Subject: [PATCH 0583/1042] Still further rationalized conversion registry [SVN r14462] --- Jamfile | 2 +- .../python/converter/arg_from_python.hpp | 2 +- .../converter/callback_from_python_base.hpp | 24 --- .../{find_from_python.hpp => from_python.hpp} | 13 +- .../python/converter/return_from_python.hpp | 10 +- src/converter/arg_to_python_base.cpp | 58 +++++++ src/converter/callback.cpp | 141 ------------------ src/converter/from_python.cpp | 94 +++++++++++- 8 files changed, 167 insertions(+), 177 deletions(-) delete mode 100644 include/boost/python/converter/callback_from_python_base.hpp rename include/boost/python/converter/{find_from_python.hpp => from_python.hpp} (76%) create mode 100644 src/converter/arg_to_python_base.cpp delete mode 100644 src/converter/callback.cpp diff --git a/Jamfile b/Jamfile index b28cf262..192982f6 100644 --- a/Jamfile +++ b/Jamfile @@ -27,7 +27,7 @@ dll bpl src/module.cpp src/objects2.cpp src/converter/builtin_converters.cpp - src/converter/callback.cpp + src/converter/arg_to_python_base.cpp src/object/iterator.cpp src/object_protocol.cpp src/object_operators.cpp diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp index 351e8a2e..7bca5040 100755 --- a/include/boost/python/converter/arg_from_python.hpp +++ b/include/boost/python/converter/arg_from_python.hpp @@ -6,7 +6,7 @@ #ifndef ARG_FROM_PYTHON_DWA2002127_HPP # define ARG_FROM_PYTHON_DWA2002127_HPP -# include +# include # include # include # include diff --git a/include/boost/python/converter/callback_from_python_base.hpp b/include/boost/python/converter/callback_from_python_base.hpp deleted file mode 100644 index 95bd2187..00000000 --- a/include/boost/python/converter/callback_from_python_base.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP -# define CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP - -namespace boost { namespace python { namespace converter { - -struct rvalue_from_python_stage1_data; -struct registration; - -namespace detail -{ - BOOST_PYTHON_DECL void* convert_rvalue(PyObject*, rvalue_from_python_stage1_data&, void* storage); - BOOST_PYTHON_DECL void* callback_convert_reference(PyObject*, registration const&); - BOOST_PYTHON_DECL void* callback_convert_pointer(PyObject*, registration const&); - BOOST_PYTHON_DECL void absorb_result(PyObject*); -} - -}}} // namespace boost::python::converter - -#endif // CALLBACK_FROM_PYTHON_BASE_DWA200237_HPP diff --git a/include/boost/python/converter/find_from_python.hpp b/include/boost/python/converter/from_python.hpp similarity index 76% rename from include/boost/python/converter/find_from_python.hpp rename to include/boost/python/converter/from_python.hpp index 629eec92..ac8b4894 100644 --- a/include/boost/python/converter/find_from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -18,11 +18,20 @@ struct rvalue_from_python_chain; BOOST_PYTHON_DECL void* get_lvalue_from_python( PyObject* source, registration const&); +BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( + PyObject* source, registration const&); + BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( PyObject* source, registration const&); -BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( - PyObject* source, registration const&); +BOOST_PYTHON_DECL void* rvalue_from_python_stage2( + PyObject*, rvalue_from_python_stage1_data&, void* storage); + +BOOST_PYTHON_DECL void* reference_from_python(PyObject*, registration const&); +BOOST_PYTHON_DECL void* pointer_from_python(PyObject*, registration const&); + +BOOST_PYTHON_DECL void void_from_python(PyObject*); + }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 8f9f31b3..902612e2 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -6,7 +6,7 @@ #ifndef RETURN_FROM_PYTHON_DWA200265_HPP # define RETURN_FROM_PYTHON_DWA200265_HPP -# include +# include # include # include # include @@ -77,7 +77,7 @@ struct return_from_python result_type operator()(PyObject* x) const { - converter::detail::absorb_result(x); + converter::void_from_python(x); # ifdef BOOST_NO_VOID_RETURNS return result_type(); # endif @@ -101,21 +101,21 @@ namespace detail inline typename return_rvalue_from_python::result_type return_rvalue_from_python::operator()(PyObject* obj) { - return *(T*)convert_rvalue(obj, m_data.stage1, m_data.storage.bytes); + return *(T*)rvalue_from_python_stage2(obj, m_data.stage1, m_data.storage.bytes); } template inline T return_reference_from_python::operator()(PyObject* obj) const { return python::detail::void_ptr_to_reference( - callback_convert_reference(obj, registered::converters) + reference_from_python(obj, registered::converters) , (T(*)())0); } template inline T return_pointer_from_python::operator()(PyObject* obj) const { - return T(callback_convert_pointer(obj, registered_pointee::converters)); + return T(pointer_from_python(obj, registered_pointee::converters)); } } diff --git a/src/converter/arg_to_python_base.cpp b/src/converter/arg_to_python_base.cpp new file mode 100644 index 00000000..7936216a --- /dev/null +++ b/src/converter/arg_to_python_base.cpp @@ -0,0 +1,58 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include +#include + +namespace boost { namespace python { namespace converter { + +namespace +{ + inline PyObject* convert_to_python(void const volatile* source, registration const& converters) + { + if (converters.to_python == 0) + { + handle<> msg( + ::PyString_FromFormat( + "No to_python (by-value) converter found for C++ type: %s" + , converters.target_type.name())); + + PyErr_SetObject(PyExc_TypeError, msg.get()); + + throw_error_already_set(); + } + + return source == 0 + ? incref(Py_None) + : converters.to_python(const_cast(source)); + } +} + +namespace detail +{ + arg_to_python_base::arg_to_python_base( + void const volatile* source, registration const& converters) +# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140 + : handle<>(converter::convert_to_python(source, converters)) +# else + : m_ptr(converter::convert_to_python(source, converters)) +# endif + { + } + + BOOST_PYTHON_DECL void throw_no_class_registered() + { + PyErr_SetString( + PyExc_TypeError + , const_cast("class not registered for to_python type")); + throw_error_already_set(); + } +} + +}}} // namespace boost::python::converter diff --git a/src/converter/callback.cpp b/src/converter/callback.cpp deleted file mode 100644 index 827d1e07..00000000 --- a/src/converter/callback.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { namespace converter { - -namespace detail -{ - - namespace - { - inline PyObject* convert_to_python(void const volatile* source, registration const& converters) - { - if (converters.to_python == 0) - { - handle<> msg( - ::PyString_FromFormat( - "No to_python (by-value) converter found for C++ type: %s" - , converters.target_type.name())); - - PyErr_SetObject(PyExc_TypeError, msg.get()); - - throw_error_already_set(); - } - - return source == 0 - ? python::detail::none() - : converters.to_python(const_cast(source)); - } - } - - arg_to_python_base::arg_to_python_base( - void const volatile* source, registration const& converters) -# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140 - : handle<>(convert_to_python(source, converters)) -# else - : m_ptr(convert_to_python(source, converters)) -# endif - { - } - - BOOST_PYTHON_DECL void* callback_convert_reference( - PyObject* source - , registration const& converters) - { - handle<> holder(source); - if (source->ob_refcnt <= 2) - { - handle<> msg( - ::PyString_FromFormat( - "Attempt to return dangling pointer/reference to object of type: %s" - , converters.target_type.name())); - - PyErr_SetObject(PyExc_ReferenceError, msg.get()); - - throw_error_already_set(); - } - void* result = get_lvalue_from_python(source, converters); - if (!result) - { - handle<> msg( - ::PyString_FromFormat( - "No registered converter was able to extract a a C++ lvalue of type %s from this Python object of type %s" - , converters.target_type.name() - , source->ob_type->tp_name - )); - - PyErr_SetObject(PyExc_TypeError, msg.get()); - - throw_error_already_set(); - } - return result; - } - - BOOST_PYTHON_DECL void* callback_convert_pointer( - PyObject* source - , registration const& converters) - { - if (source == Py_None) - { - Py_DECREF(source); - return 0; - } - return callback_convert_reference(source, converters); - } - - BOOST_PYTHON_DECL void throw_no_class_registered() - { - PyErr_SetString( - PyExc_TypeError - , const_cast("class not registered for to_python type")); - throw_error_already_set(); - } - - BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_from_python_stage1_data& data, void* storage) - { - handle<> holder(src); - - void const* converters_ = data.convertible; - registration const& converters = *static_cast(converters_); - data = rvalue_from_python_stage1(src, converters); - - if (!data.convertible) - { - handle<> msg( - ::PyString_FromFormat( - "No registered converter was able to produce a C++ lvalue of type %s from this Python object of type %s" - , converters.target_type.name() - , src->ob_type->tp_name - )); - - PyErr_SetObject(PyExc_TypeError, msg.get()); - throw_error_already_set(); - } - - // If a construct function was registered (i.e. we found an - // rvalue conversion), call it now. - if (data.construct != 0) - data.construct(src, &data); - - // Return the address of the resulting C++ object - return data.convertible; - } - - BOOST_PYTHON_DECL void absorb_result(PyObject* o) - { - Py_DECREF(expect_non_null(o)); - } -} - -}}} // namespace boost::python::converter diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index f68bf0fa..b9dc8614 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -4,11 +4,10 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include #include #include -#include -#include +#include #include #include @@ -35,6 +34,37 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( return data; } +BOOST_PYTHON_DECL void* rvalue_from_python_stage2( + PyObject* src, rvalue_from_python_stage1_data& data, void* storage) +{ + handle<> holder(src); + + void const* converters_ = data.convertible; + registration const& converters = *static_cast(converters_); + data = rvalue_from_python_stage1(src, converters); + + if (!data.convertible) + { + handle<> msg( + ::PyString_FromFormat( + "No registered converter was able to produce a C++ lvalue of type %s from this Python object of type %s" + , converters.target_type.name() + , src->ob_type->tp_name + )); + + PyErr_SetObject(PyExc_TypeError, msg.get()); + throw_error_already_set(); + } + + // If a construct function was registered (i.e. we found an + // rvalue conversion), call it now. + if (data.construct != 0) + data.construct(src, &data); + + // Return the address of the resulting C++ object + return data.convertible; +} + BOOST_PYTHON_DECL void* get_lvalue_from_python( PyObject* source , registration const& converters) @@ -100,4 +130,62 @@ BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( return chain; } +BOOST_PYTHON_DECL void* reference_from_python( + PyObject* source + , registration const& converters) +{ + handle<> holder(source); + if (source->ob_refcnt <= 2) + { + handle<> msg( + ::PyString_FromFormat( + "Attempt to return dangling pointer/reference to object of type: %s" + , converters.target_type.name())); + + PyErr_SetObject(PyExc_ReferenceError, msg.get()); + + throw_error_already_set(); + } + void* result = get_lvalue_from_python(source, converters); + if (!result) + { + handle<> msg( + ::PyString_FromFormat( + "No registered converter was able to extract a a C++ lvalue of type %s from this Python object of type %s" + , converters.target_type.name() + , source->ob_type->tp_name + )); + + PyErr_SetObject(PyExc_TypeError, msg.get()); + + throw_error_already_set(); + } + return result; +} + +BOOST_PYTHON_DECL void* pointer_from_python( + PyObject* source + , registration const& converters) +{ + if (source == Py_None) + { + Py_DECREF(source); + return 0; + } + return reference_from_python(source, converters); +} + +BOOST_PYTHON_DECL void throw_no_class_registered() +{ + PyErr_SetString( + PyExc_TypeError + , const_cast("class not registered for to_python type")); + throw_error_already_set(); +} + +BOOST_PYTHON_DECL void void_from_python(PyObject* o) +{ + Py_DECREF(expect_non_null(o)); +} + }}} // namespace boost::python::converter From ba1eab1bf0ef918995fe630c9b2c7d4557c4bcb3 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 15 Jul 2002 19:09:57 +0000 Subject: [PATCH 0584/1042] is_string_literal specialization enabled for MIPSpro; this fixes the list.test failures. [SVN r14468] --- include/boost/python/detail/string_literal.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/string_literal.hpp b/include/boost/python/detail/string_literal.hpp index ddafa401..dc8b0791 100644 --- a/include/boost/python/detail/string_literal.hpp +++ b/include/boost/python/detail/string_literal.hpp @@ -27,7 +27,8 @@ struct is_string_literal BOOST_STATIC_CONSTANT(bool, value = true); }; -# if defined(__DECCXX_VER) && __DECCXX_VER <= 60590014 +# if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590014) \ + || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) // This compiler mistakenly gets the type of string literals as char* // instead of char[NN]. template <> From ea5cfdcdce49866a934d788605a69f5d64b22aa3 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 15 Jul 2002 20:07:04 +0000 Subject: [PATCH 0585/1042] missing inline keywords added (MIPSpro 7.3 diagnostics) [SVN r14469] --- include/boost/python/long.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp index 5d39093e..2dfebf65 100644 --- a/include/boost/python/long.hpp +++ b/include/boost/python/long.hpp @@ -31,8 +31,8 @@ class long_ : public object { } public: // implementation detail -- for internal use only - explicit long_(detail::borrowed_reference); - explicit long_(detail::new_reference); + explicit inline long_(detail::borrowed_reference); + explicit inline long_(detail::new_reference); private: static BOOST_PYTHON_DECL detail::new_reference call(object const&); From fa779034b5aafc3b812ec880b6608abb0c2bb560 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 16 Jul 2002 11:31:36 +0000 Subject: [PATCH 0586/1042] VC7.1 workarounds [SVN r14477] --- src/converter/arg_to_python_base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/converter/arg_to_python_base.cpp b/src/converter/arg_to_python_base.cpp index 7936216a..b20a2a9c 100644 --- a/src/converter/arg_to_python_base.cpp +++ b/src/converter/arg_to_python_base.cpp @@ -38,7 +38,7 @@ namespace detail { arg_to_python_base::arg_to_python_base( void const volatile* source, registration const& converters) -# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102140 +# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102171 : handle<>(converter::convert_to_python(source, converters)) # else : m_ptr(converter::convert_to_python(source, converters)) From 2bfeb20550e046fd17a095880f082edab96cb935 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 16 Jul 2002 11:45:10 +0000 Subject: [PATCH 0587/1042] Added type checking when converting some Python types from python as return values. [SVN r14478] --- .../boost/python/converter/from_python.hpp | 10 +-- .../converter/pytype_result_from_python.hpp | 18 +++++ .../python/converter/return_from_python.hpp | 11 ++-- include/boost/python/list.hpp | 3 +- include/boost/python/long.hpp | 3 +- src/converter/from_python.cpp | 65 +++++++++++++++++-- src/list.cpp | 44 ++++++++++--- src/object/inheritance.cpp | 3 + test/list.cpp | 6 ++ test/list.py | 30 ++++++++- 10 files changed, 165 insertions(+), 28 deletions(-) create mode 100644 include/boost/python/converter/pytype_result_from_python.hpp diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index ac8b4894..26373ce0 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -24,13 +24,13 @@ BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( PyObject* source, registration const&); -BOOST_PYTHON_DECL void* rvalue_from_python_stage2( - PyObject*, rvalue_from_python_stage1_data&, void* storage); +BOOST_PYTHON_DECL void* rvalue_result_from_python( + PyObject*, rvalue_from_python_stage1_data&); -BOOST_PYTHON_DECL void* reference_from_python(PyObject*, registration const&); -BOOST_PYTHON_DECL void* pointer_from_python(PyObject*, registration const&); +BOOST_PYTHON_DECL void* reference_result_from_python(PyObject*, registration const&); +BOOST_PYTHON_DECL void* pointer_result_from_python(PyObject*, registration const&); -BOOST_PYTHON_DECL void void_from_python(PyObject*); +BOOST_PYTHON_DECL void void_result_from_python(PyObject*); }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/pytype_result_from_python.hpp b/include/boost/python/converter/pytype_result_from_python.hpp new file mode 100644 index 00000000..b1a13e89 --- /dev/null +++ b/include/boost/python/converter/pytype_result_from_python.hpp @@ -0,0 +1,18 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef PYTYPE_RESULT_FROM_PYTHON_DWA2002716_HPP +# define PYTYPE_RESULT_FROM_PYTHON_DWA2002716_HPP + +# include + +namespace boost { namespace python { namespace converter { + +BOOST_PYTHON_DECL python::detail::new_reference +pytype_result_from_python(PyTypeObject* type, PyObject* source); + +}}} // namespace boost::python::converter + +#endif // PYTYPE_RESULT_FROM_PYTHON_DWA2002716_HPP diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 902612e2..8cdaf81d 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -77,7 +77,7 @@ struct return_from_python result_type operator()(PyObject* x) const { - converter::void_from_python(x); + (void_result_from_python)(x); # ifdef BOOST_NO_VOID_RETURNS return result_type(); # endif @@ -101,21 +101,24 @@ namespace detail inline typename return_rvalue_from_python::result_type return_rvalue_from_python::operator()(PyObject* obj) { - return *(T*)rvalue_from_python_stage2(obj, m_data.stage1, m_data.storage.bytes); + return *(T*) + (rvalue_result_from_python)(obj, m_data.stage1); } template inline T return_reference_from_python::operator()(PyObject* obj) const { return python::detail::void_ptr_to_reference( - reference_from_python(obj, registered::converters) + (reference_result_from_python)(obj, registered::converters) , (T(*)())0); } template inline T return_pointer_from_python::operator()(PyObject* obj) const { - return T(pointer_from_python(obj, registered_pointee::converters)); + return T( + (pointer_result_from_python)(obj, registered_pointee::converters) + ); } } diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp index 3de6dedd..b7948b04 100644 --- a/include/boost/python/list.hpp +++ b/include/boost/python/list.hpp @@ -8,6 +8,7 @@ # include # include +# include namespace boost { namespace python { @@ -153,7 +154,7 @@ namespace converter result_type operator()(PyObject* x) const { - return list(python::detail::new_reference(x)); + return list((pytype_result_from_python)(&PyList_Type, x)); } }; } diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp index 2dfebf65..1b47728e 100644 --- a/include/boost/python/long.hpp +++ b/include/boost/python/long.hpp @@ -8,6 +8,7 @@ # include # include +# include namespace boost { namespace python { @@ -91,7 +92,7 @@ namespace converter result_type operator()(PyObject* x) const { - return long_(python::detail::new_reference(x)); + return long_((pytype_result_from_python)(&PyLong_Type, x)); } }; } diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index b9dc8614..953bf946 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -8,11 +8,28 @@ #include #include #include +#include #include #include namespace boost { namespace python { namespace converter { +// rvalue_from_python_stage1 -- do the first stage of a conversion +// from a Python object to a C++ rvalue. +// +// source - the Python object to be converted +// converters - the registry entry for the target type T +// +// Postcondition: where x is the result, one of: +// +// 1. x.convertible == 0, indicating failure +// +// 2. x.construct == 0, x.convertible is the address of an object of +// type T. Indicates a successful lvalue conversion +// +// 3. where y is of type rvalue_from_python_data, +// x.construct(source, y) attempts to construct an object of type T +// in y. Indicates an rvalue converter was found BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( PyObject* source , registration const& converters) @@ -34,20 +51,36 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( return data; } -BOOST_PYTHON_DECL void* rvalue_from_python_stage2( - PyObject* src, rvalue_from_python_stage1_data& data, void* storage) +// rvalue_result_from_python -- return the address of a C++ object which +// can be used as the result of calling a Python function. +// +// src - the Python object to be converted +// +// data - a reference to the base part of a +// rvalue_from_python_data object, where T is the +// target type of the conversion. +// +// Requires: data.convertible == ®istered::converters +// +BOOST_PYTHON_DECL void* rvalue_result_from_python( + PyObject* src, rvalue_from_python_stage1_data& data) { + // Take possession of the source object. handle<> holder(src); + // Retrieve the registration + // Cast in two steps for less-capable compilers void const* converters_ = data.convertible; registration const& converters = *static_cast(converters_); + + // Look for an eligible converter data = rvalue_from_python_stage1(src, converters); if (!data.convertible) { handle<> msg( ::PyString_FromFormat( - "No registered converter was able to produce a C++ lvalue of type %s from this Python object of type %s" + "No registered converter was able to produce a C++ rvalue of type %s from this Python object of type %s" , converters.target_type.name() , src->ob_type->tp_name )); @@ -130,7 +163,7 @@ BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( return chain; } -BOOST_PYTHON_DECL void* reference_from_python( +BOOST_PYTHON_DECL void* reference_result_from_python( PyObject* source , registration const& converters) { @@ -163,7 +196,7 @@ BOOST_PYTHON_DECL void* reference_from_python( return result; } -BOOST_PYTHON_DECL void* pointer_from_python( +BOOST_PYTHON_DECL void* pointer_result_from_python( PyObject* source , registration const& converters) { @@ -172,7 +205,7 @@ BOOST_PYTHON_DECL void* pointer_from_python( Py_DECREF(source); return 0; } - return reference_from_python(source, converters); + return reference_result_from_python(source, converters); } BOOST_PYTHON_DECL void throw_no_class_registered() @@ -183,9 +216,27 @@ BOOST_PYTHON_DECL void throw_no_class_registered() throw_error_already_set(); } -BOOST_PYTHON_DECL void void_from_python(PyObject* o) +BOOST_PYTHON_DECL void void_result_from_python(PyObject* o) { Py_DECREF(expect_non_null(o)); } +BOOST_PYTHON_DECL python::detail::new_reference +pytype_result_from_python(PyTypeObject* type, PyObject* source) +{ + if (!PyType_IsSubtype(source->ob_type, type)) + { + handle<> keeper(source); + handle<> msg( + ::PyString_FromFormat( + "Expecting a Python %s return type, but got an object of type %s instead" + , type + , source->ob_type->tp_name + )); + PyErr_SetObject(PyExc_TypeError, msg.get()); + throw_error_already_set(); + } + return python::detail::new_reference(source); +} + }}} // namespace boost::python::converter diff --git a/src/list.cpp b/src/list.cpp index 7931c899..ed7e675f 100644 --- a/src/list.cpp +++ b/src/list.cpp @@ -24,8 +24,15 @@ BOOST_PYTHON_DECL list::list(object_cref sequence) BOOST_PYTHON_DECL void list::append(object_cref x) { - if (PyList_Append(this->ptr(), x.ptr()) == -1) - throw_error_already_set(); + if (PyList_CheckExact(this->ptr())) + { + if (PyList_Append(this->ptr(), x.ptr()) == -1) + throw_error_already_set(); + } + else + { + this->attr("append")(x); + } } BOOST_PYTHON_DECL long list::count(object_cref value) const @@ -53,8 +60,15 @@ BOOST_PYTHON_DECL long list::index(object_cref value) const BOOST_PYTHON_DECL void list::insert(int index, object_cref item) { - if (PyList_Insert(this->ptr(), index, item.ptr()) == -1) - throw_error_already_set(); + if (PyList_CheckExact(this->ptr())) + { + if (PyList_Insert(this->ptr(), index, item.ptr()) == -1) + throw_error_already_set(); + } + else + { + this->attr("insert")(index, item); + } } BOOST_PYTHON_DECL void list::insert(object const& index, object_cref x) @@ -87,14 +101,28 @@ BOOST_PYTHON_DECL void list::remove(object_cref value) BOOST_PYTHON_DECL void list::reverse() { - if (PyList_Reverse(this->ptr()) == -1) - throw_error_already_set(); + if (PyList_CheckExact(this->ptr())) + { + if (PyList_Reverse(this->ptr()) == -1) + throw_error_already_set(); + } + else + { + this->attr("reverse")(); + } } BOOST_PYTHON_DECL void list::sort() { - if (PyList_Sort(this->ptr()) == -1) - throw_error_already_set(); + if (PyList_CheckExact(this->ptr())) + { + if (PyList_Sort(this->ptr()) == -1) + throw_error_already_set(); + } + else + { + this->attr("sort")(); + } } BOOST_PYTHON_DECL void list::sort(object_cref cmpfunc) diff --git a/src/object/inheritance.cpp b/src/object/inheritance.cpp index 6725b95d..d84e2b36 100644 --- a/src/object/inheritance.cpp +++ b/src/object/inheritance.cpp @@ -6,6 +6,9 @@ #include #include #include +#if defined(BOOST_MSVC) && _MSC_FULL_VER == 13102171 +# include +#endif #include #include #include diff --git a/test/list.cpp b/test/list.cpp index 4ad285b4..a5c9bc87 100644 --- a/test/list.cpp +++ b/test/list.cpp @@ -38,6 +38,11 @@ object apply_object_list(object f, list x) return f(x); } +list apply_list_list(object f, list x) +{ + return call(f.ptr(), x); +} + void append_object(list& x, object y) { x.append(y); @@ -126,6 +131,7 @@ BOOST_PYTHON_MODULE_INIT(list_ext) .def("listify", listify) .def("listify_string", listify_string) .def("apply_object_list", apply_object_list) + .def("apply_list_list", apply_list_list) .def("append_object", append_object) .def("append_list", append_list) diff --git a/test/list.py b/test/list.py index a7387e2d..0357b9a2 100644 --- a/test/list.py +++ b/test/list.py @@ -20,9 +20,17 @@ X(22) 5 is not convertible to a list ->>> try: apply_object_list(identity, 5) +>>> try: result = apply_object_list(identity, 5) ... except TypeError: pass -... else: print 'expected an exception' +... else: print 'expected an exception, got', result, 'instead' + +>>> assert apply_list_list(identity, letters) is letters + + 5 is not convertible to a list as a return value + +>>> try: result = apply_list_list(len, letters) +... except TypeError: pass +... else: print 'expected an exception, got', result, 'instead' >>> append_object(letters, '.') >>> letters @@ -38,6 +46,24 @@ X(22) >>> letters ['h', 'e', 'l', 'l', 'o', '.', [1, 2]] + Check that subclass functions are properly called + +>>> class mylist(list): +... def append(self, o): +... list.append(self, o) +... if not hasattr(self, 'nappends'): +... self.nappends = 1 +... else: +... self.nappends += 1 +... +>>> l2 = mylist() +>>> append_object(l2, 'hello') +>>> append_object(l2, 'world') +>>> l2 +['hello', 'world'] +>>> l2.nappends +2 + >>> def printer(*args): ... for x in args: print x, ... print From 7a05b89a93f87695891ea5974090d52bba293576 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 16 Jul 2002 17:15:36 +0000 Subject: [PATCH 0588/1042] MSVC6 workaround [SVN r14484] --- include/boost/python/converter/pytype_result_from_python.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/converter/pytype_result_from_python.hpp b/include/boost/python/converter/pytype_result_from_python.hpp index b1a13e89..9cb95712 100644 --- a/include/boost/python/converter/pytype_result_from_python.hpp +++ b/include/boost/python/converter/pytype_result_from_python.hpp @@ -11,7 +11,7 @@ namespace boost { namespace python { namespace converter { BOOST_PYTHON_DECL python::detail::new_reference -pytype_result_from_python(PyTypeObject* type, PyObject* source); +pytype_result_from_python(PyTypeObject*, PyObject* source); }}} // namespace boost::python::converter From 1d2dc98f50e69c124d89499642520cf5251b47ca Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 16 Jul 2002 20:01:38 +0000 Subject: [PATCH 0589/1042] MSVC6 workaround [SVN r14485] --- src/converter/from_python.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 953bf946..30c31f4f 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -222,15 +223,15 @@ BOOST_PYTHON_DECL void void_result_from_python(PyObject* o) } BOOST_PYTHON_DECL python::detail::new_reference -pytype_result_from_python(PyTypeObject* type, PyObject* source) +pytype_result_from_python(PyTypeObject* type_, PyObject* source) { - if (!PyType_IsSubtype(source->ob_type, type)) + if (!PyObject_IsInstance(source, python::upcast(type_))) { handle<> keeper(source); handle<> msg( ::PyString_FromFormat( "Expecting a Python %s return type, but got an object of type %s instead" - , type + , type_ , source->ob_type->tp_name )); PyErr_SetObject(PyExc_TypeError, msg.get()); From 134bc44c452e66fd182f420ae152cbc7a4c6c76d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Jul 2002 01:53:33 +0000 Subject: [PATCH 0590/1042] destroy_reference -> destroy_referent [SVN r14486] --- .../python/converter/rvalue_from_python_data.hpp | 2 +- include/boost/python/detail/destroy.hpp | 6 +++--- test/destroy_test.cpp | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp index f30ceadb..658cedb6 100644 --- a/include/boost/python/converter/rvalue_from_python_data.hpp +++ b/include/boost/python/converter/rvalue_from_python_data.hpp @@ -129,7 +129,7 @@ template inline rvalue_from_python_data::~rvalue_from_python_data() { if (this->stage1.convertible == this->storage.bytes) - python::detail::destroy_reference(this->storage.bytes); + python::detail::destroy_referent(this->storage.bytes); } }}} // namespace boost::python::converter diff --git a/include/boost/python/detail/destroy.hpp b/include/boost/python/detail/destroy.hpp index 07738e2f..89e82f73 100644 --- a/include/boost/python/detail/destroy.hpp +++ b/include/boost/python/detail/destroy.hpp @@ -62,7 +62,7 @@ struct value_destroyer }; template -inline void destroy_reference_impl(void* p, T& (*)()) +inline void destroy_referent_impl(void* p, T& (*)()) { // note: cv-qualification needed for MSVC6 // must come *before* T for metrowerks @@ -73,9 +73,9 @@ inline void destroy_reference_impl(void* p, T& (*)()) } template -inline void destroy_reference(void* p, T(*)() = 0) +inline void destroy_referent(void* p, T(*)() = 0) { - destroy_reference_impl(p, (T(*)())0); + destroy_referent_impl(p, (T(*)())0); } }}} // namespace boost::python::detail diff --git a/test/destroy_test.cpp b/test/destroy_test.cpp index c6be42fc..38d5d1d5 100644 --- a/test/destroy_test.cpp +++ b/test/destroy_test.cpp @@ -5,7 +5,7 @@ struct bar; namespace boost { - // lie to the library about bar so we can show that it's destructor is optimized away. + // lie to the library about bar so we can show that its destructor is optimized away. template <> struct has_trivial_destructor { @@ -48,33 +48,33 @@ int main() typedef int a[2]; foo* f1 = new foo; - boost::python::detail::destroy_reference(f1); + boost::python::detail::destroy_referent(f1); assert_destructions(1); foo* f2 = new foo[2]; typedef foo x[2]; - boost::python::detail::destroy_reference(f2); + boost::python::detail::destroy_referent(f2); assert_destructions(3); typedef foo y[2][2]; x* f3 = new y; - boost::python::detail::destroy_reference(f3); + boost::python::detail::destroy_referent(f3); assert_destructions(7); bar* b1 = new bar; - boost::python::detail::destroy_reference(b1); + boost::python::detail::destroy_referent(b1); assert_destructions(7); bar* b2 = new bar[2]; typedef bar xb[2]; - boost::python::detail::destroy_reference(b2); + boost::python::detail::destroy_referent(b2); assert_destructions(7); typedef bar yb[2][2]; xb* b3 = new yb; - boost::python::detail::destroy_reference(b3); + boost::python::detail::destroy_referent(b3); assert_destructions(7); return 0; From 244e0fa5e6843a780b7481fde1bbff635b9b9336 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Jul 2002 01:54:58 +0000 Subject: [PATCH 0591/1042] More converter centralization [SVN r14487] --- .../always_extract_object_manager.hpp | 35 ++++++ .../python/converter/arg_from_python.hpp | 45 +++++--- .../converter/obj_mgr_arg_from_python.hpp | 105 ++++++++++++++++++ .../boost/python/converter/object_manager.hpp | 41 ++++++- .../pytype_extract_object_manager.hpp | 48 ++++++++ .../python/converter/return_from_python.hpp | 35 +++++- include/boost/python/detail/construct.hpp | 37 ++++++ include/boost/python/detail/raw_pyobject.hpp | 6 +- include/boost/python/list.hpp | 68 +----------- include/boost/python/long.hpp | 70 +----------- include/boost/python/object_core.hpp | 101 ++++------------- src/list.cpp | 10 +- src/long.cpp | 8 +- 13 files changed, 369 insertions(+), 240 deletions(-) create mode 100644 include/boost/python/converter/always_extract_object_manager.hpp create mode 100644 include/boost/python/converter/obj_mgr_arg_from_python.hpp create mode 100644 include/boost/python/converter/pytype_extract_object_manager.hpp create mode 100644 include/boost/python/detail/construct.hpp diff --git a/include/boost/python/converter/always_extract_object_manager.hpp b/include/boost/python/converter/always_extract_object_manager.hpp new file mode 100644 index 00000000..02f18143 --- /dev/null +++ b/include/boost/python/converter/always_extract_object_manager.hpp @@ -0,0 +1,35 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ALWAYS_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP +# define ALWAYS_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP + +# include + +namespace boost { namespace python { namespace converter { + +// Derive specializations of extract_object_manager from this when the +// object manager is indiscriminate about the Python objects it manages +struct always_extract_object_manager +{ + BOOST_STATIC_CONSTANT(bool, is_specialized = true); + static inline bool check(PyObject* x); +}; + +// Provide a forward declaration as a convenience for clients, who all +// need it. +template struct extract_object_manager; + +// +// implementations +// +inline bool always_extract_object_manager::check(PyObject* x) +{ + return true; +} + +}}} // namespace boost::python::converter + +#endif // ALWAYS_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp index 7bca5040..289b4945 100755 --- a/include/boost/python/converter/arg_from_python.hpp +++ b/include/boost/python/converter/arg_from_python.hpp @@ -19,6 +19,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -139,6 +140,12 @@ struct back_reference_arg_from_python template struct select_arg_from_python { + BOOST_STATIC_CONSTANT( + bool, obj_mgr = is_object_manager::value); + + BOOST_STATIC_CONSTANT( + bool, obj_mgr_ref = is_reference_to_object_manager::value); + BOOST_STATIC_CONSTANT( bool, ptr = is_pointer::value); @@ -159,22 +166,30 @@ struct select_arg_from_python boost::python::is_back_reference::value); typedef typename mpl::select_type< - ptr - , pointer_arg_from_python - , typename mpl::select_type< - ptr_cref - , pointer_cref_arg_from_python - , typename mpl::select_type< - ref - , reference_arg_from_python - , typename mpl::select_type< - back_ref - , back_reference_arg_from_python - , arg_rvalue_from_python - >::type - >::type + obj_mgr + , object_manager_value_arg_from_python + , mpl::select_type< + obj_mgr_ref + , object_manager_ref_arg_from_python + , mpl::select_type< + ptr + , pointer_arg_from_python + , typename mpl::select_type< + ptr_cref + , pointer_cref_arg_from_python + , typename mpl::select_type< + ref + , reference_arg_from_python + , typename mpl::select_type< + back_ref + , back_reference_arg_from_python + , arg_rvalue_from_python + >::type + >::type + >::type + >::type >::type - >::type type; + >::type type; }; // ================== diff --git a/include/boost/python/converter/obj_mgr_arg_from_python.hpp b/include/boost/python/converter/obj_mgr_arg_from_python.hpp new file mode 100644 index 00000000..58cf85e4 --- /dev/null +++ b/include/boost/python/converter/obj_mgr_arg_from_python.hpp @@ -0,0 +1,105 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP +# define OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP + +# include +# include +# include +# include +# include + +// +// arg_from_python converters for Python type wrappers, to be used as +// base classes for specializations. +// +namespace boost { namespace python { namespace converter { + +template +struct object_manager_value_arg_from_python +{ + typedef T result_type; + + object_manager_value_arg_from_python(PyObject*); + bool convertible() const; + T operator()(PyObject*) const; + private: + PyObject* m_source; +}; + +template +struct object_manager_ref_arg_from_python +{ + typedef Ref result_type; + + object_manager_ref_arg_from_python(PyObject*); + bool convertible() const; + Ref operator()(PyObject*) const; + ~object_manager_ref_arg_from_python(); + private: + typename python::detail::referent_storage::type m_result; +}; + +// +// implementations +// + +template +inline object_manager_value_arg_from_python::object_manager_value_arg_from_python(PyObject* x) + : m_source(x) +{ +} + +template +inline bool object_manager_value_arg_from_python::convertible() const +{ + return extract_object_manager::check(m_source); +} + +template +inline T object_manager_value_arg_from_python::operator()(PyObject* x) const +{ + return T(python::detail::borrowed_reference(x)); +} + +template +inline object_manager_ref_arg_from_python::object_manager_ref_arg_from_python(PyObject* x) +{ + python::detail::construct_referent(&m_result.bytes, python::detail::borrowed_reference(x)); +} + +template +inline object_manager_ref_arg_from_python::~object_manager_ref_arg_from_python() +{ + python::detail::destroy_referent(this->m_result.bytes); +} + +namespace detail +{ + template + inline bool object_manager_ref_check(T const& x) + { + return extract_object_manager::check((get_managed_object)(x)); + } +} + +template +inline bool object_manager_ref_arg_from_python::convertible() const +{ + return detail::object_manager_ref_check( + python::detail::void_ptr_to_reference(this->m_result.bytes, (Ref(*)())0)); +} + +template +inline Ref object_manager_ref_arg_from_python::operator()(PyObject*) const +{ + return python::detail::void_ptr_to_reference( + this->m_result.bytes, (Ref(*)())0); +} + +}}} // namespace boost::python::converter + +#endif // OBJ_MGR_ARG_FROM_PYTHON_DWA2002628_HPP diff --git a/include/boost/python/converter/object_manager.hpp b/include/boost/python/converter/object_manager.hpp index 23e70a1e..ac0ceb02 100755 --- a/include/boost/python/converter/object_manager.hpp +++ b/include/boost/python/converter/object_manager.hpp @@ -12,22 +12,55 @@ # include # include -namespace boost { namespace python { namespace api { - -class object; +// Facilities for dealing with types which always manage Python +// objects. Some examples are object, list, et. al. Different +// to_python/from_python conversion rules apply here because in +// contrast to other types which are typically embedded inside a +// Python object, these are wrapped around a Python object. For most +// object managers T, a C++ non-const T reference argument does not +// imply the existence of a T lvalue embedded in the corresponding +// Python argument, since mutating member functions on T actually only +// modify the held Python object. +// +// Note also that handle<> does not qualify as an object manager because: +// a. It might not manage a Python object (it can be null) +// b. Mutating operations visible to users modify the handle<> itself. +namespace boost { namespace python { namespace api +{ + class object; // forward declaration }}} namespace boost { namespace python { namespace converter { +// Used to create object managers of type T, taking ownership of a +// given PyObject*. Specializations X must satisfy the following, +// where p is a non-null PyObject*: +// +// X::is_specialized == true +// +// T(X::execute(p)) - constructs a T object from p, or throws a +// TypeError exception if p doesn't have an appropriate type. +// +// X::check(p), convertible to bool. True iff T(X::execute(p)) will +// not throw. +template +struct extract_object_manager +{ + BOOST_STATIC_CONSTANT(bool, is_specialized = false); +}; + +// A metafunction returning true iff its argument is an object manager. template struct is_object_manager { private: + // handle the cases that would otherwise require partial specialization BOOST_STATIC_CONSTANT(bool, hdl = is_handle::value); BOOST_STATIC_CONSTANT(bool, borrowed = python::detail::is_borrowed_ptr::value); + BOOST_STATIC_CONSTANT(bool, extract_specialized = extract_object_manager::is_specialized); public: - BOOST_STATIC_CONSTANT(bool, value = (hdl | borrowed)); + BOOST_STATIC_CONSTANT(bool, value = (hdl | borrowed | extract_specialized)); }; # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION diff --git a/include/boost/python/converter/pytype_extract_object_manager.hpp b/include/boost/python/converter/pytype_extract_object_manager.hpp new file mode 100644 index 00000000..cd4cadc9 --- /dev/null +++ b/include/boost/python/converter/pytype_extract_object_manager.hpp @@ -0,0 +1,48 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef PYTYPE_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP +# define PYTYPE_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP + +# include +# include +# include +# include + +namespace boost { namespace python { namespace converter { + +// Provide a forward declaration as a convenience for clients, who all +// need it. +template struct extract_object_manager; + +// Derive specializations of extract_object_manager from this class +// when T is an object manager for a particular Python type hierarchy. +// +template +struct pytype_extract_object_manager +{ + BOOST_STATIC_CONSTANT(bool, is_specialized = true); + static inline python::detail::new_reference execute(PyObject*); + static inline bool check(PyObject* x); +}; + +// +// implementations +// +template +inline python::detail::new_reference pytype_extract_object_manager::execute(PyObject* x) +{ + return pytype_result_from_python(pytype, x); +} + +template +inline bool pytype_extract_object_manager::check(PyObject* x) +{ + return ::PyObject_IsInstance(x, python::upcast(pytype)); +} + +}}} // namespace boost::python::converter + +#endif // PYTYPE_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 8cdaf81d..1f2d74cf 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -6,6 +6,7 @@ #ifndef RETURN_FROM_PYTHON_DWA200265_HPP # define RETURN_FROM_PYTHON_DWA200265_HPP +# include # include # include # include @@ -42,9 +43,19 @@ namespace detail rvalue_from_python_data m_data; }; + template + struct return_object_manager_from_python + { + typedef T result_type; + result_type operator()(PyObject*) const; + }; + template struct select_return_from_python { + BOOST_STATIC_CONSTANT( + bool, obj_mgr = is_object_manager::value); + BOOST_STATIC_CONSTANT( bool, ptr = is_pointer::value); @@ -52,14 +63,18 @@ namespace detail bool, ref = is_reference::value); typedef typename mpl::select_type< - ptr - , return_pointer_from_python + obj_mgr + , return_object_manager_from_python , typename mpl::select_type< - ref - , return_reference_from_python - , return_rvalue_from_python + ptr + , return_pointer_from_python + , typename mpl::select_type< + ref + , return_reference_from_python + , return_rvalue_from_python + >::type >::type - >::type type; + >::type type; }; } @@ -120,6 +135,14 @@ namespace detail (pointer_result_from_python)(obj, registered_pointee::converters) ); } + + template + inline T return_object_manager_from_python::operator()(PyObject* obj) const + { + return T( + extract_object_manager::execute(obj) + ); + } } }}} // namespace boost::python::converter diff --git a/include/boost/python/detail/construct.hpp b/include/boost/python/detail/construct.hpp new file mode 100644 index 00000000..55c0873f --- /dev/null +++ b/include/boost/python/detail/construct.hpp @@ -0,0 +1,37 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CONSTRUCT_REFERENCE_DWA2002716_HPP +# define CONSTRUCT_REFERENCE_DWA2002716_HPP + +namespace boost { namespace python { namespace detail { + +template +void construct_pointee(void* storage, Arg& x, T const volatile*) +{ + new (storage) T(x); +} + +template +void construct_referent_impl(void* storage, Arg& x, T&(*)()) +{ + construct_pointee(storage, x, (T*)0); +} + +template +void construct_referent(void* storage, Arg const& x, T(*tag)() = 0) +{ + construct_referent_impl(storage, x, tag); +} + +template +void construct_referent(void* storage, Arg& x, T(*tag)() = 0) +{ + construct_referent_impl(storage, x, tag); +} + +}}} // namespace boost::python::detail + +#endif // CONSTRUCT_REFERENCE_DWA2002716_HPP diff --git a/include/boost/python/detail/raw_pyobject.hpp b/include/boost/python/detail/raw_pyobject.hpp index 5d87da56..e9d36901 100644 --- a/include/boost/python/detail/raw_pyobject.hpp +++ b/include/boost/python/detail/raw_pyobject.hpp @@ -16,7 +16,7 @@ namespace boost { namespace python { namespace detail { // friendship to all the appropriate parties. // -// New references are checked for null +// New references are normally checked for null struct new_reference_t; typedef new_reference_t* new_reference; @@ -24,6 +24,10 @@ typedef new_reference_t* new_reference; struct borrowed_reference_t; typedef borrowed_reference_t* borrowed_reference; +// New references which aren't checked for null +struct new_non_null_reference_t; +typedef new_non_null_reference_t* new_non_null_reference; + }}} // namespace boost::python::detail #endif // RAW_PYOBJECT_DWA2002628_HPP diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp index b7948b04..63ee469b 100644 --- a/include/boost/python/list.hpp +++ b/include/boost/python/list.hpp @@ -7,8 +7,7 @@ # define LIST_DWA2002627_HPP # include -# include -# include +# include namespace boost { namespace python { @@ -95,81 +94,24 @@ class list : public object } public: // implementation detail -- for internal use only - inline explicit list(detail::borrowed_reference); - inline explicit list(detail::new_reference); + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list) private: - static BOOST_PYTHON_DECL detail::new_reference call(object const&); + static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&); }; // // Converter Specializations // -template struct arg_from_python; - -template <> -struct arg_from_python - : converter::pytype_wrapper_value_arg_from_python -{ - typedef converter::pytype_wrapper_value_arg_from_python base; - typedef list result_type; - - arg_from_python(PyObject* p) : base(p) {} -}; - -template <> -struct arg_from_python - : arg_from_python -{ - arg_from_python(PyObject* p) - : arg_from_python(p) {} -}; - -template <> -struct arg_from_python - : converter::pytype_wrapper_ref_arg_from_python -{ - typedef converter::pytype_wrapper_ref_arg_from_python base; - typedef list result_type; - - arg_from_python(PyObject* p) - : base(p) {} -}; - namespace converter { - template struct is_object_manager; - template <> - struct is_object_manager + struct extract_object_manager + : pytype_extract_object_manager<&PyList_Type,list> { - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template struct return_from_python; - template <> - struct return_from_python - { - typedef list result_type; - - result_type operator()(PyObject* x) const - { - return list((pytype_result_from_python)(&PyList_Type, x)); - } }; } -// -// list implementation -// -inline list::list(detail::borrowed_reference p) - : object(p) -{} - -inline list::list(detail::new_reference p) - : object(p) -{} - }} // namespace boost::python #endif // LIST_DWA2002627_HPP diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp index 1b47728e..0f1fcdf6 100644 --- a/include/boost/python/long.hpp +++ b/include/boost/python/long.hpp @@ -7,8 +7,7 @@ # define LONG_DWA2002627_HPP # include -# include -# include +# include namespace boost { namespace python { @@ -32,82 +31,25 @@ class long_ : public object { } public: // implementation detail -- for internal use only - explicit inline long_(detail::borrowed_reference); - explicit inline long_(detail::new_reference); + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_) private: - static BOOST_PYTHON_DECL detail::new_reference call(object const&); - static BOOST_PYTHON_DECL detail::new_reference call(object const&, object const&); + static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&); + static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&, object const&); }; // // Converter Specializations // -template struct arg_from_python; - -template <> -struct arg_from_python - : converter::pytype_wrapper_value_arg_from_python -{ - typedef converter::pytype_wrapper_value_arg_from_python base; - typedef long_ result_type; - - arg_from_python(PyObject* p) : base(p) {} -}; - -template <> -struct arg_from_python - : arg_from_python -{ - arg_from_python(PyObject* p) - : arg_from_python(p) {} -}; - -template <> -struct arg_from_python - : converter::pytype_wrapper_ref_arg_from_python -{ - typedef converter::pytype_wrapper_ref_arg_from_python base; - typedef long_ result_type; - - arg_from_python(PyObject* p) - : base(p) {} -}; - namespace converter { - template struct is_object_manager; - template <> - struct is_object_manager + struct extract_object_manager + : pytype_extract_object_manager<&PyLong_Type,long_> { - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template struct return_from_python; - template <> - struct return_from_python - { - typedef long_ result_type; - - result_type operator()(PyObject* x) const - { - return long_((pytype_result_from_python)(&PyLong_Type, x)); - } }; } -// -// long_ implementation -// -inline long_::long_(detail::borrowed_reference p) - : object(p) -{} - -inline long_::long_(detail::new_reference p) - : object(p) -{} - }} // namespace boost::python #endif // LONG_DWA2002627_HPP diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 7684e044..965e966e 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -14,6 +14,7 @@ # include # include # include +# include # include # include @@ -227,8 +228,18 @@ namespace api public: // implementation detail -- for internal use only explicit object(detail::borrowed_reference); explicit object(detail::new_reference); + explicit object(detail::new_non_null_reference); }; + // Derived classes will usually want these as an implementation detail +# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived) \ + inline explicit derived(python::detail::borrowed_reference p) \ + : object(p) {} \ + inline explicit derived(python::detail::new_reference p) \ + : object(p) {} \ + inline explicit derived(python::detail::new_non_null_reference p) \ + : object(p) {} + // // object_initializer -- get the handle to construct the object with, // based on whether T is a proxy or derived from object @@ -266,53 +277,13 @@ using api::object; // // Converter Specializations // -template struct arg_from_python; - -template <> -struct arg_from_python -{ - typedef object result_type; - - arg_from_python(PyObject*); - bool convertible() const; - object operator()(PyObject* x) const; -}; - -template <> -struct arg_from_python - : arg_from_python -{ - arg_from_python(PyObject*); -}; - -template <> -struct arg_from_python -{ - typedef object& result_type; - - arg_from_python(PyObject*); - bool convertible() const; - object& operator()(PyObject* x) const; - private: - mutable object m_result; -}; - namespace converter { - template struct is_object_manager; - template <> - struct is_object_manager + struct extract_object_manager + : always_extract_object_manager { - BOOST_STATIC_CONSTANT(bool, value = true); - }; - - template struct return_from_python; - template <> - struct return_from_python - { - typedef object result_type; - result_type operator()(PyObject* x) const; + static python::detail::borrowed_reference execute(PyObject* x); }; } @@ -345,7 +316,6 @@ inline api::object_base& api::object_base::operator=(api::object_base const& rhs return *this; } - inline api::object_base::~object_base() { Py_DECREF(m_ptr); @@ -360,6 +330,10 @@ inline object::object(detail::new_reference p) : object_base(expect_non_null((PyObject*)p)) {} +inline object::object(detail::new_non_null_reference p) + : object_base((PyObject*)p) +{} + inline PyObject* api::object_base::ptr() const { return m_ptr; @@ -368,45 +342,14 @@ inline PyObject* api::object_base::ptr() const // // Converter specialization implementations // -inline arg_from_python::arg_from_python(PyObject*) -{} - -inline bool arg_from_python::convertible() const -{ - return true; -} - -inline object arg_from_python::operator()(PyObject* x) const -{ - return object(detail::borrowed_reference(x)); -} - -inline arg_from_python::arg_from_python(PyObject*) - : arg_from_python(0) -{} - -inline arg_from_python::arg_from_python(PyObject* x) - : m_result(detail::borrowed_reference(x)) -{} - -inline bool arg_from_python::convertible() const -{ - return true; -} - -inline object& arg_from_python::operator()(PyObject* x) const -{ - return m_result; -} - namespace converter { - inline object - return_from_python::operator()(PyObject* x) const + inline python::detail::borrowed_reference + extract_object_manager::execute(PyObject* x) { - return object(python::detail::new_reference(x)); + return python::detail::borrowed_reference(python::incref(x)); } - + inline PyObject* get_managed_object(object const& x) { return x.ptr(); diff --git a/src/list.cpp b/src/list.cpp index ed7e675f..484ae121 100644 --- a/src/list.cpp +++ b/src/list.cpp @@ -7,11 +7,13 @@ namespace boost { namespace python { -BOOST_PYTHON_DECL detail::new_reference list::call(object const& arg) +BOOST_PYTHON_DECL detail::new_non_null_reference list::call(object const& arg) { - return (detail::new_reference)PyObject_CallFunction( - (PyObject*)&PyList_Type, "(O)", - arg.ptr()); + return (detail::new_non_null_reference) + (expect_non_null)( + PyObject_CallFunction( + (PyObject*)&PyList_Type, "(O)", + arg.ptr())); } BOOST_PYTHON_DECL list::list() diff --git a/src/long.cpp b/src/long.cpp index 46d3d7c5..43d4526d 100644 --- a/src/long.cpp +++ b/src/long.cpp @@ -7,16 +7,16 @@ namespace boost { namespace python { -BOOST_PYTHON_DECL detail::new_reference long_::call(object const& arg) +BOOST_PYTHON_DECL detail::new_non_null_reference long_::call(object const& arg) { - return (detail::new_reference)PyObject_CallFunction( + return (detail::new_non_null_reference)PyObject_CallFunction( (PyObject*)&PyLong_Type, "(O)", arg.ptr()); } -BOOST_PYTHON_DECL detail::new_reference long_::call(object const& arg, object const& base) +BOOST_PYTHON_DECL detail::new_non_null_reference long_::call(object const& arg, object const& base) { - return (detail::new_reference)PyObject_CallFunction( + return (detail::new_non_null_reference)PyObject_CallFunction( (PyObject*)&PyLong_Type, "(OO)", arg.ptr(), base.ptr()); } From 61ba4cd1ce3d73d661b4b1c6c2fd454e1f3540ef Mon Sep 17 00:00:00 2001 From: David Hawkes Date: Wed, 17 Jul 2002 06:51:08 +0000 Subject: [PATCH 0592/1042] Sub-module / sub-class and API changes [SVN r14488] --- Jamfile | 1 + include/boost/python/class.hpp | 38 +- include/boost/python/detail/module_base.hpp | 16 + include/boost/python/detail/module_info.hpp | 51 + include/boost/python/detail/module_init.hpp | 18 +- include/boost/python/module.hpp | 27 +- include/boost/python/object/class.hpp | 5 + include/boost/python/object_core.hpp | 1 - include/boost/python/py_interface.hpp | 700 ++++++++++++ src/gen_py_api.py | 776 +++++++++++++ src/module.cpp | 139 ++- src/object/class.cpp | 117 +- src/py_interface.cpp | 1103 +++++++++++++++++++ test/Jamfile | 1 + test/submod_subclass_api.cpp | 231 ++++ 15 files changed, 3204 insertions(+), 20 deletions(-) create mode 100644 include/boost/python/detail/module_info.hpp create mode 100644 include/boost/python/py_interface.hpp create mode 100644 src/gen_py_api.py create mode 100644 src/py_interface.cpp create mode 100644 test/submod_subclass_api.cpp diff --git a/Jamfile b/Jamfile index 192982f6..503db998 100644 --- a/Jamfile +++ b/Jamfile @@ -23,6 +23,7 @@ dll bpl src/object/function.cpp src/object/inheritance.cpp src/object/life_support.cpp + src/py_interface.cpp src/errors.cpp src/module.cpp src/objects2.cpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 861d8e72..d2a4a2f0 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -14,6 +14,7 @@ # include # include # include +# include # include # include # include @@ -86,12 +87,12 @@ 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_(); + class_(base const& parent_class = empty_class_base()); // Construct with the class name. [ Would have used a default // argument but gcc-2.95.2 choked on typeid(T).name() as a default // parameter value] - class_(char const* name); + class_(char const* name, base const& parent_class = empty_class_base()); // Wrap a member function or a non-member function which can take @@ -195,6 +196,22 @@ class class_ : public objects::class_base self& setattr(char const* name, handle<> const&); + // add to module + self& add(module &m) + { + // redundant + // m.add(*this); + return *this; + } + + // add to current module + self& add() + { + // redundant + // boost::python::add(*this); + return *this; + } + private: // types typedef objects::class_id class_id; @@ -231,7 +248,7 @@ class class_ : public objects::class_base // implementations // template -inline class_::class_() +inline class_::class_(base const& parent_class) : base(typeid(T).name(), id_vector::size, id_vector().ids) { // register converters @@ -241,10 +258,16 @@ inline class_::class_() mpl::bool_t() , objects::select_holder((held_type*)0).get() , this->object()); + + // get the context to add the class to + handle<> parent(parent_class.object() ? handle<>(parent_class.object()) : + base::get_class_context_object(typeid(T).name(), object())); + // add the class to the current module + boost::python::detail::module_base::add(object(), parent); } template -inline class_::class_(char const* name) +inline class_::class_(char const* name, base const& parent_class) : base(name, id_vector::size, id_vector().ids) { // register converters @@ -254,8 +277,13 @@ inline class_::class_(char const* name) mpl::bool_t() , objects::select_holder((held_type*)0).get() , this->object()); -} + // get the context to add the class to + handle<> parent(parent_class.object() ? handle<>(parent_class.object()) : + base::get_class_context_object(name, object())); + // add the class to the current module + boost::python::detail::module_base::add(object(), parent); +} template inline class_& class_::add_property(char const* name, handle<> const& fget) diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp index aaa6a135..71044c96 100644 --- a/include/boost/python/detail/module_base.hpp +++ b/include/boost/python/detail/module_base.hpp @@ -10,6 +10,8 @@ namespace boost { namespace python { namespace detail { +class module_info; + class BOOST_PYTHON_DECL module_base { public: @@ -21,14 +23,22 @@ class BOOST_PYTHON_DECL module_base void setattr(const char* name, PyObject*); void setattr(const char* name, handle<> const&); void add(type_handle const&); // just use the type's name + static module_info* get_module_info(); + static void set_module_info(module_info& mi); + static handle<> get_prior_module(); + static void set_prior_module(handle<> const& m); + static void add(type_handle const& class_obj, handle<> const& context); // Return a reference to the Python module object being built inline handle<> object() const; protected: + module_base(handle<> const &m) : m_module(m) {} void add_class(type_handle const& class_obj); + void add_class(type_handle const& class_obj, handle<> const& context); private: + static module_info*& get_module_info_ref(); handle<> m_module; static PyMethodDef initial_methods[1]; }; @@ -41,6 +51,12 @@ inline handle<> module_base::object() const return m_module; } +inline void module_base::add(type_handle const& class_obj, handle<> const& context) +{ + module_base mb(get_prior_module()); + mb.add_class(class_obj, context); +} + }}} // namespace boost::python::detail #endif // MODULE_BASE_DWA2002227_HPP diff --git a/include/boost/python/detail/module_info.hpp b/include/boost/python/detail/module_info.hpp new file mode 100644 index 00000000..ba3f91cc --- /dev/null +++ b/include/boost/python/detail/module_info.hpp @@ -0,0 +1,51 @@ +// Copyright David Hawkes 2002. +// Permission is hereby granted to copy, use and modify this software +// for any purpose, including commercial distribution, provided this +// copyright notice is not removed. No warranty WHATSOEVER is provided with this +// software. Any user(s) accepts this software "as is" and as such they will not +// bind the author(s) to any claim of suitabilty for any purpose. + +#ifndef MODULE_INFO +# define MODULE_INFO + +#include + +namespace boost { namespace python { namespace detail { + +class module_info +{ +public: + module_info(const char *name) + { + m_module_name = name; + } + void set_module(object const& m) + { + if(!m_primary_module) + m_primary_module = m; + } + object const& get_module() const + { + return m_primary_module; + } + void set_prior_module(object const& m) + { + m_prior_module = m; + } + object const& get_prior_module() const + { + return m_prior_module; + } + const char* get_module_name() const + { + return m_module_name; + } +private: + object m_primary_module; + object m_prior_module; + const char* m_module_name; +}; + +}}} + +#endif // MODULE_INFO diff --git a/include/boost/python/detail/module_init.hpp b/include/boost/python/detail/module_init.hpp index 5b5ce9f5..79a55119 100644 --- a/include/boost/python/detail/module_init.hpp +++ b/include/boost/python/detail/module_init.hpp @@ -8,13 +8,23 @@ # ifndef BOOST_PYTHON_MODULE_INIT +# define PRE_INIT_FUNC(name) \ +void init_module_base_##name() \ +{ \ + boost::python::detail::module_info mi(#name); \ + boost::python::detail::module_base::set_module_info(mi); \ + boost::python::module(); \ + init_module_##name(); \ +} + # if defined(_WIN32) || defined(__CYGWIN__) # define BOOST_PYTHON_MODULE_INIT(name) \ void init_module_##name(); \ +PRE_INIT_FUNC(name) \ extern "C" __declspec(dllexport) void init##name() \ { \ - boost::python::handle_exception(&init_module_##name); \ + boost::python::handle_exception(&init_module_base_##name); \ } \ void init_module_##name() @@ -22,13 +32,14 @@ void init_module_##name() # include # define BOOST_PYTHON_MODULE_INIT(name) \ +PRE_INIT_FUNC(name) \ void init_module_##name(); \ extern "C" \ { \ extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \ void init##name() \ { \ - boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_##name); \ + boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_base_##name); \ } \ } \ void init_module_##name() @@ -36,10 +47,11 @@ void init_module_##name() # else # define BOOST_PYTHON_MODULE_INIT(name) \ +PRE_INIT_FUNC(name) \ void init_module_##name(); \ extern "C" void init##name() \ { \ - boost::python::handle_exception(&init_module_##name); \ + boost::python::handle_exception(&init_module_base_##name); \ } \ void init_module_##name() diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 8ee63485..d32e0935 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -13,6 +13,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -21,7 +22,7 @@ class module : public detail::module_base public: typedef detail::module_base base; - module(const char* name) + module(const char* name = "") : base(name) {} // Add elements to the module @@ -33,7 +34,8 @@ class module : public detail::module_base template module& add(class_ const& c) { - this->add_class(c.object()); + // redundant + // this->add_class(c.object()); return *this; } @@ -51,6 +53,14 @@ class module : public detail::module_base this->setattr(name, boost::python::make_function(fn, handler)); return *this; } + + static module get_prior_module() + { + return module(module_base::get_prior_module()); + } + + private: + module(handle<> const& m) : base(m) {} }; // @@ -80,6 +90,19 @@ inline module& module::add(PyTypeObject* x) return *this; } +template +inline void def(char const* name, Fn fn) +{ + module::get_prior_module().def(name, fn); +} + + +template +inline void def(char const* name, Fn fn, ResultHandler handler) +{ + module::get_prior_module().def(name, fn, handler); +} + }} // namespace boost::python #endif // MODULE_DWA20011221_HPP diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 8cf29b23..8e4cf586 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -39,7 +39,12 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable void add_property(char const* name, handle<> const& fget); void add_property(char const* name, handle<> const& fget, handle<> const& fset); void setattr(char const* name, handle<> const&); + static handle<> get_class_context_object(const char* name, type_handle const& class_obj); + protected: + static class_base const& empty_class_base(); private: + // construct an empty base class + class_base(); type_handle m_object; }; diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 965e966e..4ac0dcea 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -325,7 +325,6 @@ inline object::object(detail::borrowed_reference p) : object_base(python::incref((PyObject*)p)) {} - inline object::object(detail::new_reference p) : object_base(expect_non_null((PyObject*)p)) {} diff --git a/include/boost/python/py_interface.hpp b/include/boost/python/py_interface.hpp new file mode 100644 index 00000000..c1416d5c --- /dev/null +++ b/include/boost/python/py_interface.hpp @@ -0,0 +1,700 @@ +// Automatically generated from py_api_gen.py +#ifndef PY_INTERFACE_HPP +#define PY_INTERFACE_HPP + +#include +#include + +namespace boost { namespace python { namespace api { + +enum call_dict_usage { use_new_dict, use_local_dict, use_global_dict }; + +namespace api_detail { + +BOOST_PYTHON_DECL object get_func(const char* name); +BOOST_PYTHON_DECL object call_statement(const char *stmt, int n, ...); +BOOST_PYTHON_DECL object call_statement_du(const char *stmt, call_dict_usage cdu, int n, ...); + +template +struct get_arg +{ + get_arg(A const &a) : h(a) {} + object h; + operator object const& () { return h; } + operator object const* () { return &h; } +}; + +template<> +struct get_arg +{ + get_arg(object const &a) : h(a) {} + object const &h; + operator object const& () { return h; } + operator object const* () { return &h; } +}; + +template<> +struct get_arg +{ + get_arg(PyObject* a) : h((python::detail::borrowed_reference)a) {} + object h; + operator object const& () { return h; } + operator object const* () { return &h; } +}; + +} + +BOOST_PYTHON_DECL object locals(); + + +template +object abs(A0 const& a0) +{ + return api_detail::get_func("abs")(api_detail::get_arg(a0)); +} +BOOST_PYTHON_DECL object abs(object const& a0); +BOOST_PYTHON_DECL object abs(short a0); +BOOST_PYTHON_DECL object abs(int a0); +BOOST_PYTHON_DECL object abs(long a0); +BOOST_PYTHON_DECL object abs(double const & a0); +BOOST_PYTHON_DECL object apply(object const& a0, object const& a1); +BOOST_PYTHON_DECL object apply(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL bool callable(object const& a0); +template +object chr(A0 const& a0) +{ + return api_detail::get_func("chr")(api_detail::get_arg(a0)); +} +BOOST_PYTHON_DECL object chr(object const& a0); +BOOST_PYTHON_DECL object chr(short a0); +BOOST_PYTHON_DECL object chr(int a0); +BOOST_PYTHON_DECL object chr(long a0); +template +int cmp(A0 const& a0, A1 const& a1) +{ + int rslt; + int r = ::PyObject_Cmp(api_detail::get_arg(a0), api_detail::get_arg(a1), &rslt); + if(r == -1) + throw_error_already_set(); + return rslt; +} +BOOST_PYTHON_DECL int cmp(object const& a0, object const& a1); +BOOST_PYTHON_DECL object coerce(object const& a0, object const& a1); +BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2); +BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2, object const& a3); +BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2, int a3); +BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); +BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2, int a3, int a4); +template +object complex(A0 const& a0) +{ + return api_detail::get_func("complex")(api_detail::get_arg(a0)); +} +BOOST_PYTHON_DECL object complex(object const& a0); +BOOST_PYTHON_DECL object complex(double const& a0); +template +object complex(A0 const& a0, A1 const& a1) +{ + return api_detail::get_func("complex")(api_detail::get_arg(a0), api_detail::get_arg(a1)); +} +BOOST_PYTHON_DECL object complex(object const& a0, object const& a1); +BOOST_PYTHON_DECL object complex(double const& a0, double const& a1); +BOOST_PYTHON_DECL object dict(); +BOOST_PYTHON_DECL object dict(object const& a0); +BOOST_PYTHON_DECL object dir(); +BOOST_PYTHON_DECL object dir(object const& a0); +template +object divmod(A0 const& a0, A1 const& a1) +{ + return api_detail::get_func("divmod")(api_detail::get_arg(a0), api_detail::get_arg(a1)); +} +BOOST_PYTHON_DECL object divmod(object const& a0, object const& a1); +BOOST_PYTHON_DECL object divmod(int a0, int a1); +BOOST_PYTHON_DECL object divmod(long a0, long a1); +BOOST_PYTHON_DECL object divmod(double const& a0, double const& a1); +BOOST_PYTHON_DECL object eval(const char* a0); +BOOST_PYTHON_DECL object eval(const char* a0, object const& a2); +BOOST_PYTHON_DECL object eval(const char* a0, object const& a2, object const& a3); +BOOST_PYTHON_DECL object exec(const char* a0); +BOOST_PYTHON_DECL object exec(const char* a0, object const& a2); +BOOST_PYTHON_DECL object exec(const char* a0, object const& a2, object const& a3); +BOOST_PYTHON_DECL object execfile(object const& a0); +BOOST_PYTHON_DECL object execfile(object const& a0, object const& a1); +BOOST_PYTHON_DECL object execfile(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object file(object const& a0); +BOOST_PYTHON_DECL object file(const char* a0); +BOOST_PYTHON_DECL object file(object const& a0, object const& a1); +BOOST_PYTHON_DECL object file(const char* a0, const char* a1); +BOOST_PYTHON_DECL object file(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object file(const char* a0, const char* a1, int a2); +BOOST_PYTHON_DECL object filter(object const& a0, object const& a1); +BOOST_PYTHON_DECL object float_(object const& a0); +BOOST_PYTHON_DECL object float_(const char* a0); +BOOST_PYTHON_DECL object float_(double const& a0); +BOOST_PYTHON_DECL object getattr(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object getattr(object const& a0, const char * a1, object const& a2); +BOOST_PYTHON_DECL object globals(); +BOOST_PYTHON_DECL bool hasattr(object const& a0, object const& a1); +BOOST_PYTHON_DECL bool hasattr(object const& a0, const char* a1); +BOOST_PYTHON_DECL long hash(object const& a0); +template +object hex(A0 const& a0) +{ + return api_detail::get_func("hex")(api_detail::get_arg(a0)); +} +BOOST_PYTHON_DECL object hex(object const& a0); +BOOST_PYTHON_DECL object hex(char a0); +BOOST_PYTHON_DECL object hex(short a0); +BOOST_PYTHON_DECL object hex(int a0); +BOOST_PYTHON_DECL object hex(long a0); +BOOST_PYTHON_DECL long id(object const& a0); +BOOST_PYTHON_DECL object input(); +BOOST_PYTHON_DECL object input(object const& a0); +BOOST_PYTHON_DECL object input(const char* a0); +BOOST_PYTHON_DECL object int_(object const& a0); +BOOST_PYTHON_DECL object int_(long a0); +BOOST_PYTHON_DECL object int_(const char* a0); +BOOST_PYTHON_DECL object intern(object const& a0); +BOOST_PYTHON_DECL object intern(const char* a0); +BOOST_PYTHON_DECL bool isinstance(object const& a0, object const& a1); +BOOST_PYTHON_DECL bool issubclass(object const& a0, object const& a1); +BOOST_PYTHON_DECL object iter(object const& a0); +BOOST_PYTHON_DECL object iter(object const& a0, object const& a1); +BOOST_PYTHON_DECL long len(object const& a0); +BOOST_PYTHON_DECL object list(); +BOOST_PYTHON_DECL object list(object const& a0); +BOOST_PYTHON_DECL object long_(object const& a0); +BOOST_PYTHON_DECL object long_(long a0); +BOOST_PYTHON_DECL object long_(const char* a0); +BOOST_PYTHON_DECL object map(object const& a0); +BOOST_PYTHON_DECL object map(object const& a0, object const& a1); +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3); +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); +template +object max(A0 const& a0) +{ + return api_detail::get_func("max")(api_detail::get_arg(a0)); +} +template +object max(A0 const& a0, A1 const& a1) +{ + return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1)); +} +template +object max(A0 const& a0, A1 const& a1, A2 const& a2) +{ + return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2)); +} +template +object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3) +{ + return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3)); +} +template +object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) +{ + return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4)); +} +template +object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) +{ + return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5)); +} +template +object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) +{ + return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6)); +} +template +object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) +{ + return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7)); +} +template +object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) +{ + return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7), api_detail::get_arg(a8)); +} +template +object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) +{ + return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7), api_detail::get_arg(a8), api_detail::get_arg(a9)); +} +BOOST_PYTHON_DECL object max(object const& a0); +BOOST_PYTHON_DECL object max(object const& a0, object const& a1); +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3); +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); +template +object min(A0 const& a0) +{ + return api_detail::get_func("min")(api_detail::get_arg(a0)); +} +template +object min(A0 const& a0, A1 const& a1) +{ + return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1)); +} +template +object min(A0 const& a0, A1 const& a1, A2 const& a2) +{ + return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2)); +} +template +object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3) +{ + return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3)); +} +template +object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) +{ + return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4)); +} +template +object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) +{ + return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5)); +} +template +object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) +{ + return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6)); +} +template +object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) +{ + return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7)); +} +template +object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) +{ + return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7), api_detail::get_arg(a8)); +} +template +object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) +{ + return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7), api_detail::get_arg(a8), api_detail::get_arg(a9)); +} +BOOST_PYTHON_DECL object min(object const& a0); +BOOST_PYTHON_DECL object min(object const& a0, object const& a1); +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3); +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); +template +object oct(A0 const& a0) +{ + return api_detail::get_func("oct")(api_detail::get_arg(a0)); +} +BOOST_PYTHON_DECL object oct(object const& a0); +BOOST_PYTHON_DECL object oct(char a0); +BOOST_PYTHON_DECL object oct(short a0); +BOOST_PYTHON_DECL object oct(int a0); +BOOST_PYTHON_DECL object oct(long a0); +BOOST_PYTHON_DECL object open(object const& a0); +BOOST_PYTHON_DECL object open(const char* a0); +BOOST_PYTHON_DECL object open(object const& a0, object const& a1); +BOOST_PYTHON_DECL object open(const char* a0, const char* a1); +BOOST_PYTHON_DECL object open(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object open(const char* a0, const char* a1, int a2); +BOOST_PYTHON_DECL long ord(object const& a0); +BOOST_PYTHON_DECL long ord(const char* a0); +template +object pow(A0 const& a0, A1 const& a1) +{ + return api_detail::get_func("pow")(api_detail::get_arg(a0), api_detail::get_arg(a1)); +} +BOOST_PYTHON_DECL object pow(object const& a0, object const& a1); +BOOST_PYTHON_DECL object pow(double const& a0, double const& a1); +BOOST_PYTHON_DECL object pow(double const& a0, double const& a1, double const& a2); +template +object print(A0 const& a0) +{ + return api_detail::call_statement_du("print _1", use_new_dict, 1, (object const*)api_detail::get_arg(a0)); +} +template +object print(A0 const& a0, A1 const& a1) +{ + return api_detail::call_statement_du("print _1, _2", use_new_dict, 2, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1)); +} +template +object print(A0 const& a0, A1 const& a1, A2 const& a2) +{ + return api_detail::call_statement_du("print _1, _2, _3", use_new_dict, 3, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2)); +} +template +object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3) +{ + return api_detail::call_statement_du("print _1, _2, _3, _4", use_new_dict, 4, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3)); +} +template +object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) +{ + return api_detail::call_statement_du("print _1, _2, _3, _4, _5", use_new_dict, 5, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4)); +} +template +object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) +{ + return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6", use_new_dict, 6, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5)); +} +template +object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) +{ + return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7", use_new_dict, 7, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6)); +} +template +object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) +{ + return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8", use_new_dict, 8, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7)); +} +template +object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) +{ + return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8, _9", use_new_dict, 9, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8)); +} +template +object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) +{ + return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8, _9, _10", use_new_dict, 10, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9)); +} +BOOST_PYTHON_DECL object print(object const& a0); +BOOST_PYTHON_DECL object print(object const& a0, object const& a1); +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3); +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); +template +object print_file(object const& a0, A1 const& a1) +{ + return api_detail::call_statement_du("print >>_1, _2", use_new_dict, 2, a0, (object const*)api_detail::get_arg(a1)); +} +template +object print_file(object const& a0, A1 const& a1, A2 const& a2) +{ + return api_detail::call_statement_du("print >>_1, _2, _3", use_new_dict, 3, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2)); +} +template +object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3) +{ + return api_detail::call_statement_du("print >>_1, _2, _3, _4", use_new_dict, 4, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3)); +} +template +object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) +{ + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5", use_new_dict, 5, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4)); +} +template +object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) +{ + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6", use_new_dict, 6, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5)); +} +template +object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) +{ + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7", use_new_dict, 7, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6)); +} +template +object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) +{ + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8", use_new_dict, 8, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7)); +} +template +object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) +{ + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9", use_new_dict, 9, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8)); +} +template +object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) +{ + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9, _10", use_new_dict, 10, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9)); +} +template +object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9, A10 const& a10) +{ + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11", use_new_dict, 11, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9), (object const*)api_detail::get_arg(a10)); +} +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1); +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3); +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10); +template +object range(A0 const& a0) +{ + return api_detail::get_func("range")(api_detail::get_arg(a0)); +} +BOOST_PYTHON_DECL object range(object const& a0); +BOOST_PYTHON_DECL object range(int a0); +template +object range(A0 const& a0, A1 const& a1) +{ + return api_detail::get_func("range")(api_detail::get_arg(a0), api_detail::get_arg(a1)); +} +BOOST_PYTHON_DECL object range(object const& a0, object const& a1); +BOOST_PYTHON_DECL object range(int a0, int a1); +template +object range(A0 const& a0, A1 const& a1, A2 const& a2) +{ + return api_detail::get_func("range")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2)); +} +BOOST_PYTHON_DECL object range(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object range(int a0, int a1, int a2); +BOOST_PYTHON_DECL object raw_input(); +BOOST_PYTHON_DECL object raw_input(object const& a0); +BOOST_PYTHON_DECL object raw_input(const char* a0); +BOOST_PYTHON_DECL object reduce(object const& a0, object const& a1); +BOOST_PYTHON_DECL object reduce(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object reload(object const& a0); +BOOST_PYTHON_DECL object repr(object const& a0); +template +object round(A0 const& a0) +{ + return api_detail::get_func("round")(api_detail::get_arg(a0)); +} +BOOST_PYTHON_DECL object round(object const& a0); +BOOST_PYTHON_DECL object round(double const& a0); +template +object round(A0 const& a0, A1 const& a1) +{ + return api_detail::get_func("round")(api_detail::get_arg(a0), api_detail::get_arg(a1)); +} +BOOST_PYTHON_DECL object round(object const& a0, object const& a1); +BOOST_PYTHON_DECL object round(double const& a0, double const& a1); +template +object slice(A0 const& a0) +{ + return api_detail::get_func("slice")(api_detail::get_arg(a0)); +} +BOOST_PYTHON_DECL object slice(object const& a0); +BOOST_PYTHON_DECL object slice(int a0); +template +object slice(A0 const& a0, A1 const& a1) +{ + return api_detail::get_func("slice")(api_detail::get_arg(a0), api_detail::get_arg(a1)); +} +BOOST_PYTHON_DECL object slice(object const& a0, object const& a1); +BOOST_PYTHON_DECL object slice(int a0, int a1); +template +object slice(A0 const& a0, A1 const& a1, A2 const& a2) +{ + return api_detail::get_func("slice")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2)); +} +BOOST_PYTHON_DECL object slice(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object slice(int a0, int a1, int a2); +BOOST_PYTHON_DECL object str(object const& a0); +BOOST_PYTHON_DECL object tuple(); +BOOST_PYTHON_DECL object tuple(object const& a0); +BOOST_PYTHON_DECL object type_(object const& a0); +template +object unichr(A0 const& a0) +{ + return api_detail::get_func("unichr")(api_detail::get_arg(a0)); +} +BOOST_PYTHON_DECL object unichr(object const& a0); +BOOST_PYTHON_DECL object unichr(short a0); +BOOST_PYTHON_DECL object unichr(int a0); +BOOST_PYTHON_DECL object unichr(long a0); +BOOST_PYTHON_DECL object unicode(object const& a0); +BOOST_PYTHON_DECL object unicode(object const& a0, object const& a1); +BOOST_PYTHON_DECL object unicode(object const& a0, const char* a1); +BOOST_PYTHON_DECL object unicode(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object unicode(object const& a0, const char* a1, const char* a2); +BOOST_PYTHON_DECL object vars(); +BOOST_PYTHON_DECL object vars(object const& a0); +template +object xrange(A0 const& a0) +{ + return api_detail::get_func("xrange")(api_detail::get_arg(a0)); +} +BOOST_PYTHON_DECL object xrange(object const& a0); +BOOST_PYTHON_DECL object xrange(int a0); +template +object xrange(A0 const& a0, A1 const& a1) +{ + return api_detail::get_func("xrange")(api_detail::get_arg(a0), api_detail::get_arg(a1)); +} +BOOST_PYTHON_DECL object xrange(object const& a0, object const& a1); +BOOST_PYTHON_DECL object xrange(int a0, int a1); +template +object xrange(A0 const& a0, A1 const& a1, A2 const& a2) +{ + return api_detail::get_func("xrange")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2)); +} +BOOST_PYTHON_DECL object xrange(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object xrange(int a0, int a1, int a2); +BOOST_PYTHON_DECL object zip(object const& a0); +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1); +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3); +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); +BOOST_PYTHON_DECL object compile_string(const char* a0, const char* a1, int a2); +BOOST_PYTHON_DECL int import_append_inittab(const char* a0, void(*a1)(void)); +BOOST_PYTHON_DECL object import_add_module(const char* a0); +BOOST_PYTHON_DECL object import_get_module_dict(); +BOOST_PYTHON_DECL object import_import(object const& a0); +BOOST_PYTHON_DECL object import_import(const char* a0); +BOOST_PYTHON_DECL object import_import_module(const char* a0); +BOOST_PYTHON_DECL object import_import_module_ex(const char* a0, object const& a1, object const& a2, object const& a3); +BOOST_PYTHON_DECL object module_get_dict(object const& a0); +BOOST_PYTHON_DECL int object_print(object const& a0, FILE* a1, int a2); +BOOST_PYTHON_DECL object run_file(FILE* a0, const char* a1, int a2, object const& a3, object const& a4); +BOOST_PYTHON_DECL int run_simple_file(FILE* a0, const char* a1); +BOOST_PYTHON_DECL int run_simple_string(const char* a0); +BOOST_PYTHON_DECL object run_string(const char* a0, int a1, object const& a2, object const& a3); +BOOST_PYTHON_DECL object call_statement(const char* a0); +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1); +template +object call_statement(const char* a0, A1 const& a1) +{ + return api_detail::call_statement(a0, 1, (object const*)api_detail::get_arg(a1)); +} +template +object call_statement(const char* a0, A1 const& a1, A2 const& a2) +{ + return api_detail::call_statement(a0, 2, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2)); +} +template +object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3) +{ + return api_detail::call_statement(a0, 3, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3)); +} +template +object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) +{ + return api_detail::call_statement(a0, 4, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4)); +} +template +object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) +{ + return api_detail::call_statement(a0, 5, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5)); +} +template +object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) +{ + return api_detail::call_statement(a0, 6, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6)); +} +template +object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) +{ + return api_detail::call_statement(a0, 7, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7)); +} +template +object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) +{ + return api_detail::call_statement(a0, 8, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8)); +} +template +object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) +{ + return api_detail::call_statement(a0, 9, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9)); +} +template +object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9, A10 const& a10) +{ + return api_detail::call_statement(a0, 10, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9), (object const*)api_detail::get_arg(a10)); +} +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1); +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2); +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3); +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4); +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10); +template +object call_statement(const char* a0, call_dict_usage a1, A2 const& a2) +{ + return api_detail::call_statement_du(a0, a1, 1, (object const*)api_detail::get_arg(a2)); +} +template +object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3) +{ + return api_detail::call_statement_du(a0, a1, 2, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3)); +} +template +object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4) +{ + return api_detail::call_statement_du(a0, a1, 3, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4)); +} +template +object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) +{ + return api_detail::call_statement_du(a0, a1, 4, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5)); +} +template +object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) +{ + return api_detail::call_statement_du(a0, a1, 5, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6)); +} +template +object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) +{ + return api_detail::call_statement_du(a0, a1, 6, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7)); +} +template +object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) +{ + return api_detail::call_statement_du(a0, a1, 7, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8)); +} +template +object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) +{ + return api_detail::call_statement_du(a0, a1, 8, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9)); +} +template +object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9, A10 const& a10) +{ + return api_detail::call_statement_du(a0, a1, 9, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9), (object const*)api_detail::get_arg(a10)); +} +template +object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9, A10 const& a10, A11 const& a11) +{ + return api_detail::call_statement_du(a0, a1, 10, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9), (object const*)api_detail::get_arg(a10), (object const*)api_detail::get_arg(a11)); +} +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2); +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3); +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4); +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5); +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10); +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10, object const& a11); + +}}} + +#endif // PY_INTERFACE_HPP + diff --git a/src/gen_py_api.py b/src/gen_py_api.py new file mode 100644 index 00000000..bc965d8f --- /dev/null +++ b/src/gen_py_api.py @@ -0,0 +1,776 @@ +# Copyright David Hawkes 2002. +# Permission is hereby granted to copy, use and modify this software +# for any purpose, including commercial distribution, provided this +# copyright notice is not removed. No warranty WHATSOEVER is provided with this +# software. Any user(s) accepts this software "as is" and as such they will not +# bind the author(s) to any claim of suitabilty for any purpose. + +# Build python API wrappers for boost python + +import re + +API_List = [ +'PyObject*{new} abs{direct}(int{template})', +'PyObject*{new} abs{direct}(PyObject*)', +'PyObject*{new} abs{direct}(short)', +'PyObject*{new} abs{direct}(int)', +'PyObject*{new} abs{direct}(long)', +'PyObject*{new} abs{direct}(double const &)', +'PyObject*{new,err=NULL} PyObject_CallObject{decl=apply}(PyObject*,PyObject*)', +'PyObject*{new,err=NULL} PyObject_Call{decl=apply}(PyObject*,PyObject*,PyObject*)', +'bool PyCallable_Check{decl=callable}(PyObject*)', +'PyObject*{new} chr{direct}(int{template})', +'PyObject*{new} chr{direct}(PyObject*)', +'PyObject*{new} chr{direct}(short)', +'PyObject*{new} chr{direct}(int)', +'PyObject*{new} chr{direct}(long)', +'int{err=-1} PyObject_Cmp{decl=cmp}(PyObject*{template},PyObject*{template},int{result})', +'int{err=-1} PyObject_Cmp{decl=cmp}(PyObject*,PyObject*,int{result})', +'PyObject*{new} coerce{direct}(PyObject*,PyObject*)', +'PyObject*{new} compile{direct}(PyObject*,PyObject*,PyObject*)', +'PyObject*{new} compile{direct}(const char*,const char*,const char*)', +'PyObject*{new} compile{direct}(PyObject*,PyObject*,PyObject*,PyObject*)', +'PyObject*{new} compile{direct}(const char*,const char*,const char*,int)', +'PyObject*{new} compile{direct}(PyObject*,PyObject*,PyObject*,PyObject*,PyObject*)', +'PyObject*{new} compile{direct}(const char*,const char*,const char*,int,int)', +'PyObject*{new} complex{direct}(int{template})', +'PyObject*{new} complex{direct}(PyObject*)', +'PyObject*{new} complex{direct}(double const&)', +'PyObject*{new} complex{direct}(int{template},int{template})', +'PyObject*{new} complex{direct}(PyObject*,PyObject*)', +'PyObject*{new} complex{direct}(double const&,double const&)', +'PyObject*{new} dict{direct}()', +'PyObject*{new} dict{direct}(PyObject*)', +'PyObject*{new} PyObject_Dir{decl=dir}(PyObject*{value=NULL})', +'PyObject*{new} PyObject_Dir{decl=dir}(PyObject*)', +'PyObject*{new} divmod{direct}(int{template},int{template})', +'PyObject*{new} divmod{direct}(PyObject*,PyObject*)', +'PyObject*{new} divmod{direct}(int,int)', +'PyObject*{new} divmod{direct}(long,long)', +'PyObject*{new} divmod{direct}(double const&,double const&)', +'PyObject*{new} PyRun_String{decl=eval}(char*{const},int{value=Py_eval_input},PyObject*{value=globals().ptr()},PyObject*{value=globals().ptr()})', +'PyObject*{new} PyRun_String{decl=eval}(char*{const},int{value=Py_eval_input},PyObject*,PyObject*{value=globals().ptr()})', +'PyObject*{new} PyRun_String{decl=eval}(char*{const},int{value=Py_eval_input},PyObject*,PyObject*)', +'PyObject*{new} PyRun_String{decl=exec}(char*{const},int{value=Py_file_input},PyObject*{value=globals().ptr()},PyObject*{value=globals().ptr()})', +'PyObject*{new} PyRun_String{decl=exec}(char*{const},int{value=Py_file_input},PyObject*,PyObject*{value=globals().ptr()})', +'PyObject*{new} PyRun_String{decl=exec}(char*{const},int{value=Py_file_input},PyObject*,PyObject*)', +'PyObject*{new} execfile{direct}(PyObject*)', +'PyObject*{new} execfile{direct}(PyObject*,PyObject*)', +'PyObject*{new} execfile{direct}(PyObject*,PyObject*,PyObject*)', +'PyObject*{new} file{direct}(PyObject*)', +'PyObject*{new} file{direct}(const char*)', +'PyObject*{new} file{direct}(PyObject*,PyObject*)', +'PyObject*{new} file{direct}(const char*,const char*)', +'PyObject*{new} file{direct}(PyObject*,PyObject*,PyObject*)', +'PyObject*{new} file{direct}(const char*,const char*,int)', +'PyObject*{new} filter{direct}(PyObject*,PyObject*)', +'PyObject*{new} float{direct,decl=float_}(PyObject*)', +'PyObject*{new} float{direct,decl=float_}(const char*)', +'PyObject*{new} float{direct,decl=float_}(double const&)', +'PyObject*{new} getattr{direct}(PyObject*,PyObject*,PyObject*)', +'PyObject*{new} getattr{direct}(PyObject*,const char *,PyObject*)', +'PyObject*{borrowed,err=NULL} PyModule_GetDict{decl=globals}(PyObject*{value=PyImport_AddModule("__main__")})', +'bool PyObject_HasAttr{decl=hasattr}(PyObject*,PyObject*)', +'bool PyObject_HasAttrString{decl=hasattr}(PyObject*,char*{const})', +'long{err=-1} PyObject_Hash{decl=hash}(PyObject*)', +'PyObject*{new} hex{direct}(int{template})', +'PyObject*{new} hex{direct}(PyObject*)', +'PyObject*{new} hex{direct}(char)', +'PyObject*{new} hex{direct}(short)', +'PyObject*{new} hex{direct}(int)', +'PyObject*{new} hex{direct}(long)', +'long id{direct}(PyObject*)', +'PyObject*{new} input{direct}()', +'PyObject*{new} input{direct}(PyObject*)', +'PyObject*{new} input{direct}(const char*)', +'PyObject*{new} int{direct,decl=int_}(PyObject*)', +'PyObject*{new} int{direct,decl=int_}(long)', +'PyObject*{new} int{direct,decl=int_}(const char*)', +'PyObject*{new} intern{direct}(PyObject*)', +'PyObject*{new} intern{direct}(const char*)', +'bool PyObject_IsInstance{decl=isinstance}(PyObject*,PyObject*)', +'bool PyObject_IsSubclass{decl=issubclass}(PyObject*,PyObject*)', +'PyObject*{new} PyObject_GetIter{decl=iter}(PyObject*)', +'PyObject*{new} iter{direct}(PyObject*,PyObject*)', +'long{err=-1} PyObject_Length{decl=len}(PyObject*)', +'PyObject*{new} list{direct}()', +'PyObject*{new} list{direct}(PyObject*)', +'PyObject*{new} long{direct,decl=long_}(PyObject*)', +'PyObject*{new} long{direct,decl=long_}(long)', +'PyObject*{new} long{direct,decl=long_}(const char*)', +'PyObject*{new} map{direct,argrepeat}(PyObject*)', +'PyObject*{new} max{direct,argrepeat}(PyObject*{template})', +'PyObject*{new} max{direct,argrepeat}(PyObject*)', +'PyObject*{new} min{direct,argrepeat}(PyObject*{template})', +'PyObject*{new} min{direct,argrepeat}(PyObject*)', +'PyObject*{new} oct{direct}(int{template})', +'PyObject*{new} oct{direct}(PyObject*)', +'PyObject*{new} oct{direct}(char)', +'PyObject*{new} oct{direct}(short)', +'PyObject*{new} oct{direct}(int)', +'PyObject*{new} oct{direct}(long)', +'PyObject*{new} open{direct}(PyObject*)', +'PyObject*{new} open{direct}(const char*)', +'PyObject*{new} open{direct}(PyObject*,PyObject*)', +'PyObject*{new} open{direct}(const char*,const char*)', +'PyObject*{new} open{direct}(PyObject*,PyObject*,PyObject*)', +'PyObject*{new} open{direct}(const char*,const char*,int)', +'long ord{direct}(PyObject*)', +'long ord{direct}(const char*)', +'PyObject*{new} pow{direct}(int{template},int{template})', +'PyObject*{new} pow{direct}(PyObject*,PyObject*)', +'PyObject*{new} pow{direct}(double const&,double const&)', +'PyObject*{new} pow{direct}(double const&,double const&,double const&)', +'PyObject*{new} print{direct,statement=print _1,argrepeat}(int{template})', +'PyObject*{new} print{direct,statement=print _1,argrepeat}(PyObject*)', +'PyObject*{new} print{decl=print_file,direct,statement="print >>_1, _2",argrepeat}(PyObject*,int{template})', +'PyObject*{new} print{decl=print_file,direct,statement="print >>_1, _2",argrepeat}(PyObject*,PyObject*)', +'PyObject*{new} range{direct}(int{template})', +'PyObject*{new} range{direct}(PyObject*)', +'PyObject*{new} range{direct}(int)', +'PyObject*{new} range{direct}(int{template},int{template})', +'PyObject*{new} range{direct}(PyObject*,PyObject*)', +'PyObject*{new} range{direct}(int,int)', +'PyObject*{new} range{direct}(int{template},int{template},int{template})', +'PyObject*{new} range{direct}(PyObject*,PyObject*,PyObject*)', +'PyObject*{new} range{direct}(int,int,int)', +'PyObject*{new} raw_input{direct}()', +'PyObject*{new} raw_input{direct}(PyObject*)', +'PyObject*{new} raw_input{direct}(const char*)', +'PyObject*{new} reduce{direct}(PyObject*,PyObject*)', +'PyObject*{new} reduce{direct}(PyObject*,PyObject*,PyObject*)', +'PyObject*{new,err=NULL} PyImport_ReloadModule{decl=reload}(PyObject*)', +'PyObject*{new} PyObject_Repr{decl=repr}(PyObject*)', +'PyObject*{new} round{direct}(int{template})', +'PyObject*{new} round{direct}(PyObject*)', +'PyObject*{new} round{direct}(double const&)', +'PyObject*{new} round{direct}(int{template},int{template})', +'PyObject*{new} round{direct}(PyObject*,PyObject*)', +'PyObject*{new} round{direct}(double const&,double const&)', +'PyObject*{new} slice{direct}(int{template})', +'PyObject*{new} slice{direct}(PyObject*)', +'PyObject*{new} slice{direct}(int)', +'PyObject*{new} slice{direct}(int{template},int{template})', +'PyObject*{new} slice{direct}(PyObject*,PyObject*)', +'PyObject*{new} slice{direct}(int,int)', +'PyObject*{new} slice{direct}(int{template},int{template},int{template})', +'PyObject*{new} slice{direct}(PyObject*,PyObject*,PyObject*)', +'PyObject*{new} slice{direct}(int,int,int)', +'PyObject*{new} PyObject_Str{decl=str}(PyObject*)', +'PyObject*{new} tuple{direct}()', +'PyObject*{new} tuple{direct}(PyObject*)', +'PyObject*{new,err=NULL} PyObject_Type{decl=type_}(PyObject*)', +'PyObject*{new} unichr{direct}(int{template})', +'PyObject*{new} unichr{direct}(PyObject*)', +'PyObject*{new} unichr{direct}(short)', +'PyObject*{new} unichr{direct}(int)', +'PyObject*{new} unichr{direct}(long)', +'PyObject*{new} PyObject_Unicode{decl=unicode}(PyObject*)', +'PyObject*{new} unicode{direct}(PyObject*,PyObject*)', +'PyObject*{new} unicode{direct}(PyObject*,const char*)', +'PyObject*{new} unicode{direct}(PyObject*,PyObject*,PyObject*)', +'PyObject*{new} unicode{direct}(PyObject*,const char*,const char*)', +'PyObject*{new} vars{direct}()', +'PyObject*{new} vars{direct}(PyObject*)', +'PyObject*{new} xrange{direct}(int{template})', +'PyObject*{new} xrange{direct}(PyObject*)', +'PyObject*{new} xrange{direct}(int)', +'PyObject*{new} xrange{direct}(int{template},int{template})', +'PyObject*{new} xrange{direct}(PyObject*,PyObject*)', +'PyObject*{new} xrange{direct}(int,int)', +'PyObject*{new} xrange{direct}(int{template},int{template},int{template})', +'PyObject*{new} xrange{direct}(PyObject*,PyObject*,PyObject*)', +'PyObject*{new} xrange{direct}(int,int,int)', +'PyObject*{new} zip{direct,argrepeat}(PyObject*)', +'PyObject*{new,err=NULL} Py_CompileString{decl=compile_string}(char*{const},char*{const},int)', +'int{err=-1} PyImport_AppendInittab{decl=import_append_inittab}(char*{const},void(*arg)(void))', +'PyObject*{borrowed,err=NULL} PyImport_AddModule{decl=import_add_module}(char*{const})', +'PyObject*{borrowed,err=NULL} PyImport_GetModuleDict{decl=import_get_module_dict}()', +'PyObject*{new,err=NULL} PyImport_Import{decl=import_import}(PyObject*)', +'PyObject*{new,err=NULL} PyImport_Import{decl=import_import}(const char*{object})', +'PyObject*{new,err=NULL} PyImport_ImportModule{decl=import_import_module}(char*{const})', +'PyObject*{new,err=NULL} PyImport_ImportModuleEx{decl=import_import_module_ex}(char*{const},PyObject*,PyObject*,PyObject*)', +'PyObject*{borrowed,err=NULL} PyModule_GetDict{decl=module_get_dict}(PyObject*)', +'int{err=-1} PyObject_Print{decl=object_print}(PyObject*,FILE*,int)', +'PyObject*{new,err=NULL} PyRun_File{decl=run_file}(FILE*,char*{const},int,PyObject*,PyObject*)', +'int{err=-1} PyRun_SimpleFile{decl=run_simple_file}(FILE*,char*{const})', +'int{err=-1} PyRun_SimpleString{decl=run_simple_string}(char*{const})', +'PyObject*{new,err=NULL} PyRun_String{decl=run_string}(char*{const},int,PyObject*,PyObject*)', +'PyObject*{new} call_statement{statement,direct}(const char*{statement})', +'PyObject*{new} call_statement{statement,direct}(const char*{statement},call_dict_usage{use_gd})', +'PyObject*{new} call_statement{argrepeat,statement,direct}(const char*{statement},int{template})', +'PyObject*{new} call_statement{argrepeat,statement,direct}(const char*{statement},PyObject*)', +'PyObject*{new} call_statement{argrepeat,statement,direct}(const char*{statement},call_dict_usage{use_gd},int{template})', +'PyObject*{new} call_statement{argrepeat,statement,direct}(const char*{statement},call_dict_usage{use_gd},PyObject*)', +] + +DeclFile = '../../../boost/python/py_interface.hpp' +ImplFile = 'py_interface.cpp' + +DeclFileHeader = '''\ +// Automatically generated from py_api_gen.py +#ifndef PY_INTERFACE_HPP +#define PY_INTERFACE_HPP + +#include +#include + +namespace boost { namespace python { namespace api { + +enum call_dict_usage { use_new_dict, use_local_dict, use_global_dict }; + +namespace api_detail { + +BOOST_PYTHON_DECL object get_func(const char* name); +BOOST_PYTHON_DECL object call_statement(const char *stmt, int n, ...); +BOOST_PYTHON_DECL object call_statement_du(const char *stmt, call_dict_usage cdu, int n, ...); + +template +struct get_arg +{ + get_arg(A const &a) : h(a) {} + object h; + operator object const& () { return h; } + operator object const* () { return &h; } +}; + +template<> +struct get_arg +{ + get_arg(object const &a) : h(a) {} + object const &h; + operator object const& () { return h; } + operator object const* () { return &h; } +}; + +template<> +struct get_arg +{ + get_arg(PyObject* a) : h((python::detail::borrowed_reference)a) {} + object h; + operator object const& () { return h; } + operator object const* () { return &h; } +}; + +} + +BOOST_PYTHON_DECL object locals(); + +''' + +DeclFileTrailer = '''\ +}}} + +#endif // PY_INTERFACE_HPP +''' + +ImplFileHeader = '''\ +// Automatically generated from py_api_gen.py + +#include + +namespace boost { namespace python { namespace api { + +namespace api_detail { + +BOOST_PYTHON_DECL object get_func(const char* name) { + object __builtin__((python::detail::borrowed_reference)::PyImport_AddModule(const_cast("__builtin__"))); + return object(__builtin__.attr(name)); +} + +inline handle<> get_current_frame() +{ + return handle<>(allow_null(borrowed((PyObject*)(PyThreadState_Get()->frame)))); +} + +inline object get_global_dict(call_dict_usage cdu, handle<> const& frame) +{ + if(frame.get()) + return object(object(frame).attr("f_globals")); + else + return api::globals(); +} + +object get_local_dict(call_dict_usage cdu, handle<> const& frame, object const& global_dict) +{ + switch(cdu) { + case use_new_dict: + return api::dict(); + case use_global_dict: + return global_dict; + default: + if(frame.get()) + return object(object(frame).attr("f_locals")); + else + return api::dict(); + } +} + +inline object call_statement(const char *stmt, object const& global_dict, object& local_dict) +{ + local_dict["_0"] = object((python::detail::borrowed_reference)Py_None); + api::run_string(stmt, Py_file_input, global_dict, local_dict); + return object(local_dict["_0"]); +} + +object call_statement(const char *stmt) +{ + handle<> frame(get_current_frame()); + if(frame.get()) { + object f(frame); + object gd(f.attr("f_globals")); + object ld(f.attr("f_locals")); + return call_statement(stmt, gd, ld); + } else { + object gd(api::globals()); + object ld(api::dict()); + return call_statement(stmt, gd, ld); + } +} + +object call_statement_du(const char *stmt, call_dict_usage cdu) +{ + handle<> frame(get_current_frame()); + object gd(get_global_dict(cdu, frame)); + return call_statement(stmt, gd, get_local_dict(cdu, frame, gd)); +} + +inline object call_statement(const char *stmt, object const& global_dict, object& local_dict, int n, va_list mk) +{ + static const char *(idx[]) = { "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8", "_9", "_10" }; + local_dict["_0"] = object((python::detail::borrowed_reference)Py_None); + for(int i = 0; i < n; ++i) + { + object const* p_arg = va_arg(mk, object const*); + object const& arg = *p_arg; + if(i < (int) (sizeof(idx) / sizeof(idx[0]))) + local_dict[idx[i]] = arg; + else { + local_dict[object("_") + object((python::detail::new_reference)PyObject_Str(object(i + 1).ptr()))] = arg; + } + } + va_end(mk); + api::run_string(stmt, Py_file_input, global_dict, local_dict); + return object(local_dict["_0"]); +} + +BOOST_PYTHON_DECL object call_statement(const char *stmt, int n, ...) +{ + va_list mk; + va_start(mk, n); + handle<> frame(get_current_frame()); + if(frame.get()) { + object f(frame); + object gd(f.attr("f_globals")); + object ld(f.attr("f_locals")); + return call_statement(stmt, gd, ld, n, mk); + } else { + object gd(api::globals()); + object ld(api::dict()); + return call_statement(stmt, gd, ld, n, mk); + } +} + +BOOST_PYTHON_DECL object call_statement_du(const char *stmt, call_dict_usage cdu, int n, ...) +{ + handle<> frame(get_current_frame()); + object gd(get_global_dict(cdu, frame)); + va_list mk; + va_start(mk, n); + return call_statement(stmt, gd, get_local_dict(cdu, frame, gd), n, mk); +} + +} + +BOOST_PYTHON_DECL object locals() +{ + handle<> frame(api_detail::get_current_frame()); + if(frame.get()) + return object(object(frame).attr("f_locals")); + else + return api::dict(); +} + +''' + +ImplFileTrailer = '''\ +}}} +''' + +def SplitOutList(l): + vals_list = [] + if l == None: + return vals_list + vals_list = re.findall(r'((?:[^,{}]|(?:{[^{}]*}))+),?\s*', l) + return vals_list + +def SplitOutListDict(l): + vals_dict = {} + if l == None: + return vals_dict + vals = re.findall(r'((?:"[^"]+"|[^,"]+)+)\s*,?', l) + for val in vals: + m = re.match(r'(?P[^\s=]+)\s*(=\s*(?P"?)(?P.+)(?P=qt))?', val).groupdict() + vals_dict[m['aname']] = m['aval'] + return vals_dict + +def SplitOutAttrs(a): + soa = {} + m = re.match(r'(?P[^{]+)({(?P[^}]+)})?', a).groupdict() + soa['name'] = m['name'] + soa.update(SplitOutListDict(m['attrs'])) + return soa + +def is_object(name): + if re.match(r'PyObject\s*\*', name['name']): + return 1 + return 0 + +def is_arg_really_const(arg): + return arg.has_key('const') + +def get_actual_rtn_type(rtn, args): + i = 0 + for a in args: + if a.has_key('result'): + true_rtn = dict(rtn) + true_rtn['name'] = a['name'] + true_rtn['arg_number'] = i + return true_rtn + i += 1 + return rtn + +def is_template(name): + return name.has_key('template') + +def decl_func_arg(arg, p): + if arg.has_key('value'): + return '' + elif arg.has_key('result'): + return '' + elif is_object(arg): + if is_template(arg): + sn = str(p) + return 'A' + sn +' const& a' + sn + else: + return 'object const& a' + str(p) + elif is_arg_really_const(arg): + return 'const ' + arg['name'] + ' a' + str(p) + elif re.search(r'arg', arg['name']): + return re.sub(r'arg', 'a' + str(p), arg['name']) + else: + if is_template(arg): + sn = str(p) + return 'A' + sn +' const& a' + sn + else: + return arg['name'] + ' a' + str(p) + +def decl_func_args(name, args): + if not len(args): + return '' + d_args = reduce(lambda x,y : x + (y and (', ' + y) or ''), map(decl_func_arg, args, xrange(len(args)))) + return d_args + +def call_func_arg(arg, p): + if arg.has_key('value'): + return arg['value'] + elif arg.has_key('result'): + return '&rslt' + elif arg.has_key('template'): + sn = str(p) + return 'api_detail::get_arg(a%s)' % (sn, sn) + elif arg.has_key('object'): + return 'object(a%s).ptr()' % str(p) + elif is_object(arg): + return 'a' + str(p) + '.ptr()' + elif is_arg_really_const(arg): + return 'const_cast<%s>(%s)' % (arg['name'], 'a' + str(p)) + else: + return 'a' + str(p) + +def call_func_args(args): + if not len(args): + return '' + d_args = reduce(lambda x,y : x + (y and ((x and ', ' or '') + y) or ''), map(call_func_arg, args, xrange(len(args)))) + return d_args + +def call_func(name, args): + return '::%s(%s)' % (name['name'], call_func_args(args)) + +def call_func_direct_arg(arg, p): + if arg.has_key('use_gd'): + return '' + elif arg.has_key('statement'): + return '' + elif arg.has_key('value'): + return arg['value'] + elif arg.has_key('template'): + sn = str(p) + if arg.has_key('addr'): + return '(object const*)api_detail::get_arg(a%s)' % (sn, sn) + else: + return 'api_detail::get_arg(a%s)' % (sn, sn) + elif is_object(arg): + if arg.has_key('addr'): + return '&a' + str(p) + else: + return 'a' + str(p) + else: + if arg.has_key('addr'): + return '&object(a%s)' % str(p) + else: + return 'object(a%s)' % str(p) + +def call_func_direct_args(args): + if not len(args): + return '' + d_args = reduce(lambda x,y : x + (y and ((x and ', ' or '') + y) or ''), map(call_func_direct_arg, args, xrange(len(args)))) + return d_args + +def get_statement_arg(args): + i = 0 + for arg in args: + if arg.has_key('statement'): + return i + i = i + 1 + return -1 + +def get_use_gd_arg(args): + i = 0 + for arg in args: + if arg.has_key('use_gd'): + return i + i = i + 1 + return -1 + +def call_func_direct(name, args): + if name.has_key('statement'): + na = len(args) + ugd = get_use_gd_arg(args) + sa = get_statement_arg(args) + if ugd >= 0: + ugd = 'a' + str(ugd) + na = na - 1 + else: + if (sa < 0) and (na > 0): + ugd = 'use_new_dict' + else: + ugd = None + if sa >= 0: + na = na - 1 + if na > 0: + if ugd: + return 'api_detail::call_statement_du(%s, %s, %s, %s)' % ('a' + str(sa), ugd, na, call_func_direct_args(args)) + else: + return 'api_detail::call_statement(%s, %s, %s)' % ('a' + str(sa), na, call_func_direct_args(args)) + else: + if ugd: + return 'api_detail::call_statement_du(%s, %s)' % ('a' + str(sa), ugd) + else: + return 'api_detail::call_statement(%s)' % ('a' + str(sa)) + else: + if na > 0: + if ugd: + return 'api_detail::call_statement_du("%s", %s, %s, %s)' % (name['statement'], ugd, na, call_func_direct_args(args)) + else: + return 'api_detail::call_statement("%s", %s, %s)' % (name['statement'], na, call_func_direct_args(args)) + else: + if ugd: + return 'api_detail::call_statement_du("%s", %s)' % (name['statement'], ugd) + else: + return 'api_detail::call_statement("%s")' % (name['statement']) + else: + return 'api_detail::get_func("%s")(%s)' % (name['name'], call_func_direct_args(args)) + +def decl_template_arg(arg, p): + if arg.has_key('value'): + return '' + elif arg.has_key('result'): + return '' + elif is_template(arg): + return 'class A' + str(p) + else: + return '' + +def decl_template_args(args): + if not len(args): + return '' + d_args = reduce(lambda x,y : x + (y and ((x and ', ' or '') + y) or ''), map(decl_template_arg, args, xrange(len(args)))) + return d_args + +def is_rtn_borrowed_object(rtn): + if is_object(rtn): + return rtn.has_key('borrowed') + else: + return 0 + +def is_rtn_new_object(rtn): + if is_object(rtn): + return not rtn.has_key('borrowed') + else: + return 0 + +def is_func_direct(name): + return name.has_key('direct') + +def rtn_call_func_direct(rtn, name, args): + if rtn['name'] == 'void': + direct_code = ' %s;' % call_func_direct(name, args) + elif is_object(rtn): + direct_code = ' return %s;' % call_func_direct(name, args) + else: + r = '''\ + object r(%s); + return boost::python::arg_from_python<%s>(r.ptr())(r.ptr());''' + direct_code = r % (call_func_direct(name, args), rtn['name']) + return direct_code + +def rtn_call_func(rtn, name, args): + if is_func_direct(name): + return rtn_call_func_direct(rtn, name, args) + true_rtn = get_actual_rtn_type(rtn, args) + err = true_rtn.get('err') + arg_number = true_rtn.get('arg_number') + if rtn['name'] == 'void': + return ' %s;' % call_func(name, args) + elif is_rtn_new_object(rtn): + if err and (err != 'NULL'): + r = '''\ + PyObject* r = %s; + if(r == %s) + throw_error_already_set(); + return object((python::detail::new_reference)r);''' + return r % (call_func(name, args), err) + else: + return ' return object((python::detail::new_reference)%s);' % call_func(name, args) + elif is_rtn_borrowed_object(rtn): + if err and (err != 'NULL'): + r = '''\ + PyObject* r = %s; + if(r == %s) + throw_error_already_set(); + return object((python::detail::borrowed_reference)r);''' + return r % (call_func(name, args), err) + else: + return ' return object((python::detail::borrowed_reference)%s);' % call_func(name, args) + else: + if err: + if arg_number == None: + r = '''\ + %s r = %s; + if(r == %s) + throw_error_already_set(); + return r;''' + return r % (rtn['name'], call_func(name, args), err) + else: + r = '''\ + %s rslt; + %s r = %s; + if(r == %s) + throw_error_already_set(); + return rslt;''' + return r % (true_rtn['name'], rtn['name'], call_func(name, args), err) + else: + return ' return %s;' % call_func(name, args) + +def decl_func(name, args): + return '%s(%s)' % (name.get('decl', name['name']), decl_func_args(name, args)) + +def rtn_decl_func(rtn, name, args): + true_rtn = get_actual_rtn_type(rtn, args) + ta = decl_template_args(args) + if ta: + decl = 'template<%s>\n' % ta + else: + decl = 'BOOST_PYTHON_DECL ' + if is_object(true_rtn): + return decl + 'object %s' % decl_func(name, args) + else: + return decl + '%s %s' % (true_rtn['name'], decl_func(name, args)) + +def is_info_template(fn_info): + for arg in fn_info['args']: + if is_template(arg): + return 1 + return 0 + +def parse_func(func): + fn_info = {} + fnm = re.match(r'(?P\S+)\s+(?P[^\s\(\){}]+({[^{}]*})?)\s*\((?P(({[^{}]*})+|(\([^\(\)]*\))+|[^\(\)]+)*)\)', func).groupdict() + fn_info['fname'] = SplitOutAttrs(fnm['fname']) + fn_info['rtn'] = SplitOutAttrs(fnm['rtn']) + fn_info['args'] = map(SplitOutAttrs, SplitOutList(fnm['args'])) + if fn_info['fname'].has_key('statement'): + if is_info_template(fn_info): + for arg in fn_info['args']: + if is_template(arg): + arg['addr'] = None + else: + for arg in fn_info['args']: + if is_object(arg): + arg['addr'] = None + return fn_info + +def get_argrepeat(fn_info): + if fn_info['fname'].has_key('argrepeat'): + argrepeat = fn_info['fname']['argrepeat'] + if argrepeat == None: + argrepeat = 10 + else: + argrepeat = 1 + return argrepeat + +def do_arg_repeat(fn_info): + fn_info['args'] = fn_info['args'] + [fn_info['args'][len(fn_info['args']) - 1],] + if fn_info['fname'].has_key('statement'): + stmt = fn_info['fname']['statement'] + if stmt: + s_args = re.findall(r'[\s,\(](?:_([0-9]+))(?=$|[\s,\)])', stmt) + if s_args: + mx = reduce(max, map(int, s_args), 0) + mx_arg = '_' + str(mx) + next_arg = '_' + str(mx + 1) + stmt = re.sub(r'(?<=[\s,\(])' + mx_arg + '(?=$|[\s,\)])', mx_arg + ', ' + next_arg, stmt, 1) + fn_info['fname']['statement'] = stmt + +def decl_funcs(fn_list): + fn_defs = '' + for fn in fn_list: + fn_info = parse_func(fn) + argrepeat = get_argrepeat(fn_info) + for ar in xrange(argrepeat): + fn_defs += rtn_decl_func(fn_info['rtn'], fn_info['fname'], fn_info['args']) + if is_info_template(fn_info): + fn_defs += '\n{\n' + rtn_call_func(fn_info['rtn'], fn_info['fname'], fn_info['args']) + '\n}\n' + else: + fn_defs += ';\n' + if ar != (argrepeat - 1): + do_arg_repeat(fn_info) + return fn_defs + +def impl_funcs(fn_list): + fn_defs = '' + for fn in fn_list: + fn_info = parse_func(fn) + if is_info_template(fn_info): + continue + argrepeat = get_argrepeat(fn_info) + for ar in xrange(argrepeat): + fn_defs += rtn_decl_func(fn_info['rtn'], fn_info['fname'], fn_info['args']) + ' {\n' + fn_defs += rtn_call_func(fn_info['rtn'], fn_info['fname'], fn_info['args']) + '\n}\n\n' + if ar != (argrepeat - 1): + do_arg_repeat(fn_info) + return fn_defs + +if __name__ == '__main__': + f = file(DeclFile, 'w') + print >>f, DeclFileHeader + print >>f, decl_funcs(API_List) + print >>f, DeclFileTrailer + f.close() + + f = file(ImplFile, 'w') + print >>f, ImplFileHeader + print >>f, impl_funcs(API_List) + print >>f, ImplFileTrailer + f.close() diff --git a/src/module.cpp b/src/module.cpp index f7edf39e..9fe86adf 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -7,16 +7,107 @@ // producing this work. #include +#include +#include #include +#include #include namespace boost { namespace python { namespace detail { -module_base::module_base(const char* name) - : m_module( - python::borrowed(Py_InitModule(const_cast(name), initial_methods)) - ) +namespace { + +object getattr_or_none(object const &obj, const char *name) { + if(PyObject_HasAttrString(obj.ptr(), const_cast(name))) + return obj.attr(name); + else + return object(); +} + +// Initialise a new sub-module, or return an existing one. +// This will also create any missing parents along the way. +handle<> init_sub_module(const char* name, PyMethodDef *initial_methods, module_info* pmi) +{ + if(name == NULL) + // just create a dummy module with an empty reference + return handle<>(); + // initialise various iterators, etc. + object parent_module(pmi->get_module()), current_module(parent_module); + std::string s_name(name), b_name; + if(s_name.size() == 0) + // use the default module name if it is not supplied + s_name = pmi->get_module_name(); + std::string::size_type p_pos(0); + for(int l = 0;;++l) { + // find the next module name in the 'dotted' name + std::string::size_type dot_pos = s_name.find('.', p_pos); + // p_pos is the absolute position, but the length is needed + if(dot_pos != std::string::npos) + dot_pos -= p_pos; + // the current module name being processed, iterating from the parent + // to the right hand sub-modules + b_name = s_name.substr(p_pos, dot_pos); + if(l == 0) { + // process the top level parent module name + if(dot_pos == 0) + // allow a shortcut module notation so we can do module(".submodule") + b_name = pmi->get_module_name(); + // check the base name is the correct parent name else assert + assert(b_name.compare(pmi->get_module_name()) == 0); + if(!parent_module) { + // The main parent module does not exist yet, so create it here + parent_module = object(python::borrowed(Py_InitModule( + const_cast(b_name.c_str()), + initial_methods))); + // and set up the module iterator + current_module = parent_module; + // initialise the global parent module so it can be found later + pmi->set_module(parent_module); + } + } else { + // now processing a sub-module + // try to find and verify an existing sub-module of the correct name and type + object existing_sub_module(getattr_or_none(current_module, b_name.c_str())); + if(existing_sub_module) { + // An attribute of the same name has been found + object module_type((python::detail::new_reference)PyObject_Type(parent_module.ptr())); + // test its type against the parent + if(!PyObject_IsSubclass(existing_sub_module.ptr(), module_type.ptr())) + // not actually a module, so it can't be used + existing_sub_module = object(); + } + // was an existing sub-module found ? + if(!existing_sub_module) { + // no, then it is created here + // build up the full path name up to and including the current sub-module + std::string full_name(s_name.substr(0, dot_pos)); + // create the module + existing_sub_module = object(python::borrowed(Py_InitModule( + const_cast(full_name.c_str()), + initial_methods))); + // add the sub-module to the attributes of its immediate parent + current_module.attr(b_name.c_str()) = existing_sub_module; + } + // we now have a new current module to iterate + current_module = existing_sub_module; + } + // no more modules ? + if(dot_pos == std::string::npos) + break; + // advance over the dot + p_pos += dot_pos + 1; + } + // return the actual sub-module that was either found or created + return handle<>(python::borrowed(current_module.ptr())); +} + +} + +module_base::module_base(const char* name) + : m_module(init_sub_module(name, initial_methods, get_module_info())) +{ + set_prior_module(m_module); } module_base::~module_base() @@ -42,7 +133,16 @@ void module_base::add(type_handle const& x) void module_base::add_class(type_handle const& class_obj) { - this->add(class_obj); + add_class(class_obj, objects::class_base:: + get_class_context_object(class_obj.get()->tp_name, class_obj)); +} + +void module_base::add_class(type_handle const& class_obj, handle<> const& context) +{ + if(context.get()) { + objects::function:: + add_to_namespace(context, ((PyTypeObject*)class_obj.get())->tp_name, class_obj); + } handle<> module_name( PyObject_GetAttrString( @@ -50,13 +150,38 @@ void module_base::add_class(type_handle const& class_obj) ); int status = PyObject_SetAttrString( - python::upcast(class_obj.get()) - , const_cast("__module__"), module_name.get()); + handle<>(class_obj).get(), const_cast("__module__"), module_name.get()); if (status == -1) throw_error_already_set(); } +void module_base::set_module_info(module_info & mi) +{ + get_module_info_ref() = &mi; +} + +module_info* module_base::get_module_info() +{ + return get_module_info_ref(); +} + +module_info*& module_base::get_module_info_ref() +{ + static module_info* pmi = NULL; + return pmi; +} + +void module_base::set_prior_module(handle<> const& m) +{ + get_module_info()->set_prior_module(python::object(m)); +} + +handle<> module_base::get_prior_module() +{ + return handle<>(python::borrowed(get_module_info()->get_prior_module().ptr())); +} + PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; }}} // namespace boost::python::detail diff --git a/src/object/class.cpp b/src/object/class.cpp index e49df96f..f2c602f6 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -3,10 +3,13 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. +#include #include #include #include #include +#include +#include #include #include #include @@ -246,6 +249,12 @@ namespace objects char const* name, std::size_t num_types, class_id const* const types) { assert(num_types >= 1); + + // is this class already registered? + m_object = query_class(types[0]); + if(m_object.get()) { + return; + } // Build a tuple of the base Python type objects. If no bases // were declared, we'll use our class_type() as the single base @@ -260,9 +269,15 @@ namespace objects PyTuple_SET_ITEM(bases.get(), i - 1, upcast(c.release())); } + // we now need just the base name + std::string base_name(name); + std::string::size_type dot_pos = base_name.rfind('.'); + if(dot_pos != std::string::npos) + base_name = base_name.substr(dot_pos + 1); + // Build the (name, bases, dict) tuple for creating the new class handle<> args(PyTuple_New(3)); - PyTuple_SET_ITEM(args.get(), 0, incref(python::object(name).ptr())); + PyTuple_SET_ITEM(args.get(), 0, incref(python::object(base_name.c_str()).ptr())); PyTuple_SET_ITEM(args.get(), 1, bases.release()); handle<> d(PyDict_New()); PyTuple_SET_ITEM(args.get(), 2, d.release()); @@ -304,9 +319,107 @@ namespace objects throw_error_already_set(); } + namespace { + class empty_class {}; + + void transfer_attributes(object const& src, object const& dst) + { + object attrs((python::detail::new_reference)PyObject_Dir(src.ptr())); + if(PyList_Check(attrs.ptr())) { + int sz = PyList_Size(attrs.ptr()); + for(int i = 0; i < sz; i++) { + PyObject *attr_name = PyList_GET_ITEM(attrs.ptr(), i); + object attr((python::detail::new_reference)PyObject_GetAttr(src.ptr(), attr_name)); + // only transfer boost classes + if(attr.ptr()->ob_type == &class_metatype_object) + PyObject_SetAttr(dst.ptr(), attr_name, attr.ptr()); + } + } + } + + + object getattr_or_none(object const &obj, const char *name) + { + if(PyObject_HasAttrString(obj.ptr(), const_cast(name))) + return obj.attr(name); + else + return object(); + } + + } + + // get a class context for nested classes + handle<> class_base::get_class_context_object(const char* name, type_handle const& class_obj) + { + // initialise various iterators, etc. + std::string s_name(name), b_name; + std::string::size_type p_pos(0); + python::object current_object(python::detail::module_base::get_prior_module()); + for(;;) { + // find the next class name in the 'dotted' name + std::string::size_type dot_pos = s_name.find('.', p_pos); + // have we completed up to the current class ? + // p_pos is the absolute position, but the length is needed + if(dot_pos != std::string::npos) + dot_pos -= p_pos; + // the current class name being processed, iterating from left to right + b_name = s_name.substr(p_pos, dot_pos); + if(dot_pos == std::string::npos) { + // this is the last class in the chain, is it here already + python::object existing_object(getattr_or_none(current_object, b_name.c_str())); + if(existing_object) { + // yes + if(PyObject_TypeCheck(existing_object.ptr(), &PyType_Type)) { + PyTypeObject *pType = (PyTypeObject *) existing_object.ptr(); + // is it one of ours? + if(pType->ob_type == &class_metatype_object) { + // then lets see if its our empty_class + type_handle r = query_class(python::type_id()); + // is it registered as the empty_class? + if(r.get() == pType) { + // yes, then we can transfer attributes + transfer_attributes(python::object(handle<>(r)), python::object(handle<>(class_obj))); + } else { + // the user must have created it already. + // so we don't need to add it + return handle<>(); + } + } + } + } + break; + } + // try to find an existing parent of the nested class + current_object = getattr_or_none(current_object, b_name.c_str()); + if(!current_object) { + // If we can't find it then insert a temporary class as a marker + std::string full_name(s_name.substr(0, dot_pos)); + current_object = python::object(handle<>(boost::python::class_(full_name.c_str()).object())); + } + // we now have a new current object to iterate + // note that we could attach the nested class to something other + // than a parent class here as we are not testing the type, + // does this really matter? + // advance over the dot + p_pos += dot_pos + 1; + } + // return the actual sub-module that was either found or created + return handle<>(python::borrowed(current_object.ptr())); + } + + class_base::class_base() + { + } + + class_base const& class_base::empty_class_base() + { + static class_base ecb; + return ecb; + } + BOOST_PYTHON_DECL type_handle registered_class_object(class_id id) { - return objects::query_class(id); + return query_class(id); } } // namespace objects diff --git a/src/py_interface.cpp b/src/py_interface.cpp new file mode 100644 index 00000000..e34bf6f9 --- /dev/null +++ b/src/py_interface.cpp @@ -0,0 +1,1103 @@ +// Automatically generated from py_api_gen.py + +#include + +namespace boost { namespace python { namespace api { + +namespace api_detail { + +BOOST_PYTHON_DECL object get_func(const char* name) { + object __builtin__((python::detail::borrowed_reference)::PyImport_AddModule(const_cast("__builtin__"))); + return object(__builtin__.attr(name)); +} + +inline handle<> get_current_frame() +{ + return handle<>(allow_null(borrowed((PyObject*)(PyThreadState_Get()->frame)))); +} + +inline object get_global_dict(call_dict_usage cdu, handle<> const& frame) +{ + if(frame.get()) + return object(object(frame).attr("f_globals")); + else + return api::globals(); +} + +object get_local_dict(call_dict_usage cdu, handle<> const& frame, object const& global_dict) +{ + switch(cdu) { + case use_new_dict: + return api::dict(); + case use_global_dict: + return global_dict; + default: + if(frame.get()) + return object(object(frame).attr("f_locals")); + else + return api::dict(); + } +} + +inline object call_statement(const char *stmt, object const& global_dict, object& local_dict) +{ + local_dict["_0"] = object((python::detail::borrowed_reference)Py_None); + api::run_string(stmt, Py_file_input, global_dict, local_dict); + return object(local_dict["_0"]); +} + +object call_statement(const char *stmt) +{ + handle<> frame(get_current_frame()); + if(frame.get()) { + object f(frame); + object gd(f.attr("f_globals")); + object ld(f.attr("f_locals")); + return call_statement(stmt, gd, ld); + } else { + object gd(api::globals()); + object ld(api::dict()); + return call_statement(stmt, gd, ld); + } +} + +object call_statement_du(const char *stmt, call_dict_usage cdu) +{ + handle<> frame(get_current_frame()); + object gd(get_global_dict(cdu, frame)); + return call_statement(stmt, gd, get_local_dict(cdu, frame, gd)); +} + +inline object call_statement(const char *stmt, object const& global_dict, object& local_dict, int n, va_list mk) +{ + static const char *(idx[]) = { "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8", "_9", "_10" }; + local_dict["_0"] = object((python::detail::borrowed_reference)Py_None); + for(int i = 0; i < n; ++i) + { + object const* p_arg = va_arg(mk, object const*); + object const& arg = *p_arg; + if(i < (int) (sizeof(idx) / sizeof(idx[0]))) + local_dict[idx[i]] = arg; + else { + local_dict[object("_") + object((python::detail::new_reference)PyObject_Str(object(i + 1).ptr()))] = arg; + } + } + va_end(mk); + api::run_string(stmt, Py_file_input, global_dict, local_dict); + return object(local_dict["_0"]); +} + +BOOST_PYTHON_DECL object call_statement(const char *stmt, int n, ...) +{ + va_list mk; + va_start(mk, n); + handle<> frame(get_current_frame()); + if(frame.get()) { + object f(frame); + object gd(f.attr("f_globals")); + object ld(f.attr("f_locals")); + return call_statement(stmt, gd, ld, n, mk); + } else { + object gd(api::globals()); + object ld(api::dict()); + return call_statement(stmt, gd, ld, n, mk); + } +} + +BOOST_PYTHON_DECL object call_statement_du(const char *stmt, call_dict_usage cdu, int n, ...) +{ + handle<> frame(get_current_frame()); + object gd(get_global_dict(cdu, frame)); + va_list mk; + va_start(mk, n); + return call_statement(stmt, gd, get_local_dict(cdu, frame, gd), n, mk); +} + +} + +BOOST_PYTHON_DECL object locals() +{ + handle<> frame(api_detail::get_current_frame()); + if(frame.get()) + return object(object(frame).attr("f_locals")); + else + return api::dict(); +} + + +BOOST_PYTHON_DECL object abs(object const& a0) { + return api_detail::get_func("abs")(a0); +} + +BOOST_PYTHON_DECL object abs(short a0) { + return api_detail::get_func("abs")(object(a0)); +} + +BOOST_PYTHON_DECL object abs(int a0) { + return api_detail::get_func("abs")(object(a0)); +} + +BOOST_PYTHON_DECL object abs(long a0) { + return api_detail::get_func("abs")(object(a0)); +} + +BOOST_PYTHON_DECL object abs(double const & a0) { + return api_detail::get_func("abs")(object(a0)); +} + +BOOST_PYTHON_DECL object apply(object const& a0, object const& a1) { + return object((python::detail::new_reference)::PyObject_CallObject(a0.ptr(), a1.ptr())); +} + +BOOST_PYTHON_DECL object apply(object const& a0, object const& a1, object const& a2) { + return object((python::detail::new_reference)::PyObject_Call(a0.ptr(), a1.ptr(), a2.ptr())); +} + +BOOST_PYTHON_DECL bool callable(object const& a0) { + return ::PyCallable_Check(a0.ptr()); +} + +BOOST_PYTHON_DECL object chr(object const& a0) { + return api_detail::get_func("chr")(a0); +} + +BOOST_PYTHON_DECL object chr(short a0) { + return api_detail::get_func("chr")(object(a0)); +} + +BOOST_PYTHON_DECL object chr(int a0) { + return api_detail::get_func("chr")(object(a0)); +} + +BOOST_PYTHON_DECL object chr(long a0) { + return api_detail::get_func("chr")(object(a0)); +} + +BOOST_PYTHON_DECL int cmp(object const& a0, object const& a1) { + int rslt; + int r = ::PyObject_Cmp(a0.ptr(), a1.ptr(), &rslt); + if(r == -1) + throw_error_already_set(); + return rslt; +} + +BOOST_PYTHON_DECL object coerce(object const& a0, object const& a1) { + return api_detail::get_func("coerce")(a0, a1); +} + +BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("compile")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2) { + return api_detail::get_func("compile")(object(a0), object(a1), object(a2)); +} + +BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2, object const& a3) { + return api_detail::get_func("compile")(a0, a1, a2, a3); +} + +BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2, int a3) { + return api_detail::get_func("compile")(object(a0), object(a1), object(a2), object(a3)); +} + +BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { + return api_detail::get_func("compile")(a0, a1, a2, a3, a4); +} + +BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2, int a3, int a4) { + return api_detail::get_func("compile")(object(a0), object(a1), object(a2), object(a3), object(a4)); +} + +BOOST_PYTHON_DECL object complex(object const& a0) { + return api_detail::get_func("complex")(a0); +} + +BOOST_PYTHON_DECL object complex(double const& a0) { + return api_detail::get_func("complex")(object(a0)); +} + +BOOST_PYTHON_DECL object complex(object const& a0, object const& a1) { + return api_detail::get_func("complex")(a0, a1); +} + +BOOST_PYTHON_DECL object complex(double const& a0, double const& a1) { + return api_detail::get_func("complex")(object(a0), object(a1)); +} + +BOOST_PYTHON_DECL object dict() { + return api_detail::get_func("dict")(); +} + +BOOST_PYTHON_DECL object dict(object const& a0) { + return api_detail::get_func("dict")(a0); +} + +BOOST_PYTHON_DECL object dir() { + return object((python::detail::new_reference)::PyObject_Dir(NULL)); +} + +BOOST_PYTHON_DECL object dir(object const& a0) { + return object((python::detail::new_reference)::PyObject_Dir(a0.ptr())); +} + +BOOST_PYTHON_DECL object divmod(object const& a0, object const& a1) { + return api_detail::get_func("divmod")(a0, a1); +} + +BOOST_PYTHON_DECL object divmod(int a0, int a1) { + return api_detail::get_func("divmod")(object(a0), object(a1)); +} + +BOOST_PYTHON_DECL object divmod(long a0, long a1) { + return api_detail::get_func("divmod")(object(a0), object(a1)); +} + +BOOST_PYTHON_DECL object divmod(double const& a0, double const& a1) { + return api_detail::get_func("divmod")(object(a0), object(a1)); +} + +BOOST_PYTHON_DECL object eval(const char* a0) { + return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_eval_input, globals().ptr(), globals().ptr())); +} + +BOOST_PYTHON_DECL object eval(const char* a0, object const& a2) { + return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_eval_input, a2.ptr(), globals().ptr())); +} + +BOOST_PYTHON_DECL object eval(const char* a0, object const& a2, object const& a3) { + return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_eval_input, a2.ptr(), a3.ptr())); +} + +BOOST_PYTHON_DECL object exec(const char* a0) { + return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_file_input, globals().ptr(), globals().ptr())); +} + +BOOST_PYTHON_DECL object exec(const char* a0, object const& a2) { + return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_file_input, a2.ptr(), globals().ptr())); +} + +BOOST_PYTHON_DECL object exec(const char* a0, object const& a2, object const& a3) { + return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_file_input, a2.ptr(), a3.ptr())); +} + +BOOST_PYTHON_DECL object execfile(object const& a0) { + return api_detail::get_func("execfile")(a0); +} + +BOOST_PYTHON_DECL object execfile(object const& a0, object const& a1) { + return api_detail::get_func("execfile")(a0, a1); +} + +BOOST_PYTHON_DECL object execfile(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("execfile")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object file(object const& a0) { + return api_detail::get_func("file")(a0); +} + +BOOST_PYTHON_DECL object file(const char* a0) { + return api_detail::get_func("file")(object(a0)); +} + +BOOST_PYTHON_DECL object file(object const& a0, object const& a1) { + return api_detail::get_func("file")(a0, a1); +} + +BOOST_PYTHON_DECL object file(const char* a0, const char* a1) { + return api_detail::get_func("file")(object(a0), object(a1)); +} + +BOOST_PYTHON_DECL object file(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("file")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object file(const char* a0, const char* a1, int a2) { + return api_detail::get_func("file")(object(a0), object(a1), object(a2)); +} + +BOOST_PYTHON_DECL object filter(object const& a0, object const& a1) { + return api_detail::get_func("filter")(a0, a1); +} + +BOOST_PYTHON_DECL object float_(object const& a0) { + return api_detail::get_func("float")(a0); +} + +BOOST_PYTHON_DECL object float_(const char* a0) { + return api_detail::get_func("float")(object(a0)); +} + +BOOST_PYTHON_DECL object float_(double const& a0) { + return api_detail::get_func("float")(object(a0)); +} + +BOOST_PYTHON_DECL object getattr(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("getattr")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object getattr(object const& a0, const char * a1, object const& a2) { + return api_detail::get_func("getattr")(a0, object(a1), a2); +} + +BOOST_PYTHON_DECL object globals() { + return object((python::detail::borrowed_reference)::PyModule_GetDict(PyImport_AddModule("__main__"))); +} + +BOOST_PYTHON_DECL bool hasattr(object const& a0, object const& a1) { + return ::PyObject_HasAttr(a0.ptr(), a1.ptr()); +} + +BOOST_PYTHON_DECL bool hasattr(object const& a0, const char* a1) { + return ::PyObject_HasAttrString(a0.ptr(), const_cast(a1)); +} + +BOOST_PYTHON_DECL long hash(object const& a0) { + long r = ::PyObject_Hash(a0.ptr()); + if(r == -1) + throw_error_already_set(); + return r; +} + +BOOST_PYTHON_DECL object hex(object const& a0) { + return api_detail::get_func("hex")(a0); +} + +BOOST_PYTHON_DECL object hex(char a0) { + return api_detail::get_func("hex")(object(a0)); +} + +BOOST_PYTHON_DECL object hex(short a0) { + return api_detail::get_func("hex")(object(a0)); +} + +BOOST_PYTHON_DECL object hex(int a0) { + return api_detail::get_func("hex")(object(a0)); +} + +BOOST_PYTHON_DECL object hex(long a0) { + return api_detail::get_func("hex")(object(a0)); +} + +BOOST_PYTHON_DECL long id(object const& a0) { + object r(api_detail::get_func("id")(a0)); + return boost::python::arg_from_python(r.ptr())(r.ptr()); +} + +BOOST_PYTHON_DECL object input() { + return api_detail::get_func("input")(); +} + +BOOST_PYTHON_DECL object input(object const& a0) { + return api_detail::get_func("input")(a0); +} + +BOOST_PYTHON_DECL object input(const char* a0) { + return api_detail::get_func("input")(object(a0)); +} + +BOOST_PYTHON_DECL object int_(object const& a0) { + return api_detail::get_func("int")(a0); +} + +BOOST_PYTHON_DECL object int_(long a0) { + return api_detail::get_func("int")(object(a0)); +} + +BOOST_PYTHON_DECL object int_(const char* a0) { + return api_detail::get_func("int")(object(a0)); +} + +BOOST_PYTHON_DECL object intern(object const& a0) { + return api_detail::get_func("intern")(a0); +} + +BOOST_PYTHON_DECL object intern(const char* a0) { + return api_detail::get_func("intern")(object(a0)); +} + +BOOST_PYTHON_DECL bool isinstance(object const& a0, object const& a1) { + return ::PyObject_IsInstance(a0.ptr(), a1.ptr()); +} + +BOOST_PYTHON_DECL bool issubclass(object const& a0, object const& a1) { + return ::PyObject_IsSubclass(a0.ptr(), a1.ptr()); +} + +BOOST_PYTHON_DECL object iter(object const& a0) { + return object((python::detail::new_reference)::PyObject_GetIter(a0.ptr())); +} + +BOOST_PYTHON_DECL object iter(object const& a0, object const& a1) { + return api_detail::get_func("iter")(a0, a1); +} + +BOOST_PYTHON_DECL long len(object const& a0) { + long r = ::PyObject_Length(a0.ptr()); + if(r == -1) + throw_error_already_set(); + return r; +} + +BOOST_PYTHON_DECL object list() { + return api_detail::get_func("list")(); +} + +BOOST_PYTHON_DECL object list(object const& a0) { + return api_detail::get_func("list")(a0); +} + +BOOST_PYTHON_DECL object long_(object const& a0) { + return api_detail::get_func("long")(a0); +} + +BOOST_PYTHON_DECL object long_(long a0) { + return api_detail::get_func("long")(object(a0)); +} + +BOOST_PYTHON_DECL object long_(const char* a0) { + return api_detail::get_func("long")(object(a0)); +} + +BOOST_PYTHON_DECL object map(object const& a0) { + return api_detail::get_func("map")(a0); +} + +BOOST_PYTHON_DECL object map(object const& a0, object const& a1) { + return api_detail::get_func("map")(a0, a1); +} + +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("map")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3) { + return api_detail::get_func("map")(a0, a1, a2, a3); +} + +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { + return api_detail::get_func("map")(a0, a1, a2, a3, a4); +} + +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { + return api_detail::get_func("map")(a0, a1, a2, a3, a4, a5); +} + +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { + return api_detail::get_func("map")(a0, a1, a2, a3, a4, a5, a6); +} + +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { + return api_detail::get_func("map")(a0, a1, a2, a3, a4, a5, a6, a7); +} + +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { + return api_detail::get_func("map")(a0, a1, a2, a3, a4, a5, a6, a7, a8); +} + +BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { + return api_detail::get_func("map")(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); +} + +BOOST_PYTHON_DECL object max(object const& a0) { + return api_detail::get_func("max")(a0); +} + +BOOST_PYTHON_DECL object max(object const& a0, object const& a1) { + return api_detail::get_func("max")(a0, a1); +} + +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("max")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3) { + return api_detail::get_func("max")(a0, a1, a2, a3); +} + +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { + return api_detail::get_func("max")(a0, a1, a2, a3, a4); +} + +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { + return api_detail::get_func("max")(a0, a1, a2, a3, a4, a5); +} + +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { + return api_detail::get_func("max")(a0, a1, a2, a3, a4, a5, a6); +} + +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { + return api_detail::get_func("max")(a0, a1, a2, a3, a4, a5, a6, a7); +} + +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { + return api_detail::get_func("max")(a0, a1, a2, a3, a4, a5, a6, a7, a8); +} + +BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { + return api_detail::get_func("max")(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); +} + +BOOST_PYTHON_DECL object min(object const& a0) { + return api_detail::get_func("min")(a0); +} + +BOOST_PYTHON_DECL object min(object const& a0, object const& a1) { + return api_detail::get_func("min")(a0, a1); +} + +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("min")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3) { + return api_detail::get_func("min")(a0, a1, a2, a3); +} + +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { + return api_detail::get_func("min")(a0, a1, a2, a3, a4); +} + +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { + return api_detail::get_func("min")(a0, a1, a2, a3, a4, a5); +} + +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { + return api_detail::get_func("min")(a0, a1, a2, a3, a4, a5, a6); +} + +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { + return api_detail::get_func("min")(a0, a1, a2, a3, a4, a5, a6, a7); +} + +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { + return api_detail::get_func("min")(a0, a1, a2, a3, a4, a5, a6, a7, a8); +} + +BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { + return api_detail::get_func("min")(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); +} + +BOOST_PYTHON_DECL object oct(object const& a0) { + return api_detail::get_func("oct")(a0); +} + +BOOST_PYTHON_DECL object oct(char a0) { + return api_detail::get_func("oct")(object(a0)); +} + +BOOST_PYTHON_DECL object oct(short a0) { + return api_detail::get_func("oct")(object(a0)); +} + +BOOST_PYTHON_DECL object oct(int a0) { + return api_detail::get_func("oct")(object(a0)); +} + +BOOST_PYTHON_DECL object oct(long a0) { + return api_detail::get_func("oct")(object(a0)); +} + +BOOST_PYTHON_DECL object open(object const& a0) { + return api_detail::get_func("open")(a0); +} + +BOOST_PYTHON_DECL object open(const char* a0) { + return api_detail::get_func("open")(object(a0)); +} + +BOOST_PYTHON_DECL object open(object const& a0, object const& a1) { + return api_detail::get_func("open")(a0, a1); +} + +BOOST_PYTHON_DECL object open(const char* a0, const char* a1) { + return api_detail::get_func("open")(object(a0), object(a1)); +} + +BOOST_PYTHON_DECL object open(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("open")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object open(const char* a0, const char* a1, int a2) { + return api_detail::get_func("open")(object(a0), object(a1), object(a2)); +} + +BOOST_PYTHON_DECL long ord(object const& a0) { + object r(api_detail::get_func("ord")(a0)); + return boost::python::arg_from_python(r.ptr())(r.ptr()); +} + +BOOST_PYTHON_DECL long ord(const char* a0) { + object r(api_detail::get_func("ord")(object(a0))); + return boost::python::arg_from_python(r.ptr())(r.ptr()); +} + +BOOST_PYTHON_DECL object pow(object const& a0, object const& a1) { + return api_detail::get_func("pow")(a0, a1); +} + +BOOST_PYTHON_DECL object pow(double const& a0, double const& a1) { + return api_detail::get_func("pow")(object(a0), object(a1)); +} + +BOOST_PYTHON_DECL object pow(double const& a0, double const& a1, double const& a2) { + return api_detail::get_func("pow")(object(a0), object(a1), object(a2)); +} + +BOOST_PYTHON_DECL object print(object const& a0) { + return api_detail::call_statement_du("print _1", use_new_dict, 1, &a0); +} + +BOOST_PYTHON_DECL object print(object const& a0, object const& a1) { + return api_detail::call_statement_du("print _1, _2", use_new_dict, 2, &a0, &a1); +} + +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2) { + return api_detail::call_statement_du("print _1, _2, _3", use_new_dict, 3, &a0, &a1, &a2); +} + +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3) { + return api_detail::call_statement_du("print _1, _2, _3, _4", use_new_dict, 4, &a0, &a1, &a2, &a3); +} + +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { + return api_detail::call_statement_du("print _1, _2, _3, _4, _5", use_new_dict, 5, &a0, &a1, &a2, &a3, &a4); +} + +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { + return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6", use_new_dict, 6, &a0, &a1, &a2, &a3, &a4, &a5); +} + +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { + return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7", use_new_dict, 7, &a0, &a1, &a2, &a3, &a4, &a5, &a6); +} + +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { + return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8", use_new_dict, 8, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7); +} + +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { + return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8, _9", use_new_dict, 9, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8); +} + +BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { + return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8, _9, _10", use_new_dict, 10, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9); +} + +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1) { + return api_detail::call_statement_du("print >>_1, _2", use_new_dict, 2, &a0, &a1); +} + +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2) { + return api_detail::call_statement_du("print >>_1, _2, _3", use_new_dict, 3, &a0, &a1, &a2); +} + +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3) { + return api_detail::call_statement_du("print >>_1, _2, _3, _4", use_new_dict, 4, &a0, &a1, &a2, &a3); +} + +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5", use_new_dict, 5, &a0, &a1, &a2, &a3, &a4); +} + +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6", use_new_dict, 6, &a0, &a1, &a2, &a3, &a4, &a5); +} + +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7", use_new_dict, 7, &a0, &a1, &a2, &a3, &a4, &a5, &a6); +} + +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8", use_new_dict, 8, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7); +} + +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9", use_new_dict, 9, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8); +} + +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9, _10", use_new_dict, 10, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9); +} + +BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10) { + return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11", use_new_dict, 11, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10); +} + +BOOST_PYTHON_DECL object range(object const& a0) { + return api_detail::get_func("range")(a0); +} + +BOOST_PYTHON_DECL object range(int a0) { + return api_detail::get_func("range")(object(a0)); +} + +BOOST_PYTHON_DECL object range(object const& a0, object const& a1) { + return api_detail::get_func("range")(a0, a1); +} + +BOOST_PYTHON_DECL object range(int a0, int a1) { + return api_detail::get_func("range")(object(a0), object(a1)); +} + +BOOST_PYTHON_DECL object range(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("range")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object range(int a0, int a1, int a2) { + return api_detail::get_func("range")(object(a0), object(a1), object(a2)); +} + +BOOST_PYTHON_DECL object raw_input() { + return api_detail::get_func("raw_input")(); +} + +BOOST_PYTHON_DECL object raw_input(object const& a0) { + return api_detail::get_func("raw_input")(a0); +} + +BOOST_PYTHON_DECL object raw_input(const char* a0) { + return api_detail::get_func("raw_input")(object(a0)); +} + +BOOST_PYTHON_DECL object reduce(object const& a0, object const& a1) { + return api_detail::get_func("reduce")(a0, a1); +} + +BOOST_PYTHON_DECL object reduce(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("reduce")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object reload(object const& a0) { + return object((python::detail::new_reference)::PyImport_ReloadModule(a0.ptr())); +} + +BOOST_PYTHON_DECL object repr(object const& a0) { + return object((python::detail::new_reference)::PyObject_Repr(a0.ptr())); +} + +BOOST_PYTHON_DECL object round(object const& a0) { + return api_detail::get_func("round")(a0); +} + +BOOST_PYTHON_DECL object round(double const& a0) { + return api_detail::get_func("round")(object(a0)); +} + +BOOST_PYTHON_DECL object round(object const& a0, object const& a1) { + return api_detail::get_func("round")(a0, a1); +} + +BOOST_PYTHON_DECL object round(double const& a0, double const& a1) { + return api_detail::get_func("round")(object(a0), object(a1)); +} + +BOOST_PYTHON_DECL object slice(object const& a0) { + return api_detail::get_func("slice")(a0); +} + +BOOST_PYTHON_DECL object slice(int a0) { + return api_detail::get_func("slice")(object(a0)); +} + +BOOST_PYTHON_DECL object slice(object const& a0, object const& a1) { + return api_detail::get_func("slice")(a0, a1); +} + +BOOST_PYTHON_DECL object slice(int a0, int a1) { + return api_detail::get_func("slice")(object(a0), object(a1)); +} + +BOOST_PYTHON_DECL object slice(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("slice")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object slice(int a0, int a1, int a2) { + return api_detail::get_func("slice")(object(a0), object(a1), object(a2)); +} + +BOOST_PYTHON_DECL object str(object const& a0) { + return object((python::detail::new_reference)::PyObject_Str(a0.ptr())); +} + +BOOST_PYTHON_DECL object tuple() { + return api_detail::get_func("tuple")(); +} + +BOOST_PYTHON_DECL object tuple(object const& a0) { + return api_detail::get_func("tuple")(a0); +} + +BOOST_PYTHON_DECL object type_(object const& a0) { + return object((python::detail::new_reference)::PyObject_Type(a0.ptr())); +} + +BOOST_PYTHON_DECL object unichr(object const& a0) { + return api_detail::get_func("unichr")(a0); +} + +BOOST_PYTHON_DECL object unichr(short a0) { + return api_detail::get_func("unichr")(object(a0)); +} + +BOOST_PYTHON_DECL object unichr(int a0) { + return api_detail::get_func("unichr")(object(a0)); +} + +BOOST_PYTHON_DECL object unichr(long a0) { + return api_detail::get_func("unichr")(object(a0)); +} + +BOOST_PYTHON_DECL object unicode(object const& a0) { + return object((python::detail::new_reference)::PyObject_Unicode(a0.ptr())); +} + +BOOST_PYTHON_DECL object unicode(object const& a0, object const& a1) { + return api_detail::get_func("unicode")(a0, a1); +} + +BOOST_PYTHON_DECL object unicode(object const& a0, const char* a1) { + return api_detail::get_func("unicode")(a0, object(a1)); +} + +BOOST_PYTHON_DECL object unicode(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("unicode")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object unicode(object const& a0, const char* a1, const char* a2) { + return api_detail::get_func("unicode")(a0, object(a1), object(a2)); +} + +BOOST_PYTHON_DECL object vars() { + return api_detail::get_func("vars")(); +} + +BOOST_PYTHON_DECL object vars(object const& a0) { + return api_detail::get_func("vars")(a0); +} + +BOOST_PYTHON_DECL object xrange(object const& a0) { + return api_detail::get_func("xrange")(a0); +} + +BOOST_PYTHON_DECL object xrange(int a0) { + return api_detail::get_func("xrange")(object(a0)); +} + +BOOST_PYTHON_DECL object xrange(object const& a0, object const& a1) { + return api_detail::get_func("xrange")(a0, a1); +} + +BOOST_PYTHON_DECL object xrange(int a0, int a1) { + return api_detail::get_func("xrange")(object(a0), object(a1)); +} + +BOOST_PYTHON_DECL object xrange(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("xrange")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object xrange(int a0, int a1, int a2) { + return api_detail::get_func("xrange")(object(a0), object(a1), object(a2)); +} + +BOOST_PYTHON_DECL object zip(object const& a0) { + return api_detail::get_func("zip")(a0); +} + +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1) { + return api_detail::get_func("zip")(a0, a1); +} + +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2) { + return api_detail::get_func("zip")(a0, a1, a2); +} + +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3) { + return api_detail::get_func("zip")(a0, a1, a2, a3); +} + +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { + return api_detail::get_func("zip")(a0, a1, a2, a3, a4); +} + +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { + return api_detail::get_func("zip")(a0, a1, a2, a3, a4, a5); +} + +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { + return api_detail::get_func("zip")(a0, a1, a2, a3, a4, a5, a6); +} + +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { + return api_detail::get_func("zip")(a0, a1, a2, a3, a4, a5, a6, a7); +} + +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { + return api_detail::get_func("zip")(a0, a1, a2, a3, a4, a5, a6, a7, a8); +} + +BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { + return api_detail::get_func("zip")(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); +} + +BOOST_PYTHON_DECL object compile_string(const char* a0, const char* a1, int a2) { + return object((python::detail::new_reference)::Py_CompileString(const_cast(a0), const_cast(a1), a2)); +} + +BOOST_PYTHON_DECL int import_append_inittab(const char* a0, void(*a1)(void)) { + int r = ::PyImport_AppendInittab(const_cast(a0), a1); + if(r == -1) + throw_error_already_set(); + return r; +} + +BOOST_PYTHON_DECL object import_add_module(const char* a0) { + return object((python::detail::borrowed_reference)::PyImport_AddModule(const_cast(a0))); +} + +BOOST_PYTHON_DECL object import_get_module_dict() { + return object((python::detail::borrowed_reference)::PyImport_GetModuleDict()); +} + +BOOST_PYTHON_DECL object import_import(object const& a0) { + return object((python::detail::new_reference)::PyImport_Import(a0.ptr())); +} + +BOOST_PYTHON_DECL object import_import(const char* a0) { + return object((python::detail::new_reference)::PyImport_Import(object(a0).ptr())); +} + +BOOST_PYTHON_DECL object import_import_module(const char* a0) { + return object((python::detail::new_reference)::PyImport_ImportModule(const_cast(a0))); +} + +BOOST_PYTHON_DECL object import_import_module_ex(const char* a0, object const& a1, object const& a2, object const& a3) { + return object((python::detail::new_reference)::PyImport_ImportModuleEx(const_cast(a0), a1.ptr(), a2.ptr(), a3.ptr())); +} + +BOOST_PYTHON_DECL object module_get_dict(object const& a0) { + return object((python::detail::borrowed_reference)::PyModule_GetDict(a0.ptr())); +} + +BOOST_PYTHON_DECL int object_print(object const& a0, FILE* a1, int a2) { + int r = ::PyObject_Print(a0.ptr(), a1, a2); + if(r == -1) + throw_error_already_set(); + return r; +} + +BOOST_PYTHON_DECL object run_file(FILE* a0, const char* a1, int a2, object const& a3, object const& a4) { + return object((python::detail::new_reference)::PyRun_File(a0, const_cast(a1), a2, a3.ptr(), a4.ptr())); +} + +BOOST_PYTHON_DECL int run_simple_file(FILE* a0, const char* a1) { + int r = ::PyRun_SimpleFile(a0, const_cast(a1)); + if(r == -1) + throw_error_already_set(); + return r; +} + +BOOST_PYTHON_DECL int run_simple_string(const char* a0) { + int r = ::PyRun_SimpleString(const_cast(a0)); + if(r == -1) + throw_error_already_set(); + return r; +} + +BOOST_PYTHON_DECL object run_string(const char* a0, int a1, object const& a2, object const& a3) { + return object((python::detail::new_reference)::PyRun_String(const_cast(a0), a1, a2.ptr(), a3.ptr())); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0) { + return api_detail::call_statement(a0); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1) { + return api_detail::call_statement_du(a0, a1); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1) { + return api_detail::call_statement(a0, 1, &a1); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2) { + return api_detail::call_statement(a0, 2, &a1, &a2); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3) { + return api_detail::call_statement(a0, 3, &a1, &a2, &a3); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4) { + return api_detail::call_statement(a0, 4, &a1, &a2, &a3, &a4); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { + return api_detail::call_statement(a0, 5, &a1, &a2, &a3, &a4, &a5); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { + return api_detail::call_statement(a0, 6, &a1, &a2, &a3, &a4, &a5, &a6); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { + return api_detail::call_statement(a0, 7, &a1, &a2, &a3, &a4, &a5, &a6, &a7); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { + return api_detail::call_statement(a0, 8, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { + return api_detail::call_statement(a0, 9, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10) { + return api_detail::call_statement(a0, 10, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2) { + return api_detail::call_statement_du(a0, a1, 1, &a2); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3) { + return api_detail::call_statement_du(a0, a1, 2, &a2, &a3); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4) { + return api_detail::call_statement_du(a0, a1, 3, &a2, &a3, &a4); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5) { + return api_detail::call_statement_du(a0, a1, 4, &a2, &a3, &a4, &a5); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { + return api_detail::call_statement_du(a0, a1, 5, &a2, &a3, &a4, &a5, &a6); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { + return api_detail::call_statement_du(a0, a1, 6, &a2, &a3, &a4, &a5, &a6, &a7); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { + return api_detail::call_statement_du(a0, a1, 7, &a2, &a3, &a4, &a5, &a6, &a7, &a8); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { + return api_detail::call_statement_du(a0, a1, 8, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10) { + return api_detail::call_statement_du(a0, a1, 9, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10); +} + +BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10, object const& a11) { + return api_detail::call_statement_du(a0, a1, 10, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11); +} + + +}}} + diff --git a/test/Jamfile b/test/Jamfile index 77ff5c7c..0bde874d 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -93,6 +93,7 @@ run bases.cpp ; run if_else.cpp ; run pointee.cpp ; run result.cpp ; +run submod_subclass_api.cpp ../bpl : : : $(PYTHON_PROPERTIES) ; compile string_literal.cpp ; compile borrowed.cpp : $(UNIT_TEST_PROPERTIES) ; compile object_manager.cpp : $(UNIT_TEST_PROPERTIES) ; diff --git a/test/submod_subclass_api.cpp b/test/submod_subclass_api.cpp new file mode 100644 index 00000000..b2c5293e --- /dev/null +++ b/test/submod_subclass_api.cpp @@ -0,0 +1,231 @@ +// Copyright David Hawkes 2002. +// Permission is hereby granted to copy, use and modify this software +// for any purpose, including commercial distribution, provided this +// copyright notice is not removed. No warranty WHATSOEVER is provided with this +// software. Any user(s) accepts this software "as is" and as such they will not +// bind the author(s) to any claim of suitabilty for any purpose. + +// embed_test.cpp : substantial test of embedding python in c++ using boost + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace boost; +using namespace boost::python; + + +// The following macros are for our convenience and coding expediency... +// There is no particular recomendation that they be used elsewhere +// as they are not feature complete and are just sufficient to suport +// the code here + + +#define DEF(fn) def(#fn, fn) +#define DEF_C(c, fn) def(#fn, &c::fn) +#define DEF_C_CB(c, fn) def(#fn, &c##_callback::base_##fn) + +#define CLASS(c) class_ >(#c) +#define CLASS_CB(c) class_, noncopyable >(#c) + +#define START_CALLBACK_CLASS(c) \ +class c##_callback : public c \ +{ \ + typedef c __base__; \ +public: \ + c##_callback(PyObject* self) : m_self(self) {} \ +private: \ + PyObject* m_self; \ +public: + +#define END_CALLBACK_CLASS }; + + +#define CALLBACK_MEMBER0(fn, rtn) \ +rtn fn() { return call_method(m_self, #fn); } \ +rtn base_##fn() { return __base__::fn(); } + + +#define CALLBACK_MEMBER0C(fn, rtn) \ +rtn fn() const { return call_method(m_self, #fn); } \ +rtn base_##fn() const { return __base__::fn(); } +// End of convenience macros + +// useful support classes +template +struct class_object : public object +{ + typedef object base; + class_object() : m_class_ptr(NULL) {} + class_object(object const& o) : base(o) { init(); } + class_object& operator=(object const& o) + { + base::operator=(o); + init(); + return *this; + } + T* operator->() const { return m_class_ptr; } + T& operator*() const { return *m_class_ptr; } +private: + void init() + { + m_class_ptr = arg_from_python(ptr())(ptr()); + } + T* m_class_ptr; +}; + +template +struct item_object : public object +{ + typedef object base; + item_object() {} + item_object(object const& o) : base(o), m_class(arg_from_python(ptr())(ptr())) {} + item_object& operator=(object const& o) + { + base::operator=(o); + init(); + return *this; + } + operator T() { return m_class; } +private: + void init() + { + m_class = arg_from_python(ptr())(ptr()); + } + T m_class; +}; +// end of useful support classes + +// pass our args in this struct +struct main_args { + main_args(int _argc, char* _argv[]) : argc(_argc), argv(_argv) {} + int argc; + char** argv; +}; +int python_main(main_args const &ma); + +// python module init +BOOST_PYTHON_MODULE_INIT(python_main) +{ + DEF(python_main); + CLASS(main_args); +} + +// sub module tests +namespace sm { + +int test_func() { return 7; } + +BOOST_PYTHON_MODULE_INIT(sm_test) +{ + // define a submodule + boost::python::module(".sm"); + // define a 2nd submodule + boost::python::module(".sm.sm2"); + // define a test function to appear in 2nd submodule + DEF(test_func); +} + +// sub-module tests +int test() +{ + api::run_simple_string("import sm_test"); + if(api::call_statement("_0 = bpl_test('sub modules', sm_test.sm.sm2.test_func, _1)", test_func())) + return 1; + return 0; +} + +} + +// sub class tests +namespace sc { + +class c1 { +public: + c1() {} + class c2 { + public: + c2() : n(2) {} + int n; + }; + c2 t; +}; + +c1::c2 test_func() { + return c1().t; +} + +BOOST_PYTHON_MODULE_INIT(sc_test) +{ + class_("c1.c2") + .def_init() + .def_readwrite("n", &c1::c2::n); + CLASS(c1) + .def_init() + .def_readwrite("t", &c1::t); + DEF(test_func); +} + +// sub-class tests +int test() +{ + api::run_simple_string("import sc_test"); + if(api::call_statement("_0 = bpl_test('sub classes', lambda : sc_test.c1.c2().n, _1.n)", test_func())) + return 1; + if(api::call_statement("_0 = bpl_test('sub classes', lambda : sc_test.c1().t.n, _1.n)", test_func())) + return 1; + return 0; +} + +} + +// new main that will have a python execution frame +int main(int argc, char* argv[]) +{ + // default return value; + int rtn = 0; + // define all the built-in modules used + PyImport_AppendInittab("python_main", initpython_main); + PyImport_AppendInittab("sm_test", sm::initsm_test); + PyImport_AppendInittab("sc_test", sc::initsc_test); + // initialize python + Py_Initialize(); + // start a new block so that any objects are released prior to finalizing + { + // import our main module - this will also initialise boost + api::run_simple_string("import python_main"); + // We call back here so we have a proper python execution frame to work with + item_object o_rtn(api::call_statement("_0 = python_main.python_main(_1)", main_args(argc, argv))); + rtn = o_rtn; + } + // clean up + Py_Finalize(); + return rtn; +} + +char *bpl_test = +"def bpl_test(name, func, result):\n" +" print 'testing %s...' % name\n" +" if func() != result:\n" +" print 'failed'\n" +" return 1\n" +" else:\n" +" print 'OK'\n" +" return 0\n"; + + +int python_main(main_args const &ma) +{ + api::print("running...\n"); + api::call_statement(bpl_test); + if(sm::test()) + return 1; + if(sc::test()) + return 1; + return 0; +} From c2e115b6a520c5bc3579206d133d0591588ef482 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Jul 2002 14:05:31 +0000 Subject: [PATCH 0593/1042] Add missing typename [SVN r14493] --- include/boost/python/converter/arg_from_python.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp index 289b4945..585a30eb 100755 --- a/include/boost/python/converter/arg_from_python.hpp +++ b/include/boost/python/converter/arg_from_python.hpp @@ -168,10 +168,10 @@ struct select_arg_from_python typedef typename mpl::select_type< obj_mgr , object_manager_value_arg_from_python - , mpl::select_type< + , typename mpl::select_type< obj_mgr_ref , object_manager_ref_arg_from_python - , mpl::select_type< + , typename mpl::select_type< ptr , pointer_arg_from_python , typename mpl::select_type< From bd72ee9cd1e757c3ad158f39dcd35e39490adffe Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Jul 2002 14:05:53 +0000 Subject: [PATCH 0594/1042] Add missing #include [SVN r14494] --- include/boost/python/converter/obj_mgr_arg_from_python.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/python/converter/obj_mgr_arg_from_python.hpp b/include/boost/python/converter/obj_mgr_arg_from_python.hpp index 58cf85e4..77e1ab8e 100644 --- a/include/boost/python/converter/obj_mgr_arg_from_python.hpp +++ b/include/boost/python/converter/obj_mgr_arg_from_python.hpp @@ -11,6 +11,7 @@ # include # include # include +# include // // arg_from_python converters for Python type wrappers, to be used as From 9d5e8b9ad801c8766bca82d96d84aea453863545 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Jul 2002 14:06:15 +0000 Subject: [PATCH 0595/1042] Bug fix [SVN r14495] --- src/converter/from_python.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 30c31f4f..bac7f2f7 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -29,8 +29,9 @@ namespace boost { namespace python { namespace converter { // type T. Indicates a successful lvalue conversion // // 3. where y is of type rvalue_from_python_data, -// x.construct(source, y) attempts to construct an object of type T -// in y. Indicates an rvalue converter was found +// x.construct(source, y) constructs an object of type T +// in y.storage.bytes and then sets y.convertible == y.storage.bytes, +// or else throws an exception and has no effect. BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( PyObject* source , registration const& converters) @@ -231,7 +232,7 @@ pytype_result_from_python(PyTypeObject* type_, PyObject* source) handle<> msg( ::PyString_FromFormat( "Expecting a Python %s return type, but got an object of type %s instead" - , type_ + , type_->tp_name , source->ob_type->tp_name )); PyErr_SetObject(PyExc_TypeError, msg.get()); From 6ac5735d145a50bb613148118ca3d2e4cde3ec4c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Jul 2002 18:31:02 +0000 Subject: [PATCH 0596/1042] MSVC fixes [SVN r14500] --- include/boost/python/detail/construct.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/construct.hpp b/include/boost/python/detail/construct.hpp index 55c0873f..f7b747f6 100644 --- a/include/boost/python/detail/construct.hpp +++ b/include/boost/python/detail/construct.hpp @@ -9,7 +9,13 @@ namespace boost { namespace python { namespace detail { template -void construct_pointee(void* storage, Arg& x, T const volatile*) +void construct_pointee(void* storage, Arg& x +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + , T const volatile* +# else + , T const* +# endif + ) { new (storage) T(x); } From f9a67b34b2ca4dc2fad96f8207dee8091a6956d6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Jul 2002 18:36:14 +0000 Subject: [PATCH 0597/1042] Roll back most of Dave Hawkes' changes for the time being. [SVN r14501] --- include/boost/python/class.hpp | 38 +----- include/boost/python/detail/module_base.hpp | 16 --- include/boost/python/detail/module_init.hpp | 18 +-- include/boost/python/module.hpp | 27 +--- include/boost/python/object/class.hpp | 5 - src/module.cpp | 137 +------------------- src/object/class.cpp | 117 +---------------- test/Jamfile | 2 +- 8 files changed, 19 insertions(+), 341 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index d2a4a2f0..861d8e72 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -14,7 +14,6 @@ # include # include # include -# include # include # include # include @@ -87,12 +86,12 @@ 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_(base const& parent_class = empty_class_base()); + class_(); // Construct with the class name. [ Would have used a default // argument but gcc-2.95.2 choked on typeid(T).name() as a default // parameter value] - class_(char const* name, base const& parent_class = empty_class_base()); + class_(char const* name); // Wrap a member function or a non-member function which can take @@ -196,22 +195,6 @@ class class_ : public objects::class_base self& setattr(char const* name, handle<> const&); - // add to module - self& add(module &m) - { - // redundant - // m.add(*this); - return *this; - } - - // add to current module - self& add() - { - // redundant - // boost::python::add(*this); - return *this; - } - private: // types typedef objects::class_id class_id; @@ -248,7 +231,7 @@ class class_ : public objects::class_base // implementations // template -inline class_::class_(base const& parent_class) +inline class_::class_() : base(typeid(T).name(), id_vector::size, id_vector().ids) { // register converters @@ -258,16 +241,10 @@ inline class_::class_(base const& parent_class) mpl::bool_t() , objects::select_holder((held_type*)0).get() , this->object()); - - // get the context to add the class to - handle<> parent(parent_class.object() ? handle<>(parent_class.object()) : - base::get_class_context_object(typeid(T).name(), object())); - // add the class to the current module - boost::python::detail::module_base::add(object(), parent); } template -inline class_::class_(char const* name, base const& parent_class) +inline class_::class_(char const* name) : base(name, id_vector::size, id_vector().ids) { // register converters @@ -277,14 +254,9 @@ inline class_::class_(char const* name, base const& parent_class) mpl::bool_t() , objects::select_holder((held_type*)0).get() , this->object()); - - // get the context to add the class to - handle<> parent(parent_class.object() ? handle<>(parent_class.object()) : - base::get_class_context_object(name, object())); - // add the class to the current module - boost::python::detail::module_base::add(object(), parent); } + template inline class_& class_::add_property(char const* name, handle<> const& fget) { diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp index 71044c96..aaa6a135 100644 --- a/include/boost/python/detail/module_base.hpp +++ b/include/boost/python/detail/module_base.hpp @@ -10,8 +10,6 @@ namespace boost { namespace python { namespace detail { -class module_info; - class BOOST_PYTHON_DECL module_base { public: @@ -23,22 +21,14 @@ class BOOST_PYTHON_DECL module_base void setattr(const char* name, PyObject*); void setattr(const char* name, handle<> const&); void add(type_handle const&); // just use the type's name - static module_info* get_module_info(); - static void set_module_info(module_info& mi); - static handle<> get_prior_module(); - static void set_prior_module(handle<> const& m); - static void add(type_handle const& class_obj, handle<> const& context); // Return a reference to the Python module object being built inline handle<> object() const; protected: - module_base(handle<> const &m) : m_module(m) {} void add_class(type_handle const& class_obj); - void add_class(type_handle const& class_obj, handle<> const& context); private: - static module_info*& get_module_info_ref(); handle<> m_module; static PyMethodDef initial_methods[1]; }; @@ -51,12 +41,6 @@ inline handle<> module_base::object() const return m_module; } -inline void module_base::add(type_handle const& class_obj, handle<> const& context) -{ - module_base mb(get_prior_module()); - mb.add_class(class_obj, context); -} - }}} // namespace boost::python::detail #endif // MODULE_BASE_DWA2002227_HPP diff --git a/include/boost/python/detail/module_init.hpp b/include/boost/python/detail/module_init.hpp index 79a55119..5b5ce9f5 100644 --- a/include/boost/python/detail/module_init.hpp +++ b/include/boost/python/detail/module_init.hpp @@ -8,23 +8,13 @@ # ifndef BOOST_PYTHON_MODULE_INIT -# define PRE_INIT_FUNC(name) \ -void init_module_base_##name() \ -{ \ - boost::python::detail::module_info mi(#name); \ - boost::python::detail::module_base::set_module_info(mi); \ - boost::python::module(); \ - init_module_##name(); \ -} - # if defined(_WIN32) || defined(__CYGWIN__) # define BOOST_PYTHON_MODULE_INIT(name) \ void init_module_##name(); \ -PRE_INIT_FUNC(name) \ extern "C" __declspec(dllexport) void init##name() \ { \ - boost::python::handle_exception(&init_module_base_##name); \ + boost::python::handle_exception(&init_module_##name); \ } \ void init_module_##name() @@ -32,14 +22,13 @@ void init_module_##name() # include # define BOOST_PYTHON_MODULE_INIT(name) \ -PRE_INIT_FUNC(name) \ void init_module_##name(); \ extern "C" \ { \ extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \ void init##name() \ { \ - boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_base_##name); \ + boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_##name); \ } \ } \ void init_module_##name() @@ -47,11 +36,10 @@ void init_module_##name() # else # define BOOST_PYTHON_MODULE_INIT(name) \ -PRE_INIT_FUNC(name) \ void init_module_##name(); \ extern "C" void init##name() \ { \ - boost::python::handle_exception(&init_module_base_##name); \ + boost::python::handle_exception(&init_module_##name); \ } \ void init_module_##name() diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index d32e0935..8ee63485 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -13,7 +13,6 @@ # include # include # include -# include namespace boost { namespace python { @@ -22,7 +21,7 @@ class module : public detail::module_base public: typedef detail::module_base base; - module(const char* name = "") + module(const char* name) : base(name) {} // Add elements to the module @@ -34,8 +33,7 @@ class module : public detail::module_base template module& add(class_ const& c) { - // redundant - // this->add_class(c.object()); + this->add_class(c.object()); return *this; } @@ -53,14 +51,6 @@ class module : public detail::module_base this->setattr(name, boost::python::make_function(fn, handler)); return *this; } - - static module get_prior_module() - { - return module(module_base::get_prior_module()); - } - - private: - module(handle<> const& m) : base(m) {} }; // @@ -90,19 +80,6 @@ inline module& module::add(PyTypeObject* x) return *this; } -template -inline void def(char const* name, Fn fn) -{ - module::get_prior_module().def(name, fn); -} - - -template -inline void def(char const* name, Fn fn, ResultHandler handler) -{ - module::get_prior_module().def(name, fn, handler); -} - }} // namespace boost::python #endif // MODULE_DWA20011221_HPP diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 8e4cf586..8cf29b23 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -39,12 +39,7 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable void add_property(char const* name, handle<> const& fget); void add_property(char const* name, handle<> const& fget, handle<> const& fset); void setattr(char const* name, handle<> const&); - static handle<> get_class_context_object(const char* name, type_handle const& class_obj); - protected: - static class_base const& empty_class_base(); private: - // construct an empty base class - class_base(); type_handle m_object; }; diff --git a/src/module.cpp b/src/module.cpp index 9fe86adf..f7edf39e 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -7,107 +7,16 @@ // producing this work. #include -#include -#include #include -#include #include namespace boost { namespace python { namespace detail { -namespace { - -object getattr_or_none(object const &obj, const char *name) -{ - if(PyObject_HasAttrString(obj.ptr(), const_cast(name))) - return obj.attr(name); - else - return object(); -} - -// Initialise a new sub-module, or return an existing one. -// This will also create any missing parents along the way. -handle<> init_sub_module(const char* name, PyMethodDef *initial_methods, module_info* pmi) -{ - if(name == NULL) - // just create a dummy module with an empty reference - return handle<>(); - // initialise various iterators, etc. - object parent_module(pmi->get_module()), current_module(parent_module); - std::string s_name(name), b_name; - if(s_name.size() == 0) - // use the default module name if it is not supplied - s_name = pmi->get_module_name(); - std::string::size_type p_pos(0); - for(int l = 0;;++l) { - // find the next module name in the 'dotted' name - std::string::size_type dot_pos = s_name.find('.', p_pos); - // p_pos is the absolute position, but the length is needed - if(dot_pos != std::string::npos) - dot_pos -= p_pos; - // the current module name being processed, iterating from the parent - // to the right hand sub-modules - b_name = s_name.substr(p_pos, dot_pos); - if(l == 0) { - // process the top level parent module name - if(dot_pos == 0) - // allow a shortcut module notation so we can do module(".submodule") - b_name = pmi->get_module_name(); - // check the base name is the correct parent name else assert - assert(b_name.compare(pmi->get_module_name()) == 0); - if(!parent_module) { - // The main parent module does not exist yet, so create it here - parent_module = object(python::borrowed(Py_InitModule( - const_cast(b_name.c_str()), - initial_methods))); - // and set up the module iterator - current_module = parent_module; - // initialise the global parent module so it can be found later - pmi->set_module(parent_module); - } - } else { - // now processing a sub-module - // try to find and verify an existing sub-module of the correct name and type - object existing_sub_module(getattr_or_none(current_module, b_name.c_str())); - if(existing_sub_module) { - // An attribute of the same name has been found - object module_type((python::detail::new_reference)PyObject_Type(parent_module.ptr())); - // test its type against the parent - if(!PyObject_IsSubclass(existing_sub_module.ptr(), module_type.ptr())) - // not actually a module, so it can't be used - existing_sub_module = object(); - } - // was an existing sub-module found ? - if(!existing_sub_module) { - // no, then it is created here - // build up the full path name up to and including the current sub-module - std::string full_name(s_name.substr(0, dot_pos)); - // create the module - existing_sub_module = object(python::borrowed(Py_InitModule( - const_cast(full_name.c_str()), - initial_methods))); - // add the sub-module to the attributes of its immediate parent - current_module.attr(b_name.c_str()) = existing_sub_module; - } - // we now have a new current module to iterate - current_module = existing_sub_module; - } - // no more modules ? - if(dot_pos == std::string::npos) - break; - // advance over the dot - p_pos += dot_pos + 1; - } - // return the actual sub-module that was either found or created - return handle<>(python::borrowed(current_module.ptr())); -} - -} - module_base::module_base(const char* name) - : m_module(init_sub_module(name, initial_methods, get_module_info())) + : m_module( + python::borrowed(Py_InitModule(const_cast(name), initial_methods)) + ) { - set_prior_module(m_module); } module_base::~module_base() @@ -133,16 +42,7 @@ void module_base::add(type_handle const& x) void module_base::add_class(type_handle const& class_obj) { - add_class(class_obj, objects::class_base:: - get_class_context_object(class_obj.get()->tp_name, class_obj)); -} - -void module_base::add_class(type_handle const& class_obj, handle<> const& context) -{ - if(context.get()) { - objects::function:: - add_to_namespace(context, ((PyTypeObject*)class_obj.get())->tp_name, class_obj); - } + this->add(class_obj); handle<> module_name( PyObject_GetAttrString( @@ -150,38 +50,13 @@ void module_base::add_class(type_handle const& class_obj, handle<> const& contex ); int status = PyObject_SetAttrString( - handle<>(class_obj).get(), const_cast("__module__"), module_name.get()); + python::upcast(class_obj.get()) + , const_cast("__module__"), module_name.get()); if (status == -1) throw_error_already_set(); } -void module_base::set_module_info(module_info & mi) -{ - get_module_info_ref() = &mi; -} - -module_info* module_base::get_module_info() -{ - return get_module_info_ref(); -} - -module_info*& module_base::get_module_info_ref() -{ - static module_info* pmi = NULL; - return pmi; -} - -void module_base::set_prior_module(handle<> const& m) -{ - get_module_info()->set_prior_module(python::object(m)); -} - -handle<> module_base::get_prior_module() -{ - return handle<>(python::borrowed(get_module_info()->get_prior_module().ptr())); -} - PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; }}} // namespace boost::python::detail diff --git a/src/object/class.cpp b/src/object/class.cpp index f2c602f6..e49df96f 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -3,13 +3,10 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include #include #include #include #include -#include -#include #include #include #include @@ -249,12 +246,6 @@ namespace objects char const* name, std::size_t num_types, class_id const* const types) { assert(num_types >= 1); - - // is this class already registered? - m_object = query_class(types[0]); - if(m_object.get()) { - return; - } // Build a tuple of the base Python type objects. If no bases // were declared, we'll use our class_type() as the single base @@ -269,15 +260,9 @@ namespace objects PyTuple_SET_ITEM(bases.get(), i - 1, upcast(c.release())); } - // we now need just the base name - std::string base_name(name); - std::string::size_type dot_pos = base_name.rfind('.'); - if(dot_pos != std::string::npos) - base_name = base_name.substr(dot_pos + 1); - // Build the (name, bases, dict) tuple for creating the new class handle<> args(PyTuple_New(3)); - PyTuple_SET_ITEM(args.get(), 0, incref(python::object(base_name.c_str()).ptr())); + PyTuple_SET_ITEM(args.get(), 0, incref(python::object(name).ptr())); PyTuple_SET_ITEM(args.get(), 1, bases.release()); handle<> d(PyDict_New()); PyTuple_SET_ITEM(args.get(), 2, d.release()); @@ -319,107 +304,9 @@ namespace objects throw_error_already_set(); } - namespace { - class empty_class {}; - - void transfer_attributes(object const& src, object const& dst) - { - object attrs((python::detail::new_reference)PyObject_Dir(src.ptr())); - if(PyList_Check(attrs.ptr())) { - int sz = PyList_Size(attrs.ptr()); - for(int i = 0; i < sz; i++) { - PyObject *attr_name = PyList_GET_ITEM(attrs.ptr(), i); - object attr((python::detail::new_reference)PyObject_GetAttr(src.ptr(), attr_name)); - // only transfer boost classes - if(attr.ptr()->ob_type == &class_metatype_object) - PyObject_SetAttr(dst.ptr(), attr_name, attr.ptr()); - } - } - } - - - object getattr_or_none(object const &obj, const char *name) - { - if(PyObject_HasAttrString(obj.ptr(), const_cast(name))) - return obj.attr(name); - else - return object(); - } - - } - - // get a class context for nested classes - handle<> class_base::get_class_context_object(const char* name, type_handle const& class_obj) - { - // initialise various iterators, etc. - std::string s_name(name), b_name; - std::string::size_type p_pos(0); - python::object current_object(python::detail::module_base::get_prior_module()); - for(;;) { - // find the next class name in the 'dotted' name - std::string::size_type dot_pos = s_name.find('.', p_pos); - // have we completed up to the current class ? - // p_pos is the absolute position, but the length is needed - if(dot_pos != std::string::npos) - dot_pos -= p_pos; - // the current class name being processed, iterating from left to right - b_name = s_name.substr(p_pos, dot_pos); - if(dot_pos == std::string::npos) { - // this is the last class in the chain, is it here already - python::object existing_object(getattr_or_none(current_object, b_name.c_str())); - if(existing_object) { - // yes - if(PyObject_TypeCheck(existing_object.ptr(), &PyType_Type)) { - PyTypeObject *pType = (PyTypeObject *) existing_object.ptr(); - // is it one of ours? - if(pType->ob_type == &class_metatype_object) { - // then lets see if its our empty_class - type_handle r = query_class(python::type_id()); - // is it registered as the empty_class? - if(r.get() == pType) { - // yes, then we can transfer attributes - transfer_attributes(python::object(handle<>(r)), python::object(handle<>(class_obj))); - } else { - // the user must have created it already. - // so we don't need to add it - return handle<>(); - } - } - } - } - break; - } - // try to find an existing parent of the nested class - current_object = getattr_or_none(current_object, b_name.c_str()); - if(!current_object) { - // If we can't find it then insert a temporary class as a marker - std::string full_name(s_name.substr(0, dot_pos)); - current_object = python::object(handle<>(boost::python::class_(full_name.c_str()).object())); - } - // we now have a new current object to iterate - // note that we could attach the nested class to something other - // than a parent class here as we are not testing the type, - // does this really matter? - // advance over the dot - p_pos += dot_pos + 1; - } - // return the actual sub-module that was either found or created - return handle<>(python::borrowed(current_object.ptr())); - } - - class_base::class_base() - { - } - - class_base const& class_base::empty_class_base() - { - static class_base ecb; - return ecb; - } - BOOST_PYTHON_DECL type_handle registered_class_object(class_id id) { - return query_class(id); + return objects::query_class(id); } } // namespace objects diff --git a/test/Jamfile b/test/Jamfile index 0bde874d..db78d895 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -93,7 +93,7 @@ run bases.cpp ; run if_else.cpp ; run pointee.cpp ; run result.cpp ; -run submod_subclass_api.cpp ../bpl : : : $(PYTHON_PROPERTIES) ; + compile string_literal.cpp ; compile borrowed.cpp : $(UNIT_TEST_PROPERTIES) ; compile object_manager.cpp : $(UNIT_TEST_PROPERTIES) ; From a6c859c9ccb1ed47f70b2751ceb2ad1a7222d5fe Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 17 Jul 2002 19:58:05 +0000 Subject: [PATCH 0598/1042] Roll back most of Dave Hawkes' changes for the time being. [SVN r14503] --- Jamfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Jamfile b/Jamfile index 503db998..192982f6 100644 --- a/Jamfile +++ b/Jamfile @@ -23,7 +23,6 @@ dll bpl src/object/function.cpp src/object/inheritance.cpp src/object/life_support.cpp - src/py_interface.cpp src/errors.cpp src/module.cpp src/objects2.cpp From a9baa519f3e0d389a9c20cd443272e3d59ff2c81 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 18 Jul 2002 05:00:34 +0000 Subject: [PATCH 0599/1042] Extract implemented [SVN r14510] --- .../always_extract_object_manager.hpp | 35 --- .../boost/python/converter/from_python.hpp | 5 + .../converter/obj_mgr_arg_from_python.hpp | 4 +- .../boost/python/converter/object_manager.hpp | 14 +- ...r.hpp => pytype_object_manager_traits.hpp} | 18 +- .../python/converter/return_from_python.hpp | 2 +- include/boost/python/extract.hpp | 239 ++++++++++++++++++ include/boost/python/list.hpp | 6 +- include/boost/python/long.hpp | 6 +- include/boost/python/object_core.hpp | 28 +- src/converter/from_python.cpp | 98 ++++--- test/Jamfile | 2 + test/extract.cpp | 118 +++++++++ test/extract.py | 102 ++++++++ 14 files changed, 568 insertions(+), 109 deletions(-) delete mode 100644 include/boost/python/converter/always_extract_object_manager.hpp rename include/boost/python/converter/{pytype_extract_object_manager.hpp => pytype_object_manager_traits.hpp} (67%) create mode 100644 include/boost/python/extract.hpp create mode 100644 test/extract.cpp create mode 100644 test/extract.py diff --git a/include/boost/python/converter/always_extract_object_manager.hpp b/include/boost/python/converter/always_extract_object_manager.hpp deleted file mode 100644 index 02f18143..00000000 --- a/include/boost/python/converter/always_extract_object_manager.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef ALWAYS_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP -# define ALWAYS_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP - -# include - -namespace boost { namespace python { namespace converter { - -// Derive specializations of extract_object_manager from this when the -// object manager is indiscriminate about the Python objects it manages -struct always_extract_object_manager -{ - BOOST_STATIC_CONSTANT(bool, is_specialized = true); - static inline bool check(PyObject* x); -}; - -// Provide a forward declaration as a convenience for clients, who all -// need it. -template struct extract_object_manager; - -// -// implementations -// -inline bool always_extract_object_manager::check(PyObject* x) -{ - return true; -} - -}}} // namespace boost::python::converter - -#endif // ALWAYS_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index 26373ce0..dabafcaa 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -24,6 +24,9 @@ BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( PyObject* source, registration const&); +BOOST_PYTHON_DECL void* rvalue_from_python_stage2( + PyObject* source, rvalue_from_python_stage1_data&, registration const&); + BOOST_PYTHON_DECL void* rvalue_result_from_python( PyObject*, rvalue_from_python_stage1_data&); @@ -32,6 +35,8 @@ BOOST_PYTHON_DECL void* pointer_result_from_python(PyObject*, registration const BOOST_PYTHON_DECL void void_result_from_python(PyObject*); +BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject*, registration const&); +BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject*, registration const&); }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/obj_mgr_arg_from_python.hpp b/include/boost/python/converter/obj_mgr_arg_from_python.hpp index 77e1ab8e..ee0980a5 100644 --- a/include/boost/python/converter/obj_mgr_arg_from_python.hpp +++ b/include/boost/python/converter/obj_mgr_arg_from_python.hpp @@ -57,7 +57,7 @@ inline object_manager_value_arg_from_python::object_manager_value_arg_from_py template inline bool object_manager_value_arg_from_python::convertible() const { - return extract_object_manager::check(m_source); + return object_manager_traits::check(m_source); } template @@ -83,7 +83,7 @@ namespace detail template inline bool object_manager_ref_check(T const& x) { - return extract_object_manager::check((get_managed_object)(x)); + return object_manager_traits::check((get_managed_object)(x)); } } diff --git a/include/boost/python/converter/object_manager.hpp b/include/boost/python/converter/object_manager.hpp index ac0ceb02..b9d64286 100755 --- a/include/boost/python/converter/object_manager.hpp +++ b/include/boost/python/converter/object_manager.hpp @@ -39,13 +39,15 @@ namespace boost { namespace python { namespace converter { // // X::is_specialized == true // -// T(X::execute(p)) - constructs a T object from p, or throws a -// TypeError exception if p doesn't have an appropriate type. +// T(X::adopt(p)) - constructs a T object, stealing a reference to +// p, or throws a TypeError exception if p doesn't have an +// appropriate type. // -// X::check(p), convertible to bool. True iff T(X::execute(p)) will +// X::check(p), convertible to bool. True iff T(X::construct(p)) will // not throw. +// template -struct extract_object_manager +struct object_manager_traits { BOOST_STATIC_CONSTANT(bool, is_specialized = false); }; @@ -58,9 +60,9 @@ struct is_object_manager // handle the cases that would otherwise require partial specialization BOOST_STATIC_CONSTANT(bool, hdl = is_handle::value); BOOST_STATIC_CONSTANT(bool, borrowed = python::detail::is_borrowed_ptr::value); - BOOST_STATIC_CONSTANT(bool, extract_specialized = extract_object_manager::is_specialized); + BOOST_STATIC_CONSTANT(bool, traits_specialized = object_manager_traits::is_specialized); public: - BOOST_STATIC_CONSTANT(bool, value = (hdl | borrowed | extract_specialized)); + BOOST_STATIC_CONSTANT(bool, value = (hdl | borrowed | traits_specialized)); }; # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION diff --git a/include/boost/python/converter/pytype_extract_object_manager.hpp b/include/boost/python/converter/pytype_object_manager_traits.hpp similarity index 67% rename from include/boost/python/converter/pytype_extract_object_manager.hpp rename to include/boost/python/converter/pytype_object_manager_traits.hpp index cd4cadc9..24893ea5 100644 --- a/include/boost/python/converter/pytype_extract_object_manager.hpp +++ b/include/boost/python/converter/pytype_object_manager_traits.hpp @@ -3,8 +3,8 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef PYTYPE_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP -# define PYTYPE_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP +#ifndef PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP +# define PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP # include # include @@ -15,16 +15,16 @@ namespace boost { namespace python { namespace converter { // Provide a forward declaration as a convenience for clients, who all // need it. -template struct extract_object_manager; +template struct object_manager_traits; -// Derive specializations of extract_object_manager from this class +// Derive specializations of object_manager_traits from this class // when T is an object manager for a particular Python type hierarchy. // template -struct pytype_extract_object_manager +struct pytype_object_manager_traits { BOOST_STATIC_CONSTANT(bool, is_specialized = true); - static inline python::detail::new_reference execute(PyObject*); + static inline python::detail::new_reference adopt(PyObject*); static inline bool check(PyObject* x); }; @@ -32,17 +32,17 @@ struct pytype_extract_object_manager // implementations // template -inline python::detail::new_reference pytype_extract_object_manager::execute(PyObject* x) +inline python::detail::new_reference pytype_object_manager_traits::adopt(PyObject* x) { return pytype_result_from_python(pytype, x); } template -inline bool pytype_extract_object_manager::check(PyObject* x) +inline bool pytype_object_manager_traits::check(PyObject* x) { return ::PyObject_IsInstance(x, python::upcast(pytype)); } }}} // namespace boost::python::converter -#endif // PYTYPE_EXTRACT_OBJECT_MANAGER_DWA2002716_HPP +#endif // PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 1f2d74cf..490d4bf7 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -140,7 +140,7 @@ namespace detail inline T return_object_manager_from_python::operator()(PyObject* obj) const { return T( - extract_object_manager::execute(obj) + object_manager_traits::adopt(obj) ); } } diff --git a/include/boost/python/extract.hpp b/include/boost/python/extract.hpp new file mode 100644 index 00000000..18d8c5c2 --- /dev/null +++ b/include/boost/python/extract.hpp @@ -0,0 +1,239 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef EXTRACT_DWA200265_HPP +# define EXTRACT_DWA200265_HPP + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +namespace converter +{ + template + struct extract_pointer + { + typedef Ptr result_type; + extract_pointer(PyObject*); + + bool check() const; + Ptr operator()() const; + + private: + PyObject* m_source; + void* m_result; + }; + + template + struct extract_reference + { + typedef Ref result_type; + extract_reference(PyObject*); + + bool check() const; + Ref operator()() const; + + private: + PyObject* m_source; + void* m_result; + }; + + template + struct extract_rvalue : private noncopyable + { + typedef typename call_traits::param_type result_type; + extract_rvalue(PyObject*); + + bool check() const; + result_type operator()() const; + private: + PyObject* m_source; + mutable rvalue_from_python_data m_data; + }; + + template + struct extract_object_manager + { + typedef T result_type; + extract_object_manager(PyObject*); + + bool check() const; + result_type operator()() const; + private: + PyObject* m_source; + }; + + template + struct select_extract + { + BOOST_STATIC_CONSTANT( + bool, obj_mgr = is_object_manager::value); + + BOOST_STATIC_CONSTANT( + bool, ptr = is_pointer::value); + + BOOST_STATIC_CONSTANT( + bool, ref = is_reference::value); + + typedef typename mpl::select_type< + obj_mgr + , extract_object_manager + , typename mpl::select_type< + ptr + , extract_pointer + , typename mpl::select_type< + ref + , extract_reference + , extract_rvalue + >::type + >::type + >::type type; + }; +} + +template +struct extract + : converter::select_extract::type +{ + private: + typedef typename converter::select_extract::type base; + typedef bool (extract::*bool_type)() const; + public: + typedef typename base::result_type result_type; + operator result_type() const + { + return (*this)(); + } + + extract(PyObject*); + extract(object const&); +}; + +// +// Implementations +// +template +inline extract::extract(PyObject* o) + : base(o) +{ +} + +template +inline extract::extract(object const& o) + : base(o.ptr()) +{ +} + +namespace converter +{ + template + inline extract_rvalue::extract_rvalue(PyObject* x) + : m_source(x) + , m_data( + (rvalue_from_python_stage1)(x, registered::converters) + ) + { + } + + template + inline bool + extract_rvalue::check() const + { + return m_data.stage1.convertible; + } + + template + inline typename extract_rvalue::result_type + extract_rvalue::operator()() const + { + return *(T*)( + // Only do the stage2 conversion once + m_data.stage1.convertible == m_data.storage.bytes + ? m_data.storage.bytes + : (rvalue_from_python_stage2)(m_source, m_data.stage1, registered::converters) + ); + } + + template + inline extract_reference::extract_reference(PyObject* obj) + : m_source(obj) + , m_result( + (get_lvalue_from_python)(obj, registered::converters) + ) + { + } + + template + inline bool extract_reference::check() const + { + return m_result != 0; + } + + template + inline Ref extract_reference::operator()() const + { + if (m_result == 0) + (throw_no_reference_from_python)(m_source, registered::converters); + + return python::detail::void_ptr_to_reference(m_result, (Ref(*)())0); + } + + template + inline extract_pointer::extract_pointer(PyObject* obj) + : m_source(obj) + , m_result( + obj == Py_None ? 0 : (get_lvalue_from_python)(obj, registered_pointee::converters) + ) + { + } + + template + inline bool extract_pointer::check() const + { + return m_source == Py_None || m_result != 0; + } + + template + inline Ptr extract_pointer::operator()() const + { + if (m_result == 0 && m_source != Py_None) + (throw_no_pointer_from_python)(m_source, registered_pointee::converters); + + return Ptr(m_result); + } + + template + inline extract_object_manager::extract_object_manager(PyObject* obj) + : m_source(obj) + { + } + + template + inline bool extract_object_manager::check() const + { + return object_manager_traits::check(m_source); + } + + template + inline T extract_object_manager::operator()() const + { + return T( + object_manager_traits::adopt(python::incref(m_source)) + ); + } +} + +}} // namespace boost::python::converter + +#endif // EXTRACT_DWA200265_HPP diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp index 63ee469b..8cff1670 100644 --- a/include/boost/python/list.hpp +++ b/include/boost/python/list.hpp @@ -7,7 +7,7 @@ # define LIST_DWA2002627_HPP # include -# include +# include namespace boost { namespace python { @@ -106,8 +106,8 @@ class list : public object namespace converter { template <> - struct extract_object_manager - : pytype_extract_object_manager<&PyList_Type,list> + struct object_manager_traits + : pytype_object_manager_traits<&PyList_Type,list> { }; } diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp index 0f1fcdf6..f5dd829e 100644 --- a/include/boost/python/long.hpp +++ b/include/boost/python/long.hpp @@ -7,7 +7,7 @@ # define LONG_DWA2002627_HPP # include -# include +# include namespace boost { namespace python { @@ -44,8 +44,8 @@ class long_ : public object namespace converter { template <> - struct extract_object_manager - : pytype_extract_object_manager<&PyLong_Type,long_> + struct object_manager_traits + : pytype_object_manager_traits<&PyLong_Type,long_> { }; } diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 4ac0dcea..72e9e5ed 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -14,7 +14,6 @@ # include # include # include -# include # include # include @@ -274,19 +273,6 @@ namespace api } using api::object; -// -// Converter Specializations -// -namespace converter -{ - template <> - struct extract_object_manager - : always_extract_object_manager - { - static python::detail::borrowed_reference execute(PyObject* x); - }; -} - // // implementation // @@ -343,11 +329,17 @@ inline PyObject* api::object_base::ptr() const // namespace converter { - inline python::detail::borrowed_reference - extract_object_manager::execute(PyObject* x) + template <> + struct object_manager_traits { - return python::detail::borrowed_reference(python::incref(x)); - } + BOOST_STATIC_CONSTANT(bool, is_specialized = true); + static bool check(PyObject*) { return true; } + + static python::detail::new_non_null_reference adopt(PyObject* x) + { + return python::detail::new_non_null_reference(x); + } + }; inline PyObject* get_managed_object(object const& x) { diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index bac7f2f7..7565af38 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -77,14 +77,19 @@ BOOST_PYTHON_DECL void* rvalue_result_from_python( // Look for an eligible converter data = rvalue_from_python_stage1(src, converters); - + return rvalue_from_python_stage2(src, data, converters); +} + +BOOST_PYTHON_DECL void* rvalue_from_python_stage2( + PyObject* source, rvalue_from_python_stage1_data& data, registration const& converters) +{ if (!data.convertible) { handle<> msg( ::PyString_FromFormat( "No registered converter was able to produce a C++ rvalue of type %s from this Python object of type %s" , converters.target_type.name() - , src->ob_type->tp_name + , source->ob_type->tp_name )); PyErr_SetObject(PyExc_TypeError, msg.get()); @@ -94,7 +99,7 @@ BOOST_PYTHON_DECL void* rvalue_result_from_python( // If a construct function was registered (i.e. we found an // rvalue conversion), call it now. if (data.construct != 0) - data.construct(src, &data); + data.construct(source, &data); // Return the address of the resulting C++ object return data.convertible; @@ -165,37 +170,66 @@ BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( return chain; } +namespace +{ + void throw_no_lvalue_from_python(PyObject* source, registration const& converters, char const* ref_type) + { + handle<> msg( + ::PyString_FromFormat( + "No registered converter was able to extract a C++ %s to type %s" + " from this Python object of type %s" + , ref_type + , converters.target_type.name() + , source->ob_type->tp_name + )); + + PyErr_SetObject(PyExc_TypeError, msg.get()); + + throw_error_already_set(); + } + + void* lvalue_result_from_python( + PyObject* source + , registration const& converters + , char const* ref_type) + { + handle<> holder(source); + if (source->ob_refcnt <= 2) + { + handle<> msg( + ::PyString_FromFormat( + "Attempt to return dangling %s to object of type: %s" + , ref_type + , converters.target_type.name())); + + PyErr_SetObject(PyExc_ReferenceError, msg.get()); + + throw_error_already_set(); + } + + void* result = get_lvalue_from_python(source, converters); + if (!result) + (throw_no_lvalue_from_python)(source, converters, ref_type); + return result; + } + +} + +BOOST_PYTHON_DECL void throw_no_pointer_from_python(PyObject* source, registration const& converters) +{ + (throw_no_lvalue_from_python)(source, converters, "pointer"); +} + +BOOST_PYTHON_DECL void throw_no_reference_from_python(PyObject* source, registration const& converters) +{ + (throw_no_lvalue_from_python)(source, converters, "reference"); +} + BOOST_PYTHON_DECL void* reference_result_from_python( PyObject* source , registration const& converters) { - handle<> holder(source); - if (source->ob_refcnt <= 2) - { - handle<> msg( - ::PyString_FromFormat( - "Attempt to return dangling pointer/reference to object of type: %s" - , converters.target_type.name())); - - PyErr_SetObject(PyExc_ReferenceError, msg.get()); - - throw_error_already_set(); - } - void* result = get_lvalue_from_python(source, converters); - if (!result) - { - handle<> msg( - ::PyString_FromFormat( - "No registered converter was able to extract a a C++ lvalue of type %s from this Python object of type %s" - , converters.target_type.name() - , source->ob_type->tp_name - )); - - PyErr_SetObject(PyExc_TypeError, msg.get()); - - throw_error_already_set(); - } - return result; + return (lvalue_result_from_python)(source, converters, "reference"); } BOOST_PYTHON_DECL void* pointer_result_from_python( @@ -207,7 +241,7 @@ BOOST_PYTHON_DECL void* pointer_result_from_python( Py_DECREF(source); return 0; } - return reference_result_from_python(source, converters); + return (lvalue_result_from_python)(source, converters, "pointer"); } BOOST_PYTHON_DECL void throw_no_class_registered() @@ -231,7 +265,7 @@ pytype_result_from_python(PyTypeObject* type_, PyObject* source) handle<> keeper(source); handle<> msg( ::PyString_FromFormat( - "Expecting a Python %s return type, but got an object of type %s instead" + "Expecting an object of type %s; got an object of type %s instead" , type_->tp_name , source->ob_type->tp_name )); diff --git a/test/Jamfile b/test/Jamfile index db78d895..1a73da53 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -75,6 +75,8 @@ bpl-test bienstman3 ; bpl-test multi_arg_constructor ; bpl-test iterator : iterator.py iterator.cpp input_iterator.cpp ; +bpl-test extract ; + if $(TEST_BIENSTMAN_NON_BUGS) { bpl-test bienstman4 ; diff --git a/test/extract.cpp b/test/extract.cpp new file mode 100644 index 00000000..0792e7c6 --- /dev/null +++ b/test/extract.cpp @@ -0,0 +1,118 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_class.hpp" +#include +#include + +using namespace boost::python; + +typedef test_class<> X; + +bool extract_bool(object x) { return extract(x); } + +boost::python::list extract_list(object x) +{ + extract get_list((x)); + + // Make sure we always have the right idea about whether it's a list + bool is_list_1 = get_list.check(); + bool is_list_2 = PyObject_IsInstance(x.ptr(), (PyObject*)&PyList_Type); + assert(is_list_1 == is_list_2); + + return get_list(); +} + +char const* extract_cstring(object x) { return extract(x); } +std::string extract_string(object x) +{ + std::string s = extract(x); + return s; +} + +std::string const& extract_string_cref(object x) +{ + std::string const& s = extract(x); + return s; +} + +X extract_X(object x) +{ + return extract(x); +} + +X* extract_X_ptr(object x) { return extract(x); } + +X& extract_X_ref(object x) +{ + extract get_x(x); + return get_x; +} + +int double_X(object n) +{ + extract x(n); + return x().value() + x().value(); +} + +bool check_bool(object x) { return extract(x).check(); } +bool check_list(object x) { return extract(x).check(); } +bool check_cstring(object x) { return extract(x).check(); } +bool check_string(object x) { return extract(x).check(); } +bool check_string_cref(object x) { return extract(x).check(); } +bool check_X(object x) { return extract(x).check(); } +bool check_X_ptr(object x) { return extract(x).check(); } +bool check_X_ref(object x) { return extract(x).check(); } + +std::string x_rep(X const& x) +{ + return "X(" + boost::lexical_cast(x.value()) + ")"; +} + +BOOST_PYTHON_MODULE_INIT(extract_ext) +{ + implicitly_convertible(); + + module("extract_ext") + .def("extract_bool", extract_bool) + .def("extract_list", extract_list) + .def("extract_cstring", extract_cstring) + .def("extract_string", extract_string) + .def("extract_string_cref", extract_string_cref, return_value_policy()) + .def("extract_X", extract_X) + .def("extract_X_ptr", extract_X_ptr, return_value_policy()) + .def("extract_X_ref", extract_X_ref, return_value_policy()) + + .def("check_bool", check_bool) + .def("check_list", check_list) + .def("check_cstring", check_cstring) + .def("check_string", check_string) + .def("check_string_cref", check_string_cref) + .def("check_X", check_X) + .def("check_X_ptr", check_X_ptr) + .def("check_X_ref", check_X_ref) + + .def("double_X", double_X) + + .def("count_Xs", &X::count) + + .add(class_("X") + .def_init(args()) + .def( "__repr__", x_rep)) + ; +} + + +#include "module_tail.cpp" + diff --git a/test/extract.py b/test/extract.py new file mode 100644 index 00000000..999dc7b3 --- /dev/null +++ b/test/extract.py @@ -0,0 +1,102 @@ +''' + >>> from extract_ext import * + +Just about anything has a truth value in Python + + >>> assert check_bool(None) + >>> extract_bool(None) + 0 + + >>> assert check_bool(2) + >>> extract_bool(2) + 1 + + >>> assert check_bool('') + +Check that object manager types work properly. These are a different +case because they wrap Python objects instead of being wrapped by them. + + >>> assert not check_list(2) + >>> try: x = extract_list(2) + ... except TypeError, x: + ... if str(x) != 'Expecting an object of type list; got an object of type int instead': + ... print x + ... else: + ... print 'expected an exception, got', x, 'instead' + +Can't extract a list from a tuple. Use list(x) to convert a sequence +to a list: + + >>> assert not check_list((1, 2, 3)) + >>> assert check_list([1, 2, 3]) + >>> extract_list([1, 2, 3]) + [1, 2, 3] + +Can get a char const* from a Python string: + + >>> assert check_cstring('hello') + >>> extract_cstring('hello') + 'hello' + +Can't get a char const* from a Python int: + + >>> assert not check_cstring(1) + >>> try: x = extract_cstring(1) + ... except TypeError: pass + ... else: + ... print 'expected an exception, got', x, 'instead' + +Extract an std::string (class) rvalue from a native Python type + + >>> assert check_string('hello') + >>> extract_string('hello') + 'hello' + +Constant references are not treated as rvalues for the purposes of +extract: + + >>> assert not check_string_cref('hello') + +We can extract lvalues where appropriate: + + >>> x = X(42) + >>> check_X(x) + 1 + >>> extract_X(x) + X(42) + + >>> check_X_ptr(x) + 1 + >>> extract_X_ptr(x) + X(42) + >>> extract_X_ref(x) + X(42) + +Demonstrate that double-extraction of an rvalue works, and all created +copies of the object are destroyed: + + >>> n = count_Xs() + >>> double_X(333) + 666 + >>> count_Xs() - n + 0 + +General check for cleanliness: + + >>> del x + >>> count_Xs() + 0 +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 94edc1339331e646688350c8485e92e1502b09e2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 18 Jul 2002 12:58:37 +0000 Subject: [PATCH 0600/1042] Doc fixup [SVN r14516] --- .../boost/python/converter/rvalue_from_python_data.hpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp index 658cedb6..72ea7bd7 100644 --- a/include/boost/python/converter/rvalue_from_python_data.hpp +++ b/include/boost/python/converter/rvalue_from_python_data.hpp @@ -46,10 +46,11 @@ namespace boost { namespace python { namespace converter { // stored in the construct field. // // If no appropriate converter is found, conversion fails and the -// convertible field is null. This step is expected not to throw an -// exception, and when used in argument conversion for wrapped C++ -// functions, it causes overload resolution to reject the current -// function but not to fail completely. If +// convertible field is null. When used in argument conversion for +// wrapped C++ functions, it causes overload resolution to reject the +// current function but not to fail completely. If an exception is +// thrown, overload resolution stops and the exception propagates back +// through the caller. // // If an lvalue converter is matched, its convertible() function is // expected to return a pointer to the stored T object; its From dfd85da9d791984e1b8402340721ba2bde4f0ebe Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 18 Jul 2002 15:17:08 +0000 Subject: [PATCH 0601/1042] str, dict, and tuple! [SVN r14517] --- Jamfile | 4 + include/boost/python/dict.hpp | 130 ++++++++++ include/boost/python/objects.hpp | 3 +- include/boost/python/objects2.hpp | 252 -------------------- include/boost/python/str.hpp | 365 ++++++++++++++++++++++++++++ include/boost/python/tuple.hpp | 47 ++++ src/dict.cpp | 172 ++++++++++++++ src/object/function.cpp | 8 +- src/objects2.cpp | 279 ---------------------- src/str.cpp | 380 ++++++++++++++++++++++++++++++ src/tuple.cpp | 20 ++ test/Jamfile | 5 + test/dict.cpp | 82 +++++++ test/dict.py | 40 ++++ test/str.cpp | 68 ++++++ test/str.py | 52 ++++ test/tuple.cpp | 23 ++ test/tuple.py | 26 ++ 18 files changed, 1419 insertions(+), 537 deletions(-) create mode 100644 include/boost/python/dict.hpp delete mode 100755 include/boost/python/objects2.hpp create mode 100644 include/boost/python/str.hpp create mode 100644 include/boost/python/tuple.hpp create mode 100644 src/dict.cpp delete mode 100755 src/objects2.cpp create mode 100644 src/str.cpp create mode 100644 src/tuple.cpp create mode 100644 test/dict.cpp create mode 100644 test/dict.py create mode 100644 test/str.cpp create mode 100644 test/str.py create mode 100644 test/tuple.cpp create mode 100644 test/tuple.py diff --git a/Jamfile b/Jamfile index 192982f6..81789b85 100644 --- a/Jamfile +++ b/Jamfile @@ -15,6 +15,10 @@ dll bpl : src/list.cpp src/long.cpp + src/dict.cpp + src/tuple.cpp + src/str.cpp + src/aix_init_module.cpp src/converter/from_python.cpp src/converter/registry.cpp diff --git a/include/boost/python/dict.hpp b/include/boost/python/dict.hpp new file mode 100644 index 00000000..2f90344e --- /dev/null +++ b/include/boost/python/dict.hpp @@ -0,0 +1,130 @@ +#ifndef DICT_20020706_HPP +#define DICT_20020706_HPP + +#include +#include +#include +#include + +namespace boost { namespace python { + +class dict : public object +{ + public: + // dict() -> new empty dictionary. + // dict(mapping) -> new dictionary initialized from a mapping object's + // (key, value) pairs. + // dict(seq) -> new dictionary initialized as if via: + BOOST_PYTHON_DECL dict(); // new dict + explicit BOOST_PYTHON_DECL dict(object_cref data); + + template + explicit dict(T const& data) + : object(dict::call(object(data))) + { + } + + // D.clear() -> None. Remove all items from D. + BOOST_PYTHON_DECL void clear(); + + // D.copy() -> a shallow copy of D + BOOST_PYTHON_DECL dict copy(); + + // D.get(k[,d]) -> D[k] if D.has_key(k), else d. d defaults to None. + BOOST_PYTHON_DECL object get(object_cref k) const; + + template + object get(T const& k) const + { + return this->get(object(k)); + } + + BOOST_PYTHON_DECL object get(object_cref k, object_cref d) const; + + template + object get(T1 const& k, T2 const& d) const + { + return this->get(object(k),object(d)); + } + + // D.has_key(k) -> 1 if D has a key k, else 0 + BOOST_PYTHON_DECL bool has_key(object_cref k) const; + + template + bool has_key(T const& k) const + { + return this->has_key(object(k)); + } + + // D.items() -> list of D's (key, value) pairs, as 2-tuples + BOOST_PYTHON_DECL list items() const; + + // D.iteritems() -> an iterator over the (key, value) items of D + BOOST_PYTHON_DECL object iteritems() const; + + // D.iterkeys() -> an iterator over the keys of D + BOOST_PYTHON_DECL object iterkeys() const; + + // D.itervalues() -> an iterator over the values of D + BOOST_PYTHON_DECL object itervalues() const; + + // D.keys() -> list of D's keys + BOOST_PYTHON_DECL list keys() const; + + // D.popitem() -> (k, v), remove and return some (key, value) pair as a + // 2-tuple; but raise KeyError if D is empty + BOOST_PYTHON_DECL tuple popitem(); + + // D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if not D.has_key(k) + BOOST_PYTHON_DECL object setdefault(object_cref k); + + template + object setdefault(T const& k) + { + return this->setdefault(object(k)); + } + + BOOST_PYTHON_DECL object setdefault(object_cref k, object_cref d); + + template + object setdefault(T1 const& k, T2 const& d) + { + return this->setdefault(object(k),object(d)); + } + + // D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k] + BOOST_PYTHON_DECL void update(object_cref E); + + template + void update(T const& E) + { + this->update(object(E)); + } + + // D.values() -> list of D's values + BOOST_PYTHON_DECL list values() const; + + public: // implementation detail -- for internal use only + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict) + + private: + static BOOST_PYTHON_DECL detail::new_reference call(object const&); +}; + + +// +// Converter Specializations +// +namespace converter +{ + template <> + struct object_manager_traits + : pytype_object_manager_traits<&PyDict_Type,dict> + { + }; +} + +}} // namespace boost::python + +#endif + diff --git a/include/boost/python/objects.hpp b/include/boost/python/objects.hpp index cab5f720..f2adb65b 100644 --- a/include/boost/python/objects.hpp +++ b/include/boost/python/objects.hpp @@ -10,8 +10,7 @@ # define OBJECTS_DWA051100_H_ # ifdef BOOST_PYTHON_V2 -# include -# include +# error obsolete # else # include # include diff --git a/include/boost/python/objects2.hpp b/include/boost/python/objects2.hpp deleted file mode 100755 index a66a422e..00000000 --- a/include/boost/python/objects2.hpp +++ /dev/null @@ -1,252 +0,0 @@ -// (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. - -#ifndef OBJECTS_DWA20020611_H -# define OBJECTS_DWA20020611_H - -# include -# include -# include -# include "boost/operators.hpp" -# include - -namespace boost { namespace python { - -class list; - -class BOOST_PYTHON_DECL objects_base -{ - public: - explicit objects_base(handle<> const& p); - - // Return a reference to the held object - handle<> reference() const; - - // Return a raw pointer to the held object - PyObject* get() const; - - private: - handle<> m_p; -}; - -class tuple; - -class BOOST_PYTHON_DECL tuple_base : public objects_base -{ - public: - explicit tuple_base(std::size_t n = 0); - explicit tuple_base(handle<> p); - - static PyTypeObject* type_obj(); - static bool accepts(handle<> p); - std::size_t size() const; - handle<> operator[](std::size_t pos) const; - - void set_item(std::size_t pos, const handle<>& rhs); - - tuple slice(int low, int high) const; - - friend BOOST_PYTHON_DECL tuple operator+(const tuple&, const tuple&); - friend BOOST_PYTHON_DECL tuple& operator+=(tuple&, const tuple&); -}; - -class tuple : public tuple_base -{ - public: - explicit tuple(std::size_t n = 0) : tuple_base(n) {} - explicit tuple(handle<> p) : tuple_base(p) {} - - template - tuple(const std::pair& x) - : tuple_base(handle<>(PyTuple_New(2))) - { - set_item(0, x.first); - set_item(1, x.second); - } - - template - tuple(const First& first, const Second& second) - : tuple_base(handle<>(PyTuple_New(2))) - { - set_item(0, first); - set_item(1, second); - } - - template - tuple(const First& first, const Second& second, const Third& third) - : tuple_base(handle<>(PyTuple_New(3))) - { - set_item(0, first); - set_item(1, second); - set_item(2, third); - } - - template - tuple(const First& first, const Second& second, const Third& third, const Fourth& fourth) - : tuple_base(handle<>(PyTuple_New(4))) - { - set_item(0, first); - set_item(1, second); - set_item(2, third); - set_item(3, fourth); - } - - void set_item(std::size_t pos, const handle<>& rhs) - { - tuple_base::set_item(pos, rhs); - } -}; - -class BOOST_PYTHON_DECL string - : public objects_base, public boost::multipliable2 -{ - public: - // Construct from an owned PyObject*. - // Precondition: p must point to a python string. - explicit string(handle<> p); - explicit string(const char* s); - string(const char* s, std::size_t length); - string(const string& rhs); - - enum interned_t { interned }; - string(const char* s, interned_t); - - // Get the type object for Strings - static PyTypeObject* type_obj(); - - // Return true if the given object is a python string - static bool accepts(handle<> o); - - // Return the length of the string. - std::size_t size() const; - - // Returns a null-terminated representation of the contents of string. - // The pointer refers to the internal buffer of string, not a copy. - // The data must not be modified in any way. It must not be de-allocated. - const char* c_str() const; - - string& operator*=(unsigned int repeat_count); - string& operator+=(const string& rhs); - friend string operator+(string x, string y); - string& operator+=(const char* rhs); - friend string operator+(string x, const char* y); - friend string operator+(const char* x, string y); - - void intern(); - - friend string operator%(const string& format, const tuple& args); -}; - -class dictionary; - -struct BOOST_PYTHON_DECL dictionary_proxy; - -class BOOST_PYTHON_DECL dictionary_base : public objects_base -{ - protected: - typedef dictionary_proxy proxy; - - public: - explicit dictionary_base(handle<> p); - dictionary_base(); - void clear(); - - static PyTypeObject* type_obj(); - static bool accepts(handle<> p); - - public: - proxy operator[](handle<> key); - handle<> operator[](handle<> key) const; - handle<> get_item(const handle<>& key) const; - handle<> get_item(const handle<>& key, const handle<>& default_) const; - - void set_item(const handle<>& key, const handle<>& value); - - void erase(handle<> key); - -// proxy operator[](const object& key); -// ref operator[](const object& key) const; - -// ref get_item(const object& key, ref default_ = ref()) const; -// void set_item(const object& key, const ref& value); - -// void erase(const object& key); - - list items() const; - list keys() const; - list values() const; - - std::size_t size() const; - // TODO: iterator support -}; - -struct BOOST_PYTHON_DECL dictionary_proxy -{ - template - const handle<>& operator=(const T& rhs) - { return (*this) = make_ref(rhs); } - const handle<>& operator=(const handle<>& rhs); - - operator handle<>() const; - private: - friend class dictionary_base; - dictionary_proxy(const handle<>& dict, const handle<>& key); - - // This is needed to work around the very strange MSVC error report that the - // return type of the built-in operator= differs from that of the ones - // defined above. Couldn't hurt to make these un-assignable anyway, though. - const handle<>& operator=(const dictionary_proxy&); // Not actually implemented - private: - handle<> m_dict; - handle<> m_key; -}; - -class dictionary : public dictionary_base -{ - typedef dictionary_proxy proxy; - public: - explicit dictionary(handle<> p) : dictionary_base(p) {} - dictionary() : dictionary_base() {} - - template - proxy operator[](const Key& key) - { return this->operator[](make_ref(key)); } - proxy operator[](handle<> key) - { return dictionary_base::operator[](key); } - - template - handle<> operator[](const Key& key) const - { return this->operator[](make_ref(key)); } - handle<> operator[](handle<> key) const - { return dictionary_base::operator[](key); } - - template - handle<> get_item(const Key& key) const - { return this->get_item(make_ref(key)); } - handle<> get_item(const handle<>& key) const - { return dictionary_base::get_item(key); } - - template - handle<> get_item(const Key& key, const Default& default_) const - { return this->get_item(make_ref(key), make_ref(default_)); } - handle<> get_item(const handle<>& key, const handle<>& default_) const - { return dictionary_base::get_item(key, default_); } - - template - void set_item(const Key& key, const Value& value) - { this->set_item(make_ref(key), make_ref(value)); } - void set_item(const handle<>& key, const handle<>& value) - { dictionary_base::set_item(key, value); } - - template - void erase(const Key& key) - { this->erase(make_ref(key)); } - void erase(handle<> key) - { dictionary_base::erase(key); } -}; - -}} // namespace boost::python - -#endif // OBJECTS_DWA20020611_H diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp new file mode 100644 index 00000000..53d7f321 --- /dev/null +++ b/include/boost/python/str.hpp @@ -0,0 +1,365 @@ +#ifndef STR_20020703_HPP +#define STR_20020703_HPP + +#include +#include +#include + +namespace boost { namespace python { + +class str : public object +{ + public: + BOOST_PYTHON_DECL str(const char* s); // new str + explicit BOOST_PYTHON_DECL str(object_cref other); + + template + explicit str(T const& other) + : object(str::call(object(other))) + { + } + + BOOST_PYTHON_DECL str capitalize() const ; + + BOOST_PYTHON_DECL str center(object_cref width) const ; + + template + str center(T const& width) const + { + return this->center(object(width)); + } + + BOOST_PYTHON_DECL long count(object_cref sub) const; + + template + long count(T const& sub) const + { + return this->count(object(sub)); + } + + BOOST_PYTHON_DECL long count(object_cref sub, object_cref start) const; + + template + str count(T1 const& sub,T2 const& start) const + { + return this->count(object(sub), object(start)); + } + + BOOST_PYTHON_DECL long count(object_cref sub, object_cref start, object_cref end) const; + + template + str count(T1 const& sub,T2 const& start, T3 const& end) const + { + return this->count(object(sub), object(start)); + } + + BOOST_PYTHON_DECL str decode() const; + BOOST_PYTHON_DECL str decode(object_cref encoding) const; + + template + str decode(T const& encoding) const + { + return this->decode(object(encoding)); + } + + BOOST_PYTHON_DECL str decode(object_cref encoding, object_cref errors) const; + + template + str decode(T1 const& encoding, T2 const& errors) const + { + return this->decode(object(encoding),object(errors)); + } + + BOOST_PYTHON_DECL str encode() const; + BOOST_PYTHON_DECL str encode(object_cref encoding) const; + + template + str encode(T const& encoding) const + { + return this->encode(object(encoding)); + } + + BOOST_PYTHON_DECL str encode(object_cref encoding, object_cref errors) const; + + template + str encode(T1 const& encoding, T2 const& errors) const + { + return this->encode(object(encoding),object(errors)); + } + + BOOST_PYTHON_DECL bool endswith(object_cref suffix) const; + + template + bool endswith(T const& suffix) const + { + return this->endswith(object(suffix)); + } + + BOOST_PYTHON_DECL bool endswith(object_cref suffix, object_cref start) const; + + template + bool endswith(T1 const& suffix, T2 const& start) const + { + return this->endswith(object(suffix), object(start)); + } + + BOOST_PYTHON_DECL bool endswith(object_cref suffix, object_cref start, object_cref end) const; + + template + bool endswith(T1 const& suffix, T2 const& start, T3 const& end) const + { + return this->endswith(object(suffix), object(start), object(end)); + } + + BOOST_PYTHON_DECL str expandtabs() const; + BOOST_PYTHON_DECL str expandtabs(object_cref tabsize) const; + + template + str expandtabs(T const& tabsize) const + { + return this->expandtabs(object(tabsize)); + } + + BOOST_PYTHON_DECL long find(object_cref sub) const; + + template + long find(T const& sub) const + { + return this->find(object(sub)); + } + + BOOST_PYTHON_DECL long find(object_cref sub, object_cref start) const; + + template + long find(T1 const& sub, T2 const& start) const + { + return this->find(object(sub), object(start)); + } + + BOOST_PYTHON_DECL long find(object_cref sub, object_cref start, object_cref end) const; + + template + long find(T1 const& sub, T2 const& start, T3 const& end) const + { + return this->find(object(sub), object(start), object(end)); + } + + BOOST_PYTHON_DECL long index(object_cref sub) const; + + template + long index(T const& sub) const + { + return this->index(object(sub)); + } + + BOOST_PYTHON_DECL long index(object_cref sub, object_cref start) const; + + template + long index(T1 const& sub, T2 const& start) const + { + return this->index(object(sub), object(start)); + } + + BOOST_PYTHON_DECL long index(object_cref sub, object_cref start, object_cref end) const; + + template + long index(T1 const& sub, T2 const& start, T3 const& end) const + { + return this->index(object(sub), object(start), object(end)); + } + + BOOST_PYTHON_DECL bool isalnum() const; + BOOST_PYTHON_DECL bool isalpha() const; + BOOST_PYTHON_DECL bool isdigit() const; + BOOST_PYTHON_DECL bool islower() const; + BOOST_PYTHON_DECL bool isspace() const; + BOOST_PYTHON_DECL bool istitle() const; + BOOST_PYTHON_DECL bool isupper() const; + + BOOST_PYTHON_DECL str join(object_cref sequence) const; + + template + str join(T const& sequence) const + { + return this->join(object(sequence)); + } + + BOOST_PYTHON_DECL str ljust(object_cref width) const; + + template + str ljust(T const& width) const + { + return this->ljust(object(width)); + } + + BOOST_PYTHON_DECL str lower() const; + BOOST_PYTHON_DECL str lstrip() const; + + BOOST_PYTHON_DECL str replace(object_cref old, object_cref new_) const ; + + template + str replace(T1 const& old, T2 const& new_) const + { + return this->replace(object(old),object(new_)); + } + + BOOST_PYTHON_DECL str replace(object_cref old, object_cref new_, object_cref maxsplit) const ; + + template + str replace(T1 const& old, T2 const& new_, T3 const& maxsplit) const + { + return this->replace(object(old),object(new_),object(maxsplit)); + } + + BOOST_PYTHON_DECL long rfind(object_cref sub) const; + + template + long rfind(T const& sub) const + { + return this->rfind(object(sub)); + } + + BOOST_PYTHON_DECL long rfind(object_cref sub, object_cref start) const; + + template + long rfind(T1 const& sub, T2 const& start) const + { + return this->rfind(object(sub), object(start)); + } + + BOOST_PYTHON_DECL long rfind(object_cref sub, object_cref start, object_cref end) const; + + template + long rfind(T1 const& sub, T2 const& start, T3 const& end) const + { + return this->rfind(object(sub), object(start), object(end)); + } + + BOOST_PYTHON_DECL long rindex(object_cref sub) const; + + template + long rindex(T const& sub) const + { + return this->rindex(object(sub)); + } + + BOOST_PYTHON_DECL long rindex(object_cref sub, object_cref start) const; + + template + long rindex(T1 const& sub, T2 const& start) const + { + return this->rindex(object(sub), object(start)); + } + + BOOST_PYTHON_DECL long rindex(object_cref sub, object_cref start, object_cref end) const; + + template + long rindex(T1 const& sub, T2 const& start, T3 const& end) const + { + return this->rindex(object(sub), object(start), object(end)); + } + + BOOST_PYTHON_DECL str rjust(object_cref width) const; + + template + str rjust(T const& width) const + { + return this->rjust(object(width)); + } + + BOOST_PYTHON_DECL str rstrip() const; + + BOOST_PYTHON_DECL list split() const; + BOOST_PYTHON_DECL list split(object_cref sep) const; + + template + list split(T const& sep) const + { + return this->split(object(sep)); + } + + BOOST_PYTHON_DECL list split(object_cref sep, object_cref maxsplit) const; + + template + list split(T1 const& sep, T2 const& maxsplit) const + { + return this->split(object(sep), object(maxsplit)); + } + + BOOST_PYTHON_DECL list splitlines() const; + BOOST_PYTHON_DECL list splitlines(object_cref keepends) const; + + template + list splitlines(T const& keepends) const + { + return this->splitlines(object(keepends)); + } + + BOOST_PYTHON_DECL bool startswith(object_cref prefix) const ; + + template + bool startswith(T const& prefix) const + { + return this->startswith(object(prefix)); + } + + BOOST_PYTHON_DECL bool startswith(object_cref prefix, object_cref start) const ; + + template + bool startswidth(T1 const& prefix, T2 const& start) const + { + return this->startswidth(object(prefix), object(start)); + } + + BOOST_PYTHON_DECL bool startswith(object_cref prefix, object_cref start, object_cref end) const ; + + template + bool startswidth(T1 const& prefix, T2 const& start, T3 const& end) const + { + return this->startswidth(object(prefix), object(start), object(end)); + } + + BOOST_PYTHON_DECL str strip() const ; + BOOST_PYTHON_DECL str swapcase() const ; + BOOST_PYTHON_DECL str title() const ; + + BOOST_PYTHON_DECL str translate(object_cref table) const; + + template + str translate(T const& table) const + { + return this->translate(object(table)); + } + + BOOST_PYTHON_DECL str translate(object_cref table, object_cref deletechars) const; + + template + str translate(T1 const& table, T2 const& deletechars) const + { + return this->translate(object(table), object(deletechars)); + } + + BOOST_PYTHON_DECL str upper() const; + + public: // implementation detail -- for internal use only + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str) + + private: + static BOOST_PYTHON_DECL detail::new_reference call(object const&); +}; + +// +// Converter Specializations +// +namespace converter +{ + template <> + struct object_manager_traits + : pytype_object_manager_traits<&PyString_Type,str> + { + }; +} + +}} // namespace boost::python + +#endif // STR_20020703_HPP diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp new file mode 100644 index 00000000..75e2eb4a --- /dev/null +++ b/include/boost/python/tuple.hpp @@ -0,0 +1,47 @@ +#ifndef TUPLE_20020706_HPP +#define TUPLE_20020706_HPP + +#include +#include + +namespace boost { namespace python { + +class tuple : public object +{ + public: + // tuple() -> an empty tuple + BOOST_PYTHON_DECL tuple(); + + // tuple(sequence) -> tuple initialized from sequence's items + BOOST_PYTHON_DECL tuple(object_cref sequence); + + template + explicit tuple(T const& sequence) + : object(tuple::call(object(sequence))) + { + } + + public: // implementation detail -- for internal use only + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple) + + private: + static BOOST_PYTHON_DECL detail::new_reference call(object const&); +}; + + +// +// Converter Specializations +// +namespace converter +{ + template <> + struct object_manager_traits + : pytype_object_manager_traits<&PyTuple_Type,tuple> + { + }; +} + +}} // namespace boost::python + +#endif + diff --git a/src/dict.cpp b/src/dict.cpp new file mode 100644 index 00000000..c8829505 --- /dev/null +++ b/src/dict.cpp @@ -0,0 +1,172 @@ +#include +#include + +namespace boost { namespace python { + +namespace +{ + // When returning list objects from methods, it may turn out that the + // derived class is returning something else, perhaps something not + // even derived from list. Since it is generally harmless for a + // Boost.Python wrapper object to hold an object of a different + // type, and because calling list() with an object may in fact + // perform a conversion, the least-bad alternative is to assume that + // we have a Python list object and stuff it into the list result. + list assume_list(object const& o) + { + return list(detail::borrowed_reference(o.ptr())); + } + + // No PyDict_CheckExact; roll our own. + inline bool check_exact(dict const* p) + { + return p->ptr()->ob_type == &PyDict_Type; + } +} + +BOOST_PYTHON_DECL detail::new_reference dict::call(object const& arg) +{ + return (detail::new_reference)PyObject_CallFunction( + (PyObject*)&PyDict_Type, "(O)", + arg.ptr()); +} + +BOOST_PYTHON_DECL dict::dict() + : object(detail::new_reference(PyDict_New())) +{} + +BOOST_PYTHON_DECL dict::dict(object_cref data) + : object(dict::call(data)) +{} + +BOOST_PYTHON_DECL void dict::clear() +{ + if (check_exact(this)) + PyDict_Clear(this->ptr()); + else + this->attr("clear")(); +} + +BOOST_PYTHON_DECL dict dict::copy() +{ + if (check_exact(this)) + { + return dict(detail::new_reference( + PyDict_Copy(this->ptr()))); + } + else + { + return dict(detail::borrowed_reference( + this->attr("copy")().ptr() + )); + } +} + +BOOST_PYTHON_DECL object dict::get(object_cref k) const +{ + if (check_exact(this)) + { + return object(detail::borrowed_reference( + PyDict_GetItem(this->ptr(),k.ptr()))); + } + else + { + return this->attr("get")(k); + } +} + +BOOST_PYTHON_DECL object dict::get(object_cref k, object_cref d) const +{ + return this->attr("get")(k,d); +} + +BOOST_PYTHON_DECL bool dict::has_key(object_cref k) const +{ + return extract(this->attr("has_key")(k)); +} + +BOOST_PYTHON_DECL list dict::items() const +{ + if (check_exact(this)) + { + return list(detail::new_reference( + PyDict_Items(this->ptr()))); + } + else + { + return assume_list(this->attr("items")()); + } +} + +BOOST_PYTHON_DECL object dict::iteritems() const +{ + return this->attr("iteritems")(); +} + +BOOST_PYTHON_DECL object dict::iterkeys() const +{ + return this->attr("iterkeys")(); +} + +BOOST_PYTHON_DECL object dict::itervalues() const +{ + return this->attr("itervalues")(); +} + +BOOST_PYTHON_DECL list dict::keys() const +{ + if (check_exact(this)) + { + return list(detail::new_reference( + PyDict_Keys(this->ptr()))); + } + else + { + return assume_list(this->attr("keys")()); + } +} + +BOOST_PYTHON_DECL tuple dict::popitem() +{ + return tuple(detail::borrowed_reference( + this->attr("popitem")().ptr() + )); +} + +BOOST_PYTHON_DECL object dict::setdefault(object_cref k) +{ + return this->attr("setdefault")(k); +} + +BOOST_PYTHON_DECL object dict::setdefault(object_cref k, object_cref d) +{ + return this->attr("setdefault")(k,d); +} + +BOOST_PYTHON_DECL void dict::update(object_cref other) +{ + if (check_exact(this)) + { + if (PyDict_Update(this->ptr(),other.ptr()) == -1) + throw_error_already_set(); + } + else + { + this->attr("update")(other); + } +} + +BOOST_PYTHON_DECL list dict::values() const +{ + if (check_exact(this)) + { + return list(detail::new_reference( + PyDict_Values(this->ptr()))); + } + else + { + return assume_list(this->attr("values")()); + } +} + +}} // namespace boost::python diff --git a/src/object/function.cpp b/src/object/function.cpp index 4e237e4e..4fc6a141 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include @@ -158,7 +158,7 @@ namespace void function::add_to_namespace( handle<> const& name_space, char const* name_, handle<> const& attribute) { - string const name(name_); + str const name(name_); PyObject* const ns = name_space.get(); if (attribute->ob_type == &function_type) @@ -175,7 +175,7 @@ void function::add_to_namespace( if (dict == 0) throw_error_already_set(); - handle<> existing( allow_null(PyObject_GetItem(dict, name.get())) ); + handle<> existing( allow_null(PyObject_GetItem(dict, name.ptr())) ); if (existing.get()) { @@ -195,7 +195,7 @@ void function::add_to_namespace( // The PyObject_GetAttrString() call above left an active error PyErr_Clear(); - if (PyObject_SetAttr(ns, name.get(), attribute.get()) < 0) + if (PyObject_SetAttr(ns, name.ptr(), attribute.get()) < 0) throw_error_already_set(); } diff --git a/src/objects2.cpp b/src/objects2.cpp deleted file mode 100755 index 462535e2..00000000 --- a/src/objects2.cpp +++ /dev/null @@ -1,279 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -// TODO: Move inline implementations from objects.cpp here - -#ifndef BOOST_PYTHON_SOURCE -# define BOOST_PYTHON_SOURCE -#endif - -#include -#include - -namespace boost { namespace python { - -objects_base::objects_base(handle<> const& p) - : m_p(borrowed(p.get())) // Do the null check here -{} - -// Return a reference to the held object -handle<> objects_base::reference() const -{ - return m_p; -} - -// Return a raw pointer to the held object -PyObject* objects_base::get() const -{ - return m_p.get(); -} - -}} // namespace boost::python - -namespace boost { namespace python { - -tuple_base::tuple_base(std::size_t n) - : objects_base(handle<>(PyTuple_New(n))) -{ - for (std::size_t i = 0; i < n; ++i) - PyTuple_SET_ITEM(get(), i, detail::none()); -} - -tuple_base::tuple_base(handle<> p) - : objects_base(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw_error_already_set(); - } -} - -PyTypeObject* tuple_base::type_obj() -{ - return &PyTuple_Type; -} - -bool tuple_base::accepts(handle<> p) -{ - return PyTuple_Check(p.get()); -} - -std::size_t tuple_base::size() const -{ - return PyTuple_Size(get()); -} - -handle<> tuple_base::operator[](std::size_t pos) const -{ - return handle<>(borrowed(PyTuple_GetItem(get(), static_cast(pos)))); -} - -void tuple_base::set_item(std::size_t pos, const handle<>& rhs) -{ - int failed = PyTuple_SetItem( - get() - , static_cast(pos) - , incref(expect_non_null(rhs.get())) - ); - (void)failed; - assert(failed == 0); -} - -tuple tuple_base::slice(int low, int high) const -{ - return tuple(handle<>(PyTuple_GetSlice(get(), low, high))); -} - -BOOST_PYTHON_DECL tuple& operator+=(tuple& self, const tuple& rhs) -{ - return self = self + rhs; -} - - -// Construct from an owned PyObject*. -// Precondition: p must point to a python string. -string::string(handle<> p) - : objects_base(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw_error_already_set(); - } -} - -string::string(const char* s) - : objects_base(handle<>(PyString_FromString(s))) {} - -string::string(const char* s, std::size_t length) - : objects_base(handle<>(PyString_FromStringAndSize(s, length))) {} - -string::string(const char* s, interned_t) - : objects_base(handle<>(PyString_InternFromString(s))) {} - -string::string(const string& rhs) - : objects_base(rhs.reference()) {} - -// Get the type object for Strings -PyTypeObject* string::type_obj() -{ return &PyString_Type; } - -// Return true if the given object is a python string -bool string::accepts(handle<> o) -{ return PyString_Check(o.get()); } - -// Return the length of the string. -std::size_t string::size() const -{ - int size = PyString_GET_SIZE(get()); - assert(size >= 0); - return static_cast(size); -} - -// Returns a null-terminated representation of the contents of string. -// The pointer refers to the internal buffer of string, not a copy. -// The data must not be modified in any way. It must not be de-allocated. -const char* string::c_str() const -{ return PyString_AS_STRING(get()); } - -void string::intern() -{ // UNTESTED!! - *this = string(handle<>(borrowed(PyString_InternFromString(c_str())))); -} - -string& string::operator*=(unsigned int repeat_count) -{ - *this = string(handle<>(PySequence_Repeat(get(), repeat_count))); - return *this; -} - -dictionary_base::dictionary_base(handle<> p) - : objects_base(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw_error_already_set(); - } -} - -dictionary_base::dictionary_base() - : objects_base(handle<>(PyDict_New())) {} - -PyTypeObject* dictionary_base::type_obj() -{ return &PyDict_Type; } - -bool dictionary_base::accepts(handle<> p) -{ return PyDict_Check(p.get()); } - -void dictionary_base::clear() -{ PyDict_Clear(get()); } - -const handle<>& dictionary_proxy::operator=(const handle<>& rhs) -{ - if (PyDict_SetItem(m_dict.get(), m_key.get(), rhs.get()) == -1) - throw_error_already_set(); - return rhs; -} - -dictionary_proxy::operator handle<>() const -{ - return handle<>( - m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get())); -} - -dictionary_proxy::dictionary_proxy(const handle<>& dict, const handle<>& key) - : m_dict(dict), m_key(key) {} - -dictionary_proxy dictionary_base::operator[](handle<> key) -{ return proxy(reference(), key); } - -handle<> dictionary_base::operator[](handle<> key) const { - // An odd MSVC bug causes the ".operator Ptr()" to be needed - return proxy(reference(), key).operator handle<>(); -} - - -handle<> dictionary_base::get_item(const handle<>& key) const -{ - return get_item(key, handle<>()); -} - -handle<> dictionary_base::get_item(const handle<>& key, const handle<>& default_) const -{ - PyObject* value_or_null = PyDict_GetItem(get(), key.get()); - if (value_or_null == 0 && !PyErr_Occurred()) - return default_; - else - return handle<>(borrowed(value_or_null)); // Will throw if there was another error -} - -void dictionary_base::set_item(const handle<>& key, const handle<>& value) -{ - if (PyDict_SetItem(get(), key.get(), value.get()) == -1) - throw_error_already_set(); -} - -void dictionary_base::erase(handle<> key) { - if (PyDict_DelItem(get(), key.get()) == -1) - throw_error_already_set(); -} - -list dictionary_base::items() const { return list(handle<>(PyDict_Items(get()))); } -list dictionary_base::keys() const { return list(handle<>(PyDict_Keys(get()))); } -list dictionary_base::values() const { return list(handle<>(PyDict_Values(get()))); } - -std::size_t dictionary_base::size() const { return static_cast(PyDict_Size(get())); } - -string operator+(string x, string y) -{ - PyObject* io_string = incref(x.get()); - PyString_Concat(&io_string, y.get()); - return string(handle<>(io_string)); -} - -string& string::operator+=(const string& rhs) -{ - return *this = *this + rhs; -} - -string& string::operator+=(const char* y) -{ - return *this += string(y); -} - -string operator%(const string& format, const tuple& args) -{ - return string(handle<>(PyString_Format(format.get(), args.reference().get()))); -} - -string operator+(string x, const char* y) -{ - return x + string(y); -} - -string operator+(const char* x, string y) -{ - return string(x) + y; -} - -tuple operator+(const tuple& x, const tuple& y) -{ - tuple result(x.size() + y.size()); - for (std::size_t xi = 0; xi < x.size(); ++xi) - result.set_item(xi, x[xi]); - for (std::size_t yi = 0; yi < y.size(); ++yi) - result.set_item(yi + x.size(), y[yi]); - return result; -} - -}} // namespace boost::python diff --git a/src/str.cpp b/src/str.cpp new file mode 100644 index 00000000..dd8ce0a7 --- /dev/null +++ b/src/str.cpp @@ -0,0 +1,380 @@ +#include +#include + +namespace boost { namespace python { + +BOOST_PYTHON_DECL detail::new_reference str::call(object const& arg) +{ + return (detail::new_reference)PyObject_CallFunction( + (PyObject*)&PyString_Type, "(O)", + arg.ptr()); +} + +BOOST_PYTHON_DECL str::str(const char* s) + : object(detail::new_reference(PyString_FromString(s))) +{} + +BOOST_PYTHON_DECL str::str(object_cref other) + : object(str::call(other)) +{} + +namespace +{ + // When returning str objects from methods, it may turn out that the + // derived class is returning something else, perhaps something not + // even derived from str. Since it is generally harmless for a + // Boost.Python wrapper object to hold an object of a different + // type, and because calling str() with an object may in fact + // perform a conversion, the least-bad alternative is to assume that + // we have a Python str object and stuff it into the str result. + str assume_str(object const& o) + { + return str(detail::borrowed_reference(o.ptr())); + } +} +BOOST_PYTHON_DECL str str::capitalize() const +{ + return assume_str(this->attr("capitalize")()); +} + +BOOST_PYTHON_DECL str str::center(object_cref width) const +{ + return assume_str( + this->attr("center")(width) + ); +} + +BOOST_PYTHON_DECL long str::count(object_cref sub) const +{ + return extract(this->attr("count")(sub)); +} + +BOOST_PYTHON_DECL long str::count(object_cref sub, object_cref start) const +{ + return extract(this->attr("count")(sub,start)); +} + +BOOST_PYTHON_DECL long str::count(object_cref sub, object_cref start, object_cref end) const +{ + return extract(this->attr("count")(sub,start,end)); +} + +BOOST_PYTHON_DECL str str::decode() const +{ + return assume_str(this->attr("decode")()); +} + +BOOST_PYTHON_DECL str str::decode(object_cref encoding) const +{ + return assume_str(this->attr("decode")(encoding)); +} + +BOOST_PYTHON_DECL str str::decode(object_cref encoding, object_cref errors) const +{ + return assume_str(this->attr("decode")(encoding,errors)); +} + +BOOST_PYTHON_DECL str str::encode() const +{ + return assume_str(this->attr("encode")()); +} + +BOOST_PYTHON_DECL str str::encode(object_cref encoding) const +{ + return assume_str(this->attr("encode")(encoding)); +} + +BOOST_PYTHON_DECL str str::encode(object_cref encoding, object_cref errors) const +{ + return assume_str(this->attr("encode")(encoding,errors)); +} + +BOOST_PYTHON_DECL bool str::endswith(object_cref suffix) const +{ + bool result = PyInt_AsLong(this->attr("endswith")(suffix).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL str str::expandtabs() const +{ + return assume_str(this->attr("expandtabs")()); +} + +BOOST_PYTHON_DECL str str::expandtabs(object_cref tabsize) const +{ + return assume_str(this->attr("expandtabs")(tabsize)); +} + +BOOST_PYTHON_DECL long str::find(object_cref sub) const +{ + long result = PyInt_AsLong(this->attr("find")(sub).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL long str::find(object_cref sub, object_cref start) const +{ + long result = PyInt_AsLong(this->attr("find")(sub,start).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL long str::find(object_cref sub, object_cref start, object_cref end) const +{ + long result = PyInt_AsLong(this->attr("find")(sub,start,end).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL long str::index(object_cref sub) const +{ + long result = PyInt_AsLong(this->attr("index")(sub).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL long str::index(object_cref sub, object_cref start) const +{ + long result = PyInt_AsLong(this->attr("index")(sub,start).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL long str::index(object_cref sub, object_cref start, object_cref end) const +{ + long result = PyInt_AsLong(this->attr("index")(sub,start,end).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL bool str::isalnum() const +{ + bool result = PyInt_AsLong(this->attr("isalnum")().ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL bool str::isalpha() const +{ + bool result = PyInt_AsLong(this->attr("isalpha")().ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL bool str::isdigit() const +{ + bool result = PyInt_AsLong(this->attr("isdigit")().ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL bool str::islower() const +{ + bool result = PyInt_AsLong(this->attr("islower")().ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL bool str::isspace() const +{ + bool result = PyInt_AsLong(this->attr("isspace")().ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL bool str::istitle() const +{ + bool result = PyInt_AsLong(this->attr("istitle")().ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL bool str::isupper() const +{ + bool result = PyInt_AsLong(this->attr("isupper")().ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL str str::join(object_cref sequence) const +{ + return assume_str(this->attr("join")(sequence)); +} + +BOOST_PYTHON_DECL str str::ljust(object_cref width) const +{ + return assume_str(this->attr("ljust")(width)); +} + +BOOST_PYTHON_DECL str str::lower() const +{ + return assume_str(this->attr("lower")()); +} + +BOOST_PYTHON_DECL str str::lstrip() const +{ + return assume_str(this->attr("lstrip")()); +} + +BOOST_PYTHON_DECL str str::replace(object_cref old, object_cref new_) const +{ + return assume_str(this->attr("replace")(old,new_)); +} + +BOOST_PYTHON_DECL str str::replace(object_cref old, object_cref new_, object_cref maxsplit) const { + return assume_str(this->attr("replace")(old,new_,maxsplit)); +} + +BOOST_PYTHON_DECL long str::rfind(object_cref sub) const +{ + long result = PyInt_AsLong(this->attr("rfind")(sub).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL long str::rfind(object_cref sub, object_cref start) const +{ + long result = PyInt_AsLong(this->attr("rfind")(sub,start).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL long str::rfind(object_cref sub, object_cref start, object_cref end) const +{ + long result = PyInt_AsLong(this->attr("rfind")(sub,start,end).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL long str::rindex(object_cref sub) const +{ + long result = PyInt_AsLong(this->attr("rindex")(sub).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL long str::rindex(object_cref sub, object_cref start) const +{ + long result = PyInt_AsLong(this->attr("rindex")(sub,start).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL long str::rindex(object_cref sub, object_cref start, object_cref end) const +{ + long result = PyInt_AsLong(this->attr("rindex")(sub,start,end).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL str str::rjust(object_cref width) const +{ + return assume_str(this->attr("rjust")(width)); +} + +BOOST_PYTHON_DECL str str::rstrip() const +{ + return assume_str(this->attr("rstrip")()); +} + +BOOST_PYTHON_DECL list str::split() const +{ + return list(this->attr("split")()); +} + +BOOST_PYTHON_DECL list str::split(object_cref sep) const +{ + return list(this->attr("split")(sep)); +} + +BOOST_PYTHON_DECL list str::split(object_cref sep, object_cref maxsplit) const +{ + return list(this->attr("split")(sep,maxsplit)); +} + +BOOST_PYTHON_DECL list str::splitlines() const +{ + return list(this->attr("splitlines")()); +} + +BOOST_PYTHON_DECL list str::splitlines(object_cref keepends) const +{ + return list(this->attr("splitlines")(keepends)); +} + +BOOST_PYTHON_DECL bool str::startswith(object_cref prefix) const +{ + bool result = PyInt_AsLong(this->attr("startswith")(prefix).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL bool str::startswith(object_cref prefix, object_cref start) const +{ + bool result = PyInt_AsLong(this->attr("startswith")(prefix,start).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL bool str::startswith(object_cref prefix, object_cref start, object_cref end) const +{ + bool result = PyInt_AsLong(this->attr("startswith")(prefix,start,end).ptr()); + if (PyErr_Occurred()) + throw_error_already_set(); + return result; +} + +BOOST_PYTHON_DECL str str::strip() const +{ + return assume_str(this->attr("strip")()); +} + +BOOST_PYTHON_DECL str str::swapcase() const +{ + return assume_str(this->attr("swapcase")()); +} + +BOOST_PYTHON_DECL str str::title() const +{ + return assume_str(this->attr("title")()); +} + +BOOST_PYTHON_DECL str str::translate(object_cref table) const +{ + return assume_str(this->attr("translate")(table)); +} + +BOOST_PYTHON_DECL str str::translate(object_cref table, object_cref deletechars) const +{ + return assume_str(this->attr("translate")(table,deletechars)); +} + +BOOST_PYTHON_DECL str str::upper() const +{ + return assume_str(this->attr("upper")()); +} + +}} // namespace boost::python diff --git a/src/tuple.cpp b/src/tuple.cpp new file mode 100644 index 00000000..92e0df92 --- /dev/null +++ b/src/tuple.cpp @@ -0,0 +1,20 @@ +#include + +namespace boost { namespace python { + +BOOST_PYTHON_DECL detail::new_reference tuple::call(object const& arg) +{ + return (detail::new_reference)PyObject_CallFunction( + (PyObject*)&PyTuple_Type, "(O)", + arg.ptr()); +} + +BOOST_PYTHON_DECL tuple::tuple() + : object(detail::new_reference(PyTuple_New(0))) +{} + +BOOST_PYTHON_DECL tuple::tuple(object_cref sequence) + : object(tuple::call(sequence)) +{} + +}} // namespace boost::python diff --git a/test/Jamfile b/test/Jamfile index 1a73da53..5fb0eff4 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -61,9 +61,14 @@ bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters bpl-test test_pointer_adoption ; bpl-test operators ; bpl-test callbacks ; + bpl-test object ; bpl-test list ; bpl-test long ; +bpl-test dict ; +bpl-test tuple ; +bpl-test str ; + bpl-test virtual_functions ; bpl-test back_reference ; bpl-test implicit ; diff --git a/test/dict.cpp b/test/dict.cpp new file mode 100644 index 00000000..d693658c --- /dev/null +++ b/test/dict.cpp @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include + +using namespace boost::python; + +object new_dict() +{ + return dict(); +} + +object data_dict() +{ + dict tmp1; + tmp1["key1"] = "value1"; + + dict tmp2; + tmp2["key2"] = "value2"; + tmp1[1] = tmp2; + return tmp1; +} + +object dict_from_sequence(object sequence) +{ + return dict(sequence); +} + +object dict_keys(dict data) +{ + return data.keys(); +} + +object dict_values(dict data) +{ + return data.values(); +} + +object dict_items(dict data) +{ + return data.items(); +} + +void work_with_dict(dict data1, dict data2) +{ + if (!data1.has_key("k1")) { + throw std::runtime_error("dict does not have key 'k1'"); + } + data1.update(data2); +} + +void test_templates(object print) +{ + std::string key = "key"; + + dict tmp; + tmp[1] = "a test string"; + print(tmp.get(1)); + //print(tmp[1]); + tmp[1.5] = 13; + print(tmp.get(1.5)); + print(tmp); + print(tmp.get(2,"default")); + print(tmp.has_key(key)); + print(tmp.setdefault(3,"default")); + //print(tmp[3]); +} + +BOOST_PYTHON_MODULE_INIT(dict_ext) +{ + module("dict_ext") + .def("new_dict", new_dict) + .def("data_dict", data_dict) + .def("dict_keys", dict_keys) + .def("dict_values", dict_values) + .def("dict_items", dict_items) + .def("dict_from_sequence", dict_from_sequence) + .def("work_with_dict", work_with_dict) + .def("test_templates", test_templates) + ; +} diff --git a/test/dict.py b/test/dict.py new file mode 100644 index 00000000..fdabf2c9 --- /dev/null +++ b/test/dict.py @@ -0,0 +1,40 @@ +""" +>>> from dict_ext import * +>>> def printer(*args): +... for x in args: print x, +... print +... +>>> print new_dict() +{} +>>> print data_dict() +{1: {'key2': 'value2'}, 'key1': 'value1'} +>>> tmp = data_dict() +>>> print dict_keys(tmp) +[1, 'key1'] +>>> print dict_values(tmp) +[{'key2': 'value2'}, 'value1'] +>>> print dict_items(tmp) +[(1, {'key2': 'value2'}), ('key1', 'value1')] +>>> print dict_from_sequence([(1,1),(2,2),(3,3)]) +{1: 1, 2: 2, 3: 3} +>>> test_templates(printer) +a test string +13 +{1.5: 13, 1: 'a test string'} +default +0 +default +""" + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) diff --git a/test/str.cpp b/test/str.cpp new file mode 100644 index 00000000..d9af0478 --- /dev/null +++ b/test/str.cpp @@ -0,0 +1,68 @@ +#include +#include +#include + +using namespace boost::python; + +object convert_to_string(object data) +{ + return str(data); +} + +void work_with_string(object print) +{ + str data("this is a demo string"); + print(data.split(" ")); + print(data.split(" ",3)); + print(str("<->").join(data.split(" "))); + print(data.capitalize()); + print('[' + data.center(30) + ']'); + print(data.count("t")); + print(data.encode("utf-8")); + print(data.decode("utf-8")); + print(data.endswith("xx")); + print(data.startswith("test")); + print(data.splitlines()); + print(data.strip()); + print(data.swapcase()); + print(data.title()); + + print("find"); + print(data.find("demo")); + print(data.find("demo"),3,5); + print(data.find(std::string("demo"))); + print(data.find(std::string("demo"),9)); + + print("expandtabs"); + str tabstr("\t\ttab\tdemo\t!"); + print(tabstr.expandtabs()); + print(tabstr.expandtabs(4)); + print(tabstr.expandtabs(7.9)); + + print("operators"); + print( str("part1") + str("part2") ); +// print( str("a test string").slice(3,_) ); +// print( str("another test")[5] ); + + print(data.replace("demo",std::string("blabla"))); + print(data.rfind("i",5)); + print(data.rindex("i",5)); + print(data.startswith("asdf")); + print(data.endswith("asdf")); + print(data.translate(str('a')*256)); + + + bool tmp = data.isalnum() || data.isalpha() || data.isdigit() || data.islower() || + data.isspace() || data.istitle() || data.isupper(); + (void)tmp; // ignored. +} + + +BOOST_PYTHON_MODULE_INIT(str_ext) +{ + module("str_ext") + .def("convert_to_string",convert_to_string) + .def("work_with_string",work_with_string) + ; +} + diff --git a/test/str.py b/test/str.py new file mode 100644 index 00000000..666096b1 --- /dev/null +++ b/test/str.py @@ -0,0 +1,52 @@ +""" +>>> from str_ext import * +>>> def printer(*args): +... for x in args: print x, +... print +... +>>> work_with_string(printer) +['this', 'is', 'a', 'demo', 'string'] +['this', 'is', 'a', 'demo string'] +this<->is<->a<->demo<->string +This is a demo string +[ this is a demo string ] +2 +this is a demo string +this is a demo string +0 +0 +['this is a demo string'] +this is a demo string +THIS IS A DEMO STRING +This Is A Demo String +find +10 +10 3 5 +10 +10 +expandtabs + tab demo ! + tab demo ! + tab demo ! +operators +part1part2 +this is a blabla string +18 +18 +0 +0 +aaaaaaaaaaaaaaaaaaaaa +""" + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) diff --git a/test/tuple.cpp b/test/tuple.cpp new file mode 100644 index 00000000..38494b76 --- /dev/null +++ b/test/tuple.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +using namespace boost::python; + +object convert_to_tuple(object data) +{ + return tuple(data); +} + +void test_operators(tuple t1, tuple t2, object print) +{ + print(t1 + t2); +} + +BOOST_PYTHON_MODULE_INIT(tuple_ext) +{ + module("tuple_ext") + .def("convert_to_tuple",convert_to_tuple) + .def("test_operators",test_operators) + ; +} diff --git a/test/tuple.py b/test/tuple.py new file mode 100644 index 00000000..74a6e9d8 --- /dev/null +++ b/test/tuple.py @@ -0,0 +1,26 @@ +""" +>>> from tuple_ext import * +>>> def printer(*args): +... for x in args: print x, +... print +... +>>> print convert_to_tuple("this is a test string") +('t', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't', ' ', 's', 't', 'r', 'i', 'n', 'g') +>>> t1 = convert_to_tuple("this is") +>>> t2 = (1,2,3,4) +>>> test_operators(t1,t2,printer) +('t', 'h', 'i', 's', ' ', 'i', 's', 1, 2, 3, 4) +""" + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From d9a58ef830c2021f5543fecc94ed60c218cb55c5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 18 Jul 2002 15:27:29 +0000 Subject: [PATCH 0602/1042] str, dict, and tuple! [SVN r14518] --- include/boost/python/module.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 8ee63485..5537171d 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -9,7 +9,6 @@ # include # include # include -# include # include # include # include From 5cfc0cce1470a600b783c4a8735c54de643de891 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 18 Jul 2002 15:52:18 +0000 Subject: [PATCH 0603/1042] str, dict, and tuple! [SVN r14519] --- Jamfile | 1 - include/boost/python/str.hpp | 24 ++++++++++++------------ src/str.cpp | 24 ++++++++++++------------ 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/Jamfile b/Jamfile index 81789b85..fea5e97a 100644 --- a/Jamfile +++ b/Jamfile @@ -29,7 +29,6 @@ dll bpl src/object/life_support.cpp src/errors.cpp src/module.cpp - src/objects2.cpp src/converter/builtin_converters.cpp src/converter/arg_to_python_base.cpp src/object/iterator.cpp diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index 53d7f321..72161c7b 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -40,7 +40,7 @@ class str : public object BOOST_PYTHON_DECL long count(object_cref sub, object_cref start) const; template - str count(T1 const& sub,T2 const& start) const + long count(T1 const& sub,T2 const& start) const { return this->count(object(sub), object(start)); } @@ -48,41 +48,41 @@ class str : public object BOOST_PYTHON_DECL long count(object_cref sub, object_cref start, object_cref end) const; template - str count(T1 const& sub,T2 const& start, T3 const& end) const + long count(T1 const& sub,T2 const& start, T3 const& end) const { return this->count(object(sub), object(start)); } - BOOST_PYTHON_DECL str decode() const; - BOOST_PYTHON_DECL str decode(object_cref encoding) const; + BOOST_PYTHON_DECL object decode() const; + BOOST_PYTHON_DECL object decode(object_cref encoding) const; template - str decode(T const& encoding) const + object decode(T const& encoding) const { return this->decode(object(encoding)); } - BOOST_PYTHON_DECL str decode(object_cref encoding, object_cref errors) const; + BOOST_PYTHON_DECL object decode(object_cref encoding, object_cref errors) const; template - str decode(T1 const& encoding, T2 const& errors) const + object decode(T1 const& encoding, T2 const& errors) const { return this->decode(object(encoding),object(errors)); } - BOOST_PYTHON_DECL str encode() const; - BOOST_PYTHON_DECL str encode(object_cref encoding) const; + BOOST_PYTHON_DECL object encode() const; + BOOST_PYTHON_DECL object encode(object_cref encoding) const; template - str encode(T const& encoding) const + object encode(T const& encoding) const { return this->encode(object(encoding)); } - BOOST_PYTHON_DECL str encode(object_cref encoding, object_cref errors) const; + BOOST_PYTHON_DECL object encode(object_cref encoding, object_cref errors) const; template - str encode(T1 const& encoding, T2 const& errors) const + object encode(T1 const& encoding, T2 const& errors) const { return this->encode(object(encoding),object(errors)); } diff --git a/src/str.cpp b/src/str.cpp index dd8ce0a7..fc045d9f 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -59,34 +59,34 @@ BOOST_PYTHON_DECL long str::count(object_cref sub, object_cref start, object_cre return extract(this->attr("count")(sub,start,end)); } -BOOST_PYTHON_DECL str str::decode() const +BOOST_PYTHON_DECL object str::decode() const { - return assume_str(this->attr("decode")()); + return this->attr("decode")(); } -BOOST_PYTHON_DECL str str::decode(object_cref encoding) const +BOOST_PYTHON_DECL object str::decode(object_cref encoding) const { - return assume_str(this->attr("decode")(encoding)); + return this->attr("decode")(encoding); } -BOOST_PYTHON_DECL str str::decode(object_cref encoding, object_cref errors) const +BOOST_PYTHON_DECL object str::decode(object_cref encoding, object_cref errors) const { - return assume_str(this->attr("decode")(encoding,errors)); + return this->attr("decode")(encoding,errors); } -BOOST_PYTHON_DECL str str::encode() const +BOOST_PYTHON_DECL object str::encode() const { - return assume_str(this->attr("encode")()); + return this->attr("encode")(); } -BOOST_PYTHON_DECL str str::encode(object_cref encoding) const +BOOST_PYTHON_DECL object str::encode(object_cref encoding) const { - return assume_str(this->attr("encode")(encoding)); + return this->attr("encode")(encoding); } -BOOST_PYTHON_DECL str str::encode(object_cref encoding, object_cref errors) const +BOOST_PYTHON_DECL object str::encode(object_cref encoding, object_cref errors) const { - return assume_str(this->attr("encode")(encoding,errors)); + return this->attr("encode")(encoding,errors); } BOOST_PYTHON_DECL bool str::endswith(object_cref suffix) const From 5c54aecdda62f1704a0551d58596a26ffe933637 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 19 Jul 2002 18:05:18 +0000 Subject: [PATCH 0604/1042] initial commit [SVN r14529] --- doc/v2/Jun2002.html | 226 +++++++++++++++++++++++++++++++++++ doc/v2/index.html | 1 + doc/v2/progress_reports.html | 44 +++++++ 3 files changed, 271 insertions(+) create mode 100644 doc/v2/Jun2002.html create mode 100644 doc/v2/progress_reports.html diff --git a/doc/v2/Jun2002.html b/doc/v2/Jun2002.html new file mode 100644 index 00000000..7863ff27 --- /dev/null +++ b/doc/v2/Jun2002.html @@ -0,0 +1,226 @@ + + + + +Boost.Python - June 2002 Progress Report + + + + + + + +
    +

    +

    +
    +

    Boost.Python

    +

    June 2002 Progress Report

    +
    +
    +

    Contents

    +
    +
    Introduction
    +
    handle<T>
    +
    object
    +
    +
    object operators
    +
    object conversions
    +
    +
    list
    +
    Numerics
    +
    Community
    +
    What's Next
    +
    + +

    Introduction

    + +July was mostly focused on allowing expressive manipulation of +individual Python objects, or what Ralf Grosse-Kunstleve calls +"Writing Python in C++". The work began with this posting, +which outlines the issues and intention. + +

    handle<T>

    + +The most basic element needed was a replacement for the +reference<> class template and the +ref typedef from Boost.Python v1, a simple smart +pointer to a Python object. The old v1 typedef +"ref" (for +reference<PyObject>) had to be retired because I +thought it would be too confusing given the importance of boost::ref() to this +library. I began a discussionof +possible names, and it was eventually decided +to rename reference to handle and supply a +default argument so that ref could be spelled +handle<> without an additional typedef. There +were also some interface changes to make it safer and more-efficient +to interface with the raw +PyObject*s forced on us by Python's 'C' API. A +discussion of those protocols can be found here. + +

    object

    + +It is intended that users will seldom need or want to work with +handle<>; its major distinguishing features are +that it gives direct access to the underlying object representation +through operator* and operator->, and +that can be NULL, both sources of danger. Instead the +library provides a class called object, which +encapsulates a valid Python object and provides a similar interface to +Python's. + +

    object operators

    + +The first challenge was to provide support for object manipulations +using a Python-like syntax, mostly in the form of operator overloads: + + + + + + + + + + + + + +
    Python C++ + +
    y = x.foo y = x.attr("foo"); +
    x.foo = 1 x.attr("foo") = 1; + +
    y = x[z] y = x[z]; +
    x[z] = 1 x[z] = 1; + +
    y = x[3:-1] y = x.slice(3,-1); + +
    y = x[3:] y = x.slice(3,_); + +
    y = x[:-2] y = x.slice(_,-2); + +
    z = x(1, y) z = x(1, y); +
    z = x.f(1, y) z = x.attr("f")(1, y); + +
    not x !x + +
    x and y x and y +
    + +I'm still a unsatisfied with the interface for attribute access. There +original proposal used a syntax like this one: +
    +y = x._("foo"); 
    +x._("foo") = 1; 
    +
    + +which was only marginally better than what we've got. Niki Spahiev +then pointed +out a potential conflict with the macro which GNU Gettext suggests +people define. This unfortunate state of affairs forced us into using +attr instead. I'd still like to find a better interface, +but the lack of overloadable C++ operators which aren't already used +in Python is an obstacle. The comma operator is still a possibility, +but it has the wrong precedence: +
    +y = x,"foo"    // error
    +x,"foo" = 1;   // error
    +
    +y = (x,"foo"); // ok
    +(x,"foo") = 1; // ok
    +
    + +Well, I guess we could consider adding that to the interface without +removing attr(), to see how it plays out... + +

    object conversions

    + +The object class also provided an opportunity to replace +Boost.Python v1's to_python() as a user-level +interface. Instead, object has a templated constructor +which can be used to convert any C++ object to Python using the same +underlying mechanisms used for the arguments to call<>. + +

    Incidentally, the implementation of operator and conversion support +for object uncovered an inordinate number of compiler bugs in our +targeted platforms. It was a lot more "interesting" than it +should have been. + +

    list

    + +With object implemented, it was time to begin replacing +the ad-hoc implementations of list, string, +and dictionary supplied by Boost.Python v1 with something +more robust. I started with list as an example. Because +object already provides all of the requisite operators, +publicly deriving list from object seemed like a good +choice. The remaining issues were what do do about the one-argument +list constructor (which in Python attempts to convert its argument to +a list), and how to deal converting with list arguments +to wrapped functions. Some of the issues are laid out in this +thread. Ultimately, it was decided that list(x) +should do the same thing in C++ as in Python (conversion), while +list arguments should only match Python +lists (and list subclasses). The +implementation worked well, and provided a roadmap +for the protocol to be used for implementation of the other built-in +types. + +

    Numerics

    + +Support for C++ long long and unsigned long +long +(and __int64 on MSVC) to/from python conversions was +added this month. We also improved handling of numeric overflows when +converting, e.g., a Python int to a type with a more limited range of +representation. + +

    Community

    + + + +Deep thanks to all the Boost.Python contributors! This project +wouldn't be possible without your participation. + +

    What's Next

    + +As I write this we are already well into the month of July, so I +suggest you consult the Mailing +List Archive if you want to know what's been happening. Otherwise +you'll just have to wait till next month (hopefully the beginning). + +

    Revised + + 19 July, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + diff --git a/doc/v2/index.html b/doc/v2/index.html index f47747f7..d1c1c0c0 100644 --- a/doc/v2/index.html +++ b/doc/v2/index.html @@ -27,6 +27,7 @@
    Rationale
    Definitions
    Frequently Asked Questions (FAQs)
    +
    Progress Reports
    Bibliography
    Acknowledgments
    diff --git a/doc/v2/progress_reports.html b/doc/v2/progress_reports.html new file mode 100644 index 00000000..5ba72b94 --- /dev/null +++ b/doc/v2/progress_reports.html @@ -0,0 +1,44 @@ + + + + +Boost.Python - Progress Reports + + + + + + + +
    +

    +

    +
    +

    Boost.Python

    +

    Progress Reports

    +
    +
    + +Monthly progress reports are required as part of Boost Consulting's +contract with LLNL for Boost.Python development. These reports contain +a useful record of the project history, including the rationale for +design decisions and links to relevant discussions. + +
    +
    February 2002
    +
    March 2002
    +
    April 2002
    +
    May 2002
    +
    June 2002
    +
    +
    +

    Revised + + 18 July, 2002 + +

    +

    © Copyright Dave Abrahams + 2002. All Rights Reserved.

    + + From c0eea6e667fc2b61a9af4faaf4756d7d8564ccbf Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 19 Jul 2002 18:06:05 +0000 Subject: [PATCH 0605/1042] fix link [SVN r14530] --- doc/v2/progress_reports.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/progress_reports.html b/doc/v2/progress_reports.html index 5ba72b94..684fb254 100644 --- a/doc/v2/progress_reports.html +++ b/doc/v2/progress_reports.html @@ -30,7 +30,7 @@ design decisions and links to relevant discussions.
    March 2002
    April 2002
    May 2002
    -
    June 2002
    +
    June 2002

    Revised From 12120413f92de565ef342fd4f22f4254324cb76d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 19 Jul 2002 20:10:11 +0000 Subject: [PATCH 0606/1042] #undef isspace etc. [SVN r14539] --- include/boost/python/str.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index 72161c7b..758aa79e 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -5,6 +5,13 @@ #include #include +// disable defines in provided by some system libraries +#undef isspace +#undef islower +#undef isalpha +#undef isdigit +#undef isalnum + namespace boost { namespace python { class str : public object From 7ecf76490c44950b63d59a3fa8b4479b92931e49 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 20 Jul 2002 00:14:20 +0000 Subject: [PATCH 0607/1042] one #undef was missing [SVN r14544] --- include/boost/python/str.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index 758aa79e..dd6548ab 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -11,6 +11,7 @@ #undef isalpha #undef isdigit #undef isalnum +#undef isupper namespace boost { namespace python { From d27e5a5e1d6e8b1275fd7031ff48486a1ac6b195 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 21 Jul 2002 05:03:11 +0000 Subject: [PATCH 0608/1042] Rationalize object_manager [SVN r14548] --- .../boost/python/converter/arg_to_python.hpp | 3 +- .../converter/obj_mgr_arg_from_python.hpp | 12 +- .../boost/python/converter/object_manager.hpp | 227 +++++++++++------- .../python/converter/pyobject_traits.hpp | 42 ++++ .../boost/python/converter/pyobject_type.hpp | 36 +++ .../pytype_object_manager_traits.hpp | 13 +- .../converter/pytype_result_from_python.hpp | 18 -- include/boost/python/detail/borrowed_ptr.hpp | 11 +- include/boost/python/errors.hpp | 6 + include/boost/python/handle.hpp | 81 ++----- include/boost/python/object_call.hpp | 16 +- include/boost/python/object_core.hpp | 65 ++++- include/boost/python/tag.hpp | 17 ++ include/boost/python/to_python_value.hpp | 3 +- src/converter/from_python.cpp | 10 +- test/extract.cpp | 30 ++- 16 files changed, 377 insertions(+), 213 deletions(-) create mode 100644 include/boost/python/converter/pyobject_traits.hpp create mode 100644 include/boost/python/converter/pyobject_type.hpp delete mode 100644 include/boost/python/converter/pytype_result_from_python.hpp create mode 100644 include/boost/python/tag.hpp diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index 9e214686..eb1cd80c 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -18,6 +18,7 @@ # include // Bring in specializations # include +# include namespace boost { namespace python { namespace converter { @@ -64,7 +65,7 @@ namespace detail PyObject* get() const { - return python::upcast(converter::get_managed_object(m_src)); + return python::upcast(get_managed_object(m_src, tag)); } private: diff --git a/include/boost/python/converter/obj_mgr_arg_from_python.hpp b/include/boost/python/converter/obj_mgr_arg_from_python.hpp index ee0980a5..75b0ae43 100644 --- a/include/boost/python/converter/obj_mgr_arg_from_python.hpp +++ b/include/boost/python/converter/obj_mgr_arg_from_python.hpp @@ -12,6 +12,7 @@ # include # include # include +# include // // arg_from_python converters for Python type wrappers, to be used as @@ -31,6 +32,15 @@ struct object_manager_value_arg_from_python PyObject* m_source; }; +// Used for converting reference-to-object-manager arguments from +// python. The process used here is a little bit odd. Upon +// construction, we build the object manager object in the m_result +// object, *forcing* it to accept the source Python object by casting +// its pointer to detail::borrowed_reference. This is supposed to +// bypass any type checking of the source object. The convertible +// check then extracts the owned object and checks it. If the check +// fails, nothing else in the program ever gets to touch this strange +// "forced" object. template struct object_manager_ref_arg_from_python { @@ -83,7 +93,7 @@ namespace detail template inline bool object_manager_ref_check(T const& x) { - return object_manager_traits::check((get_managed_object)(x)); + return object_manager_traits::check(get_managed_object(x, tag)); } } diff --git a/include/boost/python/converter/object_manager.hpp b/include/boost/python/converter/object_manager.hpp index b9d64286..431ef708 100755 --- a/include/boost/python/converter/object_manager.hpp +++ b/include/boost/python/converter/object_manager.hpp @@ -8,12 +8,13 @@ # include # include +# include # include # include # include // Facilities for dealing with types which always manage Python -// objects. Some examples are object, list, et. al. Different +// objects. Some examples are object, list, str, et. al. Different // to_python/from_python conversion rules apply here because in // contrast to other types which are typically embedded inside a // Python object, these are wrapped around a Python object. For most @@ -22,47 +23,103 @@ // Python argument, since mutating member functions on T actually only // modify the held Python object. // -// Note also that handle<> does not qualify as an object manager because: -// a. It might not manage a Python object (it can be null) -// b. Mutating operations visible to users modify the handle<> itself. +// handle is an object manager, though strictly speaking it should +// not be. In other words, even though mutating member functions of +// hanlde actually modify the handle and not the T object, +// handle& arguments of wrapped functions will bind to "rvalues" +// wrapping the actual Python argument, just as with other object +// manager classes. Making an exception for handle is simply not +// worth the trouble. +// +// borrowed cv* is an object manager so that we can use the general +// to_python mechanisms to convert raw Python object pointers to +// python, without the usual semantic problems of using raw pointers. -namespace boost { namespace python { namespace api + +// Object Manager Concept requirements: +// +// T is an Object Manager +// p is a PyObject* +// x is a T +// +// * object_manager_traits::is_specialized == true +// +// * T(detail::borrowed_reference(p)) +// Manages p without checking its type +// +// * get_managed_object(x, boost::python::tag) +// Convertible to PyObject* +// +// Additional requirements if T can be converted from_python: +// +// * T(object_manager_traits::adopt(p)) +// steals a reference to p, or throws a TypeError exception if +// p doesn't have an appropriate type. May assume p is non-null +// +// * X::check(p) +// convertible to bool. True iff T(X::construct(p)) will not +// throw. + +// Forward declarations +// +namespace boost { namespace python { - class object; // forward declaration -}}} + namespace api + { + class object; + } +}} namespace boost { namespace python { namespace converter { -// Used to create object managers of type T, taking ownership of a -// given PyObject*. Specializations X must satisfy the following, -// where p is a non-null PyObject*: -// -// X::is_specialized == true -// -// T(X::adopt(p)) - constructs a T object, stealing a reference to -// p, or throws a TypeError exception if p doesn't have an -// appropriate type. -// -// X::check(p), convertible to bool. True iff T(X::construct(p)) will -// not throw. -// + +// Specializations for handle template -struct object_manager_traits +struct handle_object_manager_traits + : pyobject_traits { - BOOST_STATIC_CONSTANT(bool, is_specialized = false); + private: + typedef pyobject_traits base; + + public: + BOOST_STATIC_CONSTANT(bool, is_specialized = true); + + // Initialize with a null_ok pointer for efficiency, bypassing the + // null check since the source is always non-null. + static null_ok* adopt(PyObject* p) + { + return python::allow_null(base::checked_downcast(p)); + } }; -// A metafunction returning true iff its argument is an object manager. +template +struct default_object_manager_traits +{ + BOOST_STATIC_CONSTANT( + bool, is_specialized = python::detail::is_borrowed_ptr::value + ); +}; + +template +struct object_manager_traits + : mpl::select_type< + is_handle::value + , handle_object_manager_traits + , default_object_manager_traits + >::type +{ +}; + +// +// Traits for detecting whether a type is an object manager or a +// (cv-qualified) reference to an object manager. +// + template struct is_object_manager { - private: - // handle the cases that would otherwise require partial specialization - BOOST_STATIC_CONSTANT(bool, hdl = is_handle::value); - BOOST_STATIC_CONSTANT(bool, borrowed = python::detail::is_borrowed_ptr::value); - BOOST_STATIC_CONSTANT(bool, traits_specialized = object_manager_traits::is_specialized); - public: - BOOST_STATIC_CONSTANT(bool, value = (hdl | borrowed | traits_specialized)); + BOOST_STATIC_CONSTANT( + bool, value = object_manager_traits::is_specialized); }; # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -102,84 +159,74 @@ namespace detail typedef char (&yes_reference_to_object_manager)[1]; typedef char (&no_reference_to_object_manager)[2]; + // A number of nastinesses go on here in order to work around MSVC6 + // bugs. template struct is_object_manager_help - : mpl::select_type< - is_object_manager::value - , yes_reference_to_object_manager - , no_reference_to_object_manager> { + typedef typename mpl::select_type< + is_object_manager::value + , yes_reference_to_object_manager + , no_reference_to_object_manager + >::type type; + + // If we just use the type instead of the result of calling this + // function, VC6 will ICE. + static type call(); }; - template - struct is_reference_to_object_manager_helper + // A set of overloads for each cv-qualification. The same argument + // is passed twice: the first one is used to unwind the cv*, and the + // second one is used to avoid relying on partial ordering for + // overload resolution. + template + typename is_object_manager_help + is_object_manager_helper(U*, void*); + + template + typename is_object_manager_help + is_object_manager_helper(U const*, void const*); + + template + typename is_object_manager_help + is_object_manager_helper(U volatile*, void volatile*); + + template + typename is_object_manager_help + is_object_manager_helper(U const volatile*, void const volatile*); + + template + struct is_reference_to_object_manager_nonref { - template - struct apply - { - static int x; - static no_reference_to_object_manager check(...); - }; + BOOST_STATIC_CONSTANT(bool, value = false); }; - template - typename is_object_manager_help::type - is_object_manager_helper(int*, double, double, U&); - - template - typename is_object_manager_help::type - is_object_manager_helper(int*, int*, double, U const&); - - template - typename is_object_manager_help::type - is_object_manager_helper(int*, double, int*, U volatile&); - - template - typename is_object_manager_help::type - is_object_manager_helper(int*, int*, int*, U const volatile&); - - no_reference_to_object_manager is_object_manager_helper(...); + template + struct is_reference_to_object_manager_ref + { + static T sample_object; + BOOST_STATIC_CONSTANT( + bool, value + = (sizeof(is_object_manager_helper(&sample_object, &sample_object).call()) + == sizeof(detail::yes_reference_to_object_manager) + ) + ); + }; } template struct is_reference_to_object_manager { typedef typename mpl::select_type< - is_reference::value, int*, double>::type r_t; - typedef typename mpl::select_type< - python::detail::is_reference_to_const::value, int*, double>::type rc_t; - typedef typename mpl::select_type< - python::detail::is_reference_to_volatile::value, int*, double>::type rv_t; - - typedef typename mpl::select_type::value, T, int>::type value_t; + is_reference::value + , detail::is_reference_to_object_manager_ref + , detail::is_reference_to_object_manager_nonref + > chooser; - static value_t sample_object; - - BOOST_STATIC_CONSTANT( - bool, value - = (sizeof(detail::is_object_manager_helper(r_t(),rc_t(),rv_t(),sample_object)) - == sizeof(detail::yes_reference_to_object_manager) - ) - ); + BOOST_STATIC_CONSTANT(bool, value = chooser::type::value); }; # endif -template -inline T* get_managed_object(handle const& h) -{ - return h.get(); -} - -template -inline T* get_managed_object(python::detail::borrowed const volatile* p) -{ - return (T*)p; -} - -// forward declaration needed because name lookup is bound by the -// definition context. -PyObject* get_managed_object(python::api::object const&); - }}} // namespace boost::python::converter #endif // OBJECT_MANAGER_DWA2002614_HPP diff --git a/include/boost/python/converter/pyobject_traits.hpp b/include/boost/python/converter/pyobject_traits.hpp new file mode 100644 index 00000000..f975360c --- /dev/null +++ b/include/boost/python/converter/pyobject_traits.hpp @@ -0,0 +1,42 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef PYOBJECT_TRAITS_DWA2002720_HPP +# define PYOBJECT_TRAITS_DWA2002720_HPP + +# include +# include + +namespace boost { namespace python { namespace converter { + +template struct pyobject_traits; + +template <> +struct pyobject_traits +{ + // All objects are convertible to PyObject + static bool check(PyObject*) { return true; } + static PyObject* checked_downcast(PyObject* x) { return x; } +}; + +// +// Specializations +// + +# define BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(T) \ + template <> struct pyobject_traits \ + : pyobject_type {} + +// This is not an exhaustive list; should be expanded. +BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Type); +BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(List); +BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Int); +BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Long); +BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Dict); +BOOST_PYTHON_BUILTIN_OBJECT_TRAITS(Tuple); + +}}} // namespace boost::python::converter + +#endif // PYOBJECT_TRAITS_DWA2002720_HPP diff --git a/include/boost/python/converter/pyobject_type.hpp b/include/boost/python/converter/pyobject_type.hpp new file mode 100644 index 00000000..63127d5b --- /dev/null +++ b/include/boost/python/converter/pyobject_type.hpp @@ -0,0 +1,36 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef PYOBJECT_TYPE_DWA2002720_HPP +# define PYOBJECT_TYPE_DWA2002720_HPP + +# include +# include + +namespace boost { namespace python { namespace converter { + +BOOST_PYTHON_DECL PyObject* checked_downcast_impl(PyObject*, PyTypeObject*); + +// Used as a base class for specializations which need to provide +// Python type checking capability. +template +struct pyobject_type +{ + static bool check(PyObject* x) + { + return ::PyObject_IsInstance(x, (PyObject*)pytype); + } + + static Object* checked_downcast(PyObject* x) + { + return python::downcast( + (checked_downcast_impl)(x, pytype) + ); + } +}; + +}}} // namespace boost::python::converter + +#endif // PYOBJECT_TYPE_DWA2002720_HPP diff --git a/include/boost/python/converter/pytype_object_manager_traits.hpp b/include/boost/python/converter/pytype_object_manager_traits.hpp index 24893ea5..94cbae64 100644 --- a/include/boost/python/converter/pytype_object_manager_traits.hpp +++ b/include/boost/python/converter/pytype_object_manager_traits.hpp @@ -6,10 +6,11 @@ #ifndef PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP # define PYTYPE_OBJECT_MANAGER_TRAITS_DWA2002716_HPP -# include # include # include # include +# include +# include namespace boost { namespace python { namespace converter { @@ -22,10 +23,10 @@ template struct object_manager_traits; // template struct pytype_object_manager_traits + : pyobject_type // provides check() { BOOST_STATIC_CONSTANT(bool, is_specialized = true); static inline python::detail::new_reference adopt(PyObject*); - static inline bool check(PyObject* x); }; // @@ -34,13 +35,7 @@ struct pytype_object_manager_traits template inline python::detail::new_reference pytype_object_manager_traits::adopt(PyObject* x) { - return pytype_result_from_python(pytype, x); -} - -template -inline bool pytype_object_manager_traits::check(PyObject* x) -{ - return ::PyObject_IsInstance(x, python::upcast(pytype)); + return python::detail::new_reference(python::pytype_check(pytype, x)); } }}} // namespace boost::python::converter diff --git a/include/boost/python/converter/pytype_result_from_python.hpp b/include/boost/python/converter/pytype_result_from_python.hpp deleted file mode 100644 index 9cb95712..00000000 --- a/include/boost/python/converter/pytype_result_from_python.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef PYTYPE_RESULT_FROM_PYTHON_DWA2002716_HPP -# define PYTYPE_RESULT_FROM_PYTHON_DWA2002716_HPP - -# include - -namespace boost { namespace python { namespace converter { - -BOOST_PYTHON_DECL python::detail::new_reference -pytype_result_from_python(PyTypeObject*, PyObject* source); - -}}} // namespace boost::python::converter - -#endif // PYTYPE_RESULT_FROM_PYTHON_DWA2002716_HPP diff --git a/include/boost/python/detail/borrowed_ptr.hpp b/include/boost/python/detail/borrowed_ptr.hpp index 527dfc46..dc50c634 100755 --- a/include/boost/python/detail/borrowed_ptr.hpp +++ b/include/boost/python/detail/borrowed_ptr.hpp @@ -11,6 +11,7 @@ # include # include # include +# include namespace boost { namespace python { namespace detail { @@ -98,6 +99,14 @@ class is_borrowed_ptr # endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -}}} // namespace boost::python::detail +} + +template +inline T* get_managed_object(detail::borrowed const volatile* p, tag_t) +{ + return (T*)p; +} + +}} // namespace boost::python::detail #endif // #ifndef BORROWED_PTR_DWA20020601_HPP diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp index 1f83b679..4c47aca8 100644 --- a/include/boost/python/errors.hpp +++ b/include/boost/python/errors.hpp @@ -46,6 +46,12 @@ inline T* expect_non_null(T* x) return x; } +# ifdef BOOST_PYTHON_V2 +// Return source if it is an instance of pytype; throw an appropriate +// exception otherwise. +BOOST_PYTHON_DECL PyObject* pytype_check(PyTypeObject* pytype, PyObject* source); +# endif + }} // namespace boost::python #endif // ERRORS_DWA052500_H_ diff --git a/include/boost/python/handle.hpp b/include/boost/python/handle.hpp index 78092a3f..8ebb1ae2 100755 --- a/include/boost/python/handle.hpp +++ b/include/boost/python/handle.hpp @@ -12,6 +12,8 @@ # include # include # include +# include +# include namespace boost { namespace python { @@ -60,8 +62,11 @@ template class handle { typedef T* (handle::*bool_type); + + public: // types + typedef T element_type; - public: + public: // member functions handle(); ~handle(); @@ -111,45 +116,22 @@ class handle } bool operator! () const; // never throws + public: // implementation details -- do not touch + // Defining this in the class body suppresses a VC7 link failure + inline handle(detail::borrowed_reference x) + : m_p( + python::incref( + downcast((PyObject*)x) + )) + { + } + private: // data members T* m_p; }; typedef handle type_handle; -// -// Converter specializations -// -template struct arg_from_python; -template <> -struct arg_from_python > -{ - typedef handle<> result_type; - - arg_from_python(PyObject*); - bool convertible() const; - handle<> operator()(PyObject* x) const; -}; - -template <> -struct arg_from_python const&> - : arg_from_python > -{ - arg_from_python(PyObject*); -}; - -namespace converter -{ - template struct return_from_python; - - template <> - struct return_from_python > - { - typedef handle<> result_type; - result_type operator()(PyObject* x) const; - }; -} - // // Compile-time introspection // @@ -245,33 +227,12 @@ inline T* handle::release() return result; } -// -// Converter specialization implementation -// -inline arg_from_python >::arg_from_python(PyObject*) -{} - -inline bool arg_from_python >::convertible() const +// Because get_managed_object must return a non-null PyObject*, we +// return Py_None if the handle is null. +template +inline PyObject* get_managed_object(handle const& h, tag_t) { - return true; -} - -inline handle<> arg_from_python >::operator()(PyObject* x) const -{ - return handle<>(python::borrowed(python::allow_null(x))); -} - -inline arg_from_python const&>::arg_from_python(PyObject*) - : arg_from_python >(0) -{} - -namespace converter -{ - inline handle<> - return_from_python >::operator()(PyObject* x) const - { - return handle<>(x); - } + return h.get() ? python::upcast(h.get()) : Py_None; } }} // namespace boost::python diff --git a/include/boost/python/object_call.hpp b/include/boost/python/object_call.hpp index 4e9c569e..22e88847 100644 --- a/include/boost/python/object_call.hpp +++ b/include/boost/python/object_call.hpp @@ -10,13 +10,13 @@ #define N BOOST_PP_ITERATION() - template - typename dependent::type - operator()(BOOST_PYTHON_BINARY_ENUM(N, A, const& a)) const - { - typedef typename dependent::type obj; - U const& self = *static_cast(this); - return call(converter::get_managed_object(self), BOOST_PYTHON_UNARY_ENUM(N, a)); - } + template + typename dependent::type + operator()(BOOST_PYTHON_BINARY_ENUM(N, A, const& a)) const + { + typedef typename dependent::type obj; + U const& self = *static_cast(this); + return call(get_managed_object(self, tag), BOOST_PYTHON_UNARY_ENUM(N, a)); + } #undef N diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 72e9e5ed..496752dc 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -15,6 +15,7 @@ # include # include # include +# include # include @@ -73,7 +74,7 @@ namespace api }; # endif - template struct object_initializer; + template struct object_initializer; // A way to turn a conrete type T into a type dependent on U. This // keeps conforming compilers from complaining about returning an @@ -216,8 +217,11 @@ namespace api // explicit conversion from any C++ object to Python template explicit object(T const& x) - : object_base(object_initializer::value>::get( - &x, detail::convertible::check(&x))) + : object_base( + object_initializer< + is_proxy::value + , converter::is_object_manager::value + >::get(&x, detail::convertible::check(&x))) { } @@ -230,20 +234,39 @@ namespace api explicit object(detail::new_non_null_reference); }; - // Derived classes will usually want these as an implementation detail -# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived) \ + // Macros for forwarding constructors in classes derived from + // object. Derived classes will usually want these as an + // implementation detail +# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived) \ inline explicit derived(python::detail::borrowed_reference p) \ : object(p) {} \ inline explicit derived(python::detail::new_reference p) \ : object(p) {} \ inline explicit derived(python::detail::new_non_null_reference p) \ : object(p) {} - + +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 +# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_ +# else + // MSVC6 has a bug which causes an explicit template constructor to + // be preferred over an appropriate implicit conversion operator + // declared on the argument type. Normally, that would cause a + // runtime failure when using extract to extract a type with a + // templated constructor. This additional constructor will turn that + // runtime failure into an ambiguity error at compile-time due to + // the lack of partial ordering, or at least a link-time error if no + // generalized template constructor is declared. +# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived) \ + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived) \ + template \ + explicit derived(extract const&); +# endif + // // object_initializer -- get the handle to construct the object with, // based on whether T is a proxy or derived from object // - template + template struct object_initializer { static PyObject* @@ -261,7 +284,7 @@ namespace api }; template <> - struct object_initializer + struct object_initializer { template static PyObject* @@ -270,8 +293,24 @@ namespace api return python::incref(x->operator object().ptr()); } }; + + template <> + struct object_initializer + { + template + static PyObject* + get(T const* x, ...) + { + return python::incref(get_managed_object(*x, tag)); + } + }; + + template <> + struct object_initializer + {}; // empty implementation should cause an error } using api::object; +template struct extract; // // implementation @@ -340,11 +379,11 @@ namespace converter return python::detail::new_non_null_reference(x); } }; - - inline PyObject* get_managed_object(object const& x) - { - return x.ptr(); - } +} + +inline PyObject* get_managed_object(object const& x, tag_t) +{ + return x.ptr(); } }} // namespace boost::python diff --git a/include/boost/python/tag.hpp b/include/boost/python/tag.hpp new file mode 100644 index 00000000..c8ce6878 --- /dev/null +++ b/include/boost/python/tag.hpp @@ -0,0 +1,17 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TAG_DWA2002720_HPP +# define TAG_DWA2002720_HPP + +namespace boost { namespace python { + +// used only to prevent argument-dependent lookup from finding the +// wrong function in some cases. Cheaper than qualification. +enum tag_t { tag }; + +}} // namespace boost::python + +#endif // TAG_DWA2002720_HPP diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp index 7363fbf7..b85eaf68 100644 --- a/include/boost/python/to_python_value.hpp +++ b/include/boost/python/to_python_value.hpp @@ -14,6 +14,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -85,7 +86,7 @@ namespace detail { return python::upcast( python::xincref( - converter::get_managed_object(x)) + get_managed_object(x, tag)) ); } } diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 7565af38..ade39a21 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -257,8 +257,10 @@ BOOST_PYTHON_DECL void void_result_from_python(PyObject* o) Py_DECREF(expect_non_null(o)); } -BOOST_PYTHON_DECL python::detail::new_reference -pytype_result_from_python(PyTypeObject* type_, PyObject* source) +} + +BOOST_PYTHON_DECL PyObject* +pytype_check(PyTypeObject* type_, PyObject* source) { if (!PyObject_IsInstance(source, python::upcast(type_))) { @@ -272,7 +274,7 @@ pytype_result_from_python(PyTypeObject* type_, PyObject* source) PyErr_SetObject(PyExc_TypeError, msg.get()); throw_error_already_set(); } - return python::detail::new_reference(source); + return source; } -}}} // namespace boost::python::converter +}} // namespace boost::python::converter diff --git a/test/extract.cpp b/test/extract.cpp index 0792e7c6..584eb60a 100644 --- a/test/extract.cpp +++ b/test/extract.cpp @@ -34,7 +34,11 @@ boost::python::list extract_list(object x) return get_list(); } -char const* extract_cstring(object x) { return extract(x); } +char const* extract_cstring(object x) +{ + return extract(x); +} + std::string extract_string(object x) { std::string s = extract(x); @@ -43,8 +47,7 @@ std::string extract_string(object x) std::string const& extract_string_cref(object x) { - std::string const& s = extract(x); - return s; + return extract(x); } X extract_X(object x) @@ -84,6 +87,13 @@ BOOST_PYTHON_MODULE_INIT(extract_ext) { implicitly_convertible(); + class_ x_class("X"); + + x_class + .def_init(args()) + .def( "__repr__", x_rep) + ; + module("extract_ext") .def("extract_bool", extract_bool) .def("extract_list", extract_list) @@ -103,14 +113,20 @@ BOOST_PYTHON_MODULE_INIT(extract_ext) .def("check_X_ptr", check_X_ptr) .def("check_X_ref", check_X_ref) + .add(x_class) .def("double_X", double_X) .def("count_Xs", &X::count) - - .add(class_("X") - .def_init(args()) - .def( "__repr__", x_rep)) ; + + // Instantiate an X object through the Python interface + type_handle xc1 = x_class.object(); + object X_(xc1); + object x_obj = X_(3); + + // Get the C++ object out of the Python object + X const& x = extract(x_obj); + assert(x.value() == 3); } From 4ef5f77161da784457cf76ba1bfa641023d80050 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 21 Jul 2002 07:49:00 +0000 Subject: [PATCH 0609/1042] additional files for pickle support; no modification of any existing files [SVN r14549] --- .../boost/python/object/pickle_support.hpp | 96 ++++++++++++++++ src/object/pickle_support.cpp | 63 +++++++++++ test/pickle1.cpp | 60 ++++++++++ test/pickle1.py | 30 +++++ test/pickle2.cpp | 101 +++++++++++++++++ test/pickle2.py | 44 +++++++ test/pickle3.cpp | 107 ++++++++++++++++++ test/pickle3.py | 38 +++++++ 8 files changed, 539 insertions(+) create mode 100644 include/boost/python/object/pickle_support.hpp create mode 100644 src/object/pickle_support.cpp create mode 100644 test/pickle1.cpp create mode 100644 test/pickle1.py create mode 100644 test/pickle2.cpp create mode 100644 test/pickle2.py create mode 100644 test/pickle3.cpp create mode 100644 test/pickle3.py diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp new file mode 100644 index 00000000..730ae639 --- /dev/null +++ b/include/boost/python/object/pickle_support.hpp @@ -0,0 +1,96 @@ +// (C) Copyright R.W. Grosse-Kunstleve 2002. +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. This +// software is provided "as is" without express or implied warranty, and +// with no claim as to its suitability for any purpose. +#ifndef BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP +#define BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP + +#include +#include + +namespace boost { namespace python { + +handle<> make_instance_reduce_function(); + +namespace error_messages { + + template + struct missing_pickle_support_function_or_incorrect_signature {}; + +} + +class pickle_support_base +{ + private: + struct dummy_return_type_ {}; + + public: + template + static + void + register_( + Class_& cl, + tuple (*getinitargs_fn)(Tgetinitargs), + dummy_return_type_* (*getstate_fn)(), + dummy_return_type_* (*setstate_fn)(), + bool) + { + cl.enable_pickle_support(false); + cl.def("__getinitargs__", getinitargs_fn); + } + + template + static + void + register_( + Class_& cl, + dummy_return_type_* (*getinitargs_fn)(), + tuple (*getstate_fn)(Tgetstate), + void (*setstate_fn)(Tsetstate, object), + bool getstate_manages_dict) + { + cl.enable_pickle_support(getstate_manages_dict); + cl.def("__getstate__", getstate_fn); + cl.def("__setstate__", setstate_fn); + } + + template + static + void + register_( + Class_& cl, + tuple (*getinitargs_fn)(Tgetinitargs), + tuple (*getstate_fn)(Tgetstate), + void (*setstate_fn)(Tsetstate, object), + bool getstate_manages_dict) + { + cl.enable_pickle_support(getstate_manages_dict); + cl.def("__getinitargs__", getinitargs_fn); + cl.def("__getstate__", getstate_fn); + cl.def("__setstate__", setstate_fn); + } + + template + static + void + register_( + Class_&, + ...) + { + typedef typename + error_messages::missing_pickle_support_function_or_incorrect_signature< + Class_>::error_type error_type; + } + + static dummy_return_type_* getinitargs() { return 0; } + static dummy_return_type_* getstate() { return 0; } + static dummy_return_type_* setstate() { return 0; } + + static bool getstate_manages_dict() { return false; } +}; + +}} // namespace boost::python + +#endif // BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP diff --git a/src/object/pickle_support.cpp b/src/object/pickle_support.cpp new file mode 100644 index 00000000..3b14c8ea --- /dev/null +++ b/src/object/pickle_support.cpp @@ -0,0 +1,63 @@ +// (C) Copyright R.W. Grosse-Kunstleve 2002. +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. This +// software is provided "as is" without express or implied warranty, and +// with no claim as to its suitability for any purpose. + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace python { + +namespace { + + tuple instance_reduce(object instance_obj) + { + list result; + object instance_class(instance_obj.attr("__class__")); + result.append(instance_class); + object none; + object getinitargs = getattr(instance_obj, "__getinitargs__", none); + tuple initargs; + if (getinitargs.ptr() != none.ptr()) { + initargs = tuple(getinitargs()); + } + result.append(initargs); + object getstate = getattr(instance_obj, "__getstate__", none); + object instance_dict = getattr(instance_obj, "__dict__", none); + long len_instance_dict = 0; + if (instance_dict.ptr() != none.ptr()) { + len_instance_dict = len(instance_dict); + } + if (getstate.ptr() != none.ptr()) { + if (len_instance_dict > 0) { + object getstate_manages_dict = getattr( + instance_obj, "__getstate_manages_dict__", none); + if (getstate_manages_dict.ptr() == none.ptr()) { + PyErr_SetString(PyExc_RuntimeError, + "Incomplete pickle support" + " (__getstate_manages_dict__ not set)"); + throw_error_already_set(); + } + } + result.append(getstate()); + } + else if (len_instance_dict > 0) { + result.append(instance_dict); + } + return tuple(result); + } + +} // namespace + +handle<> make_instance_reduce_function() +{ + static handle<> result(make_function(&instance_reduce)); + return result; +} + +}} // namespace boost::python diff --git a/test/pickle1.cpp b/test/pickle1.cpp new file mode 100644 index 00000000..b8b0fa92 --- /dev/null +++ b/test/pickle1.cpp @@ -0,0 +1,60 @@ +// Example by Ralf W. Grosse-Kunstleve + +/* + This example shows how to make an Extension Class "pickleable". + + The world class below can be fully restored by passing the + appropriate argument to the constructor. Therefore it is sufficient + to define the pickle interface method __getinitargs__. + + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include +#include +#include +#include + +#include + +namespace { + + // A friendly class. + class world + { + private: + std::string country; + public: + world(const std::string& country) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + }; + + struct world_pickle_support : boost::python::pickle_support_base + { + static + boost::python::tuple + getinitargs(const world& w) + { + using namespace boost::python; + list result; + result.append(object(w.get_country())); + return tuple(result); + } + }; + +} + +BOOST_PYTHON_MODULE_INIT(pickle1_ext) +{ + using namespace boost::python; + module("pickle1_ext") + .add(class_("world") + .def_init(args()) + .def("greet", &world::greet) + .pickle_support(world_pickle_support()) + ) + ; +} diff --git a/test/pickle1.py b/test/pickle1.py new file mode 100644 index 00000000..1aeabc70 --- /dev/null +++ b/test/pickle1.py @@ -0,0 +1,30 @@ +r'''>>> import pickle1_ext + >>> import pickle + >>> pickle1_ext.world.__module__ + 'pickle1_ext' + >>> pickle1_ext.world.__safe_for_unpickling__ + 1 + >>> pickle1_ext.world.__name__ + 'world' + >>> pickle1_ext.world('Hello').__reduce__() + (, ('Hello',)) + >>> wd = pickle1_ext.world('California') + >>> pstr = pickle.dumps(wd) + >>> wl = pickle.loads(pstr) + >>> print wd.greet() + Hello from California! + >>> print wl.greet() + Hello from California! +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, pickle1 + return doctest.testmod(pickle1) + +if __name__ == '__main__': + import sys + sys.exit(run()[0]) + diff --git a/test/pickle2.cpp b/test/pickle2.cpp new file mode 100644 index 00000000..fed1066b --- /dev/null +++ b/test/pickle2.cpp @@ -0,0 +1,101 @@ +// Example by Ralf W. Grosse-Kunstleve + +/* + This example shows how to make an Extension Class "pickleable". + + The world class below contains member data (secret_number) that + cannot be restored by any of the constructors. Therefore it is + necessary to provide the __getstate__/__setstate__ pair of pickle + interface methods. + + For simplicity, the __dict__ is not included in the result of + __getstate__. This is not generally recommended, but a valid + approach if it is anticipated that the object's __dict__ will + always be empty. Note that safety guards are provided to catch + the cases where this assumption is not true. + + pickle3.cpp shows how to include the object's __dict__ in the + result of __getstate__. + + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include + +#include +#include +#include +#include +#include +#include + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + void set_secret_number(int number) { secret_number = number; } + int get_secret_number() const { return secret_number; } + private: + std::string country; + int secret_number; + }; + + struct world_pickle_support : boost::python::pickle_support_base + { + static + boost::python::tuple + getinitargs(const world& w) + { + using namespace boost::python; + list result; + result.append(object(w.get_country())); + return tuple(result); + } + + static + boost::python::tuple + getstate(const world& w) + { + using namespace boost::python; + list result; + result.append(object(w.get_secret_number())); + return tuple(result); + } + + static + void + setstate(world& w, boost::python::object state) + { + using namespace boost::python; + extract state_proxy(state); + if (!state_proxy.check() || len(state_proxy()) != 1) { + PyErr_SetString(PyExc_ValueError, + "Unexpected argument in call to __setstate__."); + throw_error_already_set(); + } + long number = extract(state_proxy()[0])(); + if (number != 42) w.set_secret_number(number); + } + }; + +} + +BOOST_PYTHON_MODULE_INIT(pickle2_ext) +{ + boost::python::module("pickle2_ext") + .add(boost::python::class_("world") + .def_init(boost::python::args()) + .def("greet", &world::greet) + .def("get_secret_number", &world::get_secret_number) + .def("set_secret_number", &world::set_secret_number) + .pickle_support(world_pickle_support()) + ) + ; +} diff --git a/test/pickle2.py b/test/pickle2.py new file mode 100644 index 00000000..7d31e48b --- /dev/null +++ b/test/pickle2.py @@ -0,0 +1,44 @@ +r'''>>> import pickle2_ext + >>> import pickle + >>> pickle2_ext.world.__module__ + 'pickle2_ext' + >>> pickle2_ext.world.__safe_for_unpickling__ + 1 + >>> pickle2_ext.world.__name__ + 'world' + >>> pickle2_ext.world('Hello').__reduce__() + (, ('Hello',), (0,)) + >>> for number in (24, 42): + ... wd = pickle2_ext.world('California') + ... wd.set_secret_number(number) + ... pstr = pickle.dumps(wd) + ... wl = pickle.loads(pstr) + ... print wd.greet(), wd.get_secret_number() + ... print wl.greet(), wl.get_secret_number() + Hello from California! 24 + Hello from California! 24 + Hello from California! 42 + Hello from California! 0 + +# Now show that the __dict__ is not taken care of. + >>> wd = pickle2_ext.world('California') + >>> wd.x = 1 + >>> wd.__dict__ + {'x': 1} + >>> try: pstr = pickle.dumps(wd) + ... except RuntimeError, err: print err[0] + ... + Incomplete pickle support (__getstate_manages_dict__ not set) +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, pickle2 + return doctest.testmod(pickle2) + +if __name__ == '__main__': + import sys + sys.exit(run()[0]) + diff --git a/test/pickle3.cpp b/test/pickle3.cpp new file mode 100644 index 00000000..617143d3 --- /dev/null +++ b/test/pickle3.cpp @@ -0,0 +1,107 @@ +// Example by Ralf W. Grosse-Kunstleve + +/* + This example shows how to make an Extension Class "pickleable". + + The world class below contains member data (secret_number) that + cannot be restored by any of the constructors. Therefore it is + necessary to provide the __getstate__/__setstate__ pair of pickle + interface methods. + + The object's __dict__ is included in the result of __getstate__. + This requires more code (compare with pickle2.cpp), but is + unavoidable if the object's __dict__ is not always empty. + + For more information refer to boost/libs/python/doc/pickle.html. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace { // Avoid cluttering the global namespace. + + // A friendly class. + class world + { + public: + world(const std::string& country) : secret_number(0) { + this->country = country; + } + std::string greet() const { return "Hello from " + country + "!"; } + std::string get_country() const { return country; } + void set_secret_number(int number) { secret_number = number; } + int get_secret_number() const { return secret_number; } + private: + std::string country; + int secret_number; + }; + + struct world_pickle_support : boost::python::pickle_support_base + { + static + boost::python::tuple + getinitargs(const world& w) + { + using namespace boost::python; + list result; + result.append(object(w.get_country())); + return tuple(result); + } + + static + boost::python::tuple + getstate(boost::python::object w_obj) + { + using namespace boost::python; + world const& w = extract(w_obj)(); + list result; + // store the object's __dict__ + result.append(w_obj.attr("__dict__")); + // store the internal state of the C++ object + result.append(object(w.get_secret_number())); + return tuple(result); + } + + static + void + setstate(boost::python::object w_obj, boost::python::object state) + { + using namespace boost::python; + world& w = extract(w_obj)(); + extract state_proxy(state); + if (!state_proxy.check() || len(state_proxy()) != 2) { + PyErr_SetString(PyExc_ValueError, + "Unexpected argument in call to __setstate__."); + throw_error_already_set(); + } + // restore the object's __dict__ + w_obj.attr("__dict__").attr("update")(object(state_proxy()[0])); + // restore the internal state of the C++ object + long number = extract(state_proxy()[1])(); + if (number != 42) w.set_secret_number(number); + } + + static bool getstate_manages_dict() { return true; } + }; + +} + +BOOST_PYTHON_MODULE_INIT(pickle3_ext) +{ + boost::python::module("pickle3_ext") + .add(boost::python::class_("world") + .def_init(boost::python::args()) + .def("greet", &world::greet) + .def("get_secret_number", &world::get_secret_number) + .def("set_secret_number", &world::set_secret_number) + .pickle_support(world_pickle_support()) + ) + ; +} diff --git a/test/pickle3.py b/test/pickle3.py new file mode 100644 index 00000000..8cce8dfb --- /dev/null +++ b/test/pickle3.py @@ -0,0 +1,38 @@ +r'''>>> import pickle3_ext + >>> import pickle + >>> pickle3_ext.world.__module__ + 'pickle3_ext' + >>> pickle3_ext.world.__safe_for_unpickling__ + 1 + >>> pickle3_ext.world.__getstate_manages_dict__ + 1 + >>> pickle3_ext.world.__name__ + 'world' + >>> pickle3_ext.world('Hello').__reduce__() + (, ('Hello',), ({}, 0)) + >>> for number in (24, 42): + ... wd = pickle3_ext.world('California') + ... wd.set_secret_number(number) + ... wd.x = 2 * number + ... wd.y = 'y' * number + ... wd.z = 3. * number + ... pstr = pickle.dumps(wd) + ... wl = pickle.loads(pstr) + ... print wd.greet(), wd.get_secret_number(), wd.x, wd.y, wd.z + ... print wl.greet(), wl.get_secret_number(), wl.x, wl.y, wl.z + Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0 + Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0 + Hello from California! 42 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0 + Hello from California! 0 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0 +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, pickle3 + return doctest.testmod(pickle3) + +if __name__ == '__main__': + import sys + sys.exit(run()[0]) From 1c5a50d4cbeb7780fabdd963a38a3132ef3dab2e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 21 Jul 2002 09:39:35 +0000 Subject: [PATCH 0610/1042] pickle support implementation details hidden in namespace detail [SVN r14550] --- .../boost/python/object/pickle_support.hpp | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp index 730ae639..abc4553b 100644 --- a/include/boost/python/object/pickle_support.hpp +++ b/include/boost/python/object/pickle_support.hpp @@ -20,20 +20,34 @@ namespace error_messages { } -class pickle_support_base +namespace detail { struct pickle_support_registration; } + +struct pickle_support_base { private: - struct dummy_return_type_ {}; - + struct inaccessible {}; + friend struct detail::pickle_support_registration; public: + static inaccessible* getinitargs() { return 0; } + static inaccessible* getstate() { return 0; } + static inaccessible* setstate() { return 0; } + static bool getstate_manages_dict() { return false; } +}; + +namespace detail { + + struct pickle_support_registration + { + typedef pickle_support_base::inaccessible inaccessible; + template static void register_( Class_& cl, tuple (*getinitargs_fn)(Tgetinitargs), - dummy_return_type_* (*getstate_fn)(), - dummy_return_type_* (*setstate_fn)(), + inaccessible* (*getstate_fn)(), + inaccessible* (*setstate_fn)(), bool) { cl.enable_pickle_support(false); @@ -45,7 +59,7 @@ class pickle_support_base void register_( Class_& cl, - dummy_return_type_* (*getinitargs_fn)(), + inaccessible* (*getinitargs_fn)(), tuple (*getstate_fn)(Tgetstate), void (*setstate_fn)(Tsetstate, object), bool getstate_manages_dict) @@ -83,13 +97,15 @@ class pickle_support_base error_messages::missing_pickle_support_function_or_incorrect_signature< Class_>::error_type error_type; } + }; - static dummy_return_type_* getinitargs() { return 0; } - static dummy_return_type_* getstate() { return 0; } - static dummy_return_type_* setstate() { return 0; } + template + struct pickle_support_finalize + : UserPickleSupportType, + pickle_support_registration + {}; - static bool getstate_manages_dict() { return false; } -}; +} // namespace detail }} // namespace boost::python From 3232c5be86e838b134e52e57356f165f779ebf90 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 21 Jul 2002 11:11:15 +0000 Subject: [PATCH 0611/1042] Fixed test of null handle returns to reflect new returning-None behavior [SVN r14553] --- test/test_builtin_converters.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index fb4725ba..f2dfa9e4 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -197,9 +197,8 @@ Check that classic classes also work >>> get_type(1) is type(1) 1 ->>> try: return_null_handle() -... except: pass -... else: print 'expectd an exception' +>>> return_null_handle() is None +1 """ def run(args = None): From e15ca5c642841b88c855467a603ea847d5c5c72c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 22 Jul 2002 06:54:39 +0000 Subject: [PATCH 0612/1042] full integration of (revised) pickle support [SVN r14557] --- Jamfile | 1 + include/boost/python/class.hpp | 14 ++++++++++ .../boost/python/detail/api_placeholder.hpp | 24 ++++++++++++++++ include/boost/python/object/class.hpp | 1 + .../boost/python/object/pickle_support.hpp | 28 +++++++++---------- src/object/class.cpp | 11 ++++++++ test/Jamfile | 4 +++ test/pickle1.cpp | 4 +-- test/pickle1.py | 13 +++++---- test/pickle2.cpp | 4 +-- test/pickle2.py | 13 +++++---- test/pickle3.cpp | 4 +-- test/pickle3.py | 12 ++++---- 13 files changed, 96 insertions(+), 37 deletions(-) create mode 100644 include/boost/python/detail/api_placeholder.hpp diff --git a/Jamfile b/Jamfile index fea5e97a..d4f30be5 100644 --- a/Jamfile +++ b/Jamfile @@ -27,6 +27,7 @@ dll bpl src/object/function.cpp src/object/inheritance.cpp src/object/life_support.cpp + src/object/pickle_support.cpp src/errors.cpp src/module.cpp src/converter/builtin_converters.cpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 861d8e72..e8610cef 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -25,6 +25,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -195,6 +196,19 @@ class class_ : public objects::class_base self& setattr(char const* name, handle<> const&); + // Pickle support + template + self& def_pickle(PickleGroupType) + { + detail::pickle_group_finalize::register_( + *this, + &PickleGroupType::getinitargs, + &PickleGroupType::getstate, + &PickleGroupType::setstate, + PickleGroupType::getstate_manages_dict()); + return *this; + } + private: // types typedef objects::class_id class_id; diff --git a/include/boost/python/detail/api_placeholder.hpp b/include/boost/python/detail/api_placeholder.hpp new file mode 100644 index 00000000..fd571d88 --- /dev/null +++ b/include/boost/python/detail/api_placeholder.hpp @@ -0,0 +1,24 @@ +#ifndef BOOST_PYTHON_API_PLACE_HOLDER_HPP +#define BOOST_PYTHON_API_PLACE_HOLDER_HPP + +namespace boost { namespace python { + + inline long len(object const& obj) + { + long result = PyObject_Length(obj.ptr()); + if (PyErr_Occurred()) throw_error_already_set(); + return result; + } + + inline object getattr(object const& a0, const char* a1, object const& a2) + { + handle<> result(allow_null(PyObject_GetAttrString( + a0.ptr(), const_cast(a1)))); + if (!PyErr_Occurred()) return object(result); + PyErr_Clear(); + return a2; + } + +}} // namespace boost::python + +#endif // BOOST_PYTHON_API_PLACE_HOLDER_HPP diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 8cf29b23..8a686505 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -39,6 +39,7 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable void add_property(char const* name, handle<> const& fget); void add_property(char const* name, handle<> const& fget, handle<> const& fset); void setattr(char const* name, handle<> const&); + void enable_pickling(bool getstate_manages_dict); private: type_handle m_object; }; diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp index abc4553b..667b60e0 100644 --- a/include/boost/python/object/pickle_support.hpp +++ b/include/boost/python/object/pickle_support.hpp @@ -16,17 +16,17 @@ handle<> make_instance_reduce_function(); namespace error_messages { template - struct missing_pickle_support_function_or_incorrect_signature {}; + struct missing_pickle_group_function_or_incorrect_signature {}; } -namespace detail { struct pickle_support_registration; } +namespace detail { struct pickle_group_registration; } -struct pickle_support_base +struct pickle_group { private: struct inaccessible {}; - friend struct detail::pickle_support_registration; + friend struct detail::pickle_group_registration; public: static inaccessible* getinitargs() { return 0; } static inaccessible* getstate() { return 0; } @@ -36,9 +36,9 @@ struct pickle_support_base namespace detail { - struct pickle_support_registration + struct pickle_group_registration { - typedef pickle_support_base::inaccessible inaccessible; + typedef pickle_group::inaccessible inaccessible; template static @@ -50,7 +50,7 @@ namespace detail { inaccessible* (*setstate_fn)(), bool) { - cl.enable_pickle_support(false); + cl.enable_pickling(false); cl.def("__getinitargs__", getinitargs_fn); } @@ -64,7 +64,7 @@ namespace detail { void (*setstate_fn)(Tsetstate, object), bool getstate_manages_dict) { - cl.enable_pickle_support(getstate_manages_dict); + cl.enable_pickling(getstate_manages_dict); cl.def("__getstate__", getstate_fn); cl.def("__setstate__", setstate_fn); } @@ -80,7 +80,7 @@ namespace detail { void (*setstate_fn)(Tsetstate, object), bool getstate_manages_dict) { - cl.enable_pickle_support(getstate_manages_dict); + cl.enable_pickling(getstate_manages_dict); cl.def("__getinitargs__", getinitargs_fn); cl.def("__getstate__", getstate_fn); cl.def("__setstate__", setstate_fn); @@ -94,15 +94,15 @@ namespace detail { ...) { typedef typename - error_messages::missing_pickle_support_function_or_incorrect_signature< + error_messages::missing_pickle_group_function_or_incorrect_signature< Class_>::error_type error_type; } }; - template - struct pickle_support_finalize - : UserPickleSupportType, - pickle_support_registration + template + struct pickle_group_finalize + : UserPickleGroupType, + pickle_group_registration {}; } // namespace detail diff --git a/src/object/class.cpp b/src/object/class.cpp index e49df96f..8b37752d 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -304,6 +305,16 @@ namespace objects throw_error_already_set(); } + void class_base::enable_pickling(bool getstate_manages_dict) + { + setattr("__reduce__", make_instance_reduce_function()); + handle<> one(PyInt_FromLong(1)); + setattr("__safe_for_unpickling__", one); + if (getstate_manages_dict) { + setattr("__getstate_manages_dict__", one); + } + } + BOOST_PYTHON_DECL type_handle registered_class_object(class_id id) { return objects::query_class(id); diff --git a/test/Jamfile b/test/Jamfile index 5fb0eff4..21be34fe 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -82,6 +82,10 @@ bpl-test iterator : iterator.py iterator.cpp input_iterator.cpp ; bpl-test extract ; +bpl-test pickle1 ; +bpl-test pickle2 ; +bpl-test pickle3 ; + if $(TEST_BIENSTMAN_NON_BUGS) { bpl-test bienstman4 ; diff --git a/test/pickle1.cpp b/test/pickle1.cpp index b8b0fa92..c2de26dd 100644 --- a/test/pickle1.cpp +++ b/test/pickle1.cpp @@ -32,7 +32,7 @@ namespace { std::string get_country() const { return country; } }; - struct world_pickle_support : boost::python::pickle_support_base + struct world_pickle_group : boost::python::pickle_group { static boost::python::tuple @@ -54,7 +54,7 @@ BOOST_PYTHON_MODULE_INIT(pickle1_ext) .add(class_("world") .def_init(args()) .def("greet", &world::greet) - .pickle_support(world_pickle_support()) + .def_pickle(world_pickle_group()) ) ; } diff --git a/test/pickle1.py b/test/pickle1.py index 1aeabc70..d333919d 100644 --- a/test/pickle1.py +++ b/test/pickle1.py @@ -18,13 +18,14 @@ r'''>>> import pickle1_ext ''' def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, pickle1 - return doctest.testmod(pickle1) + import sys + import doctest + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + if __name__ == '__main__': + print "running..." import sys sys.exit(run()[0]) - diff --git a/test/pickle2.cpp b/test/pickle2.cpp index fed1066b..916f99cf 100644 --- a/test/pickle2.cpp +++ b/test/pickle2.cpp @@ -47,7 +47,7 @@ namespace { // Avoid cluttering the global namespace. int secret_number; }; - struct world_pickle_support : boost::python::pickle_support_base + struct world_pickle_group : boost::python::pickle_group { static boost::python::tuple @@ -95,7 +95,7 @@ BOOST_PYTHON_MODULE_INIT(pickle2_ext) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) - .pickle_support(world_pickle_support()) + .def_pickle(world_pickle_group()) ) ; } diff --git a/test/pickle2.py b/test/pickle2.py index 7d31e48b..ec141bc9 100644 --- a/test/pickle2.py +++ b/test/pickle2.py @@ -32,13 +32,14 @@ r'''>>> import pickle2_ext ''' def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, pickle2 - return doctest.testmod(pickle2) + import sys + import doctest + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + if __name__ == '__main__': + print "running..." import sys sys.exit(run()[0]) - diff --git a/test/pickle3.cpp b/test/pickle3.cpp index 617143d3..b6d00a82 100644 --- a/test/pickle3.cpp +++ b/test/pickle3.cpp @@ -43,7 +43,7 @@ namespace { // Avoid cluttering the global namespace. int secret_number; }; - struct world_pickle_support : boost::python::pickle_support_base + struct world_pickle_group : boost::python::pickle_group { static boost::python::tuple @@ -101,7 +101,7 @@ BOOST_PYTHON_MODULE_INIT(pickle3_ext) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) - .pickle_support(world_pickle_support()) + .def_pickle(world_pickle_group()) ) ; } diff --git a/test/pickle3.py b/test/pickle3.py index 8cce8dfb..b700c1b0 100644 --- a/test/pickle3.py +++ b/test/pickle3.py @@ -27,12 +27,14 @@ r'''>>> import pickle3_ext ''' def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, pickle3 - return doctest.testmod(pickle3) + import sys + import doctest + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + if __name__ == '__main__': + print "running..." import sys sys.exit(run()[0]) From bfe2a6656ca83af432f19480e4ae623c809be51c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 22 Jul 2002 19:35:44 +0000 Subject: [PATCH 0613/1042] pickle_group renamed -> pickle_suite [SVN r14565] --- include/boost/python/class.hpp | 14 ++++++------ .../boost/python/object/pickle_support.hpp | 22 +++++++++---------- test/pickle1.cpp | 4 ++-- test/pickle2.cpp | 4 ++-- test/pickle3.cpp | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index e8610cef..8491ba9c 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -197,15 +197,15 @@ class class_ : public objects::class_base self& setattr(char const* name, handle<> const&); // Pickle support - template - self& def_pickle(PickleGroupType) + template + self& def_pickle(PickleSuiteType) { - detail::pickle_group_finalize::register_( + detail::pickle_suite_finalize::register_( *this, - &PickleGroupType::getinitargs, - &PickleGroupType::getstate, - &PickleGroupType::setstate, - PickleGroupType::getstate_manages_dict()); + &PickleSuiteType::getinitargs, + &PickleSuiteType::getstate, + &PickleSuiteType::setstate, + PickleSuiteType::getstate_manages_dict()); return *this; } diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp index 667b60e0..6b68c47a 100644 --- a/include/boost/python/object/pickle_support.hpp +++ b/include/boost/python/object/pickle_support.hpp @@ -16,17 +16,17 @@ handle<> make_instance_reduce_function(); namespace error_messages { template - struct missing_pickle_group_function_or_incorrect_signature {}; + struct missing_pickle_suite_function_or_incorrect_signature {}; } -namespace detail { struct pickle_group_registration; } +namespace detail { struct pickle_suite_registration; } -struct pickle_group +struct pickle_suite { private: struct inaccessible {}; - friend struct detail::pickle_group_registration; + friend struct detail::pickle_suite_registration; public: static inaccessible* getinitargs() { return 0; } static inaccessible* getstate() { return 0; } @@ -36,9 +36,9 @@ struct pickle_group namespace detail { - struct pickle_group_registration + struct pickle_suite_registration { - typedef pickle_group::inaccessible inaccessible; + typedef pickle_suite::inaccessible inaccessible; template static @@ -94,15 +94,15 @@ namespace detail { ...) { typedef typename - error_messages::missing_pickle_group_function_or_incorrect_signature< + error_messages::missing_pickle_suite_function_or_incorrect_signature< Class_>::error_type error_type; } }; - template - struct pickle_group_finalize - : UserPickleGroupType, - pickle_group_registration + template + struct pickle_suite_finalize + : PickleSuiteType, + pickle_suite_registration {}; } // namespace detail diff --git a/test/pickle1.cpp b/test/pickle1.cpp index c2de26dd..cecb9c6a 100644 --- a/test/pickle1.cpp +++ b/test/pickle1.cpp @@ -32,7 +32,7 @@ namespace { std::string get_country() const { return country; } }; - struct world_pickle_group : boost::python::pickle_group + struct world_pickle_suite : boost::python::pickle_suite { static boost::python::tuple @@ -54,7 +54,7 @@ BOOST_PYTHON_MODULE_INIT(pickle1_ext) .add(class_("world") .def_init(args()) .def("greet", &world::greet) - .def_pickle(world_pickle_group()) + .def_pickle(world_pickle_suite()) ) ; } diff --git a/test/pickle2.cpp b/test/pickle2.cpp index 916f99cf..47d655c6 100644 --- a/test/pickle2.cpp +++ b/test/pickle2.cpp @@ -47,7 +47,7 @@ namespace { // Avoid cluttering the global namespace. int secret_number; }; - struct world_pickle_group : boost::python::pickle_group + struct world_pickle_suite : boost::python::pickle_suite { static boost::python::tuple @@ -95,7 +95,7 @@ BOOST_PYTHON_MODULE_INIT(pickle2_ext) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) - .def_pickle(world_pickle_group()) + .def_pickle(world_pickle_suite()) ) ; } diff --git a/test/pickle3.cpp b/test/pickle3.cpp index b6d00a82..911eb7b8 100644 --- a/test/pickle3.cpp +++ b/test/pickle3.cpp @@ -43,7 +43,7 @@ namespace { // Avoid cluttering the global namespace. int secret_number; }; - struct world_pickle_group : boost::python::pickle_group + struct world_pickle_suite : boost::python::pickle_suite { static boost::python::tuple @@ -101,7 +101,7 @@ BOOST_PYTHON_MODULE_INIT(pickle3_ext) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) - .def_pickle(world_pickle_group()) + .def_pickle(world_pickle_suite()) ) ; } From e25fee71a2c3ff1fe7fc6049e3824017d66ba240 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 22 Jul 2002 23:43:00 +0000 Subject: [PATCH 0614/1042] additional compile-time check: must_be_derived_from_pickle_suite [SVN r14568] --- include/boost/python/class.hpp | 1 + include/boost/python/object/pickle_support.hpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 8491ba9c..1abf41cb 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -200,6 +200,7 @@ class class_ : public objects::class_base template self& def_pickle(PickleSuiteType) { + error_messages::must_be_derived_from_pickle_suite(PickleSuiteType()); detail::pickle_suite_finalize::register_( *this, &PickleSuiteType::getinitargs, diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp index 6b68c47a..44e2103e 100644 --- a/include/boost/python/object/pickle_support.hpp +++ b/include/boost/python/object/pickle_support.hpp @@ -13,11 +13,14 @@ namespace boost { namespace python { handle<> make_instance_reduce_function(); +struct pickle_suite; + namespace error_messages { template struct missing_pickle_suite_function_or_incorrect_signature {}; + inline void must_be_derived_from_pickle_suite(pickle_suite const&) {} } namespace detail { struct pickle_suite_registration; } From a2feb0450909952b42a8e6c1b6a9af4192d628f7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 24 Jul 2002 13:31:29 +0000 Subject: [PATCH 0615/1042] pytype_object_manager_traits -> pytype_object_mgr_traits (< 31 chars) [SVN r14587] --- ...e_object_manager_traits.hpp => pytype_object_mgr_traits.hpp} | 0 include/boost/python/dict.hpp | 2 +- include/boost/python/list.hpp | 2 +- include/boost/python/long.hpp | 2 +- include/boost/python/str.hpp | 2 +- include/boost/python/tuple.hpp | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename include/boost/python/converter/{pytype_object_manager_traits.hpp => pytype_object_mgr_traits.hpp} (100%) diff --git a/include/boost/python/converter/pytype_object_manager_traits.hpp b/include/boost/python/converter/pytype_object_mgr_traits.hpp similarity index 100% rename from include/boost/python/converter/pytype_object_manager_traits.hpp rename to include/boost/python/converter/pytype_object_mgr_traits.hpp diff --git a/include/boost/python/dict.hpp b/include/boost/python/dict.hpp index 2f90344e..b593f902 100644 --- a/include/boost/python/dict.hpp +++ b/include/boost/python/dict.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include namespace boost { namespace python { diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp index 8cff1670..501eeed5 100644 --- a/include/boost/python/list.hpp +++ b/include/boost/python/list.hpp @@ -7,7 +7,7 @@ # define LIST_DWA2002627_HPP # include -# include +# include namespace boost { namespace python { diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp index f5dd829e..3ba4f434 100644 --- a/include/boost/python/long.hpp +++ b/include/boost/python/long.hpp @@ -7,7 +7,7 @@ # define LONG_DWA2002627_HPP # include -# include +# include namespace boost { namespace python { diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index dd6548ab..ad2689e9 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -3,7 +3,7 @@ #include #include -#include +#include // disable defines in provided by some system libraries #undef isspace diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp index 75e2eb4a..d18eb0c3 100644 --- a/include/boost/python/tuple.hpp +++ b/include/boost/python/tuple.hpp @@ -2,7 +2,7 @@ #define TUPLE_20020706_HPP #include -#include +#include namespace boost { namespace python { From b7421fd5cd4237f53cf38d2787829d65dcd30ff9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 24 Jul 2002 16:58:46 +0000 Subject: [PATCH 0616/1042] Fix Ralf's boo-boo. [SVN r14592] --- include/boost/python/class.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 1abf41cb..1a5890c6 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -198,9 +198,9 @@ class class_ : public objects::class_base // Pickle support template - self& def_pickle(PickleSuiteType) + self& def_pickle(PickleSuiteType const& x) { - error_messages::must_be_derived_from_pickle_suite(PickleSuiteType()); + error_messages::must_be_derived_from_pickle_suite(x); detail::pickle_suite_finalize::register_( *this, &PickleSuiteType::getinitargs, From f458dbdbcbaf26f935fabb9eedb58a843a2425f5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 25 Jul 2002 02:23:01 +0000 Subject: [PATCH 0617/1042] Added scope [SVN r14593] --- .../boost/python/detail/aix_init_module.hpp | 2 +- include/boost/python/module.hpp | 2 +- .../boost/python/{detail => }/module_init.hpp | 61 +++++++++++-------- include/boost/python/scope.hpp | 60 ++++++++++++++++++ src/aix_init_module.cpp | 3 +- src/module.cpp | 41 ++++++++++++- 6 files changed, 139 insertions(+), 30 deletions(-) rename include/boost/python/{detail => }/module_init.hpp (57%) create mode 100644 include/boost/python/scope.hpp diff --git a/include/boost/python/detail/aix_init_module.hpp b/include/boost/python/detail/aix_init_module.hpp index e73210d5..6eda62ea 100644 --- a/include/boost/python/detail/aix_init_module.hpp +++ b/include/boost/python/detail/aix_init_module.hpp @@ -16,7 +16,7 @@ extern "C" typedef PyObject* (*so_load_function)(char*,char*,FILE*); } -void aix_init_module(so_load_function, void (*init_module)()); +void aix_init_module(so_load_function, char const* name, void (*init_module)()); }}} // namespace boost::python::detail # endif diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 5537171d..7a774496 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -11,7 +11,7 @@ # include # include # include -# include +# include namespace boost { namespace python { diff --git a/include/boost/python/detail/module_init.hpp b/include/boost/python/module_init.hpp similarity index 57% rename from include/boost/python/detail/module_init.hpp rename to include/boost/python/module_init.hpp index 5b5ce9f5..1d65308a 100644 --- a/include/boost/python/detail/module_init.hpp +++ b/include/boost/python/module_init.hpp @@ -3,48 +3,59 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef MODULE_INIT_DWA2002529_HPP -# define MODULE_INIT_DWA2002529_HPP +#ifndef MODULE_INIT_DWA20020722_HPP +# define MODULE_INIT_DWA20020722_HPP + +# include +# include # ifndef BOOST_PYTHON_MODULE_INIT +namespace boost { namespace python { namespace detail { + +BOOST_PYTHON_DECL void init_module(char const* name, void(*)()); + +}}} + # if defined(_WIN32) || defined(__CYGWIN__) -# define BOOST_PYTHON_MODULE_INIT(name) \ -void init_module_##name(); \ -extern "C" __declspec(dllexport) void init##name() \ -{ \ - boost::python::handle_exception(&init_module_##name); \ -} \ +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" __declspec(dllexport) void init##name() \ +{ \ + boost::python::detail::init_module( \ + #name,&init_module_##name); \ +} \ void init_module_##name() # elif defined(_AIX) # include -# define BOOST_PYTHON_MODULE_INIT(name) \ -void init_module_##name(); \ -extern "C" \ -{ \ - extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \ - void init##name() \ - { \ - boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_##name); \ - } \ -} \ +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" \ +{ \ + extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \ + void init##name() \ + { \ + boost::python::detail::aix_init_module( \ + _PyImport_LoadDynamicModule, #name, &init_module_##name); \ + } \ +} \ void init_module_##name() # else -# define BOOST_PYTHON_MODULE_INIT(name) \ -void init_module_##name(); \ -extern "C" void init##name() \ -{ \ - boost::python::handle_exception(&init_module_##name); \ -} \ +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" void init##name() \ +{ \ + boost::python::detail::init_module(#name, &init_module_##name); \ +} \ void init_module_##name() # endif # endif -#endif // MODULE_INIT_DWA2002529_HPP +#endif // MODULE_INIT_DWA20020722_HPP diff --git a/include/boost/python/scope.hpp b/include/boost/python/scope.hpp new file mode 100644 index 00000000..edcfe02a --- /dev/null +++ b/include/boost/python/scope.hpp @@ -0,0 +1,60 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef SCOPE_DWA2002724_HPP +# define SCOPE_DWA2002724_HPP + +# include +# include +# include + +namespace boost { namespace python { + +class BOOST_PYTHON_DECL scope : public object, noncopyable +{ + public: + inline scope(object const&); + inline ~scope(); + static inline object get(); + + private: // data members + PyObject* m_previous_scope; + + private: // static members + + // Use a PyObject* to avoid problems with static destruction after Py_Finalize + static PyObject* current_scope; +}; + +inline scope::scope(object const& new_scope) + : object(new_scope) + , m_previous_scope(current_scope) +{ + current_scope = python::incref(new_scope.ptr()); +} + +inline scope::~scope() +{ + python::decref(current_scope); + current_scope = m_previous_scope; +} + +inline object scope::get() +{ + return object(detail::borrowed_reference(current_scope)); +} + +namespace converter +{ + template <> + struct object_manager_traits + : object_manager_traits + { + }; +} + +}} // namespace boost::python + +#endif // SCOPE_DWA2002724_HPP diff --git a/src/aix_init_module.cpp b/src/aix_init_module.cpp index 61422e6b..fb623579 100644 --- a/src/aix_init_module.cpp +++ b/src/aix_init_module.cpp @@ -98,6 +98,7 @@ namespace void aix_init_module( so_load_function load_dynamic_module + , char const* module_name , void (*init_module)()) { static bool initialized; @@ -133,7 +134,7 @@ void aix_init_module( initialized = true; } - python::handle_exception(init_module); + python::detail::init_module(module_name, init_module); } }}} // namespace boost::python diff --git a/src/module.cpp b/src/module.cpp index f7edf39e..dcb64397 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -9,13 +9,18 @@ #include #include #include +#include +#include +#include +#include namespace boost { namespace python { namespace detail { module_base::module_base(const char* name) : m_module( - python::borrowed(Py_InitModule(const_cast(name), initial_methods)) - ) + allow_null(python::borrowed( + scope::get().ptr() + ))) { } @@ -59,4 +64,36 @@ void module_base::add_class(type_handle const& class_obj) PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; +namespace +{ + PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; +} + +BOOST_PYTHON_DECL void init_module(char const* name, void(*init_function)()) +{ + + PyObject* m + = Py_InitModule(const_cast(name), initial_methods); + + if (m != 0) + { + ; + + // Create the current module scope + scope current_module( + (object( + ((borrowed_reference_t*)m) + )) + ); + + handle_exception(init_function); + } +} + }}} // namespace boost::python::detail + +namespace boost { namespace python { + +BOOST_PYTHON_DECL PyObject* scope::current_scope; + +}} From 63eed8994af462f7b36157fd00a3f5f147d6230c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 25 Jul 2002 04:41:21 +0000 Subject: [PATCH 0618/1042] class_<> is now derived from object [SVN r14594] --- include/boost/python/class.hpp | 22 +++++--- include/boost/python/iterator.hpp | 28 ++++++++-- include/boost/python/module.hpp | 2 +- include/boost/python/object/class.hpp | 6 +- include/boost/python/object/class_wrapper.hpp | 8 +-- include/boost/python/object/function.hpp | 3 +- include/boost/python/object/iterator.hpp | 56 +++++++++---------- .../boost/python/object/pointer_holder.hpp | 2 +- include/boost/python/object_fwd.hpp | 17 ++++++ src/module.cpp | 2 +- src/object/class.cpp | 23 +++++--- src/object/function.cpp | 14 ++--- test/extract.cpp | 4 +- 13 files changed, 115 insertions(+), 72 deletions(-) create mode 100644 include/boost/python/object_fwd.hpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 1a5890c6..2e59189e 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -47,14 +47,14 @@ namespace detail // to the type of holder that must be created. The 3rd argument is a // reference to the Python type object to be created. template - static inline void register_copy_constructor(mpl::bool_t const&, Holder*, handle<> const& obj, T* = 0) + static inline void register_copy_constructor(mpl::bool_t const&, Holder*, object const& obj, T* = 0) { objects::class_wrapper x(obj); } // Tag dispatched to have no effect. template - static inline void register_copy_constructor(mpl::bool_t const&, Holder*, handle<> const&, T* = 0) + static inline void register_copy_constructor(mpl::bool_t const&, Holder*, object const&, T* = 0) { } } @@ -104,11 +104,13 @@ class class_ : public objects::class_base // Use function::add_to_namespace to achieve overloading if // appropriate. objects::function::add_to_namespace( - this->object(), name, - handle<>(detail::wrap_function( + *this, name + , object( + detail::new_reference( + detail::wrap_function( // This bit of nastiness casts F to a member function of T if possible. detail::member_function_cast::stage1(f).stage2((T*)0).stage3(f) - ))); + )))); return *this; } @@ -132,8 +134,10 @@ class class_ : public objects::class_base // Use function::add_to_namespace to achieve overloading if // appropriate. objects::function::add_to_namespace( - this->object(), op.name(), - handle<>(detail::wrap_function(&op_t::template apply::execute))); + *this, op.name() + , object( + detail::new_reference( + detail::wrap_function(&op_t::template apply::execute)))); return *this; } @@ -255,7 +259,7 @@ inline class_::class_() detail::register_copy_constructor( mpl::bool_t() , objects::select_holder((held_type*)0).get() - , this->object()); + , *this); } template @@ -268,7 +272,7 @@ inline class_::class_(char const* name) detail::register_copy_constructor( mpl::bool_t() , objects::select_holder((held_type*)0).get() - , this->object()); + , *this); } diff --git a/include/boost/python/iterator.hpp b/include/boost/python/iterator.hpp index 724b926a..673d26e6 100644 --- a/include/boost/python/iterator.hpp +++ b/include/boost/python/iterator.hpp @@ -8,6 +8,7 @@ # include # include +# include # include # include @@ -19,7 +20,7 @@ namespace detail // objects::make_iterator(...), which allows us to pass member // function and member data pointers. template - inline handle<> make_iterator( + inline object make_iterator( Accessor1 get_start, Accessor2 get_finish, boost::type* target = 0, NextPolicies* = 0) { return objects::make_iterator_function( @@ -70,9 +71,14 @@ struct iterators template handle<> range(Accessor1 start, Accessor2 finish) { - return detail::make_iterator( - start, finish - , detail::target(start)); + return handle<>( + borrowed(allow_null( + detail::make_iterator( + start, finish + , detail::target(start)) + .ptr() + )) + ); } // Create an iterator-building function which uses the given accessors @@ -80,7 +86,12 @@ handle<> range(Accessor1 start, Accessor2 finish) template handle<> range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) { - return detail::make_iterator(start, finish, detail::target(start)); + return handle<>( + borrowed( + allow_null( + detail::make_iterator(start, finish, detail::target(start)) + .ptr() + ))); } // Create an iterator-building function which uses the given accessors @@ -89,7 +100,12 @@ template handle<> range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type* = 0) { typedef typename add_reference::type target; - return detail::make_iterator(start, finish); + return handle<>( + borrowed( + allow_null( + detail::make_iterator(start, finish) + .ptr() + ))); } // A Python callable object which produces an iterator traversing diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 7a774496..25f8cf05 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -32,7 +32,7 @@ class module : public detail::module_base template module& add(class_ const& c) { - this->add_class(c.object()); + this->add_class(type_handle(borrowed((PyTypeObject*)c.ptr()))); return *this; } diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 8a686505..babd409a 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -12,6 +12,7 @@ # include # include # include +# include # include namespace boost { namespace python { @@ -23,7 +24,7 @@ namespace objects { // To identify a class, we don't need cv/reference decorations typedef type_info class_id; -struct BOOST_PYTHON_DECL class_base : private noncopyable +struct BOOST_PYTHON_DECL class_base : python::api::object { // constructor class_base( @@ -35,13 +36,10 @@ struct BOOST_PYTHON_DECL class_base : private noncopyable ); // Retrieve the underlying object - type_handle object() const { return m_object; } void add_property(char const* name, handle<> const& fget); void add_property(char const* name, handle<> const& fget, handle<> const& fset); void setattr(char const* name, handle<> const&); void enable_pickling(bool getstate_manages_dict); - private: - type_handle m_object; }; BOOST_PYTHON_DECL type_handle registered_class_object(class_id id); diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index 73804fbf..2e06f921 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -15,11 +15,11 @@ template struct class_wrapper : to_python_converter > { - class_wrapper(handle<> const& type_) + class_wrapper(object const& type_) : m_class_object_keeper(type_) { - assert(type_->ob_type == (PyTypeObject*)class_metatype().get()); - m_class_object = (PyTypeObject*)type_.get(); + assert(type_.ptr()->ob_type == (PyTypeObject*)class_metatype().get()); + m_class_object = (PyTypeObject*)type_.ptr(); } static PyObject* convert(T const& x) @@ -48,7 +48,7 @@ struct class_wrapper } private: - handle<> m_class_object_keeper; + object m_class_object_keeper; static PyTypeObject* m_class_object; }; diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index ef2f1251..ebd2a8c3 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -10,6 +10,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -27,7 +28,7 @@ struct BOOST_PYTHON_DECL function : PyObject // a function object (this class), and an existing function is // already there, add it as an overload. static void add_to_namespace( - handle<> const& name_space, char const* name, handle<> const& attribute); + object const& name_space, char const* name, object const& attribute); private: // helper functions void argument_error(PyObject* args, PyObject* keywords) const; diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index c9434a4f..124759d6 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -17,6 +17,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -113,30 +114,28 @@ namespace detail // policies, creating it if neccessary. Requires: NextPolicies is // default-constructible. template - handle<> demand_iterator_class(char const* name, Iterator* = 0, NextPolicies const& policies = NextPolicies()) + object demand_iterator_class(char const* name, Iterator* = 0, NextPolicies const& policies = NextPolicies()) { typedef iterator_range range_; // Check the registry. If one is already registered, return it. - handle<> result( + handle<> class_obj( objects::registered_class_object(python::type_id())); - if (result.get() == 0) - { - // Make a callable object which can be used as the iterator's next() function. - handle<> next_function( - new objects::function( - objects::py_function( - bind(&detail::iterator_next::execute, _1, _2, policies)) - , 1)); - - result = class_(name) - .def("__iter__", identity_function()) - .setattr("next", next_function) - .object(); + if (class_obj.get() != 0) + return object(class_obj); - } - return result; + // Make a callable object which can be used as the iterator's next() function. + handle<> next_function( + new objects::function( + objects::py_function( + bind(&detail::iterator_next::execute, _1, _2, policies)) + , 1)); + + return class_(name) + .def("__iter__", identity_function()) + .setattr("next", next_function) + ; } // This class template acts as a generator for an ordinary function @@ -187,22 +186,23 @@ namespace detail // iterators for the range, and an instance of NextPolicies is used as // CallPolicies for the Python iterator's next() function. template -inline handle<> make_iterator_function( +inline object make_iterator_function( Accessor1 const& get_start, Accessor2 const& get_finish , boost::type* = 0, NextPolicies* = 0) { typedef typename Accessor1::result_type result_type; - return handle<>( - new objects::function( - objects::py_function( - boost::bind( - &detail::make_iterator_help< - Target,result_type,Accessor1,Accessor2,NextPolicies - >::create - , get_start, get_finish, _1, _2) - ) - ,1 )); + return object( + python::detail::new_non_null_reference( + new objects::function( + objects::py_function( + boost::bind( + &detail::make_iterator_help< + Target,result_type,Accessor1,Accessor2,NextPolicies + >::create + , get_start, get_finish, _1, _2)) + ,1 )) + ); } // diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 72cecdfc..8498a8df 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -11,7 +11,7 @@ # include -# include +# include # include # include # include diff --git a/include/boost/python/object_fwd.hpp b/include/boost/python/object_fwd.hpp new file mode 100644 index 00000000..8b0c093e --- /dev/null +++ b/include/boost/python/object_fwd.hpp @@ -0,0 +1,17 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OBJECT_FWD_DWA2002724_HPP +# define OBJECT_FWD_DWA2002724_HPP + +namespace boost { namespace python { +namespace api +{ + class object; +} +using api::object; +}} // namespace boost::python + +#endif // OBJECT_FWD_DWA2002724_HPP diff --git a/src/module.cpp b/src/module.cpp index dcb64397..4a30f6f0 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -37,7 +37,7 @@ void module_base::setattr(char const* name, handle<> const& x) { // Use function::add_to_namespace to achieve overloading if // appropriate. - objects::function::add_to_namespace(m_module, name, x); + objects::function::add_to_namespace(python::object(m_module), name, python::object(x)); } void module_base::add(type_handle const& x) diff --git a/src/object/class.cpp b/src/object/class.cpp index 8b37752d..def44c33 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -243,9 +243,12 @@ namespace objects // corresponding to the class being created, and the // rest corresponding to its declared bases. // - class_base::class_base( - char const* name, std::size_t num_types, class_id const* const types) + + namespace { + inline object + new_class(char const* name, std::size_t num_types, class_id const* const types) + { assert(num_types >= 1); // Build a tuple of the base Python type objects. If no bases @@ -271,14 +274,20 @@ namespace objects // Call the class metatype to create a new class PyObject* c = PyObject_CallObject(upcast(class_metatype().get()), args.get()); assert(PyType_IsSubtype(c->ob_type, &PyType_Type)); - m_object = type_handle((PyTypeObject*)c); - + return object(python::detail::new_reference(c)); + } + } + + class_base::class_base( + char const* name, std::size_t num_types, class_id const* const types) + : object(new_class(name, num_types, types)) + { // Insert the new class object in the registry converter::registration& converters = const_cast( converter::registry::lookup(types[0])); // Class object is leaked, for now - converters.class_object = (PyTypeObject*)incref(m_object.get()); + converters.class_object = (PyTypeObject*)incref(this->ptr()); } extern "C" @@ -301,7 +310,7 @@ namespace objects void class_base::setattr(char const* name, handle<> const& x) { - if (PyObject_SetAttrString(upcast(object().get()), const_cast(name), x.get()) < 0) + if (PyObject_SetAttrString(this->ptr(), const_cast(name), x.get()) < 0) throw_error_already_set(); } @@ -317,7 +326,7 @@ namespace objects BOOST_PYTHON_DECL type_handle registered_class_object(class_id id) { - return objects::query_class(id); + return query_class(id); } } // namespace objects diff --git a/src/object/function.cpp b/src/object/function.cpp index 4fc6a141..dad36dd5 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -156,12 +156,12 @@ namespace } void function::add_to_namespace( - handle<> const& name_space, char const* name_, handle<> const& attribute) + object const& name_space, char const* name_, object const& attribute) { str const name(name_); - PyObject* const ns = name_space.get(); + PyObject* const ns = name_space.ptr(); - if (attribute->ob_type == &function_type) + if (attribute.ptr()->ob_type == &function_type) { PyObject* dict = 0; @@ -175,27 +175,27 @@ void function::add_to_namespace( if (dict == 0) throw_error_already_set(); - handle<> existing( allow_null(PyObject_GetItem(dict, name.ptr())) ); + handle<> existing( allow_null(::PyObject_GetItem(dict, name.ptr())) ); if (existing.get()) { if (existing->ob_type == &function_type) { - static_cast(attribute.get())->add_overload( + static_cast(attribute.ptr())->add_overload( static_cast(existing.get())); } } // Binary operators need an additional overload which returns NotImplemented else if (is_binary_operator(name_)) { - static_cast(attribute.get())->add_overload( + static_cast(attribute.ptr())->add_overload( not_implemented_function()); } } // The PyObject_GetAttrString() call above left an active error PyErr_Clear(); - if (PyObject_SetAttr(ns, name.ptr(), attribute.get()) < 0) + if (PyObject_SetAttr(ns, name.ptr(), attribute.ptr()) < 0) throw_error_already_set(); } diff --git a/test/extract.cpp b/test/extract.cpp index 584eb60a..59e7e120 100644 --- a/test/extract.cpp +++ b/test/extract.cpp @@ -120,9 +120,7 @@ BOOST_PYTHON_MODULE_INIT(extract_ext) ; // Instantiate an X object through the Python interface - type_handle xc1 = x_class.object(); - object X_(xc1); - object x_obj = X_(3); + object x_obj = x_class(3); // Get the C++ object out of the Python object X const& x = extract(x_obj); From 5976005c4a9cbca7a86075bcfbf80b98910838c5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 25 Jul 2002 10:52:10 +0000 Subject: [PATCH 0619/1042] Make Boost.Python v1 work again [SVN r14595] --- include/boost/python/detail/module_init.hpp | 53 +++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 include/boost/python/detail/module_init.hpp diff --git a/include/boost/python/detail/module_init.hpp b/include/boost/python/detail/module_init.hpp new file mode 100644 index 00000000..5b2366f6 --- /dev/null +++ b/include/boost/python/detail/module_init.hpp @@ -0,0 +1,53 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifdef BOOST_PYTHON_V2 +# error obsolete +#endif +#ifndef MODULE_INIT_DWA2002529_HPP +# define MODULE_INIT_DWA2002529_HPP + +# ifndef BOOST_PYTHON_MODULE_INIT + +# if defined(_WIN32) || defined(__CYGWIN__) + +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" __declspec(dllexport) void init##name() \ +{ \ + boost::python::handle_exception(&init_module_##name); \ +} \ +void init_module_##name() + +# elif defined(_AIX) + +# include +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" \ +{ \ + extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \ + void init##name() \ + { \ + boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_##name); \ + } \ +} \ +void init_module_##name() + +# else + +# define BOOST_PYTHON_MODULE_INIT(name) \ +void init_module_##name(); \ +extern "C" void init##name() \ +{ \ + boost::python::handle_exception(&init_module_##name); \ +} \ +void init_module_##name() + +# endif + +# endif + +#endif // MODULE_INIT_DWA2002529_HPP From 8763fd1c53e4d0dd7e10dee2724b9ac96636f05a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 25 Jul 2002 14:52:11 +0000 Subject: [PATCH 0620/1042] scope default constructor gets current scope; killed scope::get() [SVN r14599] --- include/boost/python/scope.hpp | 15 +++++++++------ src/module.cpp | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/include/boost/python/scope.hpp b/include/boost/python/scope.hpp index edcfe02a..298f1eaa 100644 --- a/include/boost/python/scope.hpp +++ b/include/boost/python/scope.hpp @@ -16,8 +16,8 @@ class BOOST_PYTHON_DECL scope : public object, noncopyable { public: inline scope(object const&); + inline scope(); inline ~scope(); - static inline object get(); private: // data members PyObject* m_previous_scope; @@ -35,17 +35,20 @@ inline scope::scope(object const& new_scope) current_scope = python::incref(new_scope.ptr()); } +inline scope::scope() + : object(detail::borrowed_reference( + current_scope + )) + , m_previous_scope(python::incref(current_scope)) +{ +} + inline scope::~scope() { python::decref(current_scope); current_scope = m_previous_scope; } -inline object scope::get() -{ - return object(detail::borrowed_reference(current_scope)); -} - namespace converter { template <> diff --git a/src/module.cpp b/src/module.cpp index 4a30f6f0..b07cfe35 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -19,7 +19,7 @@ namespace boost { namespace python { namespace detail { module_base::module_base(const char* name) : m_module( allow_null(python::borrowed( - scope::get().ptr() + scope().ptr() ))) { } @@ -94,6 +94,6 @@ BOOST_PYTHON_DECL void init_module(char const* name, void(*init_function)()) namespace boost { namespace python { -BOOST_PYTHON_DECL PyObject* scope::current_scope; +BOOST_PYTHON_DECL PyObject* scope::current_scope = Py_None; }} From 30ef9c6418ec79e31d5fa5b057c3816e70766642 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 25 Jul 2002 15:20:06 +0000 Subject: [PATCH 0621/1042] back_reference<> uses object instead of handle<> [SVN r14600] --- include/boost/python/back_reference.hpp | 11 ++++++----- include/boost/python/operators2.hpp | 3 ++- test/back_reference.cpp | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/boost/python/back_reference.hpp b/include/boost/python/back_reference.hpp index 3ad7d240..5e9f02ba 100644 --- a/include/boost/python/back_reference.hpp +++ b/include/boost/python/back_reference.hpp @@ -7,6 +7,7 @@ # define BACK_REFERENCE_DWA2002510_HPP # include +# include namespace boost { namespace python { @@ -17,10 +18,10 @@ struct back_reference typedef T type; back_reference(PyObject*, T); - handle<> reference() const; + object const& source() const; T get() const; private: - handle<> m_reference; + object m_source; T m_value; }; @@ -75,15 +76,15 @@ class is_back_reference // template back_reference::back_reference(PyObject* p, T x) - : m_reference(python::borrowed(p)) + : m_source(detail::borrowed_reference(p)) , m_value(x) { } template -handle<> back_reference::reference() const +object const& back_reference::source() const { - return m_reference; + return m_source; } template diff --git a/include/boost/python/operators2.hpp b/include/boost/python/operators2.hpp index d4bffb05..8c56abf7 100755 --- a/include/boost/python/operators2.hpp +++ b/include/boost/python/operators2.hpp @@ -15,6 +15,7 @@ # include # include # include +# include # include # include @@ -251,7 +252,7 @@ namespace detail \ execute(back_reference l, R const& r) \ { \ l.get() op r; \ - return l.reference().release(); \ + return python::incref(l.source().ptr()); \ } \ }; \ static char const* name() { return "__" #id "__"; } \ diff --git a/test/back_reference.cpp b/test/back_reference.cpp index 577aa6ef..39f9127e 100644 --- a/test/back_reference.cpp +++ b/test/back_reference.cpp @@ -75,9 +75,9 @@ namespace boost { namespace python }} // prove that back_references get initialized with the right PyObject* -PyObject* y_identity(back_reference y) +object y_identity(back_reference y) { - return y.reference().release(); + return y.source(); } // prove that back_references contain the right value From ddb1236f2f5fc9db8456ed696c1a70210744252e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 25 Jul 2002 16:29:30 +0000 Subject: [PATCH 0622/1042] Begin transition away from handle<> [SVN r14602] --- include/boost/python/class.hpp | 15 +++---- include/boost/python/data_members.hpp | 43 +++++++++---------- include/boost/python/detail/wrap_function.hpp | 11 +++-- include/boost/python/iterator.hpp | 35 +++++---------- include/boost/python/object/class.hpp | 4 +- include/boost/python/object/function.hpp | 4 -- .../boost/python/object/function_object.hpp | 23 ++++++++++ src/object/class.cpp | 8 ++-- src/object/function.cpp | 8 ++-- 9 files changed, 77 insertions(+), 74 deletions(-) create mode 100644 include/boost/python/object/function_object.hpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 2e59189e..b2d960b0 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -181,22 +181,19 @@ class class_ : public objects::class_base template self& def_readonly(char const* name, D T::*pm) { - handle<> fget(make_getter(pm)); - this->add_property(name, fget); + this->add_property(name, make_getter(pm)); return *this; } template self& def_readwrite(char const* name, D T::*pm) { - handle<> fget(make_getter(pm)); - handle<> fset(make_setter(pm)); - return this->add_property(name, fget, fset); + return this->add_property(name, make_getter(pm), make_setter(pm)); } // Property creation - self& add_property(char const* name, handle<> const& fget); - self& add_property(char const* name, handle<> const& fget, handle<> const& fset); + self& add_property(char const* name, object const& fget); + self& add_property(char const* name, object const& fget, object const& fset); self& setattr(char const* name, handle<> const&); @@ -277,14 +274,14 @@ inline class_::class_(char const* name) template -inline class_& class_::add_property(char const* name, handle<> const& fget) +inline class_& class_::add_property(char const* name, object const& fget) { base::add_property(name, fget); return *this; } template -inline class_& class_::add_property(char const* name, handle<> const& fget, handle<> const& fset) +inline class_& class_::add_property(char const* name, object const& fget, object const& fset) { base::add_property(name, fget, fset); return *this; diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp index b9114403..f186c1d0 100644 --- a/include/boost/python/data_members.hpp +++ b/include/boost/python/data_members.hpp @@ -13,6 +13,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -61,47 +62,45 @@ namespace detail } template -objects::function* make_getter(D C::*pm) +object make_getter(D C::*pm) { typedef return_value_policy default_policy; - return new objects::function( - objects::py_function( - ::boost::bind( - &detail::member::get, pm, _1, _2 - , default_policy())) + + return objects::function_object( + ::boost::bind( + &detail::member::get, pm, _1, _2 + , default_policy()) , 1); + } template -objects::function* make_getter(D C::*pm, Policies const& policies) +object make_getter(D C::*pm, Policies const& policies) { - return new objects::function( - objects::py_function( + return objects::function_object( ::boost::bind( &detail::member::get, pm, _1, _2 - , policies)) + , policies) , 1); } template -objects::function* make_setter(D C::*pm) +object make_setter(D C::*pm) { - return new objects::function( - objects::py_function( - ::boost::bind( - &detail::member::set, pm, _1, _2 - , default_call_policies())) + return objects::function_object( + ::boost::bind( + &detail::member::set, pm, _1, _2 + , default_call_policies()) , 2); } template -objects::function* make_setter(D C::*pm, Policies const& policies) +object make_setter(D C::*pm, Policies const& policies) { - return new objects::function( - objects::py_function( - ::boost::bind( - &detail::member::set, pm, _1, _2 - , policies)) + return objects::function_object( + ::boost::bind( + &detail::member::set, pm, _1, _2 + , policies) , 2); } diff --git a/include/boost/python/detail/wrap_function.hpp b/include/boost/python/detail/wrap_function.hpp index 71ee967e..dcc3daca 100644 --- a/include/boost/python/detail/wrap_function.hpp +++ b/include/boost/python/detail/wrap_function.hpp @@ -12,6 +12,8 @@ # include # include # include +# include +# include namespace boost { namespace python { @@ -28,13 +30,16 @@ namespace detail { // object. template -inline PyObject* wrap_function_aux(F f, PyObject*) { return f; } +inline PyObject* wrap_function_aux(F const& f, PyObject*) { return f; } template -inline PyObject* wrap_function_aux(F f, boost::python::handle x) { return x.release(); } +inline PyObject* wrap_function_aux(F const&, boost::python::handle x) { return x.release(); } template -inline PyObject* wrap_function_aux(F f, ...) { return make_function(f); } +inline PyObject* wrap_function_aux(F const&, object const& x) { return python::incref(x.ptr()); } + +template +inline PyObject* wrap_function_aux(F const& f, ...) { return make_function(f); } template PyObject* wrap_function(F f) diff --git a/include/boost/python/iterator.hpp b/include/boost/python/iterator.hpp index 673d26e6..3f477034 100644 --- a/include/boost/python/iterator.hpp +++ b/include/boost/python/iterator.hpp @@ -69,43 +69,28 @@ struct iterators // accessors. Deduce the Target type from the accessors. The iterator // returns copies of the inderlying elements. template -handle<> range(Accessor1 start, Accessor2 finish) +object range(Accessor1 start, Accessor2 finish) { - return handle<>( - borrowed(allow_null( - detail::make_iterator( + return detail::make_iterator( start, finish - , detail::target(start)) - .ptr() - )) - ); + , detail::target(start)); } // Create an iterator-building function which uses the given accessors // and next() policies. Deduce the Target type. template -handle<> range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) +object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0) { - return handle<>( - borrowed( - allow_null( - detail::make_iterator(start, finish, detail::target(start)) - .ptr() - ))); + return detail::make_iterator(start, finish, detail::target(start)); } // Create an iterator-building function which uses the given accessors // and next() policies, operating on the given Target type template -handle<> range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type* = 0) +object range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type* = 0) { typedef typename add_reference::type target; - return handle<>( - borrowed( - allow_null( - detail::make_iterator(start, finish) - .ptr() - ))); + return detail::make_iterator(start, finish); } // A Python callable object which produces an iterator traversing @@ -114,11 +99,11 @@ handle<> range(Accessor1 start, Accessor2 finish, NextPolicies* = 0, boost::type // next() function. template -struct iterator : handle<> +struct iterator : object { iterator() - : handle<>( - range( + : object( + python::range( &iterators::begin, &iterators::end )) { diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index babd409a..1367337b 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -36,8 +36,8 @@ struct BOOST_PYTHON_DECL class_base : python::api::object ); // Retrieve the underlying object - void add_property(char const* name, handle<> const& fget); - void add_property(char const* name, handle<> const& fget, handle<> const& fset); + void add_property(char const* name, object const& fget); + void add_property(char const* name, object const& fget, object const& fset); void setattr(char const* name, handle<> const&); void enable_pickling(bool getstate_manages_dict); }; diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index ebd2a8c3..80a50dd0 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -41,10 +41,6 @@ struct BOOST_PYTHON_DECL function : PyObject function* m_overloads; }; -// -// implementations -// - }}} // namespace boost::python::objects #endif // FUNCTION_DWA20011214_HPP diff --git a/include/boost/python/object/function_object.hpp b/include/boost/python/object/function_object.hpp new file mode 100644 index 00000000..b638ac01 --- /dev/null +++ b/include/boost/python/object/function_object.hpp @@ -0,0 +1,23 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FUNCTION_OBJECT_DWA2002725_HPP +# define FUNCTION_OBJECT_DWA2002725_HPP +# include +# include + +namespace boost { namespace python { namespace objects { + +template +inline object function_object(F const& f, unsigned min_args, unsigned max_args = 0) +{ + return python::object( + python::detail::new_non_null_reference( + new function(objects::py_function(f), min_args, max_args))); +} + +}}} // namespace boost::python::object + +#endif // FUNCTION_OBJECT_DWA2002725_HPP diff --git a/src/object/class.cpp b/src/object/class.cpp index def44c33..b3c6c5e0 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -296,15 +296,15 @@ namespace objects extern DL_IMPORT(PyTypeObject) PyProperty_Type; } - void class_base::add_property(char const* name, handle<> const& fget) + void class_base::add_property(char const* name, object const& fget) { - handle<> property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.get())); + handle<> property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.ptr())); setattr(name, property); } - void class_base::add_property(char const* name, handle<> const& fget, handle<> const& fset) + void class_base::add_property(char const* name, object const& fget, object const& fset) { - handle<> property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.get(), fset.get())); + handle<> property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.ptr(), fset.ptr())); setattr(name, property); } diff --git a/src/object/function.cpp b/src/object/function.cpp index dad36dd5..53cad982 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -4,7 +4,7 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include #include #include #include @@ -148,10 +148,8 @@ namespace function* not_implemented_function() { - static function* result = new function(py_function(¬_implemented_impl), 2, 3); - static handle<> keeper(result); - - return result; + static object keeper(function_object(¬_implemented_impl, 2, 3)); + return (function*)keeper.ptr(); } } From 19036c14f531652e8cf47869bbff7970284903e0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 25 Jul 2002 18:07:25 +0000 Subject: [PATCH 0623/1042] handle<> -> object [SVN r14603] --- include/boost/python/class.hpp | 10 ++++++-- include/boost/python/object/class.hpp | 2 +- include/boost/python/object/iterator.hpp | 2 +- src/object/class.cpp | 29 +++++++++++++++--------- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index b2d960b0..d7a01edd 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -195,7 +195,13 @@ class class_ : public objects::class_base self& add_property(char const* name, object const& fget); self& add_property(char const* name, object const& fget, object const& fset); - self& setattr(char const* name, handle<> const&); + self& setattr(char const* name, object const&); + + template + self& bind(char const* name, T const& x) + { + return this->setattr(name, object(x)); + } // Pickle support template @@ -288,7 +294,7 @@ inline class_& class_::add_property(char const* name, ob } template -inline class_& class_::setattr(char const* name, handle<> const& x) +inline class_& class_::setattr(char const* name, object const& x) { base::setattr(name, x); return *this; diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 1367337b..d6af07e1 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -38,7 +38,7 @@ struct BOOST_PYTHON_DECL class_base : python::api::object // Retrieve the underlying object void add_property(char const* name, object const& fget); void add_property(char const* name, object const& fget, object const& fset); - void setattr(char const* name, handle<> const&); + void setattr(char const* name, object const&); void enable_pickling(bool getstate_manages_dict); }; diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 124759d6..8590d531 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -134,7 +134,7 @@ namespace detail return class_(name) .def("__iter__", identity_function()) - .setattr("next", next_function) + .bind("next", next_function) ; } diff --git a/src/object/class.cpp b/src/object/class.cpp index b3c6c5e0..d5d854dd 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -298,29 +298,36 @@ namespace objects void class_base::add_property(char const* name, object const& fget) { - handle<> property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.ptr())); - setattr(name, property); + object property( + python::detail::new_reference( + PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.ptr()))); + + this->setattr(name, property); } void class_base::add_property(char const* name, object const& fget, object const& fset) { - handle<> property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.ptr(), fset.ptr())); - setattr(name, property); + object property( + python::detail::new_reference( + PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.ptr(), fset.ptr()))); + + this->setattr(name, property); } - void class_base::setattr(char const* name, handle<> const& x) + void class_base::setattr(char const* name, object const& x) { - if (PyObject_SetAttrString(this->ptr(), const_cast(name), x.get()) < 0) + if (PyObject_SetAttrString(this->ptr(), const_cast(name), x.ptr()) < 0) throw_error_already_set(); } void class_base::enable_pickling(bool getstate_manages_dict) { - setattr("__reduce__", make_instance_reduce_function()); - handle<> one(PyInt_FromLong(1)); - setattr("__safe_for_unpickling__", one); - if (getstate_manages_dict) { - setattr("__getstate_manages_dict__", one); + setattr("__reduce__", object(make_instance_reduce_function())); + setattr("__safe_for_unpickling__", object(true)); + + if (getstate_manages_dict) + { + setattr("__getstate_manages_dict__", object(true)); } } From 6907df145798f0ab54c2b576640d49da45e4c43c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 27 Jul 2002 05:50:10 +0000 Subject: [PATCH 0624/1042] bug fixes [SVN r14623] --- include/boost/python/class.hpp | 16 ++++------------ include/boost/python/object/iterator.hpp | 10 +++++----- src/object/class.cpp | 8 ++++---- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index d7a01edd..e03f1838 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -195,12 +195,11 @@ class class_ : public objects::class_base self& add_property(char const* name, object const& fget); self& add_property(char const* name, object const& fget, object const& fset); - self& setattr(char const* name, object const&); - - template - self& bind(char const* name, T const& x) + template + self& setattr(char const* name, U const& x) { - return this->setattr(name, object(x)); + this->base::setattr(name, object(x)); + return *this; } // Pickle support @@ -293,13 +292,6 @@ inline class_& class_::add_property(char const* name, ob return *this; } -template -inline class_& class_::setattr(char const* name, object const& x) -{ - base::setattr(name, x); - return *this; -} - namespace detail { // This is an mpl BinaryMetaFunction object with a runtime behavior, diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 8590d531..c39131c6 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -43,9 +43,9 @@ struct default_iterator_call_policies template struct iterator_range { - iterator_range(handle<> sequence, Iterator start, Iterator finish); + iterator_range(object sequence, Iterator start, Iterator finish); - handle<> m_sequence; // Keeps the sequence alive while iterating. + object m_sequence; // Keeps the sequence alive while iterating. Iterator m_start; Iterator m_finish; }; @@ -134,7 +134,7 @@ namespace detail return class_(name) .def("__iter__", identity_function()) - .bind("next", next_function) + .setattr("next", next_function) ; } @@ -173,7 +173,7 @@ namespace detail // Build and convert the iterator_range<>. return cr( iterator_range( - handle<>(python::borrowed(arg0)) + object((python::detail::borrowed_reference)arg0) , get_start(x), get_finish(x))); } }; @@ -210,7 +210,7 @@ inline object make_iterator_function( // template inline iterator_range::iterator_range( - handle<> sequence, Iterator start, Iterator finish) + object sequence, Iterator start, Iterator finish) : m_sequence(sequence), m_start(start), m_finish(finish) { } diff --git a/src/object/class.cpp b/src/object/class.cpp index d5d854dd..4306a684 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -299,8 +299,8 @@ namespace objects void class_base::add_property(char const* name, object const& fget) { object property( - python::detail::new_reference( - PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.ptr()))); + (python::detail::new_reference) + PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.ptr())); this->setattr(name, property); } @@ -308,8 +308,8 @@ namespace objects void class_base::add_property(char const* name, object const& fget, object const& fset) { object property( - python::detail::new_reference( - PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.ptr(), fset.ptr()))); + (python::detail::new_reference) + PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.ptr(), fset.ptr())); this->setattr(name, property); } From 88b3bf18877135ec8a18c34e459814f54c8642d5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 5 Aug 2002 21:55:28 +0000 Subject: [PATCH 0625/1042] VC 7, 7.1a workaround [SVN r14701] --- include/boost/python/detail/force_instantiate.hpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/boost/python/detail/force_instantiate.hpp b/include/boost/python/detail/force_instantiate.hpp index 6248501c..6a08cf56 100755 --- a/include/boost/python/detail/force_instantiate.hpp +++ b/include/boost/python/detail/force_instantiate.hpp @@ -10,9 +10,24 @@ namespace boost { namespace python { namespace detail { // Allows us to force the argument to be instantiated without // incurring unused variable warnings + +# if !defined(BOOST_MSVC) || BOOST_MSVC == 1200 || _MSC_FULL_VER > 13102171 + template inline void force_instantiate(T const&) {} +# else + +# pragma optimize("g", off) +inline void force_instantiate_impl(...) {} +# pragma optimize("", on) +template +inline void force_instantiate(T const& x) +{ + detail::force_instantiate_impl(&x); +} +# endif + }}} // namespace boost::python::detail #endif // FORCE_INSTANTIATE_DWA200265_HPP From 88528e338b151d7a3ec17fba9daa3df81e129acd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Aug 2002 22:36:43 +0000 Subject: [PATCH 0626/1042] Correct version for VC7.1 workaround [SVN r14719] --- include/boost/python/detail/force_instantiate.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/force_instantiate.hpp b/include/boost/python/detail/force_instantiate.hpp index 6a08cf56..62446c32 100755 --- a/include/boost/python/detail/force_instantiate.hpp +++ b/include/boost/python/detail/force_instantiate.hpp @@ -11,7 +11,7 @@ namespace boost { namespace python { namespace detail { // Allows us to force the argument to be instantiated without // incurring unused variable warnings -# if !defined(BOOST_MSVC) || BOOST_MSVC == 1200 || _MSC_FULL_VER > 13102171 +# if !defined(BOOST_MSVC) || BOOST_MSVC == 1200 || _MSC_FULL_VER > 13102196 template inline void force_instantiate(T const&) {} From bd8b6a2a64bf7e6f71e6b2d27f67d6681ce41aa3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Aug 2002 23:23:28 +0000 Subject: [PATCH 0627/1042] Workaround a CWPro7.2 bug [SVN r14720] --- include/boost/python/handle.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/handle.hpp b/include/boost/python/handle.hpp index 8ebb1ae2..7fea1134 100755 --- a/include/boost/python/handle.hpp +++ b/include/boost/python/handle.hpp @@ -61,7 +61,7 @@ namespace detail template class handle { - typedef T* (handle::*bool_type); + typedef T* (handle::* bool_type )() const; public: // types typedef T element_type; @@ -112,7 +112,7 @@ class handle operator bool_type() const // never throws { - return m_p ? &handle::m_p : 0; + return m_p ? &handle::get : 0; } bool operator! () const; // never throws From 2bdf958663321407b0a5f69da7110fe163ce9fb4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Aug 2002 23:32:52 +0000 Subject: [PATCH 0628/1042] Suppress warnings by eliminating unneeded specializations of is_pointer_to_function<>. [SVN r14721] --- .../boost/python/detail/indirect_traits.hpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index f22c270b..faabecc2 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -75,24 +75,7 @@ struct is_pointer_to_function template struct is_pointer_to_function { - BOOST_STATIC_CONSTANT(bool, value = is_function::value); -}; - -template -struct is_pointer_to_function -{ - BOOST_STATIC_CONSTANT(bool, value = is_function::value); -}; - -template -struct is_pointer_to_function -{ - BOOST_STATIC_CONSTANT(bool, value = is_function::value); -}; - -template -struct is_pointer_to_function -{ + // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those BOOST_STATIC_CONSTANT(bool, value = is_function::value); }; From f59ed991fe46ed3f0fa81f66b56c432da29c3c46 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Aug 2002 23:44:31 +0000 Subject: [PATCH 0629/1042] VC6 bug workarounds [SVN r14722] --- src/dict.cpp | 4 ++-- src/list.cpp | 4 ++-- src/long.cpp | 8 ++++---- src/str.cpp | 4 ++-- src/tuple.cpp | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/dict.cpp b/src/dict.cpp index c8829505..6cd72c27 100644 --- a/src/dict.cpp +++ b/src/dict.cpp @@ -24,11 +24,11 @@ namespace } } -BOOST_PYTHON_DECL detail::new_reference dict::call(object const& arg) +BOOST_PYTHON_DECL detail::new_reference dict::call(object const& arg_) { return (detail::new_reference)PyObject_CallFunction( (PyObject*)&PyDict_Type, "(O)", - arg.ptr()); + arg_.ptr()); } BOOST_PYTHON_DECL dict::dict() diff --git a/src/list.cpp b/src/list.cpp index 484ae121..ee8bceb3 100644 --- a/src/list.cpp +++ b/src/list.cpp @@ -7,13 +7,13 @@ namespace boost { namespace python { -BOOST_PYTHON_DECL detail::new_non_null_reference list::call(object const& arg) +BOOST_PYTHON_DECL detail::new_non_null_reference list::call(object const& arg_) { return (detail::new_non_null_reference) (expect_non_null)( PyObject_CallFunction( (PyObject*)&PyList_Type, "(O)", - arg.ptr())); + arg_.ptr())); } BOOST_PYTHON_DECL list::list() diff --git a/src/long.cpp b/src/long.cpp index 43d4526d..2cf98610 100644 --- a/src/long.cpp +++ b/src/long.cpp @@ -7,18 +7,18 @@ namespace boost { namespace python { -BOOST_PYTHON_DECL detail::new_non_null_reference long_::call(object const& arg) +BOOST_PYTHON_DECL detail::new_non_null_reference long_::call(object const& arg_) { return (detail::new_non_null_reference)PyObject_CallFunction( (PyObject*)&PyLong_Type, "(O)", - arg.ptr()); + arg_.ptr()); } -BOOST_PYTHON_DECL detail::new_non_null_reference long_::call(object const& arg, object const& base) +BOOST_PYTHON_DECL detail::new_non_null_reference long_::call(object const& arg_, object const& base) { return (detail::new_non_null_reference)PyObject_CallFunction( (PyObject*)&PyLong_Type, "(OO)", - arg.ptr(), base.ptr()); + arg_.ptr(), base.ptr()); } BOOST_PYTHON_DECL long_::long_() diff --git a/src/str.cpp b/src/str.cpp index fc045d9f..12031548 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -3,11 +3,11 @@ namespace boost { namespace python { -BOOST_PYTHON_DECL detail::new_reference str::call(object const& arg) +BOOST_PYTHON_DECL detail::new_reference str::call(object const& arg_) { return (detail::new_reference)PyObject_CallFunction( (PyObject*)&PyString_Type, "(O)", - arg.ptr()); + arg_.ptr()); } BOOST_PYTHON_DECL str::str(const char* s) diff --git a/src/tuple.cpp b/src/tuple.cpp index 92e0df92..d6a33a56 100644 --- a/src/tuple.cpp +++ b/src/tuple.cpp @@ -2,11 +2,11 @@ namespace boost { namespace python { -BOOST_PYTHON_DECL detail::new_reference tuple::call(object const& arg) +BOOST_PYTHON_DECL detail::new_reference tuple::call(object const& arg_) { return (detail::new_reference)PyObject_CallFunction( (PyObject*)&PyTuple_Type, "(O)", - arg.ptr()); + arg_.ptr()); } BOOST_PYTHON_DECL tuple::tuple() From 61d030748c79817d8025ea10c97b3c14c3c94824 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Aug 2002 23:51:51 +0000 Subject: [PATCH 0630/1042] Moving an #include works around a VC6 ICE [SVN r14723] --- test/extract.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/extract.cpp b/test/extract.cpp index 59e7e120..ae9b5c17 100644 --- a/test/extract.cpp +++ b/test/extract.cpp @@ -4,6 +4,7 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. +#include "test_class.hpp" #include #include #include @@ -12,7 +13,6 @@ #include #include #include -#include "test_class.hpp" #include #include From 56e7b2a592e74cdacf4518565970f7f50dd3f571 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 6 Aug 2002 23:59:27 +0000 Subject: [PATCH 0631/1042] * object(f), where f is a function pointer now works. Returning a * function pointer from a function should work also. * make_function/make_constructor now return object instead of a raw pointer. * module::setattr() now accepts anything which can be passed to object's constructor. * Rework upcast<> to catch more errors at compile-time instead of infinite-looping. * Rationalize class<>::def() in preparation for docstring support * Partial docstring support in module::def (untested) * dependent<> trick moved to detail namespace and separate header * Added __doc__ attribute to C++ function wrapper objects * Sunk implementation of function_object into a library source file. [SVN r14724] --- include/boost/python/back_reference.hpp | 11 +- include/boost/python/cast.hpp | 47 +++++++- include/boost/python/class.hpp | 53 ++++----- .../boost/python/converter/arg_to_python.hpp | 41 +++++-- include/boost/python/data_members.hpp | 3 +- include/boost/python/detail/dependent.hpp | 28 +++++ include/boost/python/detail/module_base.hpp | 4 +- include/boost/python/detail/wrap_function.hpp | 52 --------- include/boost/python/make_function.hpp | 37 +++--- include/boost/python/module.hpp | 43 +++---- .../boost/python/object/add_to_namespace.hpp | 24 ++++ include/boost/python/object/function.hpp | 34 ++++-- .../boost/python/object/function_handle.hpp | 40 +++++++ .../boost/python/object/function_object.hpp | 11 +- include/boost/python/object/iterator.hpp | 30 +++-- include/boost/python/object/iterator_core.hpp | 5 +- .../boost/python/object/pickle_support.hpp | 3 +- include/boost/python/object/py_function.hpp | 22 ++++ include/boost/python/object_call.hpp | 4 +- include/boost/python/object_core.hpp | 11 +- src/module.cpp | 11 +- src/object/function.cpp | 106 ++++++++++++++---- src/object/iterator.cpp | 6 +- src/object/pickle_support.cpp | 4 +- test/list.cpp | 2 +- 25 files changed, 401 insertions(+), 231 deletions(-) create mode 100644 include/boost/python/detail/dependent.hpp delete mode 100644 include/boost/python/detail/wrap_function.hpp create mode 100644 include/boost/python/object/add_to_namespace.hpp create mode 100644 include/boost/python/object/function_handle.hpp create mode 100644 include/boost/python/object/py_function.hpp diff --git a/include/boost/python/back_reference.hpp b/include/boost/python/back_reference.hpp index 5e9f02ba..29ad6163 100644 --- a/include/boost/python/back_reference.hpp +++ b/include/boost/python/back_reference.hpp @@ -7,21 +7,24 @@ # define BACK_REFERENCE_DWA2002510_HPP # include -# include +# include +# include namespace boost { namespace python { template struct back_reference { + private: // types + typedef typename detail::dependent::type source_t; public: typedef T type; back_reference(PyObject*, T); - object const& source() const; + source_t const& source() const; T get() const; private: - object m_source; + source_t m_source; T m_value; }; @@ -82,7 +85,7 @@ back_reference::back_reference(PyObject* p, T x) } template -object const& back_reference::source() const +typename back_reference::source_t const& back_reference::source() const { return m_source; } diff --git a/include/boost/python/cast.hpp b/include/boost/python/cast.hpp index 1897fc60..d20cbd3a 100755 --- a/include/boost/python/cast.hpp +++ b/include/boost/python/cast.hpp @@ -8,6 +8,7 @@ # include # include +# include # include # include # include @@ -16,19 +17,42 @@ namespace boost { namespace python { namespace detail { - template - inline Target* upcast(Target* p, yes_convertible) + template inline Target* upcast_impl(Source*, Target*); + + template + inline Target* upcast(Source* p, yes_convertible, no_convertible, Target*) { return p; } - template - inline Target* upcast(Source* p, no_convertible, boost::type* = 0) + template + inline Target* upcast(Source* p, no_convertible, no_convertible, Target*) { typedef typename base_type_traits::type base; - return detail::upcast((base*)p, convertible::check((base*)0)); + + return detail::upcast_impl((base*)p, (Target*)0); } + template + struct upcaster + { + template + static inline T* execute(T* x, T*) { return x; } + }; + + template <> + struct upcaster + { + template + static inline Target* execute(Source* x, Target*) + { + return detail::upcast( + x, detail::convertible::check(x) + , detail::convertible::check((Target*)0) + , (Target*)0); + } + }; + template inline Target* downcast(Source* p, yes_convertible) @@ -48,6 +72,16 @@ namespace detail { typedef char must_be_a_complete_type[sizeof(T)]; } + + template + inline Target* upcast_impl(Source* x, Target*) + { + typedef typename add_cv::type src_t; + typedef typename add_cv::type target_t; + static bool const same = is_same::value; + + return detail::upcaster::execute(x, (Target*)0); + } } template @@ -55,7 +89,8 @@ inline Target* upcast(Source* x, Target* = 0) { detail::assert_castable(); detail::assert_castable(); - return detail::upcast(x, detail::convertible::check(x)); + return detail::upcast_impl(x, (Target*)0); + } template diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index e03f1838..799fd498 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -12,7 +12,6 @@ # include # include # include -# include # include # include # include @@ -26,6 +25,8 @@ # include # include # include +# include +# include namespace boost { namespace python { @@ -101,30 +102,19 @@ class class_ : public objects::class_base template self& def(char const* name, F f) { - // Use function::add_to_namespace to achieve overloading if - // appropriate. - objects::function::add_to_namespace( - *this, name - , object( - detail::new_reference( - detail::wrap_function( - // This bit of nastiness casts F to a member function of T if possible. - detail::member_function_cast::stage1(f).stage2((T*)0).stage3(f) - )))); + this->def_impl(name, f, 0, &f); return *this; } template self& def(char const* name, Fn fn, CallPolicy policy) { - this->def(name + return this->def(name , boost::python::make_function( // 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) , policy) ); - - return *this; } template @@ -133,12 +123,7 @@ class class_ : public objects::class_base typedef detail::operator_ op_t; // Use function::add_to_namespace to achieve overloading if // appropriate. - objects::function::add_to_namespace( - *this, op.name() - , object( - detail::new_reference( - detail::wrap_function(&op_t::template apply::execute)))); - return *this; + return this->def(op.name(), &op_t::template apply::execute); } // Define the constructor with the given Args, which should be an @@ -146,26 +131,24 @@ class class_ : public objects::class_base template self& def_init(Args const&) { - def("__init__", - make_constructor( + return this->def("__init__", + python::make_constructor( // Using runtime type selection works around a CWPro7 bug. objects::select_holder((held_type*)0).get() ) ); - return *this; } template self& def_init(Args const&, CallPolicy policy) { - def("__init__", - make_constructor( + return this->def("__init__", + python::make_constructor( policy // Using runtime type selection works around a CWPro7 bug. , objects::select_holder((held_type*)0).get() ) ); - return *this; } // Define the default constructor. @@ -216,6 +199,24 @@ class class_ : public objects::class_base return *this; } + private: // helper functions + + template + inline void def_impl(char const* name, F const& f, char const* doc, ...) + { + objects::add_to_namespace( + *this, name, make_function( + // This bit of nastiness casts F to a member function of T if possible. + detail::member_function_cast::stage1(f).stage2((T*)0).stage3(f)) + , doc); + } + + template + inline void def_impl(char const* name, F const& f, char const* doc, object const volatile*) + { + objects::add_to_namespace(*this, name, f, doc); + } + private: // types typedef objects::class_id class_id; diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index eb1cd80c..c936b81d 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -13,12 +13,16 @@ # include # include # include +# include +# include +# include # include # include # include // Bring in specializations # include # include +# include namespace boost { namespace python { namespace converter { @@ -26,6 +30,12 @@ namespace detail { BOOST_PYTHON_DECL void throw_no_class_registered(); + template + struct function_arg_to_python : handle<> + { + function_arg_to_python(T const& x); + }; + template struct reference_arg_to_python : handle<> { @@ -80,6 +90,9 @@ namespace detail BOOST_STATIC_CONSTANT( bool, is_string = python::detail::is_string_literal::value); + BOOST_STATIC_CONSTANT( + bool, function = is_function::value | python::detail::is_pointer_to_function::value | is_member_function_pointer::value); + BOOST_STATIC_CONSTANT( bool, manager = is_object_manager::value); @@ -99,18 +112,22 @@ namespace detail is_string , arg_to_python , typename mpl::select_type< - manager - , object_manager_arg_to_python + function + , function_arg_to_python , typename mpl::select_type< - ptr - , pointer_deep_arg_to_python + manager + , object_manager_arg_to_python , typename mpl::select_type< - ptr_wrapper - , pointer_shallow_arg_to_python + ptr + , pointer_deep_arg_to_python , typename mpl::select_type< - ref_wrapper - , reference_arg_to_python - , value_arg_to_python + ptr_wrapper + , pointer_shallow_arg_to_python + , typename mpl::select_type< + ref_wrapper + , reference_arg_to_python + , value_arg_to_python + >::type >::type >::type >::type @@ -168,6 +185,12 @@ namespace detail } // --------- + template + inline function_arg_to_python::function_arg_to_python(T const& x) + : handle<>(python::objects::make_function_handle(x)) + { + } + template inline value_arg_to_python::value_arg_to_python(T const& x) : arg_to_python_base(&x, registered::converters) diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp index f186c1d0..01190811 100644 --- a/include/boost/python/data_members.hpp +++ b/include/boost/python/data_members.hpp @@ -8,12 +8,13 @@ # include # include -# include # include # include # include # include # include +# include +# include namespace boost { namespace python { diff --git a/include/boost/python/detail/dependent.hpp b/include/boost/python/detail/dependent.hpp new file mode 100644 index 00000000..4fc48766 --- /dev/null +++ b/include/boost/python/detail/dependent.hpp @@ -0,0 +1,28 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef DEPENDENT_DWA200286_HPP +# define DEPENDENT_DWA200286_HPP + +namespace boost { namespace python { namespace detail { + +// A way to turn a concrete type T into a type dependent on U. This +// keeps conforming compilers (those implementing proper 2-phase +// name lookup for templates) from complaining about incomplete +// types in situations where it would otherwise be inconvenient or +// impossible to re-order code so that all types are defined in time. + +// One such use is when we must return an incomplete T from a member +// function template (which must be defined in the class body to +// keep MSVC happy). +template +struct dependent +{ + typedef T type; +}; + +}}} // namespace boost::python::detail + +#endif // DEPENDENT_DWA200286_HPP diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp index aaa6a135..4ef00cfd 100644 --- a/include/boost/python/detail/module_base.hpp +++ b/include/boost/python/detail/module_base.hpp @@ -7,6 +7,7 @@ # define MODULE_BASE_DWA2002227_HPP # include # include +# include namespace boost { namespace python { namespace detail { @@ -18,14 +19,13 @@ class BOOST_PYTHON_DECL module_base ~module_base(); // Add elements to the module - void setattr(const char* name, PyObject*); - void setattr(const char* name, handle<> const&); void add(type_handle const&); // just use the type's name // Return a reference to the Python module object being built inline handle<> object() const; protected: + void setattr_doc(const char* name, python::object const&, char const* doc); void add_class(type_handle const& class_obj); private: diff --git a/include/boost/python/detail/wrap_function.hpp b/include/boost/python/detail/wrap_function.hpp deleted file mode 100644 index dcc3daca..00000000 --- a/include/boost/python/detail/wrap_function.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef WRAP_FUNCTION_DWA2002118_HPP -# define WRAP_FUNCTION_DWA2002118_HPP - -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -template class reference; - -namespace detail { - -// A function which converts its argument into a Python callable -// object. Not very general yet! - -// This should eventually be replaced with a mechanism for specialized -// wrap/unwrap objects. In other words, to_python(f), where f is a -// function pointer or function type, should produce a callable Python -// object. - -template -inline PyObject* wrap_function_aux(F const& f, PyObject*) { return f; } - -template -inline PyObject* wrap_function_aux(F const&, boost::python::handle x) { return x.release(); } - -template -inline PyObject* wrap_function_aux(F const&, object const& x) { return python::incref(x.ptr()); } - -template -inline PyObject* wrap_function_aux(F const& f, ...) { return make_function(f); } - -template -PyObject* wrap_function(F f) -{ - return wrap_function_aux(f, f); -} - -}}} // namespace boost::python::detail - -#endif // WRAP_FUNCTION_DWA2002118_HPP diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index 7b2ba79d..decdf5b4 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -6,7 +6,7 @@ #ifndef MAKE_FUNCTION_DWA20011221_HPP # define MAKE_FUNCTION_DWA20011221_HPP -# include +# include # include # include # include @@ -17,48 +17,45 @@ namespace boost { namespace python { template -objects::function* make_function(F f) +object make_function(F f) { - return new objects::function( - objects::py_function( - ::boost::bind(detail::caller(), f, _1, _2, default_call_policies())) + return objects::function_object( + ::boost::bind(detail::caller(), f, _1, _2, default_call_policies()) , detail::arg_tuple_size::value); } template -objects::function* make_function(F f, Policies const& policies) +object make_function(F f, Policies const& policies) { - return new objects::function( - objects::py_function( - ::boost::bind(detail::caller(), f, _1, _2, policies)) + return objects::function_object( + ::boost::bind(detail::caller(), f, _1, _2, policies) , detail::arg_tuple_size::value); } template -objects::function* make_constructor(HolderGenerator* = 0, ArgList* = 0) +object make_constructor(HolderGenerator* = 0, ArgList* = 0) { enum { nargs = mpl::size::value }; - return new objects::function( - objects::py_function( - ::boost::bind(detail::caller(), - objects::make_holder - ::template apply::execute - , _1, _2, default_call_policies())) + return objects::function_object( + ::boost::bind( + detail::caller() + , objects::make_holder + ::template apply::execute + , _1, _2, default_call_policies()) , nargs + 1); } template -objects::function* make_constructor(Policies const& policies, HolderGenerator* = 0, ArgList* = 0) +object make_constructor(Policies const& policies, HolderGenerator* = 0, ArgList* = 0) { enum { nargs = mpl::size::value }; - return new objects::function( - objects::py_function( + return objects::function_object( ::boost::bind(detail::caller(), objects::make_holder ::template apply::execute - , _1, _2, policies)) + , _1, _2, policies) , nargs + 1); } diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 25f8cf05..a4d7a4db 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -12,6 +12,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -24,10 +25,14 @@ class module : public detail::module_base : base(name) {} // Add elements to the module - module& setattr(const char* name, PyObject*); - module& setattr(const char* name, PyTypeObject*); - module& setattr(const char* name, handle<> const&); - module& add(PyTypeObject* x); // just use the type's name + template + module& setattr(const char* name, T const& x) + { + 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) @@ -37,17 +42,17 @@ class module : public detail::module_base } template - module& def(char const* name, Fn fn) + module& def(char const* name, Fn fn, char const* doc = 0) { - this->setattr(name, boost::python::make_function(fn)); + this->setattr_doc(name, boost::python::make_function(fn), doc); return *this; } template - module& def(char const* name, Fn fn, ResultHandler handler) + module& def(char const* name, Fn fn, ResultHandler handler, char const* doc = 0) { - this->setattr(name, boost::python::make_function(fn, handler)); + this->setattr_doc(name, boost::python::make_function(fn, handler), doc); return *this; } }; @@ -55,27 +60,9 @@ class module : public detail::module_base // // inline implementations // -inline module& module::setattr(const char* name, PyObject* x) +inline module& module::add(type_handle x) { - this->base::setattr(name, x); - return *this; -} - -inline module& module::setattr(const char* name, PyTypeObject* x) -{ - this->base::setattr(name, (PyObject*)x); - return *this; -} - -inline module& module::setattr(const char* name, handle<> const& x) -{ - this->base::setattr(name, x); - return *this; -} - -inline module& module::add(PyTypeObject* x) -{ - this->base::add(handle<>(borrowed(x))); + this->base::add(x); return *this; } diff --git a/include/boost/python/object/add_to_namespace.hpp b/include/boost/python/object/add_to_namespace.hpp new file mode 100644 index 00000000..6a862b3d --- /dev/null +++ b/include/boost/python/object/add_to_namespace.hpp @@ -0,0 +1,24 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ADD_TO_NAMESPACE_DWA200286_HPP +# define ADD_TO_NAMESPACE_DWA200286_HPP + +# include + +namespace boost { namespace python { namespace objects { + +// +// A setattr that's "smart" about function overloading (and docstrings). +// +BOOST_PYTHON_DECL void add_to_namespace( + object const& name_space, char const* name, object const& attribute); + +BOOST_PYTHON_DECL void add_to_namespace( + object const& name_space, char const* name, object const& attribute, char const* doc); + +}}} // namespace boost::python::objects + +#endif // ADD_TO_NAMESPACE_DWA200286_HPP diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index 80a50dd0..1e5fdfe8 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -10,37 +10,55 @@ # include # include # include -# include +# include +# include namespace boost { namespace python { namespace objects { -// We use boost::function to avoid generating lots of virtual tables -typedef boost::function2 py_function; - struct BOOST_PYTHON_DECL function : PyObject { - function(py_function, unsigned min_args, unsigned max_args = 0); + function(py_function const&, unsigned min_args, unsigned max_args = 0); ~function(); PyObject* call(PyObject*, PyObject*) const; - // Add an attributeto the name_space with the given name. If it is + // Add an attribute to the name_space with the given name. If it is // a function object (this class), and an existing function is // already there, add it as an overload. static void add_to_namespace( object const& name_space, char const* name, object const& attribute); + + static void add_to_namespace( + object const& name_space, char const* name, object const& attribute, char const* doc); + + object const& doc() const; + void doc(object const& x); private: // helper functions void argument_error(PyObject* args, PyObject* keywords) const; - void add_overload(function*); + void add_overload(handle const&); private: // data members py_function m_fn; unsigned m_min_args; unsigned m_max_args; - function* m_overloads; + handle m_overloads; + object m_doc; }; +// +// implementations +// +inline object const& function::doc() const +{ + return this->m_doc; +} + +inline void function::doc(object const& x) +{ + this->m_doc = x; +} + }}} // namespace boost::python::objects #endif // FUNCTION_DWA20011214_HPP diff --git a/include/boost/python/object/function_handle.hpp b/include/boost/python/object/function_handle.hpp new file mode 100644 index 00000000..f29c2e35 --- /dev/null +++ b/include/boost/python/object/function_handle.hpp @@ -0,0 +1,40 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef FUNCTION_HANDLE_DWA2002725_HPP +# define FUNCTION_HANDLE_DWA2002725_HPP +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace objects { + +BOOST_PYTHON_DECL handle<> function_handle_impl(py_function const& f, unsigned min_args, unsigned max_args = 0); + +// Just like function_object, but returns a handle<> instead. Using +// this for arg_to_python<> allows us to break a circular dependency +// between object and arg_to_python. +template +inline handle<> function_handle(F const& f, unsigned min_args, unsigned max_args = 0) +{ + return objects::function_handle_impl(objects::py_function(f), min_args, max_args); +} + +// Just like make_function, but returns a handle<> intead. Same +// reasoning as above. +template +handle<> make_function_handle(F f) +{ + return objects::function_handle( + ::boost::bind(python::detail::caller(), f, _1, _2, default_call_policies()) + , python::detail::arg_tuple_size::value); +} + +}}} // namespace boost::python::objects + +#endif // FUNCTION_HANDLE_DWA2002725_HPP diff --git a/include/boost/python/object/function_object.hpp b/include/boost/python/object/function_object.hpp index b638ac01..03535ec3 100644 --- a/include/boost/python/object/function_object.hpp +++ b/include/boost/python/object/function_object.hpp @@ -5,19 +5,20 @@ // to its suitability for any purpose. #ifndef FUNCTION_OBJECT_DWA2002725_HPP # define FUNCTION_OBJECT_DWA2002725_HPP -# include +# include +# include # include namespace boost { namespace python { namespace objects { +BOOST_PYTHON_DECL api::object function_object_impl(boost::function2 const& f, unsigned min_args, unsigned max_args = 0); + template inline object function_object(F const& f, unsigned min_args, unsigned max_args = 0) { - return python::object( - python::detail::new_non_null_reference( - new function(objects::py_function(f), min_args, max_args))); + return objects::function_object_impl(boost::function2(f), min_args, max_args); } -}}} // namespace boost::python::object +}}} // namespace boost::python::objects #endif // FUNCTION_OBJECT_DWA2002725_HPP diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index c39131c6..13862e6f 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -10,7 +10,7 @@ # include # include # include -# include +# include # include # include # include @@ -126,11 +126,10 @@ namespace detail return object(class_obj); // Make a callable object which can be used as the iterator's next() function. - handle<> next_function( - new objects::function( - objects::py_function( - bind(&detail::iterator_next::execute, _1, _2, policies)) - , 1)); + object next_function = + objects::function_object( + bind(&detail::iterator_next::execute, _1, _2, policies) + , 1); return class_(name) .def("__iter__", identity_function()) @@ -192,17 +191,14 @@ inline object make_iterator_function( { typedef typename Accessor1::result_type result_type; - return object( - python::detail::new_non_null_reference( - new objects::function( - objects::py_function( - boost::bind( - &detail::make_iterator_help< - Target,result_type,Accessor1,Accessor2,NextPolicies - >::create - , get_start, get_finish, _1, _2)) - ,1 )) - ); + return + objects::function_object( + boost::bind( + &detail::make_iterator_help< + Target,result_type,Accessor1,Accessor2,NextPolicies + >::create + , get_start, get_finish, _1, _2) + , 1 ); } // diff --git a/include/boost/python/object/iterator_core.hpp b/include/boost/python/object/iterator_core.hpp index c3d5f6ae..655fc71e 100644 --- a/include/boost/python/object/iterator_core.hpp +++ b/include/boost/python/object/iterator_core.hpp @@ -6,11 +6,12 @@ #ifndef ITERATOR_CORE_DWA2002512_HPP # define ITERATOR_CORE_DWA2002512_HPP -# include +# include +# include namespace boost { namespace python { namespace objects { -BOOST_PYTHON_DECL handle<> identity_function(); +BOOST_PYTHON_DECL object const& identity_function(); BOOST_PYTHON_DECL void set_stop_iteration_error(); }}} // namespace boost::python::object diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp index 44e2103e..10a5f4f8 100644 --- a/include/boost/python/object/pickle_support.hpp +++ b/include/boost/python/object/pickle_support.hpp @@ -8,10 +8,11 @@ #include #include +#include namespace boost { namespace python { -handle<> make_instance_reduce_function(); +BOOST_PYTHON_DECL object const& make_instance_reduce_function(); struct pickle_suite; diff --git a/include/boost/python/object/py_function.hpp b/include/boost/python/object/py_function.hpp new file mode 100644 index 00000000..0682d692 --- /dev/null +++ b/include/boost/python/object/py_function.hpp @@ -0,0 +1,22 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef PY_FUNCTION_DWA200286_HPP +# define PY_FUNCTION_DWA200286_HPP +# include + +namespace boost { namespace python { namespace objects { + +// This type is used as a "generalized Python callback", wrapping the +// function signature: +// +// PyObject* (PyObject* args, PyObject* keywords) +// +// We use boost::function to avoid generating lots of virtual tables +typedef boost::function2 py_function; + +}}} // namespace boost::python::objects + +#endif // PY_FUNCTION_DWA200286_HPP diff --git a/include/boost/python/object_call.hpp b/include/boost/python/object_call.hpp index 22e88847..31b2eff9 100644 --- a/include/boost/python/object_call.hpp +++ b/include/boost/python/object_call.hpp @@ -11,10 +11,10 @@ #define N BOOST_PP_ITERATION() template - typename dependent::type + typename detail::dependent::type operator()(BOOST_PYTHON_BINARY_ENUM(N, A, const& a)) const { - typedef typename dependent::type obj; + typedef typename detail::dependent::type obj; U const& self = *static_cast(this); return call(get_managed_object(self, tag), BOOST_PYTHON_UNARY_ENUM(N, a)); } diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 496752dc..22bd2750 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -16,6 +16,7 @@ # include # include # include +# include # include @@ -76,16 +77,6 @@ namespace api template struct object_initializer; - // A way to turn a conrete type T into a type dependent on U. This - // keeps conforming compilers from complaining about returning an - // incomplete T from a template member function (which must be - // defined in the class body to keep MSVC happy). - template - struct dependent - { - typedef T type; - }; - class object; typedef PyObject* (object::*bool_type)() const; diff --git a/src/module.cpp b/src/module.cpp index b07cfe35..4563db31 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -28,21 +28,16 @@ module_base::~module_base() { } -void module_base::setattr(const char* name, PyObject* x) -{ - setattr(name, handle<>(x)); -} - -void module_base::setattr(char const* name, handle<> const& x) +void module_base::setattr_doc(const char* name, python::object const& x, char const* doc) { // Use function::add_to_namespace to achieve overloading if // appropriate. - objects::function::add_to_namespace(python::object(m_module), name, python::object(x)); + objects::function::add_to_namespace(python::object(m_module), name, x, doc); } void module_base::add(type_handle const& x) { - this->setattr(x->tp_name, x); + this->setattr_doc(x->tp_name, python::object(x), 0); } void module_base::add_class(type_handle const& class_obj) diff --git a/src/object/function.cpp b/src/object/function.cpp index 53cad982..a09717fc 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -4,22 +4,24 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. +#include #include +#include #include #include #include #include #include +#include namespace boost { namespace python { namespace objects { extern PyTypeObject function_type; -function::function(py_function implementation, unsigned min_args, unsigned max_args) +function::function(py_function const& implementation, unsigned min_args, unsigned max_args) : m_fn(implementation) , m_min_args(min_args) - , m_max_args(std::max(max_args,min_args)) - , m_overloads(0) + , m_max_args(std::max(max_args,min_args)) { PyObject* p = this; PyObject_INIT(p, &function_type); @@ -27,8 +29,6 @@ function::function(py_function implementation, unsigned min_args, unsigned max_a function::~function() { - PyObject* overloads = m_overloads; - Py_XDECREF(overloads); } PyObject* function::call(PyObject* args, PyObject* keywords) const @@ -52,7 +52,7 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const if (result != 0 || PyErr_Occurred()) return result; } - f = f->m_overloads; + f = f->m_overloads.get(); } while (f); // None of the overloads matched; time to generate the error message @@ -66,17 +66,18 @@ void function::argument_error(PyObject* args, PyObject* keywords) const PyErr_BadArgument(); } -void function::add_overload(function* overload_) +void function::add_overload(handle const& overload_) { - Py_XINCREF(overload_); - function* parent = this; - while (parent->m_overloads != 0) - { - parent = parent->m_overloads; - } + while (parent->m_overloads) + parent = parent->m_overloads.get(); + parent->m_overloads = overload_; + + // If we have no documentation, get the docs from the overload + if (!m_doc) + m_doc = overload_->m_doc; } namespace @@ -146,10 +147,10 @@ namespace return Py_NotImplemented; } - function* not_implemented_function() + handle not_implemented_function() { static object keeper(function_object(¬_implemented_impl, 2, 3)); - return (function*)keeper.ptr(); + return handle(borrowed(downcast(keeper.ptr()))); } } @@ -172,16 +173,17 @@ void function::add_to_namespace( if (dict == 0) throw_error_already_set(); - - handle<> existing( allow_null(::PyObject_GetItem(dict, name.ptr())) ); + + // This isn't quite typesafe. We'll shoot first by assuming + // the thing is a function*, then ask questions later. The code works nicer that way. + handle existing( + allow_null(downcast(::PyObject_GetItem(dict, name.ptr()))) + ); if (existing.get()) { if (existing->ob_type == &function_type) - { - static_cast(attribute.ptr())->add_overload( - static_cast(existing.get())); - } + static_cast(attribute.ptr())->add_overload(existing); } // Binary operators need an additional overload which returns NotImplemented else if (is_binary_operator(name_)) @@ -190,13 +192,24 @@ void function::add_to_namespace( not_implemented_function()); } } - + // The PyObject_GetAttrString() call above left an active error PyErr_Clear(); if (PyObject_SetAttr(ns, name.ptr(), attribute.ptr()) < 0) throw_error_already_set(); } +void function::add_to_namespace( + object const& name_space, char const* name_, object const& attribute, char const* doc) +{ + add_to_namespace(name_space, name_, attribute); + if (doc != 0) + { + object attr_copy(attribute); + attr_copy.attr("__doc__") = doc; + } +} + namespace { struct bind_return @@ -245,6 +258,24 @@ extern "C" handle_exception(bind_return(result, static_cast(func), args, kw)); return result; } + + static PyObject* function_get_doc(PyObject* op, void*) + { + function* f = downcast(op); + return incref(f->doc().ptr()); + } + + static int function_set_doc(PyObject* op, PyObject* doc) + { + function* f = downcast(op); + f->doc(doc ? object(python::detail::borrowed_reference(doc)) : object()); + return 0; + } + + static PyGetSetDef function_getsetlist[] = { + {"__doc__", function_get_doc, (setter)function_set_doc}, + {NULL} /* Sentinel */ + }; } PyTypeObject function_type = { @@ -277,8 +308,8 @@ PyTypeObject function_type = { 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ - 0, // func_memberlist, /* tp_members */ - 0, //func_getsetlist, /* tp_getset */ + 0, // func_memberlist, /* tp_members */ + function_getsetlist, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ function_descr_get, /* tp_descr_get */ @@ -290,4 +321,31 @@ PyTypeObject function_type = { 0 /* tp_new */ }; +object function_object_impl(py_function const& f, unsigned min_args, unsigned max_args) +{ + return python::object( + python::detail::new_non_null_reference( + new function(f, min_args, max_args))); +} + +handle<> function_handle_impl(py_function const& f, unsigned min_args, unsigned max_args) +{ + return python::handle<>( + allow_null( + new function(f, min_args, max_args))); +} + +BOOST_PYTHON_DECL void add_to_namespace( + object const& name_space, char const* name, object const& attribute) +{ + function::add_to_namespace(name_space, name, attribute); +} + +BOOST_PYTHON_DECL void add_to_namespace( + object const& name_space, char const* name, object const& attribute, char const* doc) +{ + function::add_to_namespace(name_space, name, attribute, doc); +} + + }}} // namespace boost::python::objects diff --git a/src/object/iterator.cpp b/src/object/iterator.cpp index 8b6da346..384d6845 100644 --- a/src/object/iterator.cpp +++ b/src/object/iterator.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include namespace boost { namespace python { namespace objects { @@ -18,9 +18,9 @@ static PyObject* identity(PyObject* args_, PyObject*) return x; } -BOOST_PYTHON_DECL handle<> identity_function() +BOOST_PYTHON_DECL object const& identity_function() { - static handle<> result(new objects::function(py_function(&identity), 1)); + static object result(function_object(&identity, 1)); return result; } diff --git a/src/object/pickle_support.cpp b/src/object/pickle_support.cpp index 3b14c8ea..6f37517f 100644 --- a/src/object/pickle_support.cpp +++ b/src/object/pickle_support.cpp @@ -54,9 +54,9 @@ namespace { } // namespace -handle<> make_instance_reduce_function() +object const& make_instance_reduce_function() { - static handle<> result(make_function(&instance_reduce)); + static object result(&instance_reduce); return result; } diff --git a/test/list.cpp b/test/list.cpp index a5c9bc87..7b0d2645 100644 --- a/test/list.cpp +++ b/test/list.cpp @@ -111,7 +111,7 @@ void exercise(list x, object y, object print) print(x); print("reverse sorted:"); - x.sort(handle<>(make_function(notcmp))); + x.sort(¬cmp); print(x); list w; From bd0257cbe5bc65f11377c9bd7b53b1c6ea58b9fc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 7 Aug 2002 23:03:02 +0000 Subject: [PATCH 0632/1042] Full docstring support [SVN r14734] --- include/boost/python/class.hpp | 57 ++++++++++--------- include/boost/python/detail/module_base.hpp | 2 +- include/boost/python/module.hpp | 24 +++++--- include/boost/python/object/class.hpp | 1 + include/boost/python/object/function.hpp | 8 +++ src/module.cpp | 4 +- src/object/class.cpp | 5 +- src/object/function.cpp | 42 +++++++++++--- test/Jamfile | 1 + test/docstring.cpp | 61 +++++++++++++++++++++ test/docstring.py | 51 +++++++++++++++++ 11 files changed, 211 insertions(+), 45 deletions(-) create mode 100644 test/docstring.cpp create mode 100644 test/docstring.py diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 799fd498..4af8d3e7 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -27,6 +27,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -57,7 +58,7 @@ namespace detail template static inline void register_copy_constructor(mpl::bool_t const&, Holder*, object const&, T* = 0) { - } + } } // @@ -93,7 +94,7 @@ class class_ : public objects::class_base // Construct with the class name. [ Would have used a default // argument but gcc-2.95.2 choked on typeid(T).name() as a default // parameter value] - class_(char const* name); + class_(char const* name, char const* doc = 0); // Wrap a member function or a non-member function which can take @@ -102,27 +103,25 @@ class class_ : public objects::class_base template self& def(char const* name, F f) { - this->def_impl(name, f, 0, &f); + this->def_impl(name, f, default_call_policies(), 0, &f); return *this; } - template - self& def(char const* name, Fn fn, CallPolicy policy) + template + self& def(char const* name, Fn fn, CallPolicyOrDoc const& policy_or_doc, char const* doc = 0) { - return this->def(name - , boost::python::make_function( - // 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) - , policy) - ); + typedef detail::def_helper helper; + + this->def_impl( + name, fn, helper::get_policy(policy_or_doc), helper::get_doc(policy_or_doc, doc), &fn); + + return *this; } template self& def(detail::operator_ const& op) { typedef detail::operator_ op_t; - // Use function::add_to_namespace to achieve overloading if - // appropriate. return this->def(op.name(), &op_t::template apply::execute); } @@ -139,15 +138,19 @@ class class_ : public objects::class_base ); } - template - self& def_init(Args const&, CallPolicy policy) + template + self& def_init(Args const&, CallPolicyOrDoc const& policy_or_doc, char const* doc = 0) { - return this->def("__init__", + typedef detail::def_helper helper; + + return this->def( + "__init__", python::make_constructor( - policy + helper::get_policy(policy_or_doc) // Using runtime type selection works around a CWPro7 bug. , objects::select_holder((held_type*)0).get() ) + , helper::get_doc(policy_or_doc, doc) ); } @@ -201,22 +204,26 @@ class class_ : public objects::class_base private: // helper functions - template - inline void def_impl(char const* name, F const& f, char const* doc, ...) + template + inline void def_impl(char const* name, Fn fn, Policies const& policies + , char const* doc, ...) { objects::add_to_namespace( - *this, name, make_function( + *this, name, + make_function( // This bit of nastiness casts F to a member function of T if possible. - detail::member_function_cast::stage1(f).stage2((T*)0).stage3(f)) + detail::member_function_cast::stage1(fn).stage2((T*)0).stage3(fn) + , policies) , doc); } template - inline void def_impl(char const* name, F const& f, char const* doc, object const volatile*) + inline void def_impl(char const* name, F f, default_call_policies const& + , char const* doc, object const*) { objects::add_to_namespace(*this, name, f, doc); } - + private: // types typedef objects::class_id class_id; @@ -266,8 +273,8 @@ inline class_::class_() } template -inline class_::class_(char const* name) - : base(name, id_vector::size, id_vector().ids) +inline class_::class_(char const* name, char const* doc) + : base(name, id_vector::size, id_vector().ids, doc) { // register converters objects::register_class_from_python(); diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp index 4ef00cfd..218caccf 100644 --- a/include/boost/python/detail/module_base.hpp +++ b/include/boost/python/detail/module_base.hpp @@ -15,7 +15,7 @@ class BOOST_PYTHON_DECL module_base { public: // Create a module. REQUIRES: only one module is created per module. - module_base(const char* name); + module_base(char const* name, char const* doc = 0); ~module_base(); // Add elements to the module diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index a4d7a4db..af6434ce 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -13,6 +13,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -21,8 +22,8 @@ class module : public detail::module_base public: typedef detail::module_base base; - module(const char* name) - : base(name) {} + module(char const* name, char const* doc = 0) + : base(name, doc) {} // Add elements to the module template @@ -42,17 +43,22 @@ class module : public detail::module_base } template - module& def(char const* name, Fn fn, char const* doc = 0) + module& def(char const* name, Fn fn) { - this->setattr_doc(name, boost::python::make_function(fn), doc); + this->setattr_doc( + name, boost::python::make_function(fn), 0); + return *this; } - - - template - module& def(char const* name, Fn fn, ResultHandler handler, char const* doc = 0) + template + module& def(char const* name, Fn fn, CallPolicyOrDoc const& policy_or_doc, char const* doc = 0) { - this->setattr_doc(name, boost::python::make_function(fn, handler), doc); + 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; } }; diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index d6af07e1..44aa31f6 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -33,6 +33,7 @@ struct BOOST_PYTHON_DECL class_base : python::api::object , std::size_t num_types // A list of class_ids. The first is the type , class_id const*const types // this is wrapping. The rest are the types of // any bases. + , char const* doc = 0 // Docstring, if any. ); // Retrieve the underlying object diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index 1e5fdfe8..c14f57e3 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -34,6 +34,8 @@ struct BOOST_PYTHON_DECL function : PyObject object const& doc() const; void doc(object const& x); + object const& name() const; + private: // helper functions void argument_error(PyObject* args, PyObject* keywords) const; void add_overload(handle const&); @@ -43,6 +45,7 @@ struct BOOST_PYTHON_DECL function : PyObject unsigned m_min_args; unsigned m_max_args; handle m_overloads; + object m_name; object m_doc; }; @@ -59,6 +62,11 @@ inline void function::doc(object const& x) this->m_doc = x; } +inline object const& function::name() const +{ + return this->m_name; +} + }}} // namespace boost::python::objects #endif // FUNCTION_DWA20011214_HPP diff --git a/src/module.cpp b/src/module.cpp index 4563db31..549ba782 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -16,12 +16,14 @@ namespace boost { namespace python { namespace detail { -module_base::module_base(const char* name) +module_base::module_base(char const* name, char const* doc) : m_module( allow_null(python::borrowed( scope().ptr() ))) { + if (doc != 0) + scope().attr("__doc__") = doc; } module_base::~module_base() diff --git a/src/object/class.cpp b/src/object/class.cpp index 4306a684..83287125 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -279,7 +279,7 @@ namespace objects } class_base::class_base( - char const* name, std::size_t num_types, class_id const* const types) + char const* name, std::size_t num_types, class_id const* const types, char const* doc) : object(new_class(name, num_types, types)) { // Insert the new class object in the registry @@ -288,6 +288,9 @@ namespace objects // Class object is leaked, for now converters.class_object = (PyTypeObject*)incref(this->ptr()); + + if (doc) + this->attr("__doc__") = doc; } extern "C" diff --git a/src/object/function.cpp b/src/object/function.cpp index a09717fc..ec461383 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -24,6 +24,7 @@ function::function(py_function const& implementation, unsigned min_args, unsigne , m_max_args(std::max(max_args,min_args)) { PyObject* p = this; + ::PyType_Ready(&function_type); PyObject_INIT(p, &function_type); } @@ -162,6 +163,7 @@ void function::add_to_namespace( if (attribute.ptr()->ob_type == &function_type) { + function* new_func = downcast(attribute.ptr()); PyObject* dict = 0; if (PyClass_Check(ns)) @@ -180,17 +182,24 @@ void function::add_to_namespace( allow_null(downcast(::PyObject_GetItem(dict, name.ptr()))) ); - if (existing.get()) + if (existing) { if (existing->ob_type == &function_type) - static_cast(attribute.ptr())->add_overload(existing); + new_func->add_overload(existing); } - // Binary operators need an additional overload which returns NotImplemented else if (is_binary_operator(name_)) { - static_cast(attribute.ptr())->add_overload( - not_implemented_function()); + // Binary operators need an additional overload which + // returns NotImplemented, so that Python will try the + // lxxx functions on the other operand. We add this + // overload already when no overloads for the operator + // already exist. + new_func->add_overload(not_implemented_function()); } + + // A function is named the first time it is added to a namespace. + if (new_func->name().ptr() == Py_None) + new_func->m_name = name; } // The PyObject_GetAttrString() call above left an active error @@ -259,21 +268,38 @@ extern "C" return result; } + // + // Here we're using the function's tp_getset rather than its + // tp_members to set up __doc__ and __name__, because tp_members + // really depends on having a POD object type (it relies on + // offsets). It might make sense to reformulate function as a POD + // at some point, but this is much more expedient. + // static PyObject* function_get_doc(PyObject* op, void*) { function* f = downcast(op); - return incref(f->doc().ptr()); + return python::incref(f->doc().ptr()); } - static int function_set_doc(PyObject* op, PyObject* doc) + static int function_set_doc(PyObject* op, PyObject* doc, void*) { function* f = downcast(op); f->doc(doc ? object(python::detail::borrowed_reference(doc)) : object()); return 0; } + static PyObject* function_get_name(PyObject* op, void*) + { + function* f = downcast(op); + if (f->name().ptr() == Py_None) + return PyString_InternFromString(""); + else + return python::incref(f->name().ptr()); + } + static PyGetSetDef function_getsetlist[] = { - {"__doc__", function_get_doc, (setter)function_set_doc}, + {"__name__", function_get_name, 0 }, + {"__doc__", function_get_doc, function_set_doc}, {NULL} /* Sentinel */ }; } diff --git a/test/Jamfile b/test/Jamfile index 21be34fe..0752ddc2 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -55,6 +55,7 @@ rule bpl-test ( name ? : files * ) } bpl-test minimal ; +bpl-test docstring ; bpl-test pearu1 : test_cltree.py cltree.cpp ; bpl-test try : newtest.py m1.cpp m2.cpp ; bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ; diff --git a/test/docstring.cpp b/test/docstring.cpp new file mode 100644 index 00000000..e8f63971 --- /dev/null +++ b/test/docstring.cpp @@ -0,0 +1,61 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include +#include "test_class.hpp" + +// Just use math.h here; trying to use std::pow() causes too much +// trouble for non-conforming compilers and libraries. +#include + +using namespace boost::python; + +typedef test_class<> X; + +X* create(int x) +{ + return new X(x); +} + +unsigned long fact(unsigned long n) +{ + return n <= 1 ? n : n * fact(n - 1); +} + +BOOST_PYTHON_MODULE_INIT(docstring_ext) +{ + module("docstring_ext", + + "A simple test module for documentation strings\n" + "Exercised by docstring.py" + ) + + .add( + class_("X", + "A simple class wrapper around a C++ int\n" + "includes some error-checking" + ) + + .def_init(args(), + "this is the __init__ function\n" + "its documentation has two lines." + ) + + .def("value", &X::value, + "gets the value of the object") + ) + + .def("create", create, return_value_policy(), + "creates a new X object") + + .def("fact", fact, "compute the factorial") + ; +} + +#include "module_tail.cpp" diff --git a/test/docstring.py b/test/docstring.py new file mode 100644 index 00000000..54bbfc45 --- /dev/null +++ b/test/docstring.py @@ -0,0 +1,51 @@ +''' +>>> from docstring_ext import * + +>>> def printdoc(x): +... print x.__doc__ + +>>> printdoc(X) +A simple class wrapper around a C++ int +includes some error-checking + +>>> printdoc(X.__init__) +this is the __init__ function +its documentation has two lines. + +>>> printdoc(X.value) +gets the value of the object + +>>> printdoc(create) +creates a new X object + +>>> printdoc(fact) +compute the factorial +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + + import docstring_ext + + result = doctest.testmod(sys.modules.get(__name__)) + + try: + print 'printing module help:' + help(docstring_ext) + except object, x: + print '********* failed **********' + print x + result = list(result) + result[0] += 1 + return tuple(result) + + return result + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From a3102b552c488b0392b0ae77ac39d55445c52668 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 8 Aug 2002 05:52:30 +0000 Subject: [PATCH 0633/1042] Add casts to work around missing extern "C" in Python headers. [SVN r14735] --- src/object/function.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/object/function.cpp b/src/object/function.cpp index ec461383..eb842a65 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -298,8 +298,8 @@ extern "C" } static PyGetSetDef function_getsetlist[] = { - {"__name__", function_get_name, 0 }, - {"__doc__", function_get_doc, function_set_doc}, + {"__name__", (getter)function_get_name, 0 }, + {"__doc__", (getter)function_get_doc, (setter)function_set_doc}, {NULL} /* Sentinel */ }; } From cf15a99730e623a5e23ba1b1947129f63af75bad Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 8 Aug 2002 06:14:48 +0000 Subject: [PATCH 0634/1042] Repair type initialization problem [SVN r14736] --- src/object/function.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/object/function.cpp b/src/object/function.cpp index eb842a65..c2d36075 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -24,7 +24,11 @@ function::function(py_function const& implementation, unsigned min_args, unsigne , m_max_args(std::max(max_args,min_args)) { PyObject* p = this; - ::PyType_Ready(&function_type); + if (function_type.ob_type == 0) + { + function_type.ob_type = &PyType_Type; + ::PyType_Ready(&function_type); + } PyObject_INIT(p, &function_type); } @@ -305,7 +309,7 @@ extern "C" } PyTypeObject function_type = { - PyObject_HEAD_INIT(&PyType_Type) + PyObject_HEAD_INIT(0) 0, "Boost.Python.function", sizeof(function), From 2103e691dba0991e9bd9bcbd3aad6418fe30b1b4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 8 Aug 2002 15:45:58 +0000 Subject: [PATCH 0635/1042] initial commit [SVN r14738] --- include/boost/python/detail/def_helper.hpp | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 include/boost/python/detail/def_helper.hpp diff --git a/include/boost/python/detail/def_helper.hpp b/include/boost/python/detail/def_helper.hpp new file mode 100644 index 00000000..1222f71b --- /dev/null +++ b/include/boost/python/detail/def_helper.hpp @@ -0,0 +1,61 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef DEF_HELPER_DWA200287_HPP +# define DEF_HELPER_DWA200287_HPP + +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +// +// def_helper -- +// +// A helper for def() functions which determines how to interpret +// an argument of type T which could be either CallPolicies or a +// string literal representing a docstring. +// +// Generates two static functions: +// +// get_policy(x), where x is of type T, returns a policies +// object: either a reference to x or default_call_policies() +// if x is a string literal. +// +// get_doc(x, s), where s convertible to char const*, returns x +// if x is a string literal, s otherwise. + +template +struct def_helper_impl +{ + template + static P const& get_policy(P const& x) { return x; } + + template + static char const* get_doc(P const&, char const* doc) { return doc; } +}; + +template <> +struct def_helper_impl +{ + static python::default_call_policies get_policy(char const*) { return default_call_policies(); } + static char const* get_doc(char const* doc, char const*) { return doc; } +}; + +template +struct def_helper + : def_helper_impl< + type_traits::ice_or< + is_string_literal::value + , is_same::value + , is_same::value +>::value +> +{}; + +}}} // namespace boost::python::detail + +#endif // DEF_HELPER_DWA200287_HPP From 0a6a213891013a1da8c656cd6b30874a749c52c0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 13 Aug 2002 00:43:51 +0000 Subject: [PATCH 0636/1042] Added a test for add_property [SVN r14799] --- test/data_members.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/data_members.cpp b/test/data_members.cpp index e4eacf17..06148835 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -18,6 +18,8 @@ typedef test_class<> X; typedef test_class<1> Y; +double get_fair_value(X const& x) { return x.value(); } + BOOST_PYTHON_MODULE_INIT(data_members_ext) { module("data_members_ext") @@ -27,6 +29,7 @@ BOOST_PYTHON_MODULE_INIT(data_members_ext) .def("value", &X::value) .def("set", &X::set) .def_readonly("x", &X::x) + .add_property("get_fair_value", object(&get_fair_value)) ) .add( class_("Y") From fe3cf386c3d6b18128ec036525ebca47d86192fe Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 13 Aug 2002 00:45:09 +0000 Subject: [PATCH 0637/1042] Python->C++ exception translation [SVN r14800] --- .../boost/python/detail/exception_handler.hpp | 48 +++++++++++++++++++ .../python/detail/translate_exception.hpp | 46 ++++++++++++++++++ include/boost/python/errors.hpp | 2 +- include/boost/python/exception_translator.hpp | 25 ++++++++++ src/errors.cpp | 45 ++++++++++++++++- test/Jamfile | 1 + test/exception_translator.cpp | 25 ++++++++++ test/exception_translator.py | 22 +++++++++ 8 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 include/boost/python/detail/exception_handler.hpp create mode 100644 include/boost/python/detail/translate_exception.hpp create mode 100644 include/boost/python/exception_translator.hpp create mode 100644 test/exception_translator.cpp create mode 100644 test/exception_translator.py diff --git a/include/boost/python/detail/exception_handler.hpp b/include/boost/python/detail/exception_handler.hpp new file mode 100644 index 00000000..9a9aa4d2 --- /dev/null +++ b/include/boost/python/detail/exception_handler.hpp @@ -0,0 +1,48 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef EXCEPTION_HANDLER_DWA2002810_HPP +# define EXCEPTION_HANDLER_DWA2002810_HPP + +# include +# include + +namespace boost { namespace python { namespace detail { + +struct BOOST_PYTHON_DECL exception_handler; + +typedef function2 const&> handler_function; + +struct BOOST_PYTHON_DECL exception_handler +{ + private: // types + + public: + explicit exception_handler(handler_function const& impl); + + inline bool handle(function0 const& f) const; + + bool operator()(function0 const& f) const; + + static exception_handler* chain; + + private: + static exception_handler* tail; + + handler_function m_impl; + exception_handler* m_next; +}; + + +inline bool exception_handler::handle(function0 const& f) const +{ + return this->m_impl(*this, f); +} + +BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f); + +}}} // namespace boost::python::detail + +#endif // EXCEPTION_HANDLER_DWA2002810_HPP diff --git a/include/boost/python/detail/translate_exception.hpp b/include/boost/python/detail/translate_exception.hpp new file mode 100644 index 00000000..ea4d5056 --- /dev/null +++ b/include/boost/python/detail/translate_exception.hpp @@ -0,0 +1,46 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef TRANSLATE_EXCEPTION_DWA2002810_HPP +# define TRANSLATE_EXCEPTION_DWA2002810_HPP + +# include +# include + +namespace boost { namespace python { namespace detail { + +struct exception_handler; + +// A ternary function object used to translate C++ exceptions of type +// ExceptionType into Python exceptions by invoking an object of type +// Translate. Typically the translate function will be curried with +// boost::bind(). +template +struct translate_exception +{ + typedef typename add_reference< + typename add_const::type + >::type exception_cref; + + inline bool operator()( + exception_handler const& handler + , function0 const& f + , typename call_traits::param_type translate) const + { + try + { + return handler(f); + } + catch(exception_cref e) + { + translate(e); + return true; + } + } +}; + +}}} // namespace boost::python::detail + +#endif // TRANSLATE_EXCEPTION_DWA2002810_HPP diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp index 4c47aca8..390f3b61 100644 --- a/include/boost/python/errors.hpp +++ b/include/boost/python/errors.hpp @@ -20,7 +20,7 @@ struct BOOST_PYTHON_DECL argument_error : error_already_set {}; // Handles exceptions caught just before returning to Python code. // Returns true iff an exception was caught. -BOOST_PYTHON_DECL bool handle_exception_impl(function0); +BOOST_PYTHON_DECL bool handle_exception_impl(function0 const&); template bool handle_exception(T f) diff --git a/include/boost/python/exception_translator.hpp b/include/boost/python/exception_translator.hpp new file mode 100644 index 00000000..830d50d2 --- /dev/null +++ b/include/boost/python/exception_translator.hpp @@ -0,0 +1,25 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef EXCEPTION_TRANSLATOR_DWA2002810_HPP +# define EXCEPTION_TRANSLATOR_DWA2002810_HPP +# include +# include +# include +# include + +namespace boost { namespace python { + +template +void register_exception_translator(Translate const& translate, boost::type* = 0) +{ + detail::register_exception_handler( + bind(detail::translate_exception(), _1, _2, translate) + ); +} + +}} // namespace boost::python + +#endif // EXCEPTION_TRANSLATOR_DWA2002810_HPP diff --git a/src/errors.cpp b/src/errors.cpp index cd188cb6..882d2917 100644 --- a/src/errors.cpp +++ b/src/errors.cpp @@ -10,14 +10,21 @@ #include #include +#ifdef BOOST_PYTHON_V2 +# include +#endif namespace boost { namespace python { // IMPORTANT: this function may only be called from within a catch block! -BOOST_PYTHON_DECL bool handle_exception_impl(function0 f) +BOOST_PYTHON_DECL bool handle_exception_impl(function0 const& f) { try { +#ifdef BOOST_PYTHON_V2 + if (detail::exception_handler::chain) + return detail::exception_handler::chain->handle(f); +#endif f(); return false; } @@ -68,6 +75,42 @@ namespace detail { // needed by void_adaptor (see void_adaptor.hpp) BOOST_PYTHON_DECL PyObject arbitrary_object = { 0 }; +#ifdef BOOST_PYTHON_V2 +bool exception_handler::operator()(function0 const& f) const +{ + if (m_next) + { + return m_next->handle(f); + } + else + { + f(); + return false; + } +} + +exception_handler::exception_handler(handler_function const& impl) + : m_impl(impl) + , m_next(0) +{ + if (chain != 0) + tail->m_next = this; + else + chain = this; + tail = this; +} + +exception_handler* exception_handler::chain; +exception_handler* exception_handler::tail; + +BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f) +{ + // the constructor links the new object into a handler chain, so + // this object isn't actaully leaked (until, of course, the + // interpreter exits). + new exception_handler(f); +} +#endif } // namespace boost::python::detail diff --git a/test/Jamfile b/test/Jamfile index 0752ddc2..eb5254d2 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -56,6 +56,7 @@ rule bpl-test ( name ? : files * ) bpl-test minimal ; bpl-test docstring ; +bpl-test exception_translator ; bpl-test pearu1 : test_cltree.py cltree.cpp ; bpl-test try : newtest.py m1.cpp m2.cpp ; bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ; diff --git a/test/exception_translator.cpp b/test/exception_translator.cpp new file mode 100644 index 00000000..58512ef2 --- /dev/null +++ b/test/exception_translator.cpp @@ -0,0 +1,25 @@ +#include +#include + +struct error {}; + +void translate(error const& e) +{ + PyErr_SetString(PyExc_RuntimeError, "!!!error!!!"); +} + +void throw_error() +{ + throw error(); + +} + +BOOST_PYTHON_MODULE_INIT(exception_translator_ext) +{ + using namespace boost::python; + + register_exception_translator(&translate); + module("exception_translator_ext") + .def("throw_error", throw_error); +} + diff --git a/test/exception_translator.py b/test/exception_translator.py new file mode 100644 index 00000000..78fe3507 --- /dev/null +++ b/test/exception_translator.py @@ -0,0 +1,22 @@ +''' +>>> from exception_translator_ext import * +>>> try: +... throw_error(); +... except RuntimeError, x: +... print x +... else: +... print 'Expected a RuntimeError!' +!!!error!!! +''' +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From e6830b2c19e5f4e3bd7b5119f4166479a524494e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 13 Aug 2002 03:06:00 +0000 Subject: [PATCH 0638/1042] Add dependency on test_exec_monitor [SVN r14801] --- test/Jamfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/Jamfile b/test/Jamfile index eb5254d2..0984a8b8 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -96,7 +96,8 @@ if $(TEST_BIENSTMAN_NON_BUGS) # --- unit tests of library components --- -local UNIT_TEST_PROPERTIES = [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] BOOST_PYTHON_STATIC_LIB ; +local UNIT_TEST_PROPERTIES = ../../test/build/test_exec_monitor + [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] BOOST_PYTHON_STATIC_LIB ; run indirect_traits_test.cpp ; run destroy_test.cpp ; @@ -120,7 +121,7 @@ run upcast.cpp run select_holder.cpp : # command-line args : # input files - : $(UNIT_TEST_PROPERTIES) + : $(UNIT_TEST_PROPERTIES) ; From f7b1e4ec09fafa38af8a9e830174cd0e356d70df Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 13 Aug 2002 04:25:23 +0000 Subject: [PATCH 0639/1042] Unit test adjustments [SVN r14802] --- test/Jamfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/Jamfile b/test/Jamfile index 0984a8b8..ef4fd7a1 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -96,12 +96,12 @@ if $(TEST_BIENSTMAN_NON_BUGS) # --- unit tests of library components --- -local UNIT_TEST_PROPERTIES = ../../test/build/test_exec_monitor +local UNIT_TEST_PROPERTIES = [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] BOOST_PYTHON_STATIC_LIB ; run indirect_traits_test.cpp ; run destroy_test.cpp ; -run pointer_type_id_test.cpp : : : $(UNIT_TEST_PROPERTIES) ; +run pointer_type_id_test.cpp ../../test/build/test_exec_monitor : : : $(UNIT_TEST_PROPERTIES) ; run member_function_cast.cpp ; run bases.cpp ; run if_else.cpp ; @@ -112,26 +112,26 @@ compile string_literal.cpp ; compile borrowed.cpp : $(UNIT_TEST_PROPERTIES) ; compile object_manager.cpp : $(UNIT_TEST_PROPERTIES) ; -run upcast.cpp +run upcast.cpp ../../test/build/test_exec_monitor : # command-line args : # input files : $(UNIT_TEST_PROPERTIES) ; -run select_holder.cpp +run select_holder.cpp ../../test/build/test_exec_monitor : # command-line args : # input files : $(UNIT_TEST_PROPERTIES) ; -run select_from_python_test.cpp ../src/converter/type_id.cpp +run select_from_python_test.cpp ../src/converter/type_id.cpp ../../test/build/test_exec_monitor : # command-line args : # input files : $(UNIT_TEST_PROPERTIES) ; -run select_arg_to_python_test.cpp ../src/converter/type_id.cpp +run select_arg_to_python_test.cpp ../src/converter/type_id.cpp ../../test/build/test_exec_monitor : # command-line args : # input files : $(UNIT_TEST_PROPERTIES) From c5ee39f54be667c5bf00dac08c12995f81b04c8f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 13 Aug 2002 05:07:50 +0000 Subject: [PATCH 0640/1042] Bug fix [SVN r14803] --- include/boost/python/errors.hpp | 2 +- src/errors.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp index 390f3b61..4c47aca8 100644 --- a/include/boost/python/errors.hpp +++ b/include/boost/python/errors.hpp @@ -20,7 +20,7 @@ struct BOOST_PYTHON_DECL argument_error : error_already_set {}; // Handles exceptions caught just before returning to Python code. // Returns true iff an exception was caught. -BOOST_PYTHON_DECL bool handle_exception_impl(function0 const&); +BOOST_PYTHON_DECL bool handle_exception_impl(function0); template bool handle_exception(T f) diff --git a/src/errors.cpp b/src/errors.cpp index 882d2917..05e40658 100644 --- a/src/errors.cpp +++ b/src/errors.cpp @@ -17,7 +17,7 @@ namespace boost { namespace python { // IMPORTANT: this function may only be called from within a catch block! -BOOST_PYTHON_DECL bool handle_exception_impl(function0 const& f) +BOOST_PYTHON_DECL bool handle_exception_impl(function0 f) { try { From 6e06ff048d2b8d6fff93194a81ed94d0d6bc947a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Aug 2002 06:26:33 +0000 Subject: [PATCH 0641/1042] Automatic class def_init(), abstract class __init__ errors Fixed line endings Suppressed warnings [SVN r14828] --- include/boost/python/args.hpp | 16 +- include/boost/python/class.hpp | 145 +++++--- include/boost/python/detail/defaults_def.hpp | 172 ++++++++++ include/boost/python/detail/defaults_gen.hpp | 320 ++++++++++++++++++ .../python/detail/translate_exception.hpp | 3 +- include/boost/python/object/class.hpp | 1 + include/boost/python/object/iterator.hpp | 2 +- include/boost/python/signature.hpp | 266 +++++++++++++++ src/object/class.cpp | 20 ++ src/object/function.cpp | 5 +- test/back_reference.cpp | 6 +- test/bienstman1.cpp | 2 +- test/bienstman3.cpp | 5 +- test/bienstman3.py | 10 + test/bienstman4.cpp | 7 +- test/callbacks.cpp | 3 +- test/data_members.cpp | 6 +- test/defaults.py | 90 +++++ test/docstring.cpp | 8 +- test/extract.cpp | 15 +- test/implicit.cpp | 3 +- test/iterator.cpp | 3 - test/list.cpp | 3 +- test/m1.cpp | 8 +- test/multi_arg_constructor.cpp | 9 +- test/operators.cpp | 6 +- test/pickle1.cpp | 4 +- test/pickle2.cpp | 4 +- test/pickle3.cpp | 4 +- test/test_pointer_adoption.cpp | 5 +- test/virtual_functions.cpp | 9 +- 31 files changed, 1045 insertions(+), 115 deletions(-) create mode 100644 include/boost/python/detail/defaults_def.hpp create mode 100644 include/boost/python/detail/defaults_gen.hpp create mode 100644 include/boost/python/signature.hpp create mode 100644 test/defaults.py diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index d3b7c5d9..841d70d2 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -16,13 +16,25 @@ # include # include +namespace boost { namespace python { + +enum no_init_t { no_init }; + +namespace detail +{ + template + struct args_base {}; +} +}} + # if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245 namespace boost { namespace python { // A type list for specifying arguments template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, boost::mpl::null_argument) > -struct args : boost::mpl::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A) >::type +struct args : detail::args_base > + , boost::mpl::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A) >::type {}; }} // namespace boost::python @@ -36,7 +48,7 @@ struct args : boost::mpl::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_AR namespace boost { namespace python { template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, boost::mpl::null_argument) > -struct args +struct args : detail::args_base > {}; }} // namespace boost::python diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 4af8d3e7..f56bc7b1 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -28,6 +28,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -58,7 +59,9 @@ namespace detail template static inline void register_copy_constructor(mpl::bool_t const&, Holder*, object const&, T* = 0) { - } + } + + template int assert_default_constructible(T const&); } // @@ -75,7 +78,8 @@ template < > class class_ : public objects::class_base { - typedef objects::class_base base; + private: // types + typedef objects::class_base base; typedef class_ self; BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable::value)); @@ -86,17 +90,67 @@ class class_ : public objects::class_base 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 + { + typedef objects::class_id class_id; + id_vector() + { + // 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]; + }; + friend struct id_vector; + public: // Automatically derive the class name - only works on some // compilers because type_info::name is sometimes mangled (gcc) - class_(); + class_(); // With default-constructor init function + class_(no_init_t); // With no init function - // Construct with the class name. [ Would have used a default - // argument but gcc-2.95.2 choked on typeid(T).name() as a default - // parameter value] + // 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); + template + inline class_(char const* name, detail::args_base const&) + : base(name, id_vector::size, id_vector().ids) + { + 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) + { + 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. @@ -224,46 +278,17 @@ class class_ : public objects::class_base objects::add_to_namespace(*this, name, f, doc); } - private: // types - 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 - { - typedef objects::class_id class_id; - id_vector() - { - // 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]; - }; - friend struct id_vector; + inline void register_() const; }; // // implementations // + // register converters template -inline class_::class_() - : base(typeid(T).name(), id_vector::size, id_vector().ids) +inline void class_::register_() const { - // register converters objects::register_class_from_python(); detail::register_copy_constructor( @@ -272,19 +297,49 @@ inline class_::class_() , *this); } + + +template +inline class_::class_() + : base(typeid(T).name(), id_vector::size, id_vector().ids) +{ + this->register_(); + detail::force_instantiate(sizeof(detail::assert_default_constructible(T()))); + this->def_init(); +} + +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) { - // register converters - objects::register_class_from_python(); - - detail::register_copy_constructor( - mpl::bool_t() - , objects::select_holder((held_type*)0).get() - , *this); + this->register_(); + detail::force_instantiate(sizeof(detail::assert_default_constructible(T()))); + this->def_init(); } +template +inline class_::class_(char const* name, no_init_t) + : base(name, id_vector::size, id_vector().ids) +{ + this->register_(); + this->def_no_init(); +} + +template +inline class_::class_(char const* name, char const* doc, no_init_t) + : base(name, id_vector::size, id_vector().ids, doc) +{ + this->register_(); + this->def_no_init(); +} template inline class_& class_::add_property(char const* name, object const& fget) diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp new file mode 100644 index 00000000..44a1939b --- /dev/null +++ b/include/boost/python/detail/defaults_def.hpp @@ -0,0 +1,172 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef DEFAULTS_DEF_JDG20020811_HPP +#define DEFAULTS_DEF_JDG20020811_HPP + +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +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: function name that will be visible to python +// 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) +// 5. char const* name: doc string +// +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_STUB_FUNC_DEF(INDEX, DATA) \ + \ + template \ + inline void \ + define_stub_function \ + ( \ + char const* name, \ + StubsT, \ + HolderT& holder, \ + boost::mpl::int_t, \ + char const* doc \ + ) \ + { \ + holder.def( \ + name, \ + &StubsT::BOOST_PP_CAT(func_, INDEX), \ + default_call_policies(), \ + doc); \ + } \ + +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 expects: +// +// 1. char const* name: function name that will be visible to python +// 2. StubsT: a function stubs struct (see defaults_gen.hpp) +// 3. HolderT& holder: a python::class_ or python::module instance +// 4. char const* name: doc string +// +// 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 { + + template + static void + def(char const* name, StubsT stubs, HolderT& holder, char const* doc) + { + // define the NTH stub function of stubs + define_stub_function(name, stubs, holder, boost::mpl::int_t(), doc); + // call the next define_with_defaults_helper + define_with_defaults_helper::def(name, stubs, holder, doc); + } + }; + +/////////////////////////////////////// + template <> + struct define_with_defaults_helper<0> { + + template + static void + def(char const* name, StubsT stubs, HolderT& holder, char const* doc) + { + // define the Oth stub function of stubs + define_stub_function(name, stubs, holder, boost::mpl::int_t<0>(), doc); + // return + } + }; + +/////////////////////////////////////////////////////////////////////////////// +// +// define_with_defaults +// +// 1. char const* name: function name that will be visible to python +// 2. StubsT: a function stubs struct (see defaults_gen.hpp) +// 3. HolderT& holder: a python::class_ or python::module instance +// 4. SigT sig: Function signature typelist (see defaults_gen.hpp) +// 5. char const* name: doc string +// +// This is the main entry point. This function recursively defines all +// stub functions of StubT (see defaults_gen.hpp) in HolderT holder which +// can be either a python::class_ or a python::module. The sig argument +// is a typelist that specifies the return type, the class (for member +// functions, and the arguments. Here are some SigT examples: +// +// int foo(int) mpl::type_list +// void bar(int, int) mpl::type_list +// void C::foo(int) mpl::type_list +// +/////////////////////////////////////////////////////////////////////////////// + template + inline void + define_with_defaults( + char const* name, + StubsT, + HolderT& holder, + SigT sig, + char const* doc) + { + typedef typename mpl::select_type + < + boost::is_same::type>::value, + typename StubsT::v_type, + typename StubsT::nv_type + > + ::type stubs_type; + + BOOST_STATIC_ASSERT( + (stubs_type::max_args + 1) <= boost::mpl::size::value); + + typedef stubs_type::template gen gen_type; + define_with_defaults_helper::def + (name, gen_type(), holder, doc); + } + +} // namespace detail + +}} // namespace boost::python + +/////////////////////////////////////////////////////////////////////////////// +#endif // DEFAULTS_DEF_JDG20020811_HPP + + diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp new file mode 100644 index 00000000..0f580d94 --- /dev/null +++ b/include/boost/python/detail/defaults_gen.hpp @@ -0,0 +1,320 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef DEFAULTS_GEN_JDG20020807_HPP +#define DEFAULTS_GEN_JDG20020807_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 { + + typedef DerivedT derived_t; + + DerivedT& derived() + { return *static_cast(this); } + + DerivedT const& derived() const + { return *static_cast(this); } +}; + +}}} // namespace boost::python::detail + +/////////////////////////////////////////////////////////////////////////////// +// Temporary BOOST_PP fix before the CVS stabalizes /*$$$ FIX ME $$$*/ + +#ifndef BOOST_PP_FIX_REPEAT_2ND +#define BOOST_PP_FIX_REPEAT_2ND(c, m, d) /* ... */ \ + BOOST_PP_CAT(BOOST_PP_R2_, c)(m, d) \ + /**/ +#endif + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_TYPEDEF_GEN(INDEX, DATA) \ + typedef typename boost::mpl::at \ + < \ + BOOST_PP_ADD(INDEX, DATA), \ + SigT \ + >::type BOOST_PP_CAT(T, INDEX); \ + +#define BPL_IMPL_ARGS_GEN(INDEX, DATA) \ + BOOST_PP_CAT(T, INDEX) BOOST_PP_CAT(arg, INDEX) \ + +#define BPL_IMPL_FUNC_WRAPPER_GEN(INDEX, DATA) \ + static RT BOOST_PP_CAT(func_, INDEX) \ + ( \ + BOOST_PP_ENUM \ + ( \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ + BPL_IMPL_ARGS_GEN, \ + BOOST_PP_EMPTY \ + ) \ + ) \ + { \ + BOOST_PP_TUPLE_ELEM(3, 2, DATA) \ + BOOST_PP_TUPLE_ELEM(3, 0, DATA) \ + ( \ + BOOST_PP_ENUM_PARAMS \ + ( \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ + arg \ + ) \ + ); \ + } \ + +#define BPL_IMPL_GEN_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); \ + \ + template \ + struct gen { \ + \ + typedef typename boost::mpl::at<0, SigT>::type RT; \ + \ + BOOST_PP_FIX_REPEAT_2ND \ + ( \ + BOOST_PP_INC(N_DFLTS), \ + BPL_IMPL_TYPEDEF_GEN, \ + 1 \ + ) \ + \ + BOOST_PP_FIX_REPEAT_2ND \ + ( \ + BOOST_PP_INC(N_DFLTS), \ + BPL_IMPL_FUNC_WRAPPER_GEN, \ + (FNAME, BOOST_PP_SUB(N_ARGS, N_DFLTS), RETURN) \ + ) \ + }; \ + }; \ + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_MEM_FUNC_WRAPPER_GEN(INDEX, DATA) \ + static RT BOOST_PP_CAT(func_, INDEX) \ + ( \ + ClassT& obj, \ + BOOST_PP_ENUM \ + ( \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ + BPL_IMPL_ARGS_GEN, \ + BOOST_PP_EMPTY \ + ) \ + ) \ + { \ + BOOST_PP_TUPLE_ELEM(3, 2, DATA) obj. \ + BOOST_PP_TUPLE_ELEM(3, 0, DATA) \ + ( \ + BOOST_PP_ENUM_PARAMS \ + ( \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), 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::at<0, SigT>::type RT; \ + typedef typename boost::mpl::at<1, SigT>::type ClassT; \ + \ + BOOST_PP_FIX_REPEAT_2ND \ + ( \ + BOOST_PP_INC(N_DFLTS), \ + BPL_IMPL_TYPEDEF_GEN, \ + 2 \ + ) \ + \ + BOOST_PP_FIX_REPEAT_2ND \ + ( \ + BOOST_PP_INC(N_DFLTS), \ + BPL_IMPL_MEM_FUNC_WRAPPER_GEN, \ + (FNAME, BOOST_PP_SUB(N_ARGS, N_DFLTS), RETURN) \ + ) \ + }; \ + }; \ + \ + +/////////////////////////////////////////////////////////////////////////////// +#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 \ + : 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; \ + }; \ + +/////////////////////////////////////////////////////////////////////////////// +#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 \ + : 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; \ + }; \ + +#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 \ + : 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; \ + }; \ + +/////////////////////////////////////////////////////////////////////////////// +#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 \ + : 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; \ + }; \ + +#endif // defined(BOOST_MSVC) + +/////////////////////////////////////////////////////////////////////////////// +// +// 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; +// +// 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_GENERATOR(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\ + BPL_IMPL_GEN_FUNCTION_STUB \ + ( \ + FNAME, \ + GENERATOR_NAME, \ + MAX_ARGS, \ + BOOST_PP_SUB(MAX_ARGS, MIN_ARGS) \ + ) \ + +#define BOOST_PYTHON_MEM_FUN_GENERATOR(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\ + BPL_IMPL_GEN_MEM_FUNCTION_STUB \ + ( \ + FNAME, \ + GENERATOR_NAME, \ + MAX_ARGS, \ + BOOST_PP_SUB(MAX_ARGS, MIN_ARGS) \ + ) \ + +/////////////////////////////////////////////////////////////////////////////// +#endif // DEFAULTS_GEN_JDG20020807_HPP + + diff --git a/include/boost/python/detail/translate_exception.hpp b/include/boost/python/detail/translate_exception.hpp index ea4d5056..aa617a2a 100644 --- a/include/boost/python/detail/translate_exception.hpp +++ b/include/boost/python/detail/translate_exception.hpp @@ -6,13 +6,12 @@ #ifndef TRANSLATE_EXCEPTION_DWA2002810_HPP # define TRANSLATE_EXCEPTION_DWA2002810_HPP +# include # include # include namespace boost { namespace python { namespace detail { -struct exception_handler; - // A ternary function object used to translate C++ exceptions of type // ExceptionType into Python exceptions by invoking an object of type // Translate. Typically the translate function will be curried with diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 44aa31f6..cd7c25f4 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -41,6 +41,7 @@ struct BOOST_PYTHON_DECL class_base : python::api::object void add_property(char const* name, object const& fget, object const& fset); void setattr(char const* name, object const&); void enable_pickling(bool getstate_manages_dict); + void def_no_init(); }; BOOST_PYTHON_DECL type_handle registered_class_object(class_id id); diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 13862e6f..b41ba621 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -131,7 +131,7 @@ namespace detail bind(&detail::iterator_next::execute, _1, _2, policies) , 1); - return class_(name) + return class_(name, no_init) .def("__iter__", identity_function()) .setattr("next", next_function) ; diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp new file mode 100644 index 00000000..d83071a1 --- /dev/null +++ b/include/boost/python/signature.hpp @@ -0,0 +1,266 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef SIGNATURE_JDG20020813_HPP +#define SIGNATURE_JDG20020813_HPP + +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace python { + +/////////////////////////////////////////////////////////////////////////////// +// +// signature +// +// This template struct acts as a type holder for the signature of a +// function or member function. This struct is used to pass in the +// return type, class (for member functions) and arguments of a +// function or member function. Examples: +// +// signature int foo(int) +// signature void foo(int, int) +// signature void C::foo(int, int) +// signature void C::foo(int, int) const +// +/////////////////////////////////////////////////////////////////////////////// +template +struct signature {}; + +namespace detail { + +/////////////////////////////////////////////////////////////////////////////// +// Temporary BOOST_PP fix before the CVS stabalizes /*$$$ FIX ME $$$*/ + +#ifndef BOOST_PP_FIX_REPEAT_2ND +#define BOOST_PP_FIX_REPEAT_2ND(c, m, d) /* ... */ \ + BOOST_PP_CAT(BOOST_PP_R2_, c)(m, d) \ + /**/ +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// The following macros generate expansions for: +// +// template +// inline boost::mpl::type_list +// get_signature(signature) +// { +// return boost::mpl::type_list(); +// } +// +// template +// inline boost::mpl::type_list +// get_signature(RT(*)(T0...TN)) +// { +// return boost::mpl::type_list(); +// } +// +// template +// inline boost::mpl::type_list +// get_signature(signature) +// { +// return boost::mpl::type_list(); +// } +// +// template +// inline boost::mpl::type_list +// get_signature(signature) +// { +// return boost::mpl::type_list(); +// } +// +// template +// inline boost::mpl::type_list +// get_signature(RT(ClassT::*)(T0...TN))) +// { +// return boost::mpl::type_list(); +// } +// +// template +// inline boost::mpl::type_list +// get_signature(RT(ClassT::*)(T0...TN) const)) +// { +// return boost::mpl::type_list(); +// } +// +// These functions extract the return type, class (for member functions) +// and arguments of the input signature and stuffs them in an mpl::type_list. +// +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_TEMPLATE_GEN(INDEX, DATA) typename BOOST_PP_CAT(T, INDEX) + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_GET_FUNCTION_SIGNATURE(INDEX, DATA) \ + \ + template \ + < \ + typename RT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature(signature) \ + { \ + return boost::mpl::type_list \ + (); \ + } \ + \ + template \ + < \ + typename RT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature(RT(*)(BOOST_PP_ENUM_PARAMS(INDEX, T))) \ + { \ + return boost::mpl::type_list \ + (); \ + } \ + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_GET_MEMBER_FUNCTION_SIGNATURE(INDEX, DATA) \ + \ + template \ + < \ + typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature(signature) \ + { \ + return boost::mpl::type_list \ + \ + (); \ + } \ + \ + \ + template \ + < \ + typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature( \ + signature) \ + { \ + return boost::mpl::type_list \ + < \ + RT, ClassT const \ + BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + >(); \ + } \ + \ + template \ + < \ + typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(INDEX, T))) \ + { \ + return boost::mpl::type_list \ + \ + (); \ + } \ + \ + template \ + < \ + typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ + BOOST_PP_ENUM \ + ( \ + INDEX, \ + BPL_IMPL_TEMPLATE_GEN, \ + BOOST_PP_EMPTY \ + ) \ + > \ + inline boost::mpl::type_list \ + < \ + RT, ClassT const \ + BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + > \ + get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(INDEX, T)) const) \ + { \ + return boost::mpl::type_list \ + < \ + RT, ClassT const \ + BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ + >(); \ + } \ + +/////////////////////////////////////////////////////////////////////////////// + +BOOST_PP_FIX_REPEAT_2ND \ +( \ + BOOST_PP_SUB(BOOST_PYTHON_MAX_ARITY, 1), \ + BPL_IMPL_GET_FUNCTION_SIGNATURE, BOOST_PP_EMPTY \ +) + +BOOST_PP_FIX_REPEAT_2ND \ +( \ + BOOST_PP_SUB(BOOST_PYTHON_MAX_ARITY, 2), \ + BPL_IMPL_GET_MEMBER_FUNCTION_SIGNATURE, BOOST_PP_EMPTY \ +) + +#undef BPL_IMPL_GET_FUNCTION_SIGNATURE +#undef BPL_IMPL_GET_MEMBER_FUNCTION_SIGNATURE +#undef BPL_IMPL_TEMPLATE_GEN + +} + +}} // namespace boost::python + +/////////////////////////////////////////////////////////////////////////////// +#endif // SIGNATURE_JDG20020813_HPP + + diff --git a/src/object/class.cpp b/src/object/class.cpp index 83287125..c6420a76 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -323,6 +323,26 @@ namespace objects throw_error_already_set(); } + namespace + { + extern "C" PyObject* no_init(PyObject*, PyObject*) + { + ::PyErr_SetString(::PyExc_RuntimeError, "This class cannot be instantiated from Python"); + return NULL; + } + static ::PyMethodDef no_init_def = { + "__init__", no_init, METH_VARARGS, + "Raises an exception\n" + "This class cannot be instantiated from Python\n" + }; + } + + void class_base::def_no_init() + { + handle<> f(::PyCFunction_New(&no_init_def, 0)); + this->setattr("__init__", object(f)); + } + void class_base::enable_pickling(bool getstate_manages_dict) { setattr("__reduce__", object(make_instance_reduce_function())); diff --git a/src/object/function.cpp b/src/object/function.cpp index c2d36075..187becc9 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -195,9 +195,8 @@ void function::add_to_namespace( { // Binary operators need an additional overload which // returns NotImplemented, so that Python will try the - // lxxx functions on the other operand. We add this - // overload already when no overloads for the operator - // already exist. + // lxxx functions on the other operand. We add this when + // no overloads for the operator already exist. new_func->add_overload(not_implemented_function()); } diff --git a/test/back_reference.cpp b/test/back_reference.cpp index 39f9127e..22477646 100644 --- a/test/back_reference.cpp +++ b/test/back_reference.cpp @@ -93,15 +93,13 @@ BOOST_PYTHON_MODULE_INIT(back_reference_ext) .def("copy_Z", copy_Z, return_value_policy()) .def("x_instances", &X::count) .add( - class_("Y") - .def_init(args()) + class_("Y", args()) .def("value", &Y::value) .def("set", &Y::set) ) .add( - class_ >("Z") - .def_init(args()) + class_ >("Z", args()) .def("value", &Z::value) .def("set", &Z::set) ) diff --git a/test/bienstman1.cpp b/test/bienstman1.cpp index ab184b22..e6d5e42f 100644 --- a/test/bienstman1.cpp +++ b/test/bienstman1.cpp @@ -30,7 +30,7 @@ BOOST_PYTHON_MODULE_INIT(bienstman1_ext) .add(class_ >("A")) .add( - class_("V") + class_("V", no_init) .def("inside", &V::inside, return_value_policy()) .def("outside", outside, diff --git a/test/bienstman3.cpp b/test/bienstman3.cpp index eb2bb30a..494965a2 100644 --- a/test/bienstman3.cpp +++ b/test/bienstman3.cpp @@ -19,12 +19,11 @@ BOOST_PYTHON_MODULE_INIT(bienstman3_ext) m .add( - class_("V") + class_("V", no_init) ) .add( - class_("B") - .def_init(args()) + class_("B", args()) ) ; } diff --git a/test/bienstman3.py b/test/bienstman3.py index 8a14c8ff..90efdd53 100644 --- a/test/bienstman3.py +++ b/test/bienstman3.py @@ -1,5 +1,15 @@ ''' >>> from bienstman3_ext import * + +>>> try: +... V() +... except RuntimeError, x: +... print x +... else: +... print 'expected an exception' +... +This class cannot be instantiated from Python + ''' def run(args = None): import sys diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp index 29e971d8..b44b4bf8 100644 --- a/test/bienstman4.cpp +++ b/test/bienstman4.cpp @@ -7,7 +7,6 @@ #include #include #include -#include struct Type1 {}; @@ -24,12 +23,10 @@ BOOST_PYTHON_MODULE_INIT(bienstman4_ext) module("bienstman4_ext") .add(class_("Expression") - .def_init() .def("add", &Expression::add)) .add(class_("T1") - .def_init()) - .add(class_("Term") - .def_init(type_list())) + .add(class_("Term" + , args())) ; diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 6e916367..230d1a3e 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -137,8 +137,7 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) .def("apply_to_string_literal", apply_to_string_literal) .add( - class_("X") - .def_init(args()) + class_("X", args()) .def_init(args()) .def("value", &X::value) .def("set", &X::set) diff --git a/test/data_members.cpp b/test/data_members.cpp index 06148835..30c8d22f 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -24,16 +24,14 @@ BOOST_PYTHON_MODULE_INIT(data_members_ext) { module("data_members_ext") .add( - class_("X") - .def_init(args()) + class_("X", args()) .def("value", &X::value) .def("set", &X::set) .def_readonly("x", &X::x) .add_property("get_fair_value", object(&get_fair_value)) ) .add( - class_("Y") - .def_init(args()) + class_("Y", args()) .def("value", &Y::value) .def("set", &Y::set) .def_readwrite("x", &Y::x) diff --git a/test/defaults.py b/test/defaults.py new file mode 100644 index 00000000..b72cea4f --- /dev/null +++ b/test/defaults.py @@ -0,0 +1,90 @@ +""" + +>>> from defaults_ext import * +>>> bar(1) +'int(1); char(D); string(default); double(0.0); ' +>>> bar(2, 'X') +'int(2); char(X); string(default); double(0.0); ' +>>> bar(3, 'Y', "Hello World") +'int(3); char(Y); string(Hello World); double(0.0); ' +>>> bar(4, 'Z', "Hi There", 3.3) +'int(4); char(Z); string(Hi There); double(3.3); ' +>>> foo(1) +'int(1); char(D); string(default); double(0.0); ' +>>> foo(2, 'X') +'int(2); char(X); string(default); double(0.0); ' +>>> foo(3, 'Y', "Hello World") +'int(3); char(Y); string(Hello World); double(0.0); ' +>>> foo(4, 'Z', "Hi There", 3.3) +'int(4); char(Z); string(Hi There); double(3.3); ' +>>> x = X() +>>> x.bar(1) +'int(1); char(D); string(default); double(0.0); ' +>>> x.bar(2, 'X') +'int(2); char(X); string(default); double(0.0); ' +>>> x.bar(3, 'Y', "Hello World") +'int(3); char(Y); string(Hello World); double(0.0); ' +>>> x.bar(4, 'Z', "Hi There", 3.3) +'int(4); char(Z); string(Hi There); double(3.3); ' +>>> + + + +""" +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/docstring.cpp b/test/docstring.cpp index e8f63971..9642c636 100644 --- a/test/docstring.cpp +++ b/test/docstring.cpp @@ -40,12 +40,12 @@ BOOST_PYTHON_MODULE_INIT(docstring_ext) class_("X", "A simple class wrapper around a C++ int\n" "includes some error-checking" - ) - - .def_init(args(), + + , args(), "this is the __init__ function\n" "its documentation has two lines." - ) + + ) .def("value", &X::value, "gets the value of the object") diff --git a/test/extract.cpp b/test/extract.cpp index ae9b5c17..aec75308 100644 --- a/test/extract.cpp +++ b/test/extract.cpp @@ -47,7 +47,19 @@ std::string extract_string(object x) std::string const& extract_string_cref(object x) { +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 +# pragma warning(push) +# pragma warning(disable:4172) // msvc lies about returning a reference to temporary +#elif defined(_MSC_VER) && defined(__ICL) && __ICL <= 600 +# pragma warning(push) +# pragma warning(disable:473) // intel/win32 does too +#endif + return extract(x); + +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 600 +# pragma warning(pop) +#endif } X extract_X(object x) @@ -87,10 +99,9 @@ BOOST_PYTHON_MODULE_INIT(extract_ext) { implicitly_convertible(); - class_ x_class("X"); + class_ x_class("X", args()); x_class - .def_init(args()) .def( "__repr__", x_rep) ; diff --git a/test/implicit.cpp b/test/implicit.cpp index 50479158..ca250b9e 100644 --- a/test/implicit.cpp +++ b/test/implicit.cpp @@ -26,8 +26,7 @@ BOOST_PYTHON_MODULE_INIT(implicit_ext) .def("x_value", x_value) .def("make_x", make_x) .add( - class_("X") - .def_init(args()) + class_("X", args()) .def("value", &X::value) .def("set", &X::set) ) diff --git a/test/iterator.cpp b/test/iterator.cpp index aeb35648..c5ce6f32 100644 --- a/test/iterator.cpp +++ b/test/iterator.cpp @@ -76,7 +76,6 @@ BOOST_PYTHON_MODULE_INIT(iterator_ext) .def("range", &::range) .add( class_("list_int") - .def_init() .def("push_back", push_back) .def("back", back) .def("__iter__", iterator()) @@ -90,7 +89,6 @@ BOOST_PYTHON_MODULE_INIT(iterator_ext) ) .add( class_("two_lists") - .def_init() // We can spcify member functions .add_property( @@ -118,7 +116,6 @@ BOOST_PYTHON_MODULE_INIT(iterator_ext) ) .add( class_("list_list") - .def_init() .def("push_back", push_list_back) .def("__iter__", iterator >()) ) diff --git a/test/list.cpp b/test/list.cpp index 7b0d2645..2e6c2ee7 100644 --- a/test/list.cpp +++ b/test/list.cpp @@ -138,8 +138,7 @@ BOOST_PYTHON_MODULE_INIT(list_ext) .def("exercise", exercise) - .add(class_("X") - .def_init(args()) + .add(class_("X", args()) .def( "__repr__", x_rep)) ; } diff --git a/test/m1.cpp b/test/m1.cpp index ada4707e..71bc3af1 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -242,7 +242,6 @@ BOOST_PYTHON_MODULE_INIT(m1) .add( class_ >("A") - .def_init() .def("name", &A::name) ) @@ -253,13 +252,11 @@ BOOST_PYTHON_MODULE_INIT(m1) m1 .add( class_, shared_ptr >("B") - .def_init() .def("name", &B::name) ) .add( class_, shared_ptr >("C") - .def_init() .def("name", &C::name) ) ; @@ -267,13 +264,12 @@ BOOST_PYTHON_MODULE_INIT(m1) m1 .add( class_, bases >("D") - .def_init() .def("name", &D::name) ) .add( - class_("complicated") - .def_init(args()) + class_("complicated", + args()) .def_init(args()) .def("get_n", &complicated::get_n) ) diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp index c4c91aea..0114e151 100644 --- a/test/multi_arg_constructor.cpp +++ b/test/multi_arg_constructor.cpp @@ -16,11 +16,10 @@ BOOST_PYTHON_MODULE_INIT(multi_arg_constructor_ext) module("multi_arg_constructor_ext") - .add(class_ >("A") - .def_init(args()) + .add(class_ >( + "A" + , args() + ) ) ; diff --git a/test/operators.cpp b/test/operators.cpp index 336207f4..9b2afc3e 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -60,8 +60,7 @@ BOOST_PYTHON_MODULE_INIT(operators_ext) { module("operators_ext") .add( - class_("X") - .def_init(args()) + class_("X", args()) .def("value", &X::value) .def(self - self) .def(self - int()) @@ -79,8 +78,7 @@ BOOST_PYTHON_MODULE_INIT(operators_ext) .def(pow(int(),self)) ) .add( - class_ >("Z") - .def_init(args()) + class_ >("Z", args()) .def(int_(self)) .def(float_(self)) .def(complex_(self)) diff --git a/test/pickle1.cpp b/test/pickle1.cpp index cecb9c6a..6edec23a 100644 --- a/test/pickle1.cpp +++ b/test/pickle1.cpp @@ -51,8 +51,8 @@ BOOST_PYTHON_MODULE_INIT(pickle1_ext) { using namespace boost::python; module("pickle1_ext") - .add(class_("world") - .def_init(args()) + .add(class_("world" + , args()) .def("greet", &world::greet) .def_pickle(world_pickle_suite()) ) diff --git a/test/pickle2.cpp b/test/pickle2.cpp index 47d655c6..62c7c4b5 100644 --- a/test/pickle2.cpp +++ b/test/pickle2.cpp @@ -90,8 +90,8 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle2_ext) { boost::python::module("pickle2_ext") - .add(boost::python::class_("world") - .def_init(boost::python::args()) + .add(boost::python::class_("world" + , boost::python::args()) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) diff --git a/test/pickle3.cpp b/test/pickle3.cpp index 911eb7b8..4aaaecb5 100644 --- a/test/pickle3.cpp +++ b/test/pickle3.cpp @@ -96,8 +96,8 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle3_ext) { boost::python::module("pickle3_ext") - .add(boost::python::class_("world") - .def_init(boost::python::args()) + .add(boost::python::class_("world" + , boost::python::args()) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index 74c869ed..2bbf84e2 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -87,19 +87,18 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) .add( - class_() + class_(no_init) .def("content", &A::content) .def("get_inner", &A::get_inner, return_internal_reference<>()) ) .add( - class_() + class_(no_init) .def("change", &inner::change) ) .add( class_("B") - .def_init() .def_init(args(), with_custodian_and_ward_postcall<1,2>()) .def("adopt", &B::adopt diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp index 3f516bf7..45fe3636 100644 --- a/test/virtual_functions.cpp +++ b/test/virtual_functions.cpp @@ -90,8 +90,7 @@ BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) { module("virtual_functions_ext") .add( - class_("concrete") - .def_init(args()) + class_("concrete", args()) .def("value", &concrete::value) .def("set", &concrete::set) .def("call_f", &concrete::call_f) @@ -99,16 +98,14 @@ BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) .add( class_ - >("abstract") + >("abstract", args()) - .def_init(args()) .def("value", &abstract::value) .def("call_f", &abstract::call_f) .def("set", &abstract::set)) .add( - class_("Y") - .def_init(args()) + class_("Y", args()) .def("value", &Y::value) .def("set", &Y::set) ) From 49e071d363596d12f822ea4fc099fb90b0254283 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 14 Aug 2002 21:09:26 +0000 Subject: [PATCH 0642/1042] Bug fix from Martin Casado (casado2@llnl.gov) [SVN r14857] --- src/aix_init_module.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/aix_init_module.cpp b/src/aix_init_module.cpp index fb623579..3d74596e 100644 --- a/src/aix_init_module.cpp +++ b/src/aix_init_module.cpp @@ -17,6 +17,7 @@ extern "C" # include # include # include +# include namespace boost { namespace python { namespace detail { From 3c5df281019e14c20d8a8de7c503dab20552732f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 19 Aug 2002 15:19:08 +0000 Subject: [PATCH 0643/1042] Bug fix for NULL pointers with return_internal_reference<>. [SVN r14952] --- doc/v2/with_custodian_and_ward.html | 6 ++- src/object/life_support.cpp | 9 +++++ test/test_pointer_adoption.cpp | 60 +++++++++++++++++------------ test/test_pointer_adoption.py | 5 +++ 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/doc/v2/with_custodian_and_ward.html b/doc/v2/with_custodian_and_ward.html index ae816063..6710d357 100644 --- a/doc/v2/with_custodian_and_ward.html +++ b/doc/v2/with_custodian_and_ward.html @@ -66,10 +66,12 @@ the custodian as long as the custodian object supports weak references (Boost.Python extension classes all support weak - references). The two class templates + references). If the custodian object does not support weak + references and is not None, an appropriate exception + will be thrown. The two class templates with_custodian_and_ward and with_custodian_and_ward_postcall differ in the point - at which they take effect. + at which they take effect.

    In order to reduce the chance of inadvertently creating dangling pointers, the default is to do lifetime binding diff --git a/src/object/life_support.cpp b/src/object/life_support.cpp index 7507c71c..a1a62bfd 100644 --- a/src/object/life_support.cpp +++ b/src/object/life_support.cpp @@ -5,6 +5,7 @@ // to its suitability for any purpose. #include #include +#include namespace boost { namespace python { namespace objects { @@ -80,9 +81,17 @@ PyTypeObject life_support_type = { PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient) { + if (nurse == Py_None) + return incref(nurse); + + if ((life_support_type.tp_flags & Py_TPFLAGS_READY) == 0) + PyType_Ready(&life_support_type); + life_support* system = PyObject_New(life_support, &life_support_type); if (!system) return 0; + + system->patient = 0; // We're going to leak this reference, but don't worry; the // life_support system decrements it when the nurse dies. diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index 2bbf84e2..cd039c9a 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -29,7 +29,12 @@ struct inner std::string s; }; -struct A +struct Base +{ + virtual ~Base() {} +}; + +struct A : Base { A(std::string const& s) : x(s) @@ -76,40 +81,47 @@ A* create(std::string const& s) return new A(s); } +A* as_A(Base* b) +{ + return dynamic_cast(b); +} + BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) { - boost::python::module("test_pointer_adoption_ext") - .def("num_a_instances", num_a_instances) + boost::python::module m("test_pointer_adoption_ext"); + m.def("num_a_instances", num_a_instances) // Specify the manage_new_object return policy to take // ownership of create's result .def("create", create, return_value_policy()) - - .add( - - class_(no_init) - .def("content", &A::content) - .def("get_inner", &A::get_inner, return_internal_reference<>()) - ) + .def("as_A", as_A, return_internal_reference<>()) .add( - class_(no_init) - .def("change", &inner::change) - ) + + class_("Base") + ); - .add( - class_("B") - .def_init(args(), with_custodian_and_ward_postcall<1,2>()) + m.add(class_ >(no_init) + .def("content", &A::content) + .def("get_inner", &A::get_inner, return_internal_reference<>()) + ) + + .add(class_(no_init) + .def("change", &inner::change) + ) + + .add(class_("B") + .def_init(args(), with_custodian_and_ward_postcall<1,2>()) - .def("adopt", &B::adopt - // Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self") - , return_internal_reference<2 - // Meanwhile, self holds a reference to the 2nd argument. - , with_custodian_and_ward<1,2> >() - ) - - .def("a_content", &B::a_content) + .def("adopt", &B::adopt + // Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self") + , return_internal_reference<2 + // Meanwhile, self holds a reference to the 2nd argument. + , with_custodian_and_ward<1,2> >() ) + + .def("a_content", &B::a_content)) ; } +#include "module_tail.cpp" diff --git a/test/test_pointer_adoption.py b/test/test_pointer_adoption.py index d28dea5c..f684b062 100644 --- a/test/test_pointer_adoption.py +++ b/test/test_pointer_adoption.py @@ -70,6 +70,11 @@ Test call policies for constructors here >>> num_a_instances() 0 +>>> as_A(create('dynalloc')) is None +0 +>>> base = Base() +>>> as_A(base) is None +1 """ def run(args = None): import sys From a5d53d1ac870982cc3308b8f62278e1bd17eb716 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 19 Aug 2002 20:14:33 +0000 Subject: [PATCH 0644/1042] new class_<> objects are always added to the current scope [SVN r14964] --- .../boost/python/detail/api_placeholder.hpp | 10 ----- include/boost/python/detail/module_base.hpp | 1 - include/boost/python/module.hpp | 2 +- include/boost/python/object_protocol.hpp | 6 +++ include/boost/python/object_protocol_core.hpp | 2 + src/module.cpp | 17 ------- src/object/class.cpp | 19 +++++++- src/object_protocol.cpp | 22 ++++++++++ test/m1.cpp | 44 +++++++------------ test/test_pointer_adoption.cpp | 22 +++++----- 10 files changed, 75 insertions(+), 70 deletions(-) diff --git a/include/boost/python/detail/api_placeholder.hpp b/include/boost/python/detail/api_placeholder.hpp index fd571d88..9a4672ab 100644 --- a/include/boost/python/detail/api_placeholder.hpp +++ b/include/boost/python/detail/api_placeholder.hpp @@ -9,16 +9,6 @@ namespace boost { namespace python { if (PyErr_Occurred()) throw_error_already_set(); return result; } - - inline object getattr(object const& a0, const char* a1, object const& a2) - { - handle<> result(allow_null(PyObject_GetAttrString( - a0.ptr(), const_cast(a1)))); - if (!PyErr_Occurred()) return object(result); - PyErr_Clear(); - return a2; - } - }} // namespace boost::python #endif // BOOST_PYTHON_API_PLACE_HOLDER_HPP diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp index 218caccf..144c1d93 100644 --- a/include/boost/python/detail/module_base.hpp +++ b/include/boost/python/detail/module_base.hpp @@ -26,7 +26,6 @@ class BOOST_PYTHON_DECL module_base protected: void setattr_doc(const char* name, python::object const&, char const* doc); - void add_class(type_handle const& class_obj); private: handle<> m_module; diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index af6434ce..7ee7b188 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -38,7 +38,7 @@ class module : public detail::module_base template module& add(class_ const& c) { - this->add_class(type_handle(borrowed((PyTypeObject*)c.ptr()))); + // Soon to disappear... return *this; } diff --git a/include/boost/python/object_protocol.hpp b/include/boost/python/object_protocol.hpp index fe21be17..975c9379 100755 --- a/include/boost/python/object_protocol.hpp +++ b/include/boost/python/object_protocol.hpp @@ -19,6 +19,12 @@ object getattr(Target const& target, Key const& key) return getattr(object(target), object(key)); } +template +object getattr(Target const& target, Key const& key, Default const& default_) +{ + return getattr(object(target), object(key), object(default_)); +} + template void setattr(object const& target, Key const& key, Value const& value) diff --git a/include/boost/python/object_protocol_core.hpp b/include/boost/python/object_protocol_core.hpp index 548f9c7a..c5c41c6a 100755 --- a/include/boost/python/object_protocol_core.hpp +++ b/include/boost/python/object_protocol_core.hpp @@ -15,12 +15,14 @@ namespace api class object; BOOST_PYTHON_DECL object getattr(object const& target, object const& key); + BOOST_PYTHON_DECL object getattr(object const& target, object const& key, object const& default_); BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value); BOOST_PYTHON_DECL void delattr(object const& target, object const& key); // These are defined for efficiency, since attributes are commonly // accessed through literal strings. BOOST_PYTHON_DECL object getattr(object const& target, char const* key); + BOOST_PYTHON_DECL object getattr(object const& target, char const* key, object const& default_); BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value); BOOST_PYTHON_DECL void delattr(object const& target, char const* key); diff --git a/src/module.cpp b/src/module.cpp index 549ba782..088773fc 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -42,23 +42,6 @@ void module_base::add(type_handle const& x) this->setattr_doc(x->tp_name, python::object(x), 0); } -void module_base::add_class(type_handle const& class_obj) -{ - this->add(class_obj); - - handle<> module_name( - PyObject_GetAttrString( - m_module.get(), const_cast("__name__")) - ); - - int status = PyObject_SetAttrString( - python::upcast(class_obj.get()) - , const_cast("__module__"), module_name.get()); - - if (status == -1) - throw_error_already_set(); -} - PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; namespace diff --git a/src/object/class.cpp b/src/object/class.cpp index c6420a76..c034b066 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -3,12 +3,14 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. +#include #include #include #include #include #include #include +#include #include #include #include @@ -264,9 +266,17 @@ namespace objects PyTuple_SET_ITEM(bases.get(), i - 1, upcast(c.release())); } + object module_name = PyObject_IsInstance(scope().ptr(), upcast(&PyModule_Type)) + ? scope().attr("__name__") + : getattr(scope(), "__module__", object("")) + ; + + if (module_name) + module_name += '.'; + // Build the (name, bases, dict) tuple for creating the new class handle<> args(PyTuple_New(3)); - PyTuple_SET_ITEM(args.get(), 0, incref(python::object(name).ptr())); + PyTuple_SET_ITEM(args.get(), 0, incref((module_name + name).ptr())); PyTuple_SET_ITEM(args.get(), 1, bases.release()); handle<> d(PyDict_New()); PyTuple_SET_ITEM(args.get(), 2, d.release()); @@ -274,7 +284,12 @@ namespace objects // Call the class metatype to create a new class PyObject* c = PyObject_CallObject(upcast(class_metatype().get()), args.get()); assert(PyType_IsSubtype(c->ob_type, &PyType_Type)); - return object(python::detail::new_reference(c)); + object result = object(python::detail::new_reference(c)); + + if (scope().ptr() != Py_None) + scope().attr(name) = result; + + return result; } } diff --git a/src/object_protocol.cpp b/src/object_protocol.cpp index cafb70f3..11979f8f 100755 --- a/src/object_protocol.cpp +++ b/src/object_protocol.cpp @@ -15,6 +15,17 @@ BOOST_PYTHON_DECL object getattr(object const& target, object const& key) return object(detail::new_reference(PyObject_GetAttr(target.ptr(), key.ptr()))); } +BOOST_PYTHON_DECL object getattr(object const& target, object const& key, object const& default_) +{ + PyObject* result = PyObject_GetAttr(target.ptr(), key.ptr()); + if (result == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) + { + PyErr_Clear(); + return default_; + } + return object(detail::new_reference(result)); +} + BOOST_PYTHON_DECL void setattr(object const& target, object const& key, object const& value) { if (PyObject_SetAttr(target.ptr(), key.ptr(), value.ptr()) == -1) @@ -35,6 +46,17 @@ BOOST_PYTHON_DECL object getattr(object const& target, char const* key) )); } +BOOST_PYTHON_DECL object getattr(object const& target, char const* key, object const& default_) +{ + PyObject* result = PyObject_GetAttrString(target.ptr(), const_cast(key)); + if (result == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) + { + PyErr_Clear(); + return default_; + } + return object(detail::new_reference(result)); + +} BOOST_PYTHON_DECL void setattr(object const& target, char const* key, object const& value) { if (PyObject_SetAttrString( diff --git a/test/m1.cpp b/test/m1.cpp index 71bc3af1..de76f64a 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -211,9 +211,7 @@ BOOST_PYTHON_MODULE_INIT(m1) lvalue_from_pytype,&SimpleType>(); - module m1("m1"); - - m1 + module("m1") // Insert the metaclass for all extension classes .setattr("xclass", boost::python::objects::class_metatype()) @@ -239,40 +237,30 @@ BOOST_PYTHON_MODULE_INIT(m1) .def("take_b", take_b) .def("take_c", take_c) .def("take_d", take_d) + ; - .add( - class_ >("A") - .def("name", &A::name) - ) - + class_ >("A") + .def("name", &A::name) ; // sequence points don't ensure that "A" is constructed before "B" // or "C" below if we make them part of the same chain - m1 - .add( - class_, shared_ptr >("B") - .def("name", &B::name) - ) + class_, shared_ptr >("B") + .def("name", &B::name) + ; - .add( - class_, shared_ptr >("C") - .def("name", &C::name) - ) + class_, shared_ptr >("C") + .def("name", &C::name) ; - m1 - .add( - class_, bases >("D") - .def("name", &D::name) - ) + class_, bases >("D") + .def("name", &D::name) + ; - .add( - class_("complicated", - args()) - .def_init(args()) - .def("get_n", &complicated::get_n) - ) + class_("complicated", + args()) + .def_init(args()) + .def("get_n", &complicated::get_n) ; } diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index cd039c9a..caefe4cb 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -88,29 +88,29 @@ A* as_A(Base* b) BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) { - boost::python::module m("test_pointer_adoption_ext"); - m.def("num_a_instances", num_a_instances) + boost::python::module("test_pointer_adoption_ext") + .def("num_a_instances", num_a_instances) // Specify the manage_new_object return policy to take // ownership of create's result .def("create", create, return_value_policy()) .def("as_A", as_A, return_internal_reference<>()) - .add( - + ; + class_("Base") - ); + ; - m.add(class_ >(no_init) + class_ >(no_init) .def("content", &A::content) .def("get_inner", &A::get_inner, return_internal_reference<>()) - ) + ; - .add(class_(no_init) + class_(no_init) .def("change", &inner::change) - ) + ; - .add(class_("B") + class_("B") .def_init(args(), with_custodian_and_ward_postcall<1,2>()) .def("adopt", &B::adopt @@ -120,7 +120,7 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) , with_custodian_and_ward<1,2> >() ) - .def("a_content", &B::a_content)) + .def("a_content", &B::a_content) ; } From 3092e0728105dbab55955759c12e5a37df2896d2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 19 Aug 2002 22:19:50 +0000 Subject: [PATCH 0645/1042] Workaround VC6 bug [SVN r14975] --- .../python/return_internal_reference.hpp | 4 ++-- include/boost/python/return_value_policy.hpp | 4 ++-- .../boost/python/with_custodian_and_ward.hpp | 20 +++++++++---------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp index 356bc9ed..3a968f45 100644 --- a/include/boost/python/return_internal_reference.hpp +++ b/include/boost/python/return_internal_reference.hpp @@ -23,9 +23,9 @@ namespace detail ; } -template +template struct return_internal_reference - : with_custodian_and_ward_postcall<0, owner_arg, Base> + : with_custodian_and_ward_postcall<0, owner_arg, BasePolicy_> { private: BOOST_STATIC_CONSTANT(bool, legal = owner_arg > 0); diff --git a/include/boost/python/return_value_policy.hpp b/include/boost/python/return_value_policy.hpp index 6a2036d7..0f3c00fe 100644 --- a/include/boost/python/return_value_policy.hpp +++ b/include/boost/python/return_value_policy.hpp @@ -9,8 +9,8 @@ namespace boost { namespace python { -template -struct return_value_policy : Base +template +struct return_value_policy : BasePolicy_ { typedef ResultConverterGenerator result_converter; }; diff --git a/include/boost/python/with_custodian_and_ward.hpp b/include/boost/python/with_custodian_and_ward.hpp index 517d690f..4d022448 100644 --- a/include/boost/python/with_custodian_and_ward.hpp +++ b/include/boost/python/with_custodian_and_ward.hpp @@ -11,14 +11,14 @@ namespace boost { namespace python { -template -struct with_custodian_and_ward : Base +template +struct with_custodian_and_ward : BasePolicy_ { static bool precall(PyObject* args); }; -template -struct with_custodian_and_ward_postcall : Base +template +struct with_custodian_and_ward_postcall : BasePolicy_ { static PyObject* postcall(PyObject* args, PyObject* result); }; @@ -26,8 +26,8 @@ struct with_custodian_and_ward_postcall : Base // // implementations // -template -bool with_custodian_and_ward::precall(PyObject* args_) +template +bool with_custodian_and_ward::precall(PyObject* args_) { BOOST_STATIC_ASSERT(custodian != ward); BOOST_STATIC_ASSERT(custodian > 0); @@ -42,7 +42,7 @@ bool with_custodian_and_ward::precall(PyObject* args_) if (life_support == 0) return false; - bool result = Base::precall(args_); + bool result = BasePolicy_::precall(args_); if (!result) Py_XDECREF(life_support); @@ -50,8 +50,8 @@ bool with_custodian_and_ward::precall(PyObject* args_) return result; } -template -PyObject* with_custodian_and_ward_postcall::postcall(PyObject* args_, PyObject* result) +template +PyObject* with_custodian_and_ward_postcall::postcall(PyObject* args_, PyObject* result) { BOOST_STATIC_ASSERT(custodian != ward); @@ -61,7 +61,7 @@ PyObject* with_custodian_and_ward_postcall::postcall(PyObje PyObject* nurse = custodian > 0 ? PyTuple_GetItem(args_, custodian - 1) : result; if (nurse == 0) return 0; - result = Base::postcall(args_, result); + result = BasePolicy_::postcall(args_, result); if (result == 0) return 0; From 1a7b331a4bdd5e7d247a51ee4279878eda338d03 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 19 Aug 2002 22:21:03 +0000 Subject: [PATCH 0646/1042] Take advantage of independent class_<> definitions everywhere. [SVN r14976] --- test/bienstman1.cpp | 11 ++--- test/bienstman2.cpp | 15 +++---- test/bienstman3.cpp | 12 +----- test/bienstman4.cpp | 17 ++++---- test/bienstman5.cpp | 10 +---- test/cltree.cpp | 41 +++++------------- test/data_members.cpp | 25 +++++------ test/extract.cpp | 11 ++--- test/iterator.cpp | 76 +++++++++++++++++----------------- test/multi_arg_constructor.cpp | 11 ++--- test/operators.cpp | 45 ++++++++++---------- test/pickle1.cpp | 7 +--- test/pickle2.cpp | 16 ++++--- test/pickle3.cpp | 16 ++++--- test/virtual_functions.cpp | 33 +++++++-------- 15 files changed, 141 insertions(+), 205 deletions(-) diff --git a/test/bienstman1.cpp b/test/bienstman1.cpp index e6d5e42f..5e035d68 100644 --- a/test/bienstman1.cpp +++ b/test/bienstman1.cpp @@ -24,18 +24,13 @@ BOOST_PYTHON_MODULE_INIT(bienstman1_ext) using boost::python::return_value_policy; using boost::python::reference_existing_object; - module m("bienstman1_ext"); - - m - .add(class_ >("A")) + class_ >("A"); - .add( - class_("V", no_init) + class_("V", no_init) .def("inside", &V::inside, return_value_policy()) .def("outside", outside, return_value_policy()) - ) - ; + ; } diff --git a/test/bienstman2.cpp b/test/bienstman2.cpp index b2ef1957..79c4dfb0 100644 --- a/test/bienstman2.cpp +++ b/test/bienstman2.cpp @@ -15,15 +15,10 @@ BOOST_PYTHON_MODULE_INIT(bienstman2_ext) { using namespace boost::python; - module m("bienstman2_ext"); - - m - .add(class_("C")) - .add(class_("D")) - .add( - class_("E") + class_("C"); + class_("D"); + class_("E") .def("fe", &E::fe) // this compiles. - .def("fe2", &E::fe2) // this doesn't. - ) - ; + .def("fe2", &E::fe2) // this doesn't... well, now it does ;-) + ; } diff --git a/test/bienstman3.cpp b/test/bienstman3.cpp index 494965a2..9b2985e1 100644 --- a/test/bienstman3.cpp +++ b/test/bienstman3.cpp @@ -15,15 +15,7 @@ BOOST_PYTHON_MODULE_INIT(bienstman3_ext) { using namespace boost::python; - module m("bienstman3_ext"); - - m - .add( - class_("V", no_init) - ) + class_("V", no_init); + class_("B", args()); - .add( - class_("B", args()) - ) - ; } diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp index b44b4bf8..22ed6b6f 100644 --- a/test/bienstman4.cpp +++ b/test/bienstman4.cpp @@ -21,15 +21,16 @@ BOOST_PYTHON_MODULE_INIT(bienstman4_ext) implicitly_convertible(); - module("bienstman4_ext") - .add(class_("Expression") - .def("add", &Expression::add)) - .add(class_("T1") - .add(class_("Term" - , args())) - ; + class_("Expression") + .def("add", &Expression::add) + ; + + class_("T1") + ; + + class_("Term", args()) + ; - Type1 t1; Expression e; e.add(t1); diff --git a/test/bienstman5.cpp b/test/bienstman5.cpp index 96eb7023..57b36f21 100644 --- a/test/bienstman5.cpp +++ b/test/bienstman5.cpp @@ -15,15 +15,9 @@ struct M {M(const std::complex&) {} }; BOOST_PYTHON_MODULE_INIT(bienstman5_ext) { using namespace boost::python; - using boost::mpl::type_list; - module m("bienstman5_ext"); - - m - .add(class_("M") - .def_init(args const&>())) - ; - + class_("M", args const&>()) + ; } diff --git a/test/cltree.cpp b/test/cltree.cpp index d99a4862..8b96aad3 100755 --- a/test/cltree.cpp +++ b/test/cltree.cpp @@ -48,40 +48,21 @@ public: }; -BOOST_PYTHON_MODULE_INIT(cltree) { - - boost::python::module m("cltree"); - m - .add( - boost::python::class_("basic") - .def_init(boost::python::args<>()) +BOOST_PYTHON_MODULE_INIT(cltree) +{ + boost::python::class_("basic") .def("__repr__",&basic::repr) - ) - ; + ; - m - .add(boost::python::class_ - ,boost::noncopyable - >("constant") - .def_init(boost::python::args<>()) - ) + boost::python::class_, boost::noncopyable>("constant") + ; - .add(boost::python::class_("symbol") - .def_init(boost::python::args<>()) - ) - .add(boost::python::class_ - ,variable_wrapper - //,boost::noncopyable // leads to compiler failure?! - >("variable") - .def_init(boost::python::args<>()) - ) - ; + boost::python::class_("symbol") + ; + + boost::python::class_, variable_wrapper>("variable") + ; } #include "module_tail.cpp" diff --git a/test/data_members.cpp b/test/data_members.cpp index 30c8d22f..5092bba9 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -22,20 +22,17 @@ double get_fair_value(X const& x) { return x.value(); } BOOST_PYTHON_MODULE_INIT(data_members_ext) { - module("data_members_ext") - .add( - class_("X", args()) - .def("value", &X::value) - .def("set", &X::set) - .def_readonly("x", &X::x) - .add_property("get_fair_value", object(&get_fair_value)) - ) - .add( - class_("Y", args()) - .def("value", &Y::value) - .def("set", &Y::set) - .def_readwrite("x", &Y::x) - ) + class_("X", args()) + .def("value", &X::value) + .def("set", &X::set) + .def_readonly("x", &X::x) + .add_property("get_fair_value", object(&get_fair_value)) + ; + + class_("Y", args()) + .def("value", &Y::value) + .def("set", &Y::set) + .def_readwrite("x", &Y::x) ; } diff --git a/test/extract.cpp b/test/extract.cpp index aec75308..946f5ba1 100644 --- a/test/extract.cpp +++ b/test/extract.cpp @@ -99,12 +99,6 @@ BOOST_PYTHON_MODULE_INIT(extract_ext) { implicitly_convertible(); - class_ x_class("X", args()); - - x_class - .def( "__repr__", x_rep) - ; - module("extract_ext") .def("extract_bool", extract_bool) .def("extract_list", extract_list) @@ -124,12 +118,15 @@ BOOST_PYTHON_MODULE_INIT(extract_ext) .def("check_X_ptr", check_X_ptr) .def("check_X_ref", check_X_ref) - .add(x_class) .def("double_X", double_X) .def("count_Xs", &X::count) ; + object x_class( + class_("X", args()) + .def( "__repr__", x_rep)); + // Instantiate an X object through the Python interface object x_obj = x_class(3); diff --git a/test/iterator.cpp b/test/iterator.cpp index c5ce6f32..8f59d4b7 100644 --- a/test/iterator.cpp +++ b/test/iterator.cpp @@ -74,51 +74,51 @@ BOOST_PYTHON_MODULE_INIT(iterator_ext) { module("iterator_ext") .def("range", &::range) - .add( - class_("list_int") - .def("push_back", push_back) - .def("back", back) - .def("__iter__", iterator()) - ) - .add( - class_("list_range") + ; - // We can specify data members - .def("__iter__" - , range(&list_range::first, &list_range::second)) - ) - .add( - class_("two_lists") + class_("list_int") + .def("push_back", push_back) + .def("back", back) + .def("__iter__", iterator()) + ; - // We can spcify member functions - .add_property( - "primes" - , range(&two_lists::one_begin, &two_lists::one_end)) + class_("list_range") - // Prove that we can explicitly specify call policies - .add_property( - "evens" - , range >( - &two_lists::two_begin, &two_lists::two_end)) + // We can specify data members + .def("__iter__" + , range(&list_range::first, &list_range::second)) + ; - // Prove that we can specify call policies and target - .add_property( - "twosies" - , range, two_lists>( - // And we can use adaptable function objects when - // partial specialization is available. + class_("two_lists") + + // We can spcify member functions + .add_property( + "primes" + , range(&two_lists::one_begin, &two_lists::one_end)) + + // Prove that we can explicitly specify call policies + .add_property( + "evens" + , range >( + &two_lists::two_begin, &two_lists::two_end)) + + // Prove that we can specify call policies and target + .add_property( + "twosies" + , range, two_lists>( + // And we can use adaptable function objects when + // partial specialization is available. # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - two_lists::two_start() + two_lists::two_start() # else - &two_lists::two_begin + &two_lists::two_begin # endif - , &two_lists::two_end)) - ) - .add( - class_("list_list") - .def("push_back", push_list_back) - .def("__iter__", iterator >()) - ) + , &two_lists::two_end)) + ; + + class_("list_list") + .def("push_back", push_list_back) + .def("__iter__", iterator >()) ; } diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp index 0114e151..562842a0 100644 --- a/test/multi_arg_constructor.cpp +++ b/test/multi_arg_constructor.cpp @@ -14,13 +14,10 @@ BOOST_PYTHON_MODULE_INIT(multi_arg_constructor_ext) using namespace boost::python; using boost::shared_ptr; - module("multi_arg_constructor_ext") - - .add(class_ >( - "A" - , args() - ) - ) + class_ >( + "A" + , args() + ) ; } diff --git a/test/operators.cpp b/test/operators.cpp index 9b2afc3e..ae90f996 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -58,31 +58,28 @@ std::ostream& operator<<(std::ostream& s, X const& x) BOOST_PYTHON_MODULE_INIT(operators_ext) { - module("operators_ext") - .add( - class_("X", args()) - .def("value", &X::value) - .def(self - self) - .def(self - int()) - .def(other() - self) - .def(-self) - .def(self < other()) - .def(self < self) - .def(1 < self) - .def(self -= self) - .def(abs(self)) - .def(str(self)) + class_("X", args()) + .def("value", &X::value) + .def(self - self) + .def(self - int()) + .def(other() - self) + .def(-self) + .def(self < other()) + .def(self < self) + .def(1 < self) + .def(self -= self) + .def(abs(self)) + .def(str(self)) - .def(pow(self,self)) - .def(pow(self,int())) - .def(pow(int(),self)) - ) - .add( - class_ >("Z", args()) - .def(int_(self)) - .def(float_(self)) - .def(complex_(self)) - ) + .def(pow(self,self)) + .def(pow(self,int())) + .def(pow(int(),self)) + ; + + class_ >("Z", args()) + .def(int_(self)) + .def(float_(self)) + .def(complex_(self)) ; } diff --git a/test/pickle1.cpp b/test/pickle1.cpp index 6edec23a..eab90299 100644 --- a/test/pickle1.cpp +++ b/test/pickle1.cpp @@ -50,11 +50,8 @@ namespace { BOOST_PYTHON_MODULE_INIT(pickle1_ext) { using namespace boost::python; - module("pickle1_ext") - .add(class_("world" - , args()) + class_("world", args()) .def("greet", &world::greet) .def_pickle(world_pickle_suite()) - ) - ; + ; } diff --git a/test/pickle2.cpp b/test/pickle2.cpp index 62c7c4b5..6fe2962d 100644 --- a/test/pickle2.cpp +++ b/test/pickle2.cpp @@ -89,13 +89,11 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle2_ext) { - boost::python::module("pickle2_ext") - .add(boost::python::class_("world" - , boost::python::args()) - .def("greet", &world::greet) - .def("get_secret_number", &world::get_secret_number) - .def("set_secret_number", &world::set_secret_number) - .def_pickle(world_pickle_suite()) - ) - ; + boost::python::class_( + "world", boost::python::args()) + .def("greet", &world::greet) + .def("get_secret_number", &world::get_secret_number) + .def("set_secret_number", &world::set_secret_number) + .def_pickle(world_pickle_suite()) + ; } diff --git a/test/pickle3.cpp b/test/pickle3.cpp index 4aaaecb5..f4f8c20e 100644 --- a/test/pickle3.cpp +++ b/test/pickle3.cpp @@ -95,13 +95,11 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle3_ext) { - boost::python::module("pickle3_ext") - .add(boost::python::class_("world" - , boost::python::args()) - .def("greet", &world::greet) - .def("get_secret_number", &world::get_secret_number) - .def("set_secret_number", &world::set_secret_number) - .def_pickle(world_pickle_suite()) - ) - ; + boost::python::class_( + "world", boost::python::args()) + .def("greet", &world::greet) + .def("get_secret_number", &world::get_secret_number) + .def("set_secret_number", &world::set_secret_number) + .def_pickle(world_pickle_suite()) + ; } diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp index 45fe3636..3864498a 100644 --- a/test/virtual_functions.cpp +++ b/test/virtual_functions.cpp @@ -88,27 +88,24 @@ int X::counter; BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) { - module("virtual_functions_ext") - .add( - class_("concrete", args()) - .def("value", &concrete::value) - .def("set", &concrete::set) - .def("call_f", &concrete::call_f) - .def("f", &concrete_callback::f_impl)) + class_("concrete", args()) + .def("value", &concrete::value) + .def("set", &concrete::set) + .def("call_f", &concrete::call_f) + .def("f", &concrete_callback::f_impl) + ; - .add( - class_ - >("abstract", args()) + class_ + >("abstract", args()) - .def("value", &abstract::value) - .def("call_f", &abstract::call_f) - .def("set", &abstract::set)) + .def("value", &abstract::value) + .def("call_f", &abstract::call_f) + .def("set", &abstract::set) + ; - .add( - class_("Y", args()) - .def("value", &Y::value) - .def("set", &Y::set) - ) + class_("Y", args()) + .def("value", &Y::value) + .def("set", &Y::set) ; } From 960ebb13db89d7246f9924b0f717c311e4f7d2c6 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Mon, 19 Aug 2002 23:29:18 +0000 Subject: [PATCH 0647/1042] init commit [SVN r14977] --- index.html | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 index.html diff --git a/index.html b/index.html new file mode 100644 index 00000000..dff3b20f --- /dev/null +++ b/index.html @@ -0,0 +1,9 @@ + + + + + +Automatic redirection failed, please go to +doc/index.html. + + \ No newline at end of file From b77262ba13dacb33afb33e050d2b240d34756d72 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 20 Aug 2002 00:41:17 +0000 Subject: [PATCH 0648/1042] Added nested class test [SVN r14980] --- test/Jamfile | 2 ++ test/nested.cpp | 35 +++++++++++++++++++++++++++++++++++ test/nested.py | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 test/nested.cpp create mode 100644 test/nested.py diff --git a/test/Jamfile b/test/Jamfile index ef4fd7a1..fe0c7261 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -88,6 +88,8 @@ bpl-test pickle1 ; bpl-test pickle2 ; bpl-test pickle3 ; +bpl-test nested ; + if $(TEST_BIENSTMAN_NON_BUGS) { bpl-test bienstman4 ; diff --git a/test/nested.cpp b/test/nested.cpp new file mode 100644 index 00000000..1187c7d8 --- /dev/null +++ b/test/nested.cpp @@ -0,0 +1,35 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include "test_class.hpp" + +typedef test_class<> X; +typedef test_class<1> Y; + +BOOST_PYTHON_MODULE_INIT(nested_ext) +{ + using namespace boost::python; + + // Establish X as the current scope. + scope x_class( + class_("X", args()) + .def(str(self)) + ); + + // Y will now be defined in the current scope + class_("Y", args()) + .def(str(self)) + ; +} + + +#include "module_tail.cpp" + + + diff --git a/test/nested.py b/test/nested.py new file mode 100644 index 00000000..97ac2a33 --- /dev/null +++ b/test/nested.py @@ -0,0 +1,35 @@ +''' + >>> from nested_ext import * + + >>> X + + + >>> X.__module__ + 'nested_ext' + + >>> X.__name__ + 'X' + + >>> X.Y + + + >>> X.Y.__module__ + 'nested_ext' + + >>> X.Y.__name__ + 'Y' + +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 6e3c6d1ba8c94e039446048cdc8cdbc0c9c5d36c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 20 Aug 2002 16:58:48 +0000 Subject: [PATCH 0649/1042] CWPro8.1 patch [SVN r15000] --- include/boost/python/object_core.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 22bd2750..29127fc9 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -174,7 +174,7 @@ namespace api // there is a confirmed CWPro8 codegen bug here. We prevent the // early destruction of a temporary by binding a named object // instead. -# if __MWERKS__ != 0x3000 +# if __MWERKS__ < 0x3000 || __MWERKS__ > 0x3001 typedef object const& object_cref2; # else typedef object const object_cref2; From c104f0167fbfff0a6ba72f1cc654c0728649723f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 20 Aug 2002 19:22:14 +0000 Subject: [PATCH 0650/1042] VC7.1 alpha adjustments [SVN r15003] --- include/boost/python/converter/arg_to_python_base.hpp | 4 ++-- src/converter/arg_to_python_base.cpp | 2 +- src/object/class.cpp | 2 +- src/object/inheritance.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/boost/python/converter/arg_to_python_base.hpp b/include/boost/python/converter/arg_to_python_base.hpp index 59f68b6d..385a7839 100755 --- a/include/boost/python/converter/arg_to_python_base.hpp +++ b/include/boost/python/converter/arg_to_python_base.hpp @@ -16,12 +16,12 @@ struct registration; namespace detail { struct BOOST_PYTHON_DECL arg_to_python_base -# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102171 +# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179 : handle<> # endif { arg_to_python_base(void const volatile* source, registration const&); -# if defined(BOOST_MSVC) && BOOST_MSVC > 1300 && _MSC_FULL_VER <= 13102171 +# if defined(BOOST_MSVC) && BOOST_MSVC > 1300 && _MSC_FULL_VER <= 13102179 PyObject* get() const { return m_ptr.get(); } PyObject* release() { return m_ptr.release(); } private: diff --git a/src/converter/arg_to_python_base.cpp b/src/converter/arg_to_python_base.cpp index b20a2a9c..1740f6ee 100644 --- a/src/converter/arg_to_python_base.cpp +++ b/src/converter/arg_to_python_base.cpp @@ -38,7 +38,7 @@ namespace detail { arg_to_python_base::arg_to_python_base( void const volatile* source, registration const& converters) -# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13102171 +# if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179 : handle<>(converter::convert_to_python(source, converters)) # else : m_ptr(converter::convert_to_python(source, converters)) diff --git a/src/object/class.cpp b/src/object/class.cpp index c034b066..e19ebfa7 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -268,7 +268,7 @@ namespace objects object module_name = PyObject_IsInstance(scope().ptr(), upcast(&PyModule_Type)) ? scope().attr("__name__") - : getattr(scope(), "__module__", object("")) + : api::getattr(scope(), "__module__", object("")) ; if (module_name) diff --git a/src/object/inheritance.cpp b/src/object/inheritance.cpp index d84e2b36..39c95f6e 100644 --- a/src/object/inheritance.cpp +++ b/src/object/inheritance.cpp @@ -6,7 +6,7 @@ #include #include #include -#if defined(BOOST_MSVC) && _MSC_FULL_VER == 13102171 +#if _MSC_FULL_VER >= 13102171 && _MSC_FULL_VER <= 13102179 # include #endif #include From 6bdc89252e56ed50c644b88aa863352b27248016 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Tue, 20 Aug 2002 20:36:25 +0000 Subject: [PATCH 0651/1042] Update (added init.hpp) [SVN r15005] --- include/boost/python/detail/defaults_def.hpp | 48 +-- include/boost/python/detail/defaults_gen.hpp | 41 +-- include/boost/python/init.hpp | 350 +++++++++++++++++++ 3 files changed, 390 insertions(+), 49 deletions(-) create mode 100644 include/boost/python/init.hpp diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index 44a1939b..03495ee9 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -7,6 +7,8 @@ // to its suitability for any purpose. // /////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_PP_IS_ITERATING) + #ifndef DEFAULTS_DEF_JDG20020811_HPP #define DEFAULTS_DEF_JDG20020811_HPP @@ -15,6 +17,7 @@ #include #include #include +#include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { @@ -45,29 +48,11 @@ namespace detail { // 5. char const* name: doc string // /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_STUB_FUNC_DEF(INDEX, DATA) \ - \ - template \ - inline void \ - define_stub_function \ - ( \ - char const* name, \ - StubsT, \ - HolderT& holder, \ - boost::mpl::int_t, \ - char const* doc \ - ) \ - { \ - holder.def( \ - name, \ - &StubsT::BOOST_PP_CAT(func_, INDEX), \ - default_call_policies(), \ - doc); \ - } \ +#define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, )) -BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY) +#include BOOST_PP_ITERATE() -#undef BPL_IMPL_STUB_FUNC_DEF /////////////////////////////////////////////////////////////////////////////// // // define_with_defaults_helper @@ -169,4 +154,25 @@ BOOST_PP_REPEAT(BOOST_PYTHON_MAX_ARITY, BPL_IMPL_STUB_FUNC_DEF, BOOST_PP_EMPTY) /////////////////////////////////////////////////////////////////////////////// #endif // DEFAULTS_DEF_JDG20020811_HPP +#else // defined(BOOST_PP_IS_ITERATING) +// PP vertical iteration code + template + inline void + define_stub_function + ( + char const* name, + StubsT, + HolderT& holder, + boost::mpl::int_t, + char const* doc + ) + { + holder.def( + name, + &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION()), + default_call_policies(), + doc); + } + +#endif // !defined(BOOST_PP_IS_ITERATING) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 0f580d94..9637ae24 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -26,28 +26,10 @@ 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. +// func_stubs_base is used as a base class for all function stubs. // /////////////////////////////////////////////////////////////////////////////// -template -struct func_stubs_base { - - typedef DerivedT derived_t; - - DerivedT& derived() - { return *static_cast(this); } - - DerivedT const& derived() const - { return *static_cast(this); } -}; +struct func_stubs_base {}; }}} // namespace boost::python::detail @@ -182,7 +164,7 @@ struct func_stubs_base { BPL_IMPL_GEN_FUNCTION \ (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _V), N_ARGS, N_DFLTS, ;) \ struct FSTUBS_NAME \ - : public boost::python::detail::func_stubs_base { \ + : 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; \ @@ -195,7 +177,7 @@ struct func_stubs_base { BPL_IMPL_GEN_MEM_FUNCTION \ (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _V), N_ARGS, N_DFLTS, ;) \ struct FSTUBS_NAME \ - : public boost::python::detail::func_stubs_base { \ + : 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; \ @@ -208,7 +190,7 @@ struct func_stubs_base { BPL_IMPL_GEN_FUNCTION \ (FNAME, BOOST_PP_CAT(FSTUBS_NAME, _NV), N_ARGS, N_DFLTS, return) \ struct FSTUBS_NAME \ - : public boost::python::detail::func_stubs_base { \ + : 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; \ @@ -219,7 +201,7 @@ struct func_stubs_base { BPL_IMPL_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 { \ + : 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; \ @@ -272,17 +254,20 @@ struct func_stubs_base { // // static RT func_0(T0 arg0) // { return foo(arg0); } -// static RT func_1(T0 arg0,T1 arg1) +// +// 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); } +// +// 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 { +// : public boost::python::detail::func_stubs_base { // // typedef foo_stubs_NV nv_type; // typedef foo_stubs_NV v_type; diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp new file mode 100644 index 00000000..71a79f7a --- /dev/null +++ b/include/boost/python/init.hpp @@ -0,0 +1,350 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// +/////////////////////////////////////////////////////////////////////////////// +#ifndef INIT_JDG20020820_HPP +#define INIT_JDG20020820_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_TEMPLATE_TYPES_WITH_DEFAULT \ + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT \ + ( \ + BOOST_PYTHON_MAX_ARITY, \ + typename T, \ + boost::mpl::null_argument \ + ) \ + +#define BPL_IMPL_TEMPLATE_TYPES \ + BOOST_PP_ENUM_PARAMS \ + ( \ + BOOST_PYTHON_MAX_ARITY, \ + typename T \ + ) \ + +#define BPL_IMPL_TEMPLATE_ARGS \ + BOOST_PP_ENUM_PARAMS \ + ( \ + BOOST_PYTHON_MAX_ARITY, \ + T \ + ) \ + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace python { + +template +struct init; + +/////////////////////////////////////// +template +struct optional; + +namespace detail { + + /////////////////////////////////////////////////////////////////////////// + // + // is_nil::value + // + // This metaprogram checks if T is nil + // + /////////////////////////////////////////////////////////////////////////// + template + struct is_nil : public boost::is_same {}; + + /////////////////////////////////////////////////////////////////////////// + // + // is_optional::value + // + // This metaprogram checks if T is an optional + // + /////////////////////////////////////////////////////////////////////////// + #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + template + struct is_optional { + + private: + + template + static boost::type_traits::yes_type f(optional); + static boost::type_traits::no_type f(...); + static T t(); + + public: + + BOOST_STATIC_CONSTANT( + bool, value = + sizeof(f(t())) == sizeof(::boost::type_traits::yes_type)); + }; + + /////////////////////////////////////// + #else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + template + struct is_optional { + + BOOST_STATIC_CONSTANT(bool, value = false); + }; + + template + struct is_optional > { + + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + #endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + + /////////////////////////////////////////////////////////////////////////// + // + // append_to_init [ and helpers ] + // + // A metaprogram appends T to the initializer type list + // + /////////////////////////////////////////////////////////////////////////// + struct append_to_init_helper1 { + + // Case 1: default case, just push T to the back of ListT + + template + struct apply { + + typedef typename boost::mpl::push_back::sequence sequence; + }; + }; + + struct append_to_init_helper2 { + + template + struct apply { + + // Case 2: optional case, T is an optional, append all + // the contents of the optional T into back of ListT + + typedef typename boost::mpl::for_each + < + typename T::sequence, + ListT, + boost::mpl::push_back + >::state sequence; + }; + }; + + struct append_to_init_helper3 { + + // Case 3: nil case, we found a nil, do nothing + + template + struct apply { + + typedef ListT sequence; + }; + }; + + template + struct append_to_init { + + typedef typename boost::mpl::select_type + < + is_optional::value, // if + append_to_init_helper2, // then + typename boost::mpl::select_type // else + < + is_nil::value, // if + append_to_init_helper3, // then + append_to_init_helper1 // else + >::type + >::type helper; + + typedef typename helper::template apply::sequence sequence; + }; + + /////////////////////////////////////////////////////////////////////////// + // + // check_init_params [ and helpers ] + // + // Check the init template parameters. Detect illegal + // arguments such as: + // + // init, int> // BAD trailing int + // init, optional > // BAD optional used twice + // + /////////////////////////////////////////////////////////////////////////// + template + struct check_init_params_helper { + + template + struct apply { + + // case where size of sequence is not zero + + typedef typename boost::mpl::pop_front::sequence rest; + + enum { + + // if first is optional then there must be no more + // elements to its right. if not then recurse and check + // the rest of the type list + + first_is_optional = + is_optional::type>::value, + size_of_rest = boost::mpl::size::value, + rest_is_nil = (size_of_rest == 0), + is_ok = first_is_optional ? rest_is_nil : + check_init_params_helper + ::template apply::is_ok + }; + }; + }; + + template <> + struct check_init_params_helper<0> { + + // case where size of sequence is zero + + template + struct apply { + + enum { is_ok = true }; + }; + }; + + template + struct check_init_params { + + typedef boost::mpl::type_list params; + + BOOST_STATIC_ASSERT + ( + check_init_params_helper::value> + ::template apply::is_ok + ); + }; + + /////////////////////////////////////////////////////////////////////////// + // + // count_optional_types [ and helpers ] + // + // count_optional_types::value computes the number of + // optional types (see init and optional below). For example: + // + // init >::value == 3 + // + /////////////////////////////////////////////////////////////////////////// + template + struct count_optionals1 { + + BOOST_STATIC_CONSTANT(int, value = 0); + }; + + template + struct count_optionals2 { + + BOOST_STATIC_CONSTANT( + int, value = boost::mpl::size::value); + }; + + template + struct count_optionals + : boost::mpl::select_type + < + is_optional::value, // if + count_optionals2, // then + count_optionals1 // else + >::type + { + }; + + template + struct count_optional_types { + + BOOST_STATIC_CONSTANT(int, value = + count_optionals::value + + count_optionals::value + + count_optionals::value + ); + }; + +} // namespace detail + +/////////////////////////////////////////////////////////////////////////////// +// +// init +// +// init::sequence returns a typelist. One of T0..TN +// mat be an optional<...> see below. There should be only one +// optional in the input types and an optional should be the +// last in the list. +// +/////////////////////////////////////////////////////////////////////////////// +#define BPL_IMPL_APPEND_TO_INIT(INDEX, D) \ + typedef typename detail::append_to_init \ + < \ + BOOST_PP_CAT(l, INDEX), \ + BOOST_PP_CAT(T, BOOST_PP_INC(INDEX)) \ + >::sequence BOOST_PP_CAT(l, BOOST_PP_INC(INDEX)); \ + + +template +struct init : detail::check_init_params { + + typedef boost::mpl::type_list l0; + BOOST_PP_REPEAT + (BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY), BPL_IMPL_APPEND_TO_INIT, 0); + + typedef BOOST_PP_CAT(l, BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY)) sequence; + + BOOST_STATIC_CONSTANT(int, n_defaults = + (detail::count_optional_types::value) + ); +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// optional +// +// optional::sequence returns a typelist. +// +/////////////////////////////////////////////////////////////////////////////// +template +struct optional { + + typedef boost::mpl::type_list sequence; +}; + +#undef BPL_IMPL_TEMPLATE_TYPES_WITH_DEFAULT +#undef BPL_IMPL_TEMPLATE_TYPES +#undef BPL_IMPL_TEMPLATE_ARGS +#undef BPL_IMPL_IS_OPTIONAL_VALUE +#undef BPL_IMPL_APPEND_TO_INIT + +}} // namespace boost { namespace python { + +/////////////////////////////////////////////////////////////////////////////// +#endif // INIT_JDG20020820_HPP + + + + + + + + From d748e371e5990689f5b2a9cffef232bae7f8e269 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 20 Aug 2002 20:56:42 +0000 Subject: [PATCH 0652/1042] CWPro7 workaround [SVN r15006] --- src/object/class.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index e19ebfa7..445b98cd 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -266,10 +266,11 @@ namespace objects PyTuple_SET_ITEM(bases.get(), i - 1, upcast(c.release())); } - object module_name = PyObject_IsInstance(scope().ptr(), upcast(&PyModule_Type)) + object module_name( + PyObject_IsInstance(scope().ptr(), upcast(&PyModule_Type)) ? scope().attr("__name__") : api::getattr(scope(), "__module__", object("")) - ; + ); if (module_name) module_name += '.'; From 78ae892db663772fa00a863815f97c9545b3a33c Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Tue, 20 Aug 2002 21:09:59 +0000 Subject: [PATCH 0653/1042] 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) ; From 4bd680cec8a54856bcecda62f80fc622565b9e9b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 20 Aug 2002 21:15:54 +0000 Subject: [PATCH 0654/1042] VC6 workaround [SVN r15009] --- test/nested.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/nested.cpp b/test/nested.cpp index 1187c7d8..9bc5be32 100644 --- a/test/nested.cpp +++ b/test/nested.cpp @@ -8,10 +8,26 @@ #include #include #include "test_class.hpp" +#if __GNUC__ != 2 +# include +#else +# include +#endif typedef test_class<> X; typedef test_class<1> Y; +std::ostream& operator<<(std::ostream& s, X const& x) +{ + return s << x.value(); +} + +std::ostream& operator<<(std::ostream& s, Y const& x) +{ + return s << x.value(); +} + + BOOST_PYTHON_MODULE_INIT(nested_ext) { using namespace boost::python; From b7e300d155219a901de4a621ecac7408532b50e7 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Tue, 20 Aug 2002 21:35:37 +0000 Subject: [PATCH 0655/1042] latest signature [SVN r15010] --- include/boost/python/signature.hpp | 363 ++++++++++++++++------------- 1 file changed, 203 insertions(+), 160 deletions(-) diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index d83071a1..9f43ae1f 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -7,6 +7,8 @@ // to its suitability for any purpose. // /////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_PP_IS_ITERATING) + #ifndef SIGNATURE_JDG20020813_HPP #define SIGNATURE_JDG20020813_HPP @@ -15,6 +17,7 @@ #include #include #include +#include #include /////////////////////////////////////////////////////////////////////////////// @@ -40,15 +43,6 @@ struct signature {}; namespace detail { -/////////////////////////////////////////////////////////////////////////////// -// Temporary BOOST_PP fix before the CVS stabalizes /*$$$ FIX ME $$$*/ - -#ifndef BOOST_PP_FIX_REPEAT_2ND -#define BOOST_PP_FIX_REPEAT_2ND(c, m, d) /* ... */ \ - BOOST_PP_CAT(BOOST_PP_R2_, c)(m, d) \ - /**/ -#endif - /////////////////////////////////////////////////////////////////////////////// // // The following macros generate expansions for: @@ -102,158 +96,10 @@ namespace detail { #define BPL_IMPL_TEMPLATE_GEN(INDEX, DATA) typename BOOST_PP_CAT(T, INDEX) /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_GET_FUNCTION_SIGNATURE(INDEX, DATA) \ - \ - template \ - < \ - typename RT BOOST_PP_COMMA_IF(INDEX) \ - BOOST_PP_ENUM \ - ( \ - INDEX, \ - BPL_IMPL_TEMPLATE_GEN, \ - BOOST_PP_EMPTY \ - ) \ - > \ - inline boost::mpl::type_list \ - < \ - RT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ - > \ - get_signature(signature) \ - { \ - return boost::mpl::type_list \ - (); \ - } \ - \ - template \ - < \ - typename RT BOOST_PP_COMMA_IF(INDEX) \ - BOOST_PP_ENUM \ - ( \ - INDEX, \ - BPL_IMPL_TEMPLATE_GEN, \ - BOOST_PP_EMPTY \ - ) \ - > \ - inline boost::mpl::type_list \ - < \ - RT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ - > \ - get_signature(RT(*)(BOOST_PP_ENUM_PARAMS(INDEX, T))) \ - { \ - return boost::mpl::type_list \ - (); \ - } \ +#define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY-1, )) -/////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_GET_MEMBER_FUNCTION_SIGNATURE(INDEX, DATA) \ - \ - template \ - < \ - typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ - BOOST_PP_ENUM \ - ( \ - INDEX, \ - BPL_IMPL_TEMPLATE_GEN, \ - BOOST_PP_EMPTY \ - ) \ - > \ - inline boost::mpl::type_list \ - < \ - RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ - > \ - get_signature(signature) \ - { \ - return boost::mpl::type_list \ - \ - (); \ - } \ - \ - \ - template \ - < \ - typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ - BOOST_PP_ENUM \ - ( \ - INDEX, \ - BPL_IMPL_TEMPLATE_GEN, \ - BOOST_PP_EMPTY \ - ) \ - > \ - inline boost::mpl::type_list \ - < \ - RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ - > \ - get_signature( \ - signature) \ - { \ - return boost::mpl::type_list \ - < \ - RT, ClassT const \ - BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ - >(); \ - } \ - \ - template \ - < \ - typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ - BOOST_PP_ENUM \ - ( \ - INDEX, \ - BPL_IMPL_TEMPLATE_GEN, \ - BOOST_PP_EMPTY \ - ) \ - > \ - inline boost::mpl::type_list \ - < \ - RT, ClassT BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ - > \ - get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(INDEX, T))) \ - { \ - return boost::mpl::type_list \ - \ - (); \ - } \ - \ - template \ - < \ - typename RT, typename ClassT BOOST_PP_COMMA_IF(INDEX) \ - BOOST_PP_ENUM \ - ( \ - INDEX, \ - BPL_IMPL_TEMPLATE_GEN, \ - BOOST_PP_EMPTY \ - ) \ - > \ - inline boost::mpl::type_list \ - < \ - RT, ClassT const \ - BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ - > \ - get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(INDEX, T)) const) \ - { \ - return boost::mpl::type_list \ - < \ - RT, ClassT const \ - BOOST_PP_COMMA_IF(INDEX) BOOST_PP_ENUM_PARAMS(INDEX, T) \ - >(); \ - } \ - -/////////////////////////////////////////////////////////////////////////////// - -BOOST_PP_FIX_REPEAT_2ND \ -( \ - BOOST_PP_SUB(BOOST_PYTHON_MAX_ARITY, 1), \ - BPL_IMPL_GET_FUNCTION_SIGNATURE, BOOST_PP_EMPTY \ -) - -BOOST_PP_FIX_REPEAT_2ND \ -( \ - BOOST_PP_SUB(BOOST_PYTHON_MAX_ARITY, 2), \ - BPL_IMPL_GET_MEMBER_FUNCTION_SIGNATURE, BOOST_PP_EMPTY \ -) - -#undef BPL_IMPL_GET_FUNCTION_SIGNATURE -#undef BPL_IMPL_GET_MEMBER_FUNCTION_SIGNATURE +#include BOOST_PP_ITERATE() #undef BPL_IMPL_TEMPLATE_GEN } @@ -264,3 +110,200 @@ BOOST_PP_FIX_REPEAT_2ND #endif // SIGNATURE_JDG20020813_HPP +#else // defined(BOOST_PP_IS_ITERATING) +// PP vertical iteration code + +/////////////////////////////////////////////////////////////////////////////// +template +< + typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM + ( + BOOST_PP_ITERATION(), + BPL_IMPL_TEMPLATE_GEN, + BOOST_PP_EMPTY + ) +> +inline boost::mpl::type_list +< + RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) +> +get_signature + (signature) +{ + return boost::mpl::type_list + < + RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) + >(); +} + +/////////////////////////////////////// +#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) + +template +< + typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM + ( + BOOST_PP_ITERATION(), + BPL_IMPL_TEMPLATE_GEN, + BOOST_PP_EMPTY + ) +> +inline boost::mpl::type_list +< + RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) +> +get_signature + (signature) +{ + return boost::mpl::type_list + < + RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) + >(); +} + +#endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) + +/////////////////////////////////////// +template +< + typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM + ( + BOOST_PP_ITERATION(), + BPL_IMPL_TEMPLATE_GEN, + BOOST_PP_EMPTY + ) +> +inline boost::mpl::type_list +< + RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) +> +get_signature + (RT(*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))) +{ + return boost::mpl::type_list + < + RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) + >(); +} + +/////////////////////////////////////////////////////////////////////////////// +#if BOOST_PP_ITERATION() <= (BOOST_PYTHON_MAX_ARITY - 2) + +template +< + typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM + ( + BOOST_PP_ITERATION(), + BPL_IMPL_TEMPLATE_GEN, + BOOST_PP_EMPTY + ) +> +inline boost::mpl::type_list +< + RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) +> +get_signature + (signature) +{ + return boost::mpl::type_list + < + RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)> + (); +} + +/////////////////////////////////////// +template +< + typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM + ( + BOOST_PP_ITERATION(), + BPL_IMPL_TEMPLATE_GEN, + BOOST_PP_EMPTY + ) +> +inline boost::mpl::type_list +< + RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) +> +get_signature + (signature) +{ + return boost::mpl::type_list + < + RT, ClassT const + BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) + >(); +} + +/////////////////////////////////////// +template +< + typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM + ( + BOOST_PP_ITERATION(), + BPL_IMPL_TEMPLATE_GEN, + BOOST_PP_EMPTY + ) +> +inline boost::mpl::type_list +< + RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) +> +get_signature + (RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))) +{ + return boost::mpl::type_list + < + RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) + >(); +} + +/////////////////////////////////////// +template +< + typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM + ( + BOOST_PP_ITERATION(), + BPL_IMPL_TEMPLATE_GEN, + BOOST_PP_EMPTY + ) +> +inline boost::mpl::type_list +< + RT, ClassT const + BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) +> +get_signature + (RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const) +{ + return boost::mpl::type_list + < + RT, ClassT const + BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) + >(); +} + +#endif // BOOST_PP_ITERATION() < (BOOST_PYTHON_MAX_ARITY - 2) + +#endif // !defined(BOOST_PP_IS_ITERATING) From d66b79f468a3e18008ca798310747eaf0faa8d37 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 21 Aug 2002 00:04:06 +0000 Subject: [PATCH 0656/1042] added defaults test from v2-dev branch [SVN r15017] --- test/defaults.cpp | 111 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 test/defaults.cpp diff --git a/test/defaults.cpp b/test/defaults.cpp new file mode 100644 index 00000000..9e8170b5 --- /dev/null +++ b/test/defaults.cpp @@ -0,0 +1,111 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include + +#if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 +# include // works around a KCC intermediate code generation bug +#endif + +using namespace boost::python; +using namespace std; + +/////////////////////////////////////////////////////////////////////////////// +object +bar(int a, char b, std::string c, double d) +{ + list abcd; + abcd.append(a); + abcd.append(b); + abcd.append(c); + abcd.append(d); + return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); +} + +object +bar(int a, char b, std::string c) +{ + list abcd; + abcd.append(a); + abcd.append(b); + abcd.append(c); + abcd.append(0.0); + return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); +} + +object +bar(int a, char b) +{ + list abcd; + abcd.append(a); + abcd.append(b); + abcd.append("default"); + abcd.append(0.0); + return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); +} + +object +bar(int a) +{ + list abcd; + abcd.append(a); + abcd.append('D'); + abcd.append("default"); + abcd.append(0.0); + return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); +} + +BOOST_PYTHON_FUNCTION_GENERATOR(bar_stubs, bar, 1, 4) + +/////////////////////////////////////////////////////////////////////////////// +object +foo(int a, char b = 'D', std::string c = "default", double d = 0.0) +{ + list abcd; + abcd.append(a); + abcd.append(b); + abcd.append(c); + abcd.append(d); + return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); +} + +BOOST_PYTHON_FUNCTION_GENERATOR(foo_stubs, foo, 1, 4) + +/////////////////////////////////////////////////////////////////////////////// + +struct X { + + object + bar(int a, char b = 'D', std::string c = "default", double d = 0.0) const + { + list abcd; + abcd.append(a); + abcd.append(b); + abcd.append(c); + abcd.append(d); + return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); + } +}; + +BOOST_PYTHON_MEM_FUN_GENERATOR(X_bar_stubs, bar, 1, 4) + +/////////////////////////////////////////////////////////////////////////////// + +BOOST_PYTHON_MODULE_INIT(defaults_ext) +{ + module m("defaults_ext"); + m.def("foo", foo, foo_stubs()); + m.def("bar", signature(), bar_stubs()); + + class_ xc("X"); + m.add(xc); + + xc.def_init(); + xc.def("bar", X::bar, X_bar_stubs()); +} + +#include "module_tail.cpp" From f96a898c517dc756ff249db24eeb810cc6d7015b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 21 Aug 2002 01:46:03 +0000 Subject: [PATCH 0657/1042] VC6 fixups [SVN r15018] --- include/boost/python/detail/defaults_def.hpp | 16 +++--- include/boost/python/signature.hpp | 55 +++++++++----------- 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index 03495ee9..16cdd55e 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -131,13 +131,15 @@ namespace detail { SigT sig, char const* doc) { - typedef typename mpl::select_type - < - boost::is_same::type>::value, - typename StubsT::v_type, - typename StubsT::nv_type - > - ::type stubs_type; + typedef typename mpl::at<0, SigT>::type nth_type; + typedef typename StubsT::v_type v_type; + typedef typename StubsT::nv_type nv_type; + + typedef typename mpl::select_type< + boost::is_same::value + , v_type + , nv_type + >::type stubs_type; BOOST_STATIC_ASSERT( (stubs_type::max_args + 1) <= boost::mpl::size::value); diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index 9f43ae1f..e5134b20 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -38,7 +38,7 @@ namespace boost { namespace python { // signature void C::foo(int, int) const // /////////////////////////////////////////////////////////////////////////////// -template +template struct signature {}; namespace detail { @@ -47,42 +47,42 @@ namespace detail { // // The following macros generate expansions for: // -// template +// template // inline boost::mpl::type_list // get_signature(signature) // { // return boost::mpl::type_list(); // } // -// template +// template // inline boost::mpl::type_list // get_signature(RT(*)(T0...TN)) // { // return boost::mpl::type_list(); // } // -// template +// template // inline boost::mpl::type_list // get_signature(signature) // { // return boost::mpl::type_list(); // } // -// template +// template // inline boost::mpl::type_list // get_signature(signature) // { // return boost::mpl::type_list(); // } // -// template +// template // inline boost::mpl::type_list // get_signature(RT(ClassT::*)(T0...TN))) // { // return boost::mpl::type_list(); // } // -// template +// template // inline boost::mpl::type_list // get_signature(RT(ClassT::*)(T0...TN) const)) // { @@ -93,7 +93,7 @@ namespace detail { // and arguments of the input signature and stuffs them in an mpl::type_list. // /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_TEMPLATE_GEN(INDEX, DATA) typename BOOST_PP_CAT(T, INDEX) +#define BPL_IMPL_TEMPLATE_GEN(INDEX, DATA) class BOOST_PP_CAT(T, INDEX) /////////////////////////////////////////////////////////////////////////////// #define BOOST_PP_ITERATION_PARAMS_1 \ @@ -113,10 +113,10 @@ namespace detail { #else // defined(BOOST_PP_IS_ITERATING) // PP vertical iteration code -/////////////////////////////////////////////////////////////////////////////// +# if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) template < - typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + class RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -139,12 +139,9 @@ get_signature >(); } -/////////////////////////////////////// -#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) - template < - typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + class RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -167,12 +164,12 @@ get_signature >(); } -#endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) +# endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) /////////////////////////////////////// template < - typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + class RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -196,11 +193,11 @@ get_signature } /////////////////////////////////////////////////////////////////////////////// -#if BOOST_PP_ITERATION() <= (BOOST_PYTHON_MAX_ARITY - 2) +# if BOOST_PP_ITERATION() <= (BOOST_PYTHON_MAX_ARITY - 2) template < - typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + class RT, class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -223,19 +220,17 @@ get_signature (); } -/////////////////////////////////////// -template -< - typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM - ( +# if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) +template < + class RT + , class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM( BOOST_PP_ITERATION(), BPL_IMPL_TEMPLATE_GEN, BOOST_PP_EMPTY ) > -inline boost::mpl::type_list -< +inline boost::mpl::type_list< RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) > @@ -249,11 +244,11 @@ get_signature BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) >(); } +# endif -/////////////////////////////////////// template < - typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + class RT, class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -279,7 +274,7 @@ get_signature /////////////////////////////////////// template < - typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + class RT, class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -304,6 +299,6 @@ get_signature >(); } -#endif // BOOST_PP_ITERATION() < (BOOST_PYTHON_MAX_ARITY - 2) +# endif // BOOST_PP_ITERATION() < (BOOST_PYTHON_MAX_ARITY - 2) #endif // !defined(BOOST_PP_IS_ITERATING) From 3173d88f3f08488fbd31614120fb6bf6fe971b9b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 21 Aug 2002 01:47:48 +0000 Subject: [PATCH 0658/1042] dump help without prompting [SVN r15019] --- test/docstring.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/docstring.py b/test/docstring.py index 54bbfc45..fd9d3cfe 100644 --- a/test/docstring.py +++ b/test/docstring.py @@ -33,9 +33,11 @@ def run(args = None): result = doctest.testmod(sys.modules.get(__name__)) + import pydoc + docmodule = pydoc.TextDoc().docmodule try: print 'printing module help:' - help(docstring_ext) + print docmodule(docstring_ext) except object, x: print '********* failed **********' print x From 3e61803e890083250ff507a585bb79107cd54e0d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 21 Aug 2002 01:48:03 +0000 Subject: [PATCH 0659/1042] simplification [SVN r15020] --- test/Jamfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Jamfile b/test/Jamfile index 6ca688a2..7dcd3351 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -63,7 +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 defaults ; bpl-test object ; bpl-test list ; From 37efd93725f3469fb56b6111ba94c222bb640acc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 21 Aug 2002 05:42:21 +0000 Subject: [PATCH 0660/1042] Bug fix [SVN r15021] --- include/boost/python/detail/defaults_def.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index 16cdd55e..2b7f1375 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -144,7 +144,7 @@ namespace detail { BOOST_STATIC_ASSERT( (stubs_type::max_args + 1) <= boost::mpl::size::value); - typedef stubs_type::template gen gen_type; + typedef typename stubs_type::template gen gen_type; define_with_defaults_helper::def (name, gen_type(), holder, doc); } From 8a049b8ee7e3e9963756a726c5cca6e916af0469 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 21 Aug 2002 12:20:26 +0000 Subject: [PATCH 0661/1042] Added missing & [SVN r15023] --- test/defaults.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/defaults.cpp b/test/defaults.cpp index 9e8170b5..a3c20a77 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -105,7 +105,7 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) m.add(xc); xc.def_init(); - xc.def("bar", X::bar, X_bar_stubs()); + xc.def("bar", &X::bar, X_bar_stubs()); } #include "module_tail.cpp" From a9bb2a017eb1325d58ec85096cc5db88fe9b8609 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 21 Aug 2002 13:46:16 +0000 Subject: [PATCH 0662/1042] VC6 workarounds [SVN r15026] --- test/Jamfile | 2 +- test/defaults.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/test/Jamfile b/test/Jamfile index 7dcd3351..6ca688a2 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -63,7 +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 ; +bpl-test defaults_ext : defaults.py defaults.cpp ; bpl-test object ; bpl-test list ; diff --git a/test/defaults.cpp b/test/defaults.cpp index a3c20a77..5c75ddda 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -99,7 +99,12 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) { module m("defaults_ext"); m.def("foo", foo, foo_stubs()); + +#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) m.def("bar", signature(), bar_stubs()); +#else // signature does not work on VC6 only (VC is ok) + m.def("bar", (object(*)(int, char, std::string, double))0, bar_stubs()); +#endif class_ xc("X"); m.add(xc); From 087c09cc652d386ca754f3f5b7783e8fa860e758 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 21 Aug 2002 13:47:02 +0000 Subject: [PATCH 0663/1042] VC6 Workaronds (cleanup) [SVN r15027] --- include/boost/python/detail/defaults_def.hpp | 18 ++++-- include/boost/python/signature.hpp | 63 ++++++++++++-------- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index 2b7f1375..f7105b6f 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -48,6 +48,9 @@ namespace detail { // 5. char const* name: doc string // /////////////////////////////////////////////////////////////////////////////// +template +struct define_stub_function {}; + #define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, BOOST_PYTHON_MAX_ARITY, )) @@ -81,7 +84,7 @@ namespace detail { def(char const* name, StubsT stubs, HolderT& holder, char const* doc) { // define the NTH stub function of stubs - define_stub_function(name, stubs, holder, boost::mpl::int_t(), doc); + define_stub_function::define(name, stubs, holder, doc); // call the next define_with_defaults_helper define_with_defaults_helper::def(name, stubs, holder, doc); } @@ -96,7 +99,7 @@ namespace detail { def(char const* name, StubsT stubs, HolderT& holder, char const* doc) { // define the Oth stub function of stubs - define_stub_function(name, stubs, holder, boost::mpl::int_t<0>(), doc); + define_stub_function<0>::define(name, stubs, holder, doc); // return } }; @@ -134,7 +137,7 @@ namespace detail { typedef typename mpl::at<0, SigT>::type nth_type; typedef typename StubsT::v_type v_type; typedef typename StubsT::nv_type nv_type; - + typedef typename mpl::select_type< boost::is_same::value , v_type @@ -159,14 +162,16 @@ namespace detail { #else // defined(BOOST_PP_IS_ITERATING) // PP vertical iteration code +template <> +struct define_stub_function { + template - inline void - define_stub_function + static void + define ( char const* name, StubsT, HolderT& holder, - boost::mpl::int_t, char const* doc ) { @@ -176,5 +181,6 @@ namespace detail { default_call_policies(), doc); } +}; #endif // !defined(BOOST_PP_IS_ITERATING) diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index e5134b20..65d90a6d 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -38,7 +38,7 @@ namespace boost { namespace python { // signature void C::foo(int, int) const // /////////////////////////////////////////////////////////////////////////////// -template +template struct signature {}; namespace detail { @@ -47,42 +47,42 @@ namespace detail { // // The following macros generate expansions for: // -// template +// template // inline boost::mpl::type_list // get_signature(signature) // { // return boost::mpl::type_list(); // } // -// template +// template // inline boost::mpl::type_list // get_signature(RT(*)(T0...TN)) // { // return boost::mpl::type_list(); // } // -// template +// template // inline boost::mpl::type_list // get_signature(signature) // { // return boost::mpl::type_list(); // } // -// template +// template // inline boost::mpl::type_list // get_signature(signature) // { // return boost::mpl::type_list(); // } // -// template +// template // inline boost::mpl::type_list // get_signature(RT(ClassT::*)(T0...TN))) // { // return boost::mpl::type_list(); // } // -// template +// template // inline boost::mpl::type_list // get_signature(RT(ClassT::*)(T0...TN) const)) // { @@ -93,7 +93,7 @@ namespace detail { // and arguments of the input signature and stuffs them in an mpl::type_list. // /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_TEMPLATE_GEN(INDEX, DATA) class BOOST_PP_CAT(T, INDEX) +#define BPL_IMPL_TEMPLATE_GEN(INDEX, DATA) typename BOOST_PP_CAT(T, INDEX) /////////////////////////////////////////////////////////////////////////////// #define BOOST_PP_ITERATION_PARAMS_1 \ @@ -113,10 +113,12 @@ namespace detail { #else // defined(BOOST_PP_IS_ITERATING) // PP vertical iteration code -# if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) +/////////////////////////////////////////////////////////////////////////////// +#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) + template < - class RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -139,9 +141,14 @@ get_signature >(); } +#endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) + +/////////////////////////////////////// +#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) + template < - class RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -164,12 +171,12 @@ get_signature >(); } -# endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) +#endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) /////////////////////////////////////// template < - class RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -193,11 +200,13 @@ get_signature } /////////////////////////////////////////////////////////////////////////////// -# if BOOST_PP_ITERATION() <= (BOOST_PYTHON_MAX_ARITY - 2) +#if BOOST_PP_ITERATION() <= (BOOST_PYTHON_MAX_ARITY - 2) + +#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) template < - class RT, class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -220,17 +229,19 @@ get_signature (); } -# if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) -template < - class RT - , class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM( +/////////////////////////////////////// +template +< + typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM + ( BOOST_PP_ITERATION(), BPL_IMPL_TEMPLATE_GEN, BOOST_PP_EMPTY ) > -inline boost::mpl::type_list< +inline boost::mpl::type_list +< RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) > @@ -244,11 +255,13 @@ get_signature BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) >(); } -# endif +#endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) + +/////////////////////////////////////// template < - class RT, class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -274,7 +287,7 @@ get_signature /////////////////////////////////////// template < - class RT, class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM ( BOOST_PP_ITERATION(), @@ -299,6 +312,6 @@ get_signature >(); } -# endif // BOOST_PP_ITERATION() < (BOOST_PYTHON_MAX_ARITY - 2) +#endif // BOOST_PP_ITERATION() < (BOOST_PYTHON_MAX_ARITY - 2) #endif // !defined(BOOST_PP_IS_ITERATING) From d5c33a203de1310f90058a3bf87cf14e1823ffba Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 21 Aug 2002 15:15:13 +0000 Subject: [PATCH 0664/1042] simplify [SVN r15030] --- test/Jamfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Jamfile b/test/Jamfile index 6ca688a2..7dcd3351 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -63,7 +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 defaults ; bpl-test object ; bpl-test list ; From 30ea4dd46e46a4fdd887e3228f6d77877a1799be Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 21 Aug 2002 15:19:06 +0000 Subject: [PATCH 0665/1042] idiomatic cleanup [SVN r15032] --- test/defaults.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/test/defaults.cpp b/test/defaults.cpp index 5c75ddda..2ff2bc21 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -97,20 +97,19 @@ BOOST_PYTHON_MEM_FUN_GENERATOR(X_bar_stubs, bar, 1, 4) BOOST_PYTHON_MODULE_INIT(defaults_ext) { - module m("defaults_ext"); - m.def("foo", foo, foo_stubs()); - + module("defaults_ext") + .def("foo", foo, foo_stubs()) + #if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) - m.def("bar", signature(), bar_stubs()); -#else // signature does not work on VC6 only (VC is ok) - m.def("bar", (object(*)(int, char, std::string, double))0, bar_stubs()); + .def("bar", signature(), bar_stubs()) +#else // signature does not work on VC6 only (VC7 is ok) + .def("bar", (object(*)(int, char, std::string, double))0, bar_stubs()) #endif + ; - class_ xc("X"); - m.add(xc); - - xc.def_init(); - xc.def("bar", &X::bar, X_bar_stubs()); + class_("X") + .def("bar", &X::bar, X_bar_stubs()) + ; } #include "module_tail.cpp" From e4f54bd53a4986594db87820d3e0c1b110215f5f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 21 Aug 2002 18:46:14 +0000 Subject: [PATCH 0666/1042] Strip out overstrike junk [SVN r15040] --- test/docstring.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/docstring.py b/test/docstring.py index fd9d3cfe..15cfdaf1 100644 --- a/test/docstring.py +++ b/test/docstring.py @@ -34,7 +34,8 @@ def run(args = None): result = doctest.testmod(sys.modules.get(__name__)) import pydoc - docmodule = pydoc.TextDoc().docmodule + import re + docmodule = lambda m: re.sub(".\10", "", pydoc.text.docmodule(m)) try: print 'printing module help:' print docmodule(docstring_ext) From cfb1aebf669dde3145782da181c4e9635bb70f5b Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Thu, 22 Aug 2002 05:23:45 +0000 Subject: [PATCH 0667/1042] + Added Ralf's test code + Fixed defaults_gen MACRO generation + Fixed signature for const member functions [SVN r15047] --- include/boost/python/detail/defaults_gen.hpp | 4 +- include/boost/python/signature.hpp | 2 +- test/defaults.cpp | 42 +++++++++++++++++++- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 9637ae24..18931a61 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -88,7 +88,7 @@ struct func_stubs_base {}; \ BOOST_PP_FIX_REPEAT_2ND \ ( \ - BOOST_PP_INC(N_DFLTS), \ + N_ARGS, \ BPL_IMPL_TYPEDEF_GEN, \ 1 \ ) \ @@ -140,7 +140,7 @@ struct func_stubs_base {}; \ BOOST_PP_FIX_REPEAT_2ND \ ( \ - BOOST_PP_INC(N_DFLTS), \ + N_ARGS, \ BPL_IMPL_TYPEDEF_GEN, \ 2 \ ) \ diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index 65d90a6d..8a82bbe7 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -242,7 +242,7 @@ template > inline boost::mpl::type_list < - RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + RT, ClassT const BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) > get_signature diff --git a/test/defaults.cpp b/test/defaults.cpp index 2ff2bc21..7e5f4d25 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -89,9 +89,39 @@ struct X { abcd.append(d); return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); } + + object + foo(int a, bool b=false) const + { + list ab; + ab.append(a); + ab.append(b); + return "int(%s); bool(%s); " % tuple(ab); + } + + object + foo(std::string a, bool b=false) const + { + list ab; + ab.append(a); + ab.append(b); + return "string(%s); bool(%s); " % tuple(ab); + } + + object + foo(list a, list b, bool c=false) const + { + list abc; + abc.append(a); + abc.append(b); + abc.append(c); + return "list(%s); list(%s); bool(%s); " % tuple(abc); + } }; BOOST_PYTHON_MEM_FUN_GENERATOR(X_bar_stubs, bar, 1, 4) +BOOST_PYTHON_MEM_FUN_GENERATOR(X_foo_2_stubs, foo, 1, 2) +BOOST_PYTHON_MEM_FUN_GENERATOR(X_foo_3_stubs, foo, 2, 3) /////////////////////////////////////////////////////////////////////////////// @@ -99,7 +129,7 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) { module("defaults_ext") .def("foo", foo, foo_stubs()) - + #if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) .def("bar", signature(), bar_stubs()) #else // signature does not work on VC6 only (VC7 is ok) @@ -109,7 +139,17 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) class_("X") .def("bar", &X::bar, X_bar_stubs()) + .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) + +#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) + .def("foo", signature(), X_foo_2_stubs()) +#else // signature does not work on VC6 only (VC7 is ok) + .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) +#endif + + .def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs()) ; } #include "module_tail.cpp" + From 68c8901c2a855ef7b538230d389875081b52549a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 22 Aug 2002 13:18:36 +0000 Subject: [PATCH 0668/1042] Metrowerks workaround [SVN r15051] --- include/boost/python/signature.hpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index 8a82bbe7..9d5129e5 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -146,6 +146,14 @@ get_signature /////////////////////////////////////// #if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) +# if defined(__MWERKS__) && __MWERKS__ <= 0x3002 && BOOST_PP_ITERATION() == 0 +template +inline boost::mpl::type_list +get_signature(signature) +{ + return boost::mpl::type_list(); +} +# else template < typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) @@ -161,8 +169,10 @@ inline boost::mpl::type_list RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) > -get_signature - (signature) +get_signature( + signature< + RT(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) + >) { return boost::mpl::type_list < @@ -170,6 +180,7 @@ get_signature BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) >(); } +# endif #endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) From e1099e9370dbc35634d254b9ee58411eb88049cb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 22 Aug 2002 13:20:58 +0000 Subject: [PATCH 0669/1042] Added make_tuple [SVN r15052] --- include/boost/python/detail/make_tuple.hpp | 31 +++++++++++ include/boost/python/tuple.hpp | 5 ++ test/defaults.cpp | 61 +++++----------------- 3 files changed, 48 insertions(+), 49 deletions(-) create mode 100644 include/boost/python/detail/make_tuple.hpp diff --git a/include/boost/python/detail/make_tuple.hpp b/include/boost/python/detail/make_tuple.hpp new file mode 100644 index 00000000..bbb67e07 --- /dev/null +++ b/include/boost/python/detail/make_tuple.hpp @@ -0,0 +1,31 @@ +# // Copyright David Abrahams 2002. Permission to copy, use, +# // modify, sell and distribute this software is granted provided this +# // copyright notice appears in all copies. This software is provided +# // "as is" without express or implied warranty, and with no claim as +# // to its suitability for any purpose. + +#if !defined(BOOST_PP_IS_ITERATING) +# error Boost.Python - do not include this file! +#endif + +#define N BOOST_PP_ITERATION() + +#define BOOST_PYTHON_MAKE_TUPLE_ARG(N, ignored) \ + PyTuple_SET_ITEM( \ + result.ptr() \ + , N \ + , python::incref(python::object(a##N).ptr()) \ + ); + + template + tuple + make_tuple(BOOST_PYTHON_BINARY_ENUM(N, A, const& a)) + { + tuple result((detail::new_reference)::PyTuple_New(N)); + BOOST_PP_REPEAT(N, BOOST_PYTHON_MAKE_TUPLE_ARG, _) + return result; + } + +#undef BOOST_PYTHON_MAKE_TUPLE_ARG + +#undef N diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp index d18eb0c3..04e2d37b 100644 --- a/include/boost/python/tuple.hpp +++ b/include/boost/python/tuple.hpp @@ -28,6 +28,11 @@ class tuple : public object static BOOST_PYTHON_DECL detail::new_reference call(object const&); }; +// for completeness +inline tuple make_tuple() { return tuple(); } + +# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, )) +# include BOOST_PP_ITERATE() // // Converter Specializations diff --git a/test/defaults.cpp b/test/defaults.cpp index 7e5f4d25..f7b2da9c 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -5,6 +5,7 @@ // to its suitability for any purpose. #include #include +#include #include #if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 @@ -14,49 +15,31 @@ using namespace boost::python; using namespace std; +char const* const format = "int(%s); char(%s); string(%s); double(%s); "; + /////////////////////////////////////////////////////////////////////////////// object bar(int a, char b, std::string c, double d) { - list abcd; - abcd.append(a); - abcd.append(b); - abcd.append(c); - abcd.append(d); - return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); + return format % make_tuple(a, b, c, d); } object bar(int a, char b, std::string c) { - list abcd; - abcd.append(a); - abcd.append(b); - abcd.append(c); - abcd.append(0.0); - return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); + return format % make_tuple(a, b, c, 0.0); } object bar(int a, char b) { - list abcd; - abcd.append(a); - abcd.append(b); - abcd.append("default"); - abcd.append(0.0); - return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); + return format % make_tuple(a, b, "default", 0.0); } object bar(int a) { - list abcd; - abcd.append(a); - abcd.append('D'); - abcd.append("default"); - abcd.append(0.0); - return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); + return format % make_tuple(a, 'D', "default", 0.0); } BOOST_PYTHON_FUNCTION_GENERATOR(bar_stubs, bar, 1, 4) @@ -65,12 +48,7 @@ BOOST_PYTHON_FUNCTION_GENERATOR(bar_stubs, bar, 1, 4) object foo(int a, char b = 'D', std::string c = "default", double d = 0.0) { - list abcd; - abcd.append(a); - abcd.append(b); - abcd.append(c); - abcd.append(d); - return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); + return format % make_tuple(a, b, c, d); } BOOST_PYTHON_FUNCTION_GENERATOR(foo_stubs, foo, 1, 4) @@ -82,40 +60,25 @@ struct X { object bar(int a, char b = 'D', std::string c = "default", double d = 0.0) const { - list abcd; - abcd.append(a); - abcd.append(b); - abcd.append(c); - abcd.append(d); - return "int(%s); char(%s); string(%s); double(%s); " % tuple(abcd); + return format % make_tuple(a, b, c, d); } object foo(int a, bool b=false) const { - list ab; - ab.append(a); - ab.append(b); - return "int(%s); bool(%s); " % tuple(ab); + return "int(%s); bool(%s); " % make_tuple(a, b); } object foo(std::string a, bool b=false) const { - list ab; - ab.append(a); - ab.append(b); - return "string(%s); bool(%s); " % tuple(ab); + return "string(%s); bool(%s); " % make_tuple(a, b); } object foo(list a, list b, bool c=false) const { - list abc; - abc.append(a); - abc.append(b); - abc.append(c); - return "list(%s); list(%s); bool(%s); " % tuple(abc); + return "list(%s); list(%s); bool(%s); " % make_tuple(a, b, c); } }; From 8a20f8b2da82b25064101bf88294cd19afda8fa4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 22 Aug 2002 13:50:28 +0000 Subject: [PATCH 0670/1042] Simplify code by taking advantage of high-level object() facilities [SVN r15053] --- src/object/class.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index 445b98cd..90999f35 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -275,17 +276,9 @@ namespace objects if (module_name) module_name += '.'; - // Build the (name, bases, dict) tuple for creating the new class - handle<> args(PyTuple_New(3)); - PyTuple_SET_ITEM(args.get(), 0, incref((module_name + name).ptr())); - PyTuple_SET_ITEM(args.get(), 1, bases.release()); - handle<> d(PyDict_New()); - PyTuple_SET_ITEM(args.get(), 2, d.release()); - // Call the class metatype to create a new class - PyObject* c = PyObject_CallObject(upcast(class_metatype().get()), args.get()); - assert(PyType_IsSubtype(c->ob_type, &PyType_Type)); - object result = object(python::detail::new_reference(c)); + object result = object(class_metatype())(module_name + name, bases, dict()); + assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type)); if (scope().ptr() != Py_None) scope().attr(name) = result; From b06e8c30226ab5b2d472b143d275e5ab468bf0bd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 22 Aug 2002 13:51:10 +0000 Subject: [PATCH 0671/1042] Qualified boost::make_tuple to avoid conflicts [SVN r15054] --- src/object/inheritance.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/object/inheritance.cpp b/src/object/inheritance.cpp index 39c95f6e..13dfaef0 100644 --- a/src/object/inheritance.cpp +++ b/src/object/inheritance.cpp @@ -190,7 +190,7 @@ namespace return std::lower_bound( type_index().begin(), type_index().end() - , make_tuple(type, vertex_t(), dynamic_id_function(0)) + , boost::make_tuple(type, vertex_t(), dynamic_id_function(0)) , boost::bind(std::less() , boost::bind(select1st(), _1) , boost::bind(select1st(), _2))); @@ -216,7 +216,7 @@ namespace vertex_t v = add_vertex(full_graph().topology()); vertex_t v2 = add_vertex(up_graph().topology()); assert(v == v2); - return type_index().insert(p, make_tuple(type, v, dynamic_id_function(0))); + return type_index().insert(p, boost::make_tuple(type, v, dynamic_id_function(0))); } // Map a two types to a vertex in the graph, inserting if neccessary @@ -408,7 +408,7 @@ namespace // Look in the cache first for a quickie address translation std::ptrdiff_t offset = (char*)p - (char*)dynamic_id.first; - cache_element seek(make_tuple(src_t, dst_t, offset, dynamic_id.second)); + cache_element seek(boost::make_tuple(src_t, dst_t, offset, dynamic_id.second)); cache_t& c = cache(); cache_t::iterator const cache_pos = std::lower_bound(c.begin(), c.end(), seek); From 26d3375900f2b05c9b3522e494a6d2103eb03ce9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 22 Aug 2002 13:57:12 +0000 Subject: [PATCH 0672/1042] Added make_tuple() tests [SVN r15055] --- test/tuple.cpp | 7 +++++++ test/tuple.py | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/test/tuple.cpp b/test/tuple.cpp index 38494b76..61b4d187 100644 --- a/test/tuple.cpp +++ b/test/tuple.cpp @@ -14,10 +14,17 @@ void test_operators(tuple t1, tuple t2, object print) print(t1 + t2); } +tuple mktuple0() { return make_tuple(); } +tuple mktuple1(int x) { return make_tuple(x); } +tuple mktuple2(char const* a1, int x) { return make_tuple(a1, x); } + BOOST_PYTHON_MODULE_INIT(tuple_ext) { module("tuple_ext") .def("convert_to_tuple",convert_to_tuple) .def("test_operators",test_operators) + .def("make_tuple", mktuple0) + .def("make_tuple", mktuple1) + .def("make_tuple", mktuple2) ; } diff --git a/test/tuple.py b/test/tuple.py index 74a6e9d8..cd899df4 100644 --- a/test/tuple.py +++ b/test/tuple.py @@ -10,6 +10,12 @@ >>> t2 = (1,2,3,4) >>> test_operators(t1,t2,printer) ('t', 'h', 'i', 's', ' ', 'i', 's', 1, 2, 3, 4) +>>> make_tuple() +() +>>> make_tuple(42) +(42,) +>>> make_tuple('hello', 42) +('hello', 42) """ def run(args = None): From 2f89a8eb584849a5fc5fa42b5c3f875317bf8b09 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 22 Aug 2002 15:23:25 +0000 Subject: [PATCH 0673/1042] additional tests for X::foo [SVN r15056] --- test/defaults.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/defaults.py b/test/defaults.py index b72cea4f..b63f972c 100644 --- a/test/defaults.py +++ b/test/defaults.py @@ -26,6 +26,24 @@ 'int(3); char(Y); string(Hello World); double(0.0); ' >>> x.bar(4, 'Z', "Hi There", 3.3) 'int(4); char(Z); string(Hi There); double(3.3); ' +>>> x.foo(5) +'int(5); bool(0); ' +>>> x.foo(6, 0) +'int(6); bool(0); ' +>>> x.foo(7, 1) +'int(7); bool(1); ' +>>> x.foo("A") +'string(A); bool(0); ' +>>> x.foo("B", False) +'string(B); bool(0); ' +>>> x.foo("C", True) +'string(C); bool(1); ' +>>> x.foo([0,1,2], [2,3,4]) +'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' +>>> x.foo([0,1,2], [2,3,4], False) +'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' +>>> x.foo([0,1,2], [2,3,4], True) +'list([0, 1, 2]); list([2, 3, 4]); bool(1); ' >>> From d779a94cfb5faa6c02c5dc1bdd441d1899b05b8d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 22 Aug 2002 18:22:35 +0000 Subject: [PATCH 0674/1042] obsoleted [SVN r15060] --- build/Jamfile | 6 +----- build/__init__.py | 22 ---------------------- 2 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 build/__init__.py diff --git a/build/Jamfile b/build/Jamfile index 889a8a29..2b583d17 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -61,11 +61,7 @@ subproject libs/python/build ; SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; -# This nasty hack works with versions of Python 1.5.2 -> 2.2 to avoid -# building any Python stuff if there's no installation. -SEARCH on __init__.py = $(PYTHON_STDLIB_PATH)/test $(SUBDIR) ; -include __init__.py ; -if ! $(gNO_PYTHON_INSTALL) +if [ check-python-config ] { local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_DYNAMIC_LIB ; diff --git a/build/__init__.py b/build/__init__.py deleted file mode 100644 index 97b20d9c..00000000 --- a/build/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Dummy file actually to be included by Jam when the python headers -# can't be found - -if ! $(gNO_PYTHON_INSTALL) -{ - ECHO "---------------------------------------------------------------------" ; - ECHO skipping Boost.Python library build ; - ECHO You can configure the location of your python installation, by setting: ; - ECHO "PYTHON_ROOT - currently" \"$(PYTHON_ROOT:J=" ")\" ; - ECHO "PYTHON_VERSION - The 2-part python Major.Minor version number (e.g." ; - ECHO " \"2.2\", NOT \"2.2.1\") - currently" \"$(PYTHON_VERSION)\" ; - ECHO ; - ECHO "The following are automatically configured from PYTHON_ROOT if not" ; - ECHO "otherwise set:" ; - ECHO " PYTHON_INCLUDES - path to Python #include directories; currently" \"$(PYTHON_INCLUDES:J=" ")\" ; - ECHO " PYTHON_LIB_PATH - path to Python library; currently" ; - ECHO " " \"$(PYTHON_LIB_PATH:J=" ")\" ; - ECHO " PYTHON_STDLIB_PATH - path to Python standard library modules; currently" ; - ECHO " " \"$(PYTHON_STDLIB_PATH:J=" ")\" ; - ECHO "---------------------------------------------------------------------" ; -} -gNO_PYTHON_INSTALL ?= true ; From 0b02fd4e995381dc3564874898eb637f70bdf089 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 22 Aug 2002 19:08:16 +0000 Subject: [PATCH 0675/1042] Use make_tuple() [SVN r15062] --- test/pickle1.cpp | 5 +---- test/pickle2.cpp | 9 ++------- test/pickle3.cpp | 16 +++++----------- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/test/pickle1.cpp b/test/pickle1.cpp index eab90299..647ef249 100644 --- a/test/pickle1.cpp +++ b/test/pickle1.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -39,9 +38,7 @@ namespace { getinitargs(const world& w) { using namespace boost::python; - list result; - result.append(object(w.get_country())); - return tuple(result); + return make_tuple(w.get_country()); } }; diff --git a/test/pickle2.cpp b/test/pickle2.cpp index 6fe2962d..cf099738 100644 --- a/test/pickle2.cpp +++ b/test/pickle2.cpp @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -54,9 +53,7 @@ namespace { // Avoid cluttering the global namespace. getinitargs(const world& w) { using namespace boost::python; - list result; - result.append(object(w.get_country())); - return tuple(result); + return make_tuple(w.get_country()); } static @@ -64,9 +61,7 @@ namespace { // Avoid cluttering the global namespace. getstate(const world& w) { using namespace boost::python; - list result; - result.append(object(w.get_secret_number())); - return tuple(result); + return make_tuple(w.get_secret_number()); } static diff --git a/test/pickle3.cpp b/test/pickle3.cpp index f4f8c20e..105bac51 100644 --- a/test/pickle3.cpp +++ b/test/pickle3.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -50,9 +49,7 @@ namespace { // Avoid cluttering the global namespace. getinitargs(const world& w) { using namespace boost::python; - list result; - result.append(object(w.get_country())); - return tuple(result); + return make_tuple(w.get_country()); } static @@ -61,12 +58,8 @@ namespace { // Avoid cluttering the global namespace. { using namespace boost::python; world const& w = extract(w_obj)(); - list result; - // store the object's __dict__ - result.append(w_obj.attr("__dict__")); - // store the internal state of the C++ object - result.append(object(w.get_secret_number())); - return tuple(result); + + return make_tuple(w_obj.attr("__dict__"), w.get_secret_number()); } static @@ -76,7 +69,8 @@ namespace { // Avoid cluttering the global namespace. using namespace boost::python; world& w = extract(w_obj)(); extract state_proxy(state); - if (!state_proxy.check() || len(state_proxy()) != 2) { + if (!state_proxy.check() || len(state_proxy()) != 2) + { PyErr_SetString(PyExc_ValueError, "Unexpected argument in call to __setstate__."); throw_error_already_set(); From cd6476e4871333922160e47778be08f9d29d9428 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 22 Aug 2002 20:22:05 +0000 Subject: [PATCH 0676/1042] Allow different arguments to setstate [SVN r15063] --- include/boost/python/object/pickle_support.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp index 10a5f4f8..bbdd1ac1 100644 --- a/include/boost/python/object/pickle_support.hpp +++ b/include/boost/python/object/pickle_support.hpp @@ -58,14 +58,14 @@ namespace detail { cl.def("__getinitargs__", getinitargs_fn); } - template + template static void register_( Class_& cl, inaccessible* (*getinitargs_fn)(), tuple (*getstate_fn)(Tgetstate), - void (*setstate_fn)(Tsetstate, object), + void (*setstate_fn)(Tsetstate, Ttuple), bool getstate_manages_dict) { cl.enable_pickling(getstate_manages_dict); @@ -74,14 +74,14 @@ namespace detail { } template + class Tgetinitargs, class Tgetstate, class Tsetstate, class Ttuple> static void register_( Class_& cl, tuple (*getinitargs_fn)(Tgetinitargs), tuple (*getstate_fn)(Tgetstate), - void (*setstate_fn)(Tsetstate, object), + void (*setstate_fn)(Tsetstate, Ttuple), bool getstate_manages_dict) { cl.enable_pickling(getstate_manages_dict); From 946942214f9bc73d15657e74fd46381710a5122d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 22 Aug 2002 20:23:27 +0000 Subject: [PATCH 0677/1042] Some simplifications [SVN r15064] --- test/pickle2.cpp | 18 +++++++++++------- test/pickle3.cpp | 23 +++++++++++++++-------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/test/pickle2.cpp b/test/pickle2.cpp index cf099738..f1bd8439 100644 --- a/test/pickle2.cpp +++ b/test/pickle2.cpp @@ -66,17 +66,21 @@ namespace { // Avoid cluttering the global namespace. static void - setstate(world& w, boost::python::object state) + setstate(world& w, boost::python::tuple state) { using namespace boost::python; - extract state_proxy(state); - if (!state_proxy.check() || len(state_proxy()) != 1) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); + if (len(state) != 1) + { + PyErr_SetObject(PyExc_ValueError, + ("expected 1-item tuple in call to __setstate__; got %s" + % state).ptr() + ); throw_error_already_set(); } - long number = extract(state_proxy()[0])(); - if (number != 42) w.set_secret_number(number); + + long number = extract(state[0]); + if (number != 42) + w.set_secret_number(number); } }; diff --git a/test/pickle3.cpp b/test/pickle3.cpp index 105bac51..367b1d81 100644 --- a/test/pickle3.cpp +++ b/test/pickle3.cpp @@ -23,6 +23,7 @@ #include #include #include +#include namespace { // Avoid cluttering the global namespace. @@ -64,22 +65,28 @@ namespace { // Avoid cluttering the global namespace. static void - setstate(boost::python::object w_obj, boost::python::object state) + setstate(boost::python::object w_obj, boost::python::tuple state) { using namespace boost::python; world& w = extract(w_obj)(); - extract state_proxy(state); - if (!state_proxy.check() || len(state_proxy()) != 2) + + if (len(state) != 2) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); + PyErr_SetObject(PyExc_ValueError, + ("expected 2-item tuple in call to __setstate__; got %s" + % state).ptr() + ); throw_error_already_set(); } + // restore the object's __dict__ - w_obj.attr("__dict__").attr("update")(object(state_proxy()[0])); + dict d = extract(w_obj.attr("__dict__"))(); + d.update(state[0]); + // restore the internal state of the C++ object - long number = extract(state_proxy()[1])(); - if (number != 42) w.set_secret_number(number); + long number = extract(state[1]); + if (number != 42) + w.set_secret_number(number); } static bool getstate_manages_dict() { return true; } From 0b33d1800d0576175e7ff926f1661fa19abcb7df Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 23 Aug 2002 04:15:37 +0000 Subject: [PATCH 0678/1042] automatic conversion to object for add_property() [SVN r15065] --- include/boost/python/class.hpp | 29 +++++++++++++---------------- test/data_members.cpp | 2 +- test/data_members.py | 3 +++ 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index a98226f0..870f644c 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -230,8 +230,19 @@ class class_ : public objects::class_base } // Property creation - self& add_property(char const* name, object const& fget); - self& add_property(char const* name, object const& fget, object const& fset); + template + self& add_property(char const* name, Get const& fget) + { + base::add_property(name, object(fget)); + return *this; + } + + template + self& add_property(char const* name, Get const& fget, Set const& fset) + { + base::add_property(name, object(fget), object(fset)); + return *this; + } template self& setattr(char const* name, U const& x) @@ -367,20 +378,6 @@ inline class_::class_(char const* name, char const* doc, no_init_t) this->def_no_init(); } -template -inline class_& class_::add_property(char const* name, object const& fget) -{ - base::add_property(name, fget); - return *this; -} - -template -inline class_& class_::add_property(char const* name, object const& fget, object const& fset) -{ - base::add_property(name, fget, fset); - return *this; -} - namespace detail { // This is an mpl BinaryMetaFunction object with a runtime behavior, diff --git a/test/data_members.cpp b/test/data_members.cpp index 5092bba9..2ee9c45d 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -26,7 +26,7 @@ BOOST_PYTHON_MODULE_INIT(data_members_ext) .def("value", &X::value) .def("set", &X::set) .def_readonly("x", &X::x) - .add_property("get_fair_value", object(&get_fair_value)) + .add_property("fair_value", &get_fair_value) ; class_("Y", args()) diff --git a/test/data_members.py b/test/data_members.py index 598d1373..ab79a90a 100644 --- a/test/data_members.py +++ b/test/data_members.py @@ -7,6 +7,9 @@ ... except AttributeError: pass ... else: print 'no error' +>>> x.fair_value +42.0 + >>> y = Y(69) >>> y.x 69 From bcaa1043ea9ae1f0ed052079d6220d066fd63c57 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 23 Aug 2002 18:07:27 +0000 Subject: [PATCH 0679/1042] More smart pointer handling [SVN r15069] --- include/boost/python/class.hpp | 10 +++-- include/boost/python/instance_holder.hpp | 4 ++ include/boost/python/object/class_wrapper.hpp | 40 ++++++++++--------- .../boost/python/object/pointer_holder.hpp | 40 +++++++++++++++++-- include/boost/python/object/value_holder.hpp | 13 +++++- test/m1.cpp | 10 ++++- test/newtest.py | 7 ++++ 7 files changed, 97 insertions(+), 27 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 870f644c..1e75a6f5 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -52,15 +52,17 @@ namespace detail // to the type of holder that must be created. The 3rd argument is a // reference to the Python type object to be created. template - static inline void register_copy_constructor(mpl::bool_t const&, Holder*, object const& obj, T* = 0) + static inline void register_copy_constructor(mpl::bool_t const&, Holder*, T* = 0) { - objects::class_wrapper x(obj); + force_instantiate(objects::class_wrapper()); + Holder::register_(); } // Tag dispatched to have no effect. template - static inline void register_copy_constructor(mpl::bool_t const&, Holder*, object const&, T* = 0) + static inline void register_copy_constructor(mpl::bool_t const&, Holder*, T* = 0) { + Holder::register_(); } template int assert_default_constructible(T const&); @@ -331,7 +333,7 @@ inline void class_::register_() const detail::register_copy_constructor( mpl::bool_t() , objects::select_holder((held_type*)0).get() - , *this); + ); } diff --git a/include/boost/python/instance_holder.hpp b/include/boost/python/instance_holder.hpp index eb148431..f4962479 100755 --- a/include/boost/python/instance_holder.hpp +++ b/include/boost/python/instance_holder.hpp @@ -24,6 +24,10 @@ struct BOOST_PYTHON_DECL instance_holder : private noncopyable virtual void* holds(type_info) = 0; void install(PyObject* inst) throw(); + + // Register any converters associated with this Holder + static inline void register_() {} + private: instance_holder* m_next; }; diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index 2e06f921..723126a4 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -8,26 +8,37 @@ # include # include +# include +# include namespace boost { namespace python { namespace objects { -template -struct class_wrapper - : to_python_converter > +template +struct copy_construct_instance { - class_wrapper(object const& type_) - : m_class_object_keeper(type_) + static Holder* execute(PyObject* instance, Src const& x) { - assert(type_.ptr()->ob_type == (PyTypeObject*)class_metatype().get()); - m_class_object = (PyTypeObject*)type_.ptr(); + return new Holder(instance, cref(x)); } - - static PyObject* convert(T const& x) +}; + +// Used to convert objects of type Src to wrapped C++ classes by +// building a new instance object and installing a Holder constructed +// from the Src object. +template > +struct class_wrapper + : to_python_converter > +{ + static PyObject* convert(Src const& x) { + // Get the class object associated with the wrapped type + typedef typename Holder::value_type value_type; + PyTypeObject* class_object = converter::registered::converters.class_object; + // Don't call the type directly to do the construction, since // that would require the registration of an appropriate // __init__ function. - PyObject* raw_result = m_class_object->tp_alloc(m_class_object, 0); + PyObject* raw_result = class_object->tp_alloc(class_object, 0); if (raw_result == 0) return 0; @@ -38,7 +49,7 @@ struct class_wrapper // Build a value_holder to contain the object using the copy // constructor - Holder* p = new Holder(raw_result, cref(x)); + Holder* p = MakeHolder::execute(raw_result, x); // Install it in the instance p->install(raw_result); @@ -46,15 +57,8 @@ struct class_wrapper // Return the new result return result.release(); } - - private: - object m_class_object_keeper; - static PyTypeObject* m_class_object; }; -template -PyTypeObject* class_wrapper::m_class_object; - }}} // namespace boost::python::objects #endif // CLASS_WRAPPER_DWA20011221_HPP diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 8498a8df..3d9e9992 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -16,6 +16,7 @@ # include # include # include +# include # include # include # include @@ -34,13 +35,26 @@ namespace boost { namespace python { namespace objects { template struct pointer_holder : instance_holder { + typedef Value value_type; + pointer_holder(Pointer); + static void register_(); + // Forward construction to the held object # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) # include BOOST_PP_ITERATE() + private: // types + struct construct_from_pointer + { + static pointer_holder* execute(PyObject*, Pointer x) + { + return new pointer_holder(x); + } + }; + private: // required holder implementation void* holds(type_info); @@ -54,9 +68,14 @@ struct pointer_holder_back_reference : instance_holder private: typedef typename python::pointee::type held_type; public: + typedef Value value_type; + // Not sure about this one -- can it work? The source object + // undoubtedly does not carry the correct back reference pointer. pointer_holder_back_reference(Pointer); + static void register_(); + // Forward construction to the held object # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 2)) # include BOOST_PP_ITERATE() @@ -76,12 +95,29 @@ inline pointer_holder::pointer_holder(Pointer p) { } +template +inline void pointer_holder::register_() +{ + python::detail::force_instantiate(class_wrapper()); + python::detail::force_instantiate(instance_finder::registration); +} + + template inline pointer_holder_back_reference::pointer_holder_back_reference(Pointer p) : m_p(p) { } +template +inline void pointer_holder_back_reference::register_() +{ + // not implemented at least until we solve the back reference issue mentioned above. + // python::detail::force_instantiate(class_wrapper()); + python::detail::force_instantiate(instance_finder::registration); + python::detail::force_instantiate(instance_finder::registration); +} + template void* pointer_holder::holds(type_info dst_t) { @@ -142,9 +178,7 @@ void* pointer_holder_back_reference::holds(type_info dst_t) : m_p(new held_type( p BOOST_PP_COMMA_IF(N) BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) )) - { - python::detail::force_instantiate(instance_finder::registration); - } + {} # undef N diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 6eb0c4ed..3d8d2ac2 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -29,6 +29,8 @@ namespace boost { namespace python { namespace objects { template struct value_holder : instance_holder { + typedef Held value_type; + // Forward construction to the held object # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) # include BOOST_PP_ITERATE() @@ -43,6 +45,10 @@ struct value_holder : instance_holder template struct value_holder_back_reference : instance_holder { + typedef Held value_type; + + static void register_(); + // Forward construction to the held object # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 2)) # include BOOST_PP_ITERATE() @@ -79,6 +85,12 @@ void* value_holder_back_reference::holds( return find_static_type(x, src_t, dst_t); } +template +void value_holder_back_reference::register_() +{ + python::detail::force_instantiate(instance_finder::registration); +} + }}} // namespace boost::python::objects # endif // VALUE_HOLDER_DWA20011215_HPP @@ -119,7 +131,6 @@ void* value_holder_back_reference::holds( BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) ) { - python::detail::force_instantiate(instance_finder::registration); } # undef N diff --git a/test/m1.cpp b/test/m1.cpp index de76f64a..34832dfa 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -190,7 +190,11 @@ A take_a(A const& a) { return a; } B take_b(B& b) { return b; } C take_c(C* c) { return *c; } D take_d(D* const& d) { return *d; } - + +D take_d_shared_ptr(boost::shared_ptr d) { return *d; } + +boost::shared_ptr d_factory() { return boost::shared_ptr(new D); } + BOOST_PYTHON_MODULE_INIT(m1) { using namespace boost::python; @@ -237,6 +241,10 @@ BOOST_PYTHON_MODULE_INIT(m1) .def("take_b", take_b) .def("take_c", take_c) .def("take_d", take_d) + + + .def("take_d_shared_ptr", take_d_shared_ptr) + .def("d_factory", d_factory) ; class_ >("A") diff --git a/test/newtest.py b/test/newtest.py index 0edd34b8..7b68a260 100644 --- a/test/newtest.py +++ b/test/newtest.py @@ -158,6 +158,13 @@ are a complicated constructor and member function, respectively. >>> take_d(d).name() 'D' +>>> take_d_shared_ptr(d).name() +'D' + +>>> d_as_a = d_factory() +>>> dd = take_d(d_as_a) +>>> dd.name() +'D' """ From 2cad1b3d93b0d5ca0c0453f121f0fafe770e0018 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 23 Aug 2002 19:27:38 +0000 Subject: [PATCH 0680/1042] revised pickle tutorial [SVN r15070] --- doc/v2/pickle.html | 294 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 doc/v2/pickle.html diff --git a/doc/v2/pickle.html b/doc/v2/pickle.html new file mode 100644 index 00000000..ac28798a --- /dev/null +++ b/doc/v2/pickle.html @@ -0,0 +1,294 @@ + + +Boost.Python Pickle Support + +

    + +c++boost.gif (8819 bytes) + +
    +

    Boost.Python Pickle Support

    + +Pickle is a Python module for object serialization, also known +as persistence, marshalling, or flattening. + +

    +It is often necessary to save and restore the contents of an object to +a file. One approach to this problem is to write a pair of functions +that read and write data from a file in a special format. A powerful +alternative approach is to use Python's pickle module. Exploiting +Python's ability for introspection, the pickle module recursively +converts nearly arbitrary Python objects into a stream of bytes that +can be written to a file. + +

    +The Boost Python Library supports the pickle module +through the interface as described in detail in the +Python Library Reference for pickle. This interface +involves the special methods __getinitargs__, +__getstate__ and __setstate__ as described +in the following. + +


    +

    The Boost.Python Pickle Interface

    + +At the user level, the Boost.Python pickle interface involves three special +methods: + +
    +
    +__getinitargs__ +
    + When an instance of a Boost.Python extension class is pickled, the + pickler tests if the instance has a __getinitargs__ method. + This method must return a Python tuple (it is most convenient to use + a boost::python::tuple). When the instance is restored by the + unpickler, the contents of this tuple are used as the arguments for + the class constructor. + +

    + If __getinitargs__ is not defined, pickle.load + will call the constructor (__init__) without arguments; + i.e., the object must be default-constructible. + +

    +

    +__getstate__ + +
    + When an instance of a Boost.Python extension class is pickled, the + pickler tests if the instance has a __getstate__ method. + This method should return a Python object representing the state of + the instance. + +

    +

    +__setstate__ + +
    + When an instance of a Boost.Python extension class is restored by the + unpickler (pickle.load), it is first constructed using the + result of __getinitargs__ as arguments (see above). Subsequently + the unpickler tests if the new instance has a __setstate__ + method. If so, this method is called with the result of + __getstate__ (a Python object) as the argument. + +
    + +The three special methods described above may be .def()'ed +individually by the user. However, Boost.Python provides an easy to use +high-level interface via the +boost::python::pickle_suite class that also +enforces consistency: __getstate__ and __setstate__ +must be defined as pairs. Use of this interface is demonstrated by the +following examples. + +
    +

    Examples

    + +There are three files in boost/libs/python/test that show how to +provide pickle support. + +
    +

    pickle1.cpp

    + + The C++ class in this example can be fully restored by passing the + appropriate argument to the constructor. Therefore it is sufficient + to define the pickle interface method __getinitargs__. + This is done in the following way: + +
      +
    • 1. Definition of the C++ pickle function: +
      +  struct world_pickle_suite : boost::python::pickle_suite
      +  {
      +    static
      +    boost::python::tuple
      +    getinitargs(world const& w)
      +    {
      +        return boost::python::make_tuple(w.get_country());
      +    }
      +  };
      +
      +
    • 2. Establishing the Python binding: +
      +  class_<world>("world", args<const std::string&>())
      +      // ...
      +      .def_pickle(world_pickle_suite())
      +      // ...
      +
      +
    + +
    +

    pickle2.cpp

    + + The C++ class in this example contains member data that cannot be + restored by any of the constructors. Therefore it is necessary to + provide the __getstate__/__setstate__ pair of + pickle interface methods: + +
      +
    • 1. Definition of the C++ pickle functions: +
      +  struct world_pickle_suite : boost::python::pickle_suite
      +  {
      +    static
      +    boost::python::tuple
      +    getinitargs(const world& w)
      +    {
      +      // ...
      +    }
      +
      +    static
      +    boost::python::tuple
      +    getstate(const world& w)
      +    {
      +      // ...
      +    }
      +
      +    static
      +    void
      +    setstate(world& w, boost::python::tuple state)
      +    {
      +      // ...
      +    }
      +  };
      +
      +
    • 2. Establishing the Python bindings for the entire suite: +
      +  class_<world>("world", args<const std::string&>())
      +      // ...
      +      .def_pickle(world_pickle_suite())
      +      // ...
      +
      +
    + +

    + For simplicity, the __dict__ is not included in the result + of __getstate__. This is not generally recommended, but a + valid approach if it is anticipated that the object's + __dict__ will always be empty. Note that the safet guard + described below will catch the cases where this assumption is violated. + +


    +

    pickle3.cpp

    + + This example is similar to pickle2.cpp. However, the + object's __dict__ is included in the result of + __getstate__. This requires a little more code but is + unavoidable if the object's __dict__ is not always empty. + +
    +

    Pitfall and Safety Guard

    + +In Boost.Python extension modules with many extension classes, +providing complete pickle support for all classes would be a +significant overhead. In general complete pickle support should only be +implemented for extension classes that will eventually be pickled. +However, the author of a Boost.Python extension module might not +anticipate correctly which classes need support for pickle. +Unfortunately, the pickle protocol described above has an important +pitfall that the end user of a Boost.Python extension module might not +be aware of: + +
    +
    + +__getstate__ is defined and the instance's __dict__ +is not empty. + +

    +

    + The author of a Boost.Python extension class might provide a + __getstate__ method without considering the possibilities + that: + +

    +

      +
    • + his class is used in Python as a base class. Most likely the + __dict__ of instances of the derived class needs to be + pickled in order to restore the instances correctly. + +

      +

    • + the user adds items to the instance's __dict__ directly. + Again, the __dict__ of the instance then needs to be + pickled. + +
    +

    + + To alert the user to this highly unobvious problem, a safety guard is + provided. If __getstate__ is defined and the instance's + __dict__ is not empty, Boost.Python tests if the class has + an attribute __getstate_manages_dict__. An exception is + raised if this attribute is not defined: + +

    +    RuntimeError: Incomplete pickle support (__getstate_manages_dict__ not set)
    +
    + + To resolve this problem, it should first be established that the + __getstate__ and __setstate__ methods manage the + instances's __dict__ correctly. Note that this can be done + both at the C++ and the Python level. Finally, the safety guard + should intentionally be overridden. E.g. in C++ (from + pickle3.cpp: + +
    +  struct world_pickle_suite : boost::python::pickle_suite
    +  {
    +    // ...
    +
    +    static bool getstate_manages_dict() { return true; }
    +  };
    +
    + + Alternatively in Python: + +
    +    import your_bpl_module
    +    class your_class(your_bpl_module.your_class):
    +      __getstate_manages_dict__ = 1
    +      def __getstate__(self):
    +        # your code here
    +      def __setstate__(self, state):
    +        # your code here
    +
    +
    + +
    +

    Practical Advice

    + +
      +
    • + Avoid using __getstate__ if the instance can also be + reconstructed by way of __getinitargs__. This automatically + avoids the pitfall described above. + +

      +

    • + If __getstate__ is required, include the instance's + __dict__ in the Python object that is returned. + +
    + +
    + +© Copyright Ralf W. Grosse-Kunstleve 20012-2002. Permission to copy, +use, modify, sell and distribute this document is granted provided this +copyright notice appears in all copies. This document is provided "as +is" without express or implied warranty, and with no claim as to its +suitability for any purpose. + +

    +Updated: Aug 2002. +

    From 0bbfa9b48374a952605d57816005c3be40c5df87 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Fri, 23 Aug 2002 21:00:31 +0000 Subject: [PATCH 0681/1042] removed signature<...> and updated defaults.cpp test [SVN r15071] --- include/boost/python/signature.hpp | 271 ++++------------------------- test/defaults.cpp | 24 +-- 2 files changed, 44 insertions(+), 251 deletions(-) diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index 9d5129e5..cef56f92 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -21,68 +21,27 @@ #include /////////////////////////////////////////////////////////////////////////////// -namespace boost { namespace python { - -/////////////////////////////////////////////////////////////////////////////// -// -// signature -// -// This template struct acts as a type holder for the signature of a -// function or member function. This struct is used to pass in the -// return type, class (for member functions) and arguments of a -// function or member function. Examples: -// -// signature int foo(int) -// signature void foo(int, int) -// signature void C::foo(int, int) -// signature void C::foo(int, int) const -// -/////////////////////////////////////////////////////////////////////////////// -template -struct signature {}; - -namespace detail { +namespace boost { namespace python { namespace detail { /////////////////////////////////////////////////////////////////////////////// // // The following macros generate expansions for: // -// template -// inline boost::mpl::type_list -// get_signature(signature) -// { -// return boost::mpl::type_list(); -// } -// -// template +// template // inline boost::mpl::type_list // get_signature(RT(*)(T0...TN)) // { // return boost::mpl::type_list(); // } // -// template -// inline boost::mpl::type_list -// get_signature(signature) -// { -// return boost::mpl::type_list(); -// } -// -// template -// inline boost::mpl::type_list -// get_signature(signature) -// { -// return boost::mpl::type_list(); -// } -// -// template +// template // inline boost::mpl::type_list // get_signature(RT(ClassT::*)(T0...TN))) // { // return boost::mpl::type_list(); // } // -// template +// template // inline boost::mpl::type_list // get_signature(RT(ClassT::*)(T0...TN) const)) // { @@ -93,14 +52,14 @@ namespace detail { // and arguments of the input signature and stuffs them in an mpl::type_list. // /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_TEMPLATE_GEN(INDEX, DATA) typename BOOST_PP_CAT(T, INDEX) +#define BOOST_PYTHON_TEMPLATE_GEN(INDEX, DATA) class BOOST_PP_CAT(T, INDEX) /////////////////////////////////////////////////////////////////////////////// #define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, BOOST_PYTHON_MAX_ARITY-1, )) #include BOOST_PP_ITERATE() -#undef BPL_IMPL_TEMPLATE_GEN +#undef BOOST_PYTHON_TEMPLATE_GEN } @@ -109,218 +68,52 @@ namespace detail { /////////////////////////////////////////////////////////////////////////////// #endif // SIGNATURE_JDG20020813_HPP - #else // defined(BOOST_PP_IS_ITERATING) // PP vertical iteration code /////////////////////////////////////////////////////////////////////////////// -#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) - -template -< - typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM - ( - BOOST_PP_ITERATION(), - BPL_IMPL_TEMPLATE_GEN, - BOOST_PP_EMPTY - ) -> -inline boost::mpl::type_list -< +template < + class RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM(BOOST_PP_ITERATION(), BOOST_PYTHON_TEMPLATE_GEN, BOOST_PP_EMPTY)> +inline boost::mpl::type_list< RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) -> -get_signature - (signature) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)> +get_signature(RT(*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))) { - return boost::mpl::type_list - < + return boost::mpl::type_list< RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) - >(); -} - -#endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) - -/////////////////////////////////////// -#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) - -# if defined(__MWERKS__) && __MWERKS__ <= 0x3002 && BOOST_PP_ITERATION() == 0 -template -inline boost::mpl::type_list -get_signature(signature) -{ - return boost::mpl::type_list(); -} -# else -template -< - typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM - ( - BOOST_PP_ITERATION(), - BPL_IMPL_TEMPLATE_GEN, - BOOST_PP_EMPTY - ) -> -inline boost::mpl::type_list -< - RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) -> -get_signature( - signature< - RT(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) - >) -{ - return boost::mpl::type_list - < - RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) - >(); -} -# endif - -#endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) - -/////////////////////////////////////// -template -< - typename RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM - ( - BOOST_PP_ITERATION(), - BPL_IMPL_TEMPLATE_GEN, - BOOST_PP_EMPTY - ) -> -inline boost::mpl::type_list -< - RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) -> -get_signature - (RT(*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))) -{ - return boost::mpl::type_list - < - RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) - >(); + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)>(); } /////////////////////////////////////////////////////////////////////////////// #if BOOST_PP_ITERATION() <= (BOOST_PYTHON_MAX_ARITY - 2) -#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) - -template -< - typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM - ( - BOOST_PP_ITERATION(), - BPL_IMPL_TEMPLATE_GEN, - BOOST_PP_EMPTY - ) -> -inline boost::mpl::type_list -< +template < + class RT, class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM(BOOST_PP_ITERATION(), BOOST_PYTHON_TEMPLATE_GEN, BOOST_PP_EMPTY)> +inline boost::mpl::type_list< RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) -> -get_signature - (signature) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)> +get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))) { - return boost::mpl::type_list - < + return boost::mpl::type_list< RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)> - (); + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)>(); } /////////////////////////////////////// -template -< - typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM - ( - BOOST_PP_ITERATION(), - BPL_IMPL_TEMPLATE_GEN, - BOOST_PP_EMPTY - ) -> -inline boost::mpl::type_list -< +template < + class RT, class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM(BOOST_PP_ITERATION(), BOOST_PYTHON_TEMPLATE_GEN, BOOST_PP_EMPTY)> +inline boost::mpl::type_list< RT, ClassT const BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) -> -get_signature - (signature) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)> +get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const) { - return boost::mpl::type_list - < - RT, ClassT const - BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) - >(); -} - -#endif // !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) - -/////////////////////////////////////// -template -< - typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM - ( - BOOST_PP_ITERATION(), - BPL_IMPL_TEMPLATE_GEN, - BOOST_PP_EMPTY - ) -> -inline boost::mpl::type_list -< - RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) -> -get_signature - (RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))) -{ - return boost::mpl::type_list - < - RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) - >(); -} - -/////////////////////////////////////// -template -< - typename RT, typename ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM - ( - BOOST_PP_ITERATION(), - BPL_IMPL_TEMPLATE_GEN, - BOOST_PP_EMPTY - ) -> -inline boost::mpl::type_list -< - RT, ClassT const - BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) -> -get_signature - (RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const) -{ - return boost::mpl::type_list - < - RT, ClassT const - BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T) - >(); + return boost::mpl::type_list< + RT, ClassT const + BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) + BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)>(); } #endif // BOOST_PP_ITERATION() < (BOOST_PYTHON_MAX_ARITY - 2) diff --git a/test/defaults.cpp b/test/defaults.cpp index f7b2da9c..5b162b1a 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -17,6 +17,10 @@ using namespace std; char const* const format = "int(%s); char(%s); string(%s); double(%s); "; +/////////////////////////////////////////////////////////////////////////////// +// +// Overloaded functions +// /////////////////////////////////////////////////////////////////////////////// object bar(int a, char b, std::string c, double d) @@ -44,6 +48,10 @@ bar(int a) BOOST_PYTHON_FUNCTION_GENERATOR(bar_stubs, bar, 1, 4) +/////////////////////////////////////////////////////////////////////////////// +// +// Functions with default arguments +// /////////////////////////////////////////////////////////////////////////////// object foo(int a, char b = 'D', std::string c = "default", double d = 0.0) @@ -54,7 +62,10 @@ foo(int a, char b = 'D', std::string c = "default", double d = 0.0) BOOST_PYTHON_FUNCTION_GENERATOR(foo_stubs, foo, 1, 4) /////////////////////////////////////////////////////////////////////////////// - +// +// Overloaded member functions with default arguments +// +/////////////////////////////////////////////////////////////////////////////// struct X { object @@ -92,24 +103,13 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) { module("defaults_ext") .def("foo", foo, foo_stubs()) - -#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) - .def("bar", signature(), bar_stubs()) -#else // signature does not work on VC6 only (VC7 is ok) .def("bar", (object(*)(int, char, std::string, double))0, bar_stubs()) -#endif ; class_("X") .def("bar", &X::bar, X_bar_stubs()) .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) - -#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1200)) - .def("foo", signature(), X_foo_2_stubs()) -#else // signature does not work on VC6 only (VC7 is ok) .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) -#endif - .def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs()) ; } From 1ee7bd2a60fd2e6d75bbebcb61ace655a429ac1d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 23 Aug 2002 22:34:05 +0000 Subject: [PATCH 0682/1042] a few refinements [SVN r15072] --- doc/v2/pickle.html | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/doc/v2/pickle.html b/doc/v2/pickle.html index ac28798a..0e40ae1b 100644 --- a/doc/v2/pickle.html +++ b/doc/v2/pickle.html @@ -173,7 +173,7 @@ provide pickle support. For simplicity, the __dict__ is not included in the result of __getstate__. This is not generally recommended, but a valid approach if it is anticipated that the object's - __dict__ will always be empty. Note that the safet guard + __dict__ will always be empty. Note that the safety guard described below will catch the cases where this assumption is violated.
    @@ -188,24 +188,15 @@ provide pickle support.

    Pitfall and Safety Guard

    -In Boost.Python extension modules with many extension classes, -providing complete pickle support for all classes would be a -significant overhead. In general complete pickle support should only be -implemented for extension classes that will eventually be pickled. -However, the author of a Boost.Python extension module might not -anticipate correctly which classes need support for pickle. -Unfortunately, the pickle protocol described above has an important -pitfall that the end user of a Boost.Python extension module might not -be aware of: - -
    -
    +The pickle protocol described above has an important pitfall that the +end user of a Boost.Python extension module might not be aware of: +

    __getstate__ is defined and the instance's __dict__ is not empty.

    -

    + The author of a Boost.Python extension class might provide a __getstate__ method without considering the possibilities that: @@ -239,9 +230,9 @@ is not empty. To resolve this problem, it should first be established that the __getstate__ and __setstate__ methods manage the instances's __dict__ correctly. Note that this can be done - both at the C++ and the Python level. Finally, the safety guard + either at the C++ or the Python level. Finally, the safety guard should intentionally be overridden. E.g. in C++ (from - pickle3.cpp: + pickle3.cpp):
       struct world_pickle_suite : boost::python::pickle_suite
    @@ -263,12 +254,19 @@ is not empty.
           def __setstate__(self, state):
             # your code here
     
    -

    Practical Advice

      +
    • + In Boost.Python extension modules with many extension classes, + providing complete pickle support for all classes would be a + significant overhead. In general complete pickle support should + only be implemented for extension classes that will eventually + be pickled. + +

    • Avoid using __getstate__ if the instance can also be reconstructed by way of __getinitargs__. This automatically From d4c50383af4b1c098f02991dee2f8eeee8a15fbc Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Fri, 23 Aug 2002 23:30:29 +0000 Subject: [PATCH 0683/1042] Got init<..> working [SVN r15073] --- include/boost/python/class.hpp | 10 ++- include/boost/python/init.hpp | 150 +++++++++++++++++++++++++-------- test/defaults.cpp | 16 ++++ test/defaults.py | 14 ++- 4 files changed, 153 insertions(+), 37 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 1e75a6f5..133b752b 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -31,6 +31,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -165,6 +166,13 @@ class class_ : public objects::class_base return *this; } + template + self& def(init const& i, char const* doc = 0) + { + define_init(*this, i, doc); + return *this; + } + template self& def(char const* name, Arg1T arg1, Arg2T const& arg2, char const* doc = 0) { @@ -238,7 +246,7 @@ class class_ : public objects::class_base base::add_property(name, object(fget)); return *this; } - + template self& add_property(char const* name, Get const& fget, Set const& fset) { diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 71a79f7a..f1c9001a 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -26,22 +27,22 @@ #include /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_TEMPLATE_TYPES_WITH_DEFAULT \ +#define BOOST_PYTHON_TEMPLATE_TYPES_WITH_DEFAULT \ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT \ ( \ BOOST_PYTHON_MAX_ARITY, \ - typename T, \ + class T, \ boost::mpl::null_argument \ ) \ -#define BPL_IMPL_TEMPLATE_TYPES \ +#define BOOST_PYTHON_TEMPLATE_TYPES \ BOOST_PP_ENUM_PARAMS \ ( \ BOOST_PYTHON_MAX_ARITY, \ - typename T \ + class T \ ) \ -#define BPL_IMPL_TEMPLATE_ARGS \ +#define BOOST_PYTHON_TEMPLATE_ARGS \ BOOST_PP_ENUM_PARAMS \ ( \ BOOST_PYTHON_MAX_ARITY, \ @@ -51,12 +52,12 @@ /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { -template -struct init; +template +struct init; // forward declaration /////////////////////////////////////// -template -struct optional; +template +struct optional; // forward declaration namespace detail { @@ -67,7 +68,7 @@ namespace detail { // This metaprogram checks if T is nil // /////////////////////////////////////////////////////////////////////////// - template + template struct is_nil : public boost::is_same {}; /////////////////////////////////////////////////////////////////////////// @@ -79,13 +80,13 @@ namespace detail { /////////////////////////////////////////////////////////////////////////// #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - template + template struct is_optional { private: - template - static boost::type_traits::yes_type f(optional); + template + static boost::type_traits::yes_type f(optional); static boost::type_traits::no_type f(...); static T t(); @@ -99,14 +100,14 @@ namespace detail { /////////////////////////////////////// #else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - template + template struct is_optional { BOOST_STATIC_CONSTANT(bool, value = false); }; - template - struct is_optional > { + template + struct is_optional > { BOOST_STATIC_CONSTANT(bool, value = true); }; @@ -227,10 +228,12 @@ namespace detail { }; }; - template - struct check_init_params { + struct init_base {}; - typedef boost::mpl::type_list params; + template + struct check_init_params : init_base { + + typedef boost::mpl::type_list params; BOOST_STATIC_ASSERT ( @@ -273,7 +276,7 @@ namespace detail { { }; - template + template struct count_optional_types { BOOST_STATIC_CONSTANT(int, value = @@ -295,7 +298,7 @@ namespace detail { // last in the list. // /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_APPEND_TO_INIT(INDEX, D) \ +#define BOOST_PYTHON_APPEND_TO_INIT(INDEX, D) \ typedef typename detail::append_to_init \ < \ BOOST_PP_CAT(l, INDEX), \ @@ -303,17 +306,19 @@ namespace detail { >::sequence BOOST_PP_CAT(l, BOOST_PP_INC(INDEX)); \ -template -struct init : detail::check_init_params { - +template +struct init : detail::check_init_params +{ typedef boost::mpl::type_list l0; BOOST_PP_REPEAT - (BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY), BPL_IMPL_APPEND_TO_INIT, 0); + (BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY), BOOST_PYTHON_APPEND_TO_INIT, 0); typedef BOOST_PP_CAT(l, BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY)) sequence; + BOOST_STATIC_CONSTANT(int, n_arguments = boost::mpl::size::value); + BOOST_STATIC_CONSTANT(int, n_defaults = - (detail::count_optional_types::value) + (detail::count_optional_types::value) ); }; @@ -324,19 +329,96 @@ struct init : detail::check_init_params { // optional::sequence returns a typelist. // /////////////////////////////////////////////////////////////////////////////// -template +template struct optional { - typedef boost::mpl::type_list sequence; + typedef boost::mpl::type_list sequence; }; -#undef BPL_IMPL_TEMPLATE_TYPES_WITH_DEFAULT -#undef BPL_IMPL_TEMPLATE_TYPES -#undef BPL_IMPL_TEMPLATE_ARGS -#undef BPL_IMPL_IS_OPTIONAL_VALUE -#undef BPL_IMPL_APPEND_TO_INIT +namespace detail { -}} // namespace boost { namespace python { + /////////////////////////////////////////////////////////////////////////////// + // + // define_class_init_helper::apply + // + // General case + // + // Accepts a class_ and an arguments list. Defines a constructor + // for the class given the arguments and recursively calls + // define_class_init_helper::apply with one less arguments (the + // rightmost argument is shaved off) + // + /////////////////////////////////////////////////////////////////////////////// + template + struct define_class_init_helper { + + template + static void apply(ClassT& cl, ArgsT const& args, char const* doc) + { + cl.def_init(args, default_call_policies(), doc); + boost::mpl::pop_back::sequence next; + define_class_init_helper::apply(cl, next, doc); + } + }; + + /////////////////////////////////////////////////////////////////////////////// + // + // define_class_init_helper<0>::apply + // + // Terminal case + // + // Accepts a class_ and an arguments list. Defines a constructor + // for the class given the arguments. + // + /////////////////////////////////////////////////////////////////////////////// + template <> + struct define_class_init_helper<0> { + + template + static void apply(ClassT& cl, ArgsT const& args, char const* doc) + { + cl.def_init(args, default_call_policies(), doc); + } + }; +} + +/////////////////////////////////////////////////////////////////////////////// +// +// define_init +// +// Accepts a class_ and an init-list. Defines a set of constructors for +// the class given the arguments. The init list (see init above) has +// n_defaults (number of default arguments and n_arguments (number of +// actual arguments). This function defines n_defaults + 1 constructors +// for the class. Each constructor after the first has one less argument +// to its right. Example: +// +// init +// +// Defines: +// +// __init__(int, char, long, double) +// __init__(int, char, long) +// __init__(int, char) +// __init__(int) +// +/////////////////////////////////////////////////////////////////////////////// +template +void +define_init(ClassT& cl, InitT const& i, char const* doc) +{ + enum { n_defaults_plus_1 = InitT::n_defaults + 1 }; + typedef typename InitT::sequence args_t; + detail::define_class_init_helper::apply(cl, args_t(), doc); +} + +}} // namespace boost::python + +#undef BOOST_PYTHON_TEMPLATE_TYPES_WITH_DEFAULT +#undef BOOST_PYTHON_TEMPLATE_TYPES +#undef BOOST_PYTHON_TEMPLATE_ARGS +#undef BOOST_PYTHON_IS_OPTIONAL_VALUE +#undef BOOST_PYTHON_APPEND_TO_INIT /////////////////////////////////////////////////////////////////////////////// #endif // INIT_JDG20020820_HPP diff --git a/test/defaults.cpp b/test/defaults.cpp index 5b162b1a..0014ab36 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -68,6 +68,12 @@ BOOST_PYTHON_FUNCTION_GENERATOR(foo_stubs, foo, 1, 4) /////////////////////////////////////////////////////////////////////////////// struct X { + X() {} + + X(int a, char b = 'D', std::string c = "constructor", double d = 0.0) + : state(format % make_tuple(a, b, c, d)) + {} + object bar(int a, char b = 'D', std::string c = "default", double d = 0.0) const { @@ -91,6 +97,14 @@ struct X { { return "list(%s); list(%s); bool(%s); " % make_tuple(a, b, c); } + + object + get_state() const + { + return state; + } + + object state; }; BOOST_PYTHON_MEM_FUN_GENERATOR(X_bar_stubs, bar, 1, 4) @@ -107,6 +121,8 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) ; class_("X") + .def(init >()) + .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) diff --git a/test/defaults.py b/test/defaults.py index b63f972c..ac890de2 100644 --- a/test/defaults.py +++ b/test/defaults.py @@ -44,8 +44,18 @@ 'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' >>> x.foo([0,1,2], [2,3,4], True) 'list([0, 1, 2]); list([2, 3, 4]); bool(1); ' ->>> - +>>> x = X(1) +>>> x.get_state() +'int(1); char(D); string(constructor); double(0.0); ' +>>> x = X(1, 'X') +>>> x.get_state() +'int(1); char(X); string(constructor); double(0.0); ' +>>> x = X(1, 'X', "Yabadabadoo") +>>> x.get_state() +'int(1); char(X); string(Yabadabadoo); double(0.0); ' +>>> x = X(1, 'X', "Phoenix", 3.65) +>>> x.get_state() +'int(1); char(X); string(Phoenix); double(3.65); ' """ From 2566b8732e05cfbfc01351106fd2a3c77c177e31 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 23 Aug 2002 23:54:35 +0000 Subject: [PATCH 0684/1042] Remove extra semicolon [SVN r15074] --- include/boost/python/init.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index f1c9001a..8e67e7c0 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -311,7 +311,7 @@ struct init : detail::check_init_params { typedef boost::mpl::type_list l0; BOOST_PP_REPEAT - (BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY), BOOST_PYTHON_APPEND_TO_INIT, 0); + (BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY), BOOST_PYTHON_APPEND_TO_INIT, 0) typedef BOOST_PP_CAT(l, BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY)) sequence; From a6cac2886bf88283c8787ac5e98d8c1478c95a2a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 24 Aug 2002 02:48:53 +0000 Subject: [PATCH 0685/1042] Work around a CWPro7.2 bug with ?: [SVN r15076] --- src/object/class.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index 90999f35..754ebe5a 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -269,7 +269,7 @@ namespace objects object module_name( PyObject_IsInstance(scope().ptr(), upcast(&PyModule_Type)) - ? scope().attr("__name__") + ? object(scope().attr("__name__")) : api::getattr(scope(), "__module__", object("")) ); From 1d94d7e604a6ab17c9f3f7b046b26c752148f8d1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 24 Aug 2002 16:52:19 +0000 Subject: [PATCH 0686/1042] Added missing typename [SVN r15082] --- include/boost/python/init.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 8e67e7c0..5ea2fdbc 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -356,7 +356,7 @@ namespace detail { static void apply(ClassT& cl, ArgsT const& args, char const* doc) { cl.def_init(args, default_call_policies(), doc); - boost::mpl::pop_back::sequence next; + typename boost::mpl::pop_back::sequence next; define_class_init_helper::apply(cl, next, doc); } }; From 780fff70c4b92ef9d4adf83bbf034ead64ddc009 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 24 Aug 2002 18:19:35 +0000 Subject: [PATCH 0687/1042] Removed unused bool_type [SVN r15084] --- include/boost/python/extract.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/extract.hpp b/include/boost/python/extract.hpp index 18d8c5c2..16efb3bf 100644 --- a/include/boost/python/extract.hpp +++ b/include/boost/python/extract.hpp @@ -108,9 +108,9 @@ struct extract { private: typedef typename converter::select_extract::type base; - typedef bool (extract::*bool_type)() const; public: typedef typename base::result_type result_type; + operator result_type() const { return (*this)(); From 5bcb9010f605d86cf4c65593f26905ed96889b26 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 25 Aug 2002 03:04:20 +0000 Subject: [PATCH 0688/1042] mention cPickle [SVN r15085] --- doc/v2/pickle.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/v2/pickle.html b/doc/v2/pickle.html index 0e40ae1b..13c7b306 100644 --- a/doc/v2/pickle.html +++ b/doc/v2/pickle.html @@ -32,7 +32,8 @@ through the interface as described in detail in the >Python Library Reference for pickle. This interface involves the special methods __getinitargs__, __getstate__ and __setstate__ as described -in the following. +in the following. Note that Boost.Python is also fully compatible +with Python's cPickle module.

      The Boost.Python Pickle Interface

      From f030618d19939790fab15b217b380b902300713f Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Mon, 26 Aug 2002 15:09:33 +0000 Subject: [PATCH 0689/1042] Initial speedup for EDG for the stub functions. The init<...> stuff is more involved... [SVN r15097] --- include/boost/python/detail/defaults_def.hpp | 7 +- include/boost/python/detail/defaults_gen.hpp | 9 +- .../boost/python/detail/type_list_utils.hpp | 115 ++++++++++++++++++ test/defaults.cpp | 8 +- 4 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 include/boost/python/detail/type_list_utils.hpp diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index f7105b6f..15eba294 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -15,9 +15,9 @@ #include #include #include -#include #include #include +#include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { @@ -134,7 +134,7 @@ struct define_stub_function {}; SigT sig, char const* doc) { - typedef typename mpl::at<0, SigT>::type nth_type; + typedef typename boost::python::detail::type_at<0, SigT>::type nth_type; typedef typename StubsT::v_type v_type; typedef typename StubsT::nv_type nv_type; @@ -145,7 +145,8 @@ struct define_stub_function {}; >::type stubs_type; BOOST_STATIC_ASSERT( - (stubs_type::max_args + 1) <= boost::mpl::size::value); + (stubs_type::max_args + 1) <= + boost::python::detail::type_list_size::value); typedef typename stubs_type::template gen gen_type; define_with_defaults_helper::def diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 18931a61..9a43ed9b 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace boost { namespace python { namespace detail { @@ -44,7 +45,7 @@ struct func_stubs_base {}; /////////////////////////////////////////////////////////////////////////////// #define BPL_IMPL_TYPEDEF_GEN(INDEX, DATA) \ - typedef typename boost::mpl::at \ + typedef typename boost::python::detail::type_at \ < \ BOOST_PP_ADD(INDEX, DATA), \ SigT \ @@ -84,7 +85,7 @@ struct func_stubs_base {}; template \ struct gen { \ \ - typedef typename boost::mpl::at<0, SigT>::type RT; \ + typedef typename boost::python::detail::type_at<0, SigT>::type RT; \ \ BOOST_PP_FIX_REPEAT_2ND \ ( \ @@ -135,8 +136,8 @@ struct func_stubs_base {}; template \ struct gen { \ \ - typedef typename boost::mpl::at<0, SigT>::type RT; \ - typedef typename boost::mpl::at<1, SigT>::type ClassT; \ + typedef typename boost::python::detail::type_at<0, SigT>::type RT; \ + typedef typename boost::python::detail::type_at<1, SigT>::type ClassT;\ \ BOOST_PP_FIX_REPEAT_2ND \ ( \ diff --git a/include/boost/python/detail/type_list_utils.hpp b/include/boost/python/detail/type_list_utils.hpp new file mode 100644 index 00000000..9f87b9bf --- /dev/null +++ b/include/boost/python/detail/type_list_utils.hpp @@ -0,0 +1,115 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +// +/////////////////////////////////////////////////////////////////////////////// +#if !defined(BOOST_PP_IS_ITERATING) + +#ifndef TYPE_LIST_UTILS_JDG20020826_HPP +#define TYPE_LIST_UTILS_JDG20020826_HPP + +# include +# include +//# include +//# include + +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +# if (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 245) \ + && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) + + template + struct type_at : public boost::mpl::at {}; + + template + struct type_list_size : public boost::mpl::size {}; + +// template +// struct pop_front : public boost::mpl::pop_front {}; +// +// template +// struct pop_back : public boost::mpl::pop_back {}; + +# else + + template + struct type_at {}; + + template + struct type_list_size {}; + +// template +// struct pop_front {}; +// +// template +// struct pop_back {}; + +// template +// struct push_back {}; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +# endif + +}}} // namespace boost::python::detail + +#endif // TYPE_LIST_UTILS_JDG20020826_HPP + +#else // defined(BOOST_PP_IS_ITERATING) + +# define N BOOST_PP_ITERATION() +# define MAX BOOST_PYTHON_MAX_ARITY + +# if (N < MAX-1) + + template + struct type_at > + { + typedef BOOST_PP_CAT(A, N) type; + }; + +// template +// struct push_back, T> +// { +// typedef boost::mpl::type_list sequence; +// }; + +# if (N > 0) + +// template +// struct pop_front > +// { +// typedef boost::mpl::type_list sequence; +// }; +// +// template +// struct pop_back > +// { +// typedef boost::mpl::type_list sequence; +// }; + +# endif +# endif + + template + struct type_list_size > + { + BOOST_STATIC_CONSTANT(long, value = N); + }; + +# undef N +# undef MAX + +#endif // !defined(BOOST_PP_IS_ITERATING) diff --git a/test/defaults.cpp b/test/defaults.cpp index 0014ab36..fab13d5f 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -121,8 +121,14 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) ; class_("X") + +# if (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 245) \ + && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) .def(init >()) - .def("get_state", &X::get_state) +#endif + + + .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) From ec4de3326e44ba4c4f728f8e8c8737ddde09e625 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 28 Aug 2002 05:42:38 +0000 Subject: [PATCH 0690/1042] bug fix: return type of __getstate__ may be any type [SVN r15106] --- include/boost/python/object/pickle_support.hpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp index bbdd1ac1..2e94faea 100644 --- a/include/boost/python/object/pickle_support.hpp +++ b/include/boost/python/object/pickle_support.hpp @@ -58,13 +58,15 @@ namespace detail { cl.def("__getinitargs__", getinitargs_fn); } - template + template static void register_( Class_& cl, inaccessible* (*getinitargs_fn)(), - tuple (*getstate_fn)(Tgetstate), + Rgetstate (*getstate_fn)(Tgetstate), void (*setstate_fn)(Tsetstate, Ttuple), bool getstate_manages_dict) { @@ -74,13 +76,15 @@ namespace detail { } template + class Tgetinitargs, + class Rgetstate, class Tgetstate, + class Tsetstate, class Ttuple> static void register_( Class_& cl, tuple (*getinitargs_fn)(Tgetinitargs), - tuple (*getstate_fn)(Tgetstate), + Rgetstate (*getstate_fn)(Tgetstate), void (*setstate_fn)(Tsetstate, Ttuple), bool getstate_manages_dict) { From 6f7957fd4086e34cc3393adc9d6903e4dcf5f016 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Fri, 30 Aug 2002 09:05:00 +0000 Subject: [PATCH 0691/1042] Fixed G++ bug that complains of specialization provided after instantiation. [SVN r15112] --- include/boost/python/tuple.hpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp index 04e2d37b..38547696 100644 --- a/include/boost/python/tuple.hpp +++ b/include/boost/python/tuple.hpp @@ -11,7 +11,7 @@ class tuple : public object public: // tuple() -> an empty tuple BOOST_PYTHON_DECL tuple(); - + // tuple(sequence) -> tuple initialized from sequence's items BOOST_PYTHON_DECL tuple(object_cref sequence); @@ -23,20 +23,15 @@ class tuple : public object public: // implementation detail -- for internal use only BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple) - + private: static BOOST_PYTHON_DECL detail::new_reference call(object const&); }; -// for completeness -inline tuple make_tuple() { return tuple(); } - -# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -// -// Converter Specializations // +// Converter Specializations // $$$ JDG $$$ moved here to prevent +// // G++ bug complaining specialization + // provided after instantiation namespace converter { template <> @@ -46,6 +41,12 @@ namespace converter }; } +// for completeness +inline tuple make_tuple() { return tuple(); } + +# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PYTHON_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + }} // namespace boost::python #endif From ec3cc6abe83683fe974e489c5d5fb3fbc4b4478a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 2 Sep 2002 23:23:27 +0000 Subject: [PATCH 0692/1042] Implemented less-liberal conversion rules [SVN r15136] --- src/converter/builtin_converters.cpp | 103 +++++++-------------------- test/extract.py | 2 +- test/test_builtin_converters.py | 59 ++++++++++----- 3 files changed, 66 insertions(+), 98 deletions(-) diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index 1d8efa29..b5916dde 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -74,15 +74,8 @@ namespace if (number_methods == 0) return 0; - // For floating types, return the float conversion slot to avoid - // creating a new object. We'll handle that below - if (PyFloat_Check(obj)) - return &number_methods->nb_float; - - if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__int__")) - return 0; - - return &number_methods->nb_int; + return (PyInt_Check(obj) || PyLong_Check(obj)) + ? &number_methods->nb_int : 0; } }; @@ -91,17 +84,17 @@ namespace { static T extract(PyObject* intermediate) { - return PyFloat_Check(intermediate) - ? numeric_cast(PyFloat_AS_DOUBLE(intermediate)) - : numeric_cast(PyInt_AS_LONG(intermediate)) - ; + return numeric_cast(PyInt_AS_LONG(intermediate)); } }; -// using Python's macro instead of Boost's - we don't seem to get the -// config right all the time. +// Checking Python's macro instead of Boost's - we don't seem to get +// the config right all the time. Furthermore, Python's is defined +// when long long is absent but __int64 is present. + #ifdef HAVE_LONG_LONG // A SlotPolicy for extracting long long types from Python objects + struct long_long_rvalue_from_python_base { static unaryfunc* get_slot(PyObject* obj) @@ -110,22 +103,17 @@ namespace if (number_methods == 0) return 0; - // For floating and integer types, return the identity - // conversion slot to avoid creating a new object. We'll - // handle that in the extract function + // Return the identity conversion slot to avoid creating a + // new object. We'll handle that in the extract function if (PyInt_Check(obj)) return &number_methods->nb_int; - - if (PyFloat_Check(obj)) - return &number_methods->nb_float; - - if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__long__")) + else if (PyLong_Check(obj)) + return &number_methods->nb_long; + else return 0; - - return &number_methods->nb_long; } }; - + struct long_long_rvalue_from_python : long_long_rvalue_from_python_base { static LONG_LONG extract(PyObject* intermediate) @@ -134,10 +122,6 @@ namespace { return PyInt_AS_LONG(intermediate); } - if (PyFloat_Check(intermediate)) - { - return numeric_cast(PyFloat_AS_DOUBLE(intermediate)); - } else { LONG_LONG result = PyLong_AsLongLong(intermediate); @@ -158,10 +142,6 @@ namespace { return numeric_cast(PyInt_AS_LONG(intermediate)); } - if (PyFloat_Check(intermediate)) - { - return numeric_cast(PyFloat_AS_DOUBLE(intermediate)); - } else { unsigned LONG_LONG result = PyLong_AsUnsignedLongLong(intermediate); @@ -175,7 +155,6 @@ namespace }; #endif - // identity_unaryfunc/py_object_identity -- manufacture a unaryfunc // "slot" which just returns its argument. Used for bool // conversions, since all Python objects are directly convertible to @@ -190,9 +169,9 @@ namespace // A SlotPolicy for extracting bool from a Python object struct bool_rvalue_from_python { - static unaryfunc* get_slot(PyObject*) + static unaryfunc* get_slot(PyObject* obj) { - return &py_object_identity; + return obj == Py_None || PyInt_Check(obj) ? &py_object_identity : 0; } static bool extract(PyObject* intermediate) @@ -214,11 +193,9 @@ namespace // creating a new object. We'll handle that below if (PyInt_Check(obj)) return &number_methods->nb_int; - - if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__float__")) - return 0; - - return &number_methods->nb_float; + + return (PyLong_Check(obj) || PyFloat_Check(obj)) + ? &number_methods->nb_float : 0; } static double extract(PyObject* intermediate) @@ -240,10 +217,8 @@ namespace // If the underlying object is "string-able" this will succeed static unaryfunc* get_slot(PyObject* obj) { - if (PyInstance_Check(obj) && !PyObject_HasAttrString(obj, "__str__")) - return 0; - - return &obj->ob_type->tp_str; + return (PyString_Check(obj)) + ? &obj->ob_type->tp_str : 0; }; // Remember that this will be used to construct the result object @@ -253,39 +228,14 @@ namespace } }; - - // to_complex_unaryfunc/py_object_to_complex -- manufacture a - // unaryfunc "slot" which calls its argument's __complex__ - // method. We have this because there's no type object nb_complex - // slot. - extern "C" PyObject* to_complex_unaryfunc(PyObject* x) - { - return PyObject_CallMethod(x, "__complex__", const_cast("()")); - } - unaryfunc py_object_to_complex = to_complex_unaryfunc; - struct complex_rvalue_from_python { static unaryfunc* get_slot(PyObject* obj) { - if (PyComplex_Check(obj)) return &py_object_identity; - - PyNumberMethods* number_methods = obj->ob_type->tp_as_number; - - // For integer types, return the tp_int conversion slot to avoid - // creating a new object. We'll handle that below - if (PyInt_Check(obj) && number_methods) - return &number_methods->nb_int; - - if (PyFloat_Check(obj) && number_methods) - return &number_methods->nb_float; - - if (!PyObject_HasAttrString((PyObject*)obj, "__complex__")) - return 0; - - return &py_object_to_complex; + else + return float_rvalue_from_python::get_slot(obj); } static std::complex extract(PyObject* intermediate) @@ -300,13 +250,10 @@ namespace { return PyInt_AS_LONG(intermediate); } - else if (!PyFloat_Check(intermediate)) + else { - PyErr_SetString(PyExc_TypeError, "__complex__ method did not return a Complex object"); - throw_error_already_set(); + return PyFloat_AS_DOUBLE(intermediate); } - - return PyFloat_AS_DOUBLE(intermediate); } }; } diff --git a/test/extract.py b/test/extract.py index 999dc7b3..328049dd 100644 --- a/test/extract.py +++ b/test/extract.py @@ -11,7 +11,7 @@ Just about anything has a truth value in Python >>> extract_bool(2) 1 - >>> assert check_bool('') + >>> assert not check_bool('') Check that object manager types work properly. These are a different case because they wrap Python objects instead of being wrapped by them. diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index f2dfa9e4..f6caf56b 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -89,8 +89,11 @@ 0 >>> rewrap_const_reference_bool(0) 0 ->>> rewrap_const_reference_bool('yes') -1 + +>>> try: rewrap_const_reference_bool('yes') +... except TypeError: pass +... else: print 'expected a TypeError exception' + >>> rewrap_const_reference_char('x') 'x' @@ -152,25 +155,30 @@ Check that None <==> NULL >>> rewrap_const_reference_cstring(None) -But when converted to a string rvalue, None becomes 'None': - ->>> rewrap_const_reference_string(None) -'None' +But None cannot be converted to a string object: +>>> try: rewrap_const_reference_string(None) +... except TypeError: pass +... else: print 'expected a TypeError exception' Now check implicit conversions between floating/integer types >>> rewrap_const_reference_float(42) 42.0 ->>> rewrap_const_reference_int(42.0) -42 +>>> rewrap_const_reference_float(42L) +42.0 + +>>> try: rewrap_const_reference_int(42.0) +... except TypeError: pass +... else: print 'expected a TypeError exception' >>> rewrap_value_float(42) 42.0 ->>> rewrap_value_int(42.0) -42 +>>> try: rewrap_value_int(42.0) +... except TypeError: pass +... else: print 'expected a TypeError exception' Check that classic classes also work @@ -184,14 +192,21 @@ Check that classic classes also work ... def __str__(self): ... return '42' ->>> rewrap_const_reference_float(FortyTwo()) -42.0 ->>> rewrap_value_int(FortyTwo()) -42 ->>> rewrap_const_reference_string(FortyTwo()) -'42' ->>> abs(rewrap_value_complex_double(FortyTwo()) - (4+.2j)) < .000001 -1 +>>> try: rewrap_const_reference_float(FortyTwo()) +... except TypeError: pass +... else: print 'expected a TypeError exception' + +>>> try: rewrap_value_int(FortyTwo()) +... except TypeError: pass +... else: print 'expected a TypeError exception' + +>>> try: rewrap_const_reference_string(FortyTwo()) +... except TypeError: pass +... else: print 'expected a TypeError exception' + +>>> try: rewrap_value_complex_double(FortyTwo()) +... except TypeError: pass +... else: print 'expected a TypeError exception' # show that arbitrary handle instantiations can be returned >>> get_type(1) is type(1) @@ -204,7 +219,13 @@ Check that classic classes also work def run(args = None): import sys import doctest - + import builtin_converters + + if 'rewrap_value_long_long' in dir(builtin_converters): + print 'LONG_LONG supported, testing...' + else: + print 'LONG_LONG not supported, skipping those tests...' + if args is not None: sys.argv = args return doctest.testmod(sys.modules.get(__name__)) From 7d35ed4eda582b4e8ea6fda514f931461b23db27 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 3 Sep 2002 05:48:20 +0000 Subject: [PATCH 0693/1042] Move converter registration from body of individual Holder classes to select_holder implementation, which prevents Holder instantiation in case the class being wrapped is abstract. [SVN r15138] --- include/boost/python/class.hpp | 17 ++--- include/boost/python/instance_holder.hpp | 4 +- .../boost/python/object/pointer_holder.hpp | 28 --------- include/boost/python/object/select_holder.hpp | 63 +++++++++++++++++-- include/boost/python/object/value_holder.hpp | 8 --- 5 files changed, 69 insertions(+), 51 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 133b752b..08a2c47d 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -52,18 +52,19 @@ namespace detail // type of the first (tag) argument. The 2nd argument is a pointer // to the type of holder that must be created. The 3rd argument is a // reference to the Python type object to be created. - template - static inline void register_copy_constructor(mpl::bool_t const&, Holder*, T* = 0) + template + static inline void register_copy_constructor(mpl::bool_t const&, SelectHolder const& , T* = 0) { - force_instantiate(objects::class_wrapper()); - Holder::register_(); + typedef typename SelectHolder::type holder; + force_instantiate(objects::class_wrapper()); + SelectHolder::register_(); } // Tag dispatched to have no effect. - template - static inline void register_copy_constructor(mpl::bool_t const&, Holder*, T* = 0) + template + static inline void register_copy_constructor(mpl::bool_t const&, SelectHolder const&, T* = 0) { - Holder::register_(); + SelectHolder::register_(); } template int assert_default_constructible(T const&); @@ -340,7 +341,7 @@ inline void class_::register_() const detail::register_copy_constructor( mpl::bool_t() - , objects::select_holder((held_type*)0).get() + , objects::select_holder((held_type*)0) ); } diff --git a/include/boost/python/instance_holder.hpp b/include/boost/python/instance_holder.hpp index f4962479..ea368c1a 100755 --- a/include/boost/python/instance_holder.hpp +++ b/include/boost/python/instance_holder.hpp @@ -25,12 +25,10 @@ struct BOOST_PYTHON_DECL instance_holder : private noncopyable void install(PyObject* inst) throw(); - // Register any converters associated with this Holder - static inline void register_() {} - private: instance_holder* m_next; }; + // This macro is needed for implementation of derived holders # define BOOST_PYTHON_UNFORWARD(N,ignored) (typename unforward::type)(a##N) diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 3d9e9992..d680df66 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -39,21 +39,12 @@ struct pointer_holder : instance_holder pointer_holder(Pointer); - static void register_(); - // Forward construction to the held object # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) # include BOOST_PP_ITERATE() private: // types - struct construct_from_pointer - { - static pointer_holder* execute(PyObject*, Pointer x) - { - return new pointer_holder(x); - } - }; private: // required holder implementation void* holds(type_info); @@ -74,8 +65,6 @@ struct pointer_holder_back_reference : instance_holder // undoubtedly does not carry the correct back reference pointer. pointer_holder_back_reference(Pointer); - static void register_(); - // Forward construction to the held object # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 2)) # include BOOST_PP_ITERATE() @@ -95,29 +84,12 @@ inline pointer_holder::pointer_holder(Pointer p) { } -template -inline void pointer_holder::register_() -{ - python::detail::force_instantiate(class_wrapper()); - python::detail::force_instantiate(instance_finder::registration); -} - - template inline pointer_holder_back_reference::pointer_holder_back_reference(Pointer p) : m_p(p) { } -template -inline void pointer_holder_back_reference::register_() -{ - // not implemented at least until we solve the back reference issue mentioned above. - // python::detail::force_instantiate(class_wrapper()); - python::detail::force_instantiate(instance_finder::registration); - python::detail::force_instantiate(instance_finder::registration); -} - template void* pointer_holder::holds(type_info dst_t) { diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index b4e451c8..a2e50c69 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -11,9 +11,11 @@ # include # include # include +# include # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -28,9 +30,24 @@ namespace detail selector , value_holder_back_reference , value_holder - >::type holder; + >::type type; - static holder* get() { return 0; } + static inline void register_() + { + select_value_holder::register_(mpl::bool_t()); + } + + static type* get() { return 0; } + + private: + static inline void register_(mpl::bool_t) + { + python::detail::force_instantiate(instance_finder::registration); + } + + static inline void register_(mpl::bool_t) + { + } }; template @@ -43,9 +60,47 @@ namespace detail selector , pointer_holder_back_reference , pointer_holder - >::type holder; + >::type type; - static holder* get() { return 0; } + static inline void register_() + { + select_pointer_holder::register_(mpl::bool_t()); + } + + static type* get() { return 0; } + + private: + static inline void register_(mpl::bool_t) + { + // not implemented at least until we solve the back + // reference issue mentioned in pointer_holder.hpp. + // + // python::detail::force_instantiate( + // class_wrapper >()); + + python::detail::force_instantiate(instance_finder::registration); + python::detail::force_instantiate(instance_finder::registration); + } + + struct construct_from_pointer + { + static type* execute(PyObject*, Ptr x) + { + return new type(x); + } + }; + + static inline void register_(mpl::bool_t) + { + python::detail::force_instantiate( + objects::class_wrapper< + Ptr + , type + , construct_from_pointer>()); + + python::detail::force_instantiate( + instance_finder::registration); + } }; } diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 3d8d2ac2..05a5c782 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -47,8 +47,6 @@ struct value_holder_back_reference : instance_holder { typedef Held value_type; - static void register_(); - // Forward construction to the held object # define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 2)) # include BOOST_PP_ITERATE() @@ -85,12 +83,6 @@ void* value_holder_back_reference::holds( return find_static_type(x, src_t, dst_t); } -template -void value_holder_back_reference::register_() -{ - python::detail::force_instantiate(instance_finder::registration); -} - }}} // namespace boost::python::objects # endif // VALUE_HOLDER_DWA20011215_HPP From 865ef2ab7f72825429c9579c892be6637f6820f7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 3 Sep 2002 05:51:15 +0000 Subject: [PATCH 0694/1042] Support for free-function def() invocation (no module object) Fix bugs relying on initialization of objects in the Python DLL [SVN r15139] --- include/boost/python/detail/defaults_def.hpp | 102 +++++++++++++----- include/boost/python/scope.hpp | 6 +- src/module.cpp | 11 +- src/object/life_support.cpp | 7 +- test/back_reference.cpp | 36 +++---- test/bienstman1.cpp | 3 +- test/bienstman2.cpp | 3 +- test/bienstman3.cpp | 3 +- test/bienstman4.cpp | 3 +- test/bienstman5.cpp | 3 +- test/callbacks.cpp | 52 +++++----- test/cltree.cpp | 3 +- test/data_members.cpp | 3 +- test/defaults.cpp | 17 ++- test/dict.cpp | 21 ++-- test/docstring.cpp | 50 +++++---- test/exception_translator.cpp | 8 +- test/extract.cpp | 42 ++++---- test/implicit.cpp | 19 ++-- test/input_iterator.cpp | 18 ++-- test/iterator.cpp | 7 +- test/list.cpp | 26 ++--- test/long.cpp | 14 +-- test/m1.cpp | 41 ++++---- test/m2.cpp | 46 ++++----- test/minimal.cpp | 4 +- test/multi_arg_constructor.cpp | 3 +- test/object.cpp | 52 +++++----- test/operators.cpp | 3 +- test/pickle1.cpp | 3 +- test/pickle2.cpp | 3 +- test/pickle3.cpp | 3 +- test/str.cpp | 9 +- test/test_builtin_converters.cpp | 103 +++++++++---------- test/test_pointer_adoption.cpp | 11 +- test/tuple.cpp | 15 ++- test/virtual_functions.cpp | 3 +- 37 files changed, 415 insertions(+), 341 deletions(-) diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index 15eba294..cc13d314 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -18,22 +18,76 @@ #include #include #include +#include +#include +#include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { +struct module; + +namespace objects +{ + struct class_base; +} + namespace detail { +template +static void name_space_def( + NameSpaceT& name_space, + char const* name, + Func f, + CallPolicies const& policies, + char const* doc, + objects::class_base* + ) +{ + name_space.def( + name, f, policies, doc); +} + +template +static void name_space_def( + object& name_space, + char const* name, + Func f, + CallPolicies const& policies, + char const* doc, + ... + ) +{ + scope within(name_space); + + def(name, f, policies, doc); +} + +// For backward compatibility +template +static void name_space_def( + NameSpaceT& name_space, + char const* name, + Func f, + CallPolicies const& policies, + char const* doc, + module* + ) +{ + name_space.def( + name, f, policies, doc); +} + /////////////////////////////////////////////////////////////////////////////// // // This Boost PP code generates expansions for // -// template +// template // inline void // define_stub_function( -// char const* name, StubsT s, HolderT& holder, boost::mpl::int_t) +// char const* name, StubsT s, NameSpaceT& name_space, boost::mpl::int_t) // { -// holder.def(name, &StubsT::func_N); +// name_space.def(name, &StubsT::func_N); // } // // where N runs from 0 to BOOST_PYTHON_MAX_ARITY @@ -42,7 +96,7 @@ namespace detail { // // 1. char const* name: function name that will be visible to python // 2. StubsT: a function stubs struct (see defaults_gen.hpp) -// 3. HolderT& holder: a python::class_ or python::module instance +// 3. NameSpaceT& name_space: a python::class_ or python::module instance // 4. int_t: the Nth overloaded function (StubsT::func_N) // (see defaults_gen.hpp) // 5. char const* name: doc string @@ -67,7 +121,7 @@ struct define_stub_function {}; // // 1. char const* name: function name that will be visible to python // 2. StubsT: a function stubs struct (see defaults_gen.hpp) -// 3. HolderT& holder: a python::class_ or python::module instance +// 3. NameSpaceT& name_space: a python::class_ or python::module instance // 4. char const* name: doc string // // The def static member function calls a corresponding @@ -79,14 +133,14 @@ struct define_stub_function {}; template struct define_with_defaults_helper { - template + template static void - def(char const* name, StubsT stubs, HolderT& holder, char const* doc) + def(char const* name, StubsT stubs, NameSpaceT& name_space, char const* doc) { // define the NTH stub function of stubs - define_stub_function::define(name, stubs, holder, doc); + define_stub_function::define(name, stubs, name_space, doc); // call the next define_with_defaults_helper - define_with_defaults_helper::def(name, stubs, holder, doc); + define_with_defaults_helper::def(name, stubs, name_space, doc); } }; @@ -94,12 +148,12 @@ struct define_stub_function {}; template <> struct define_with_defaults_helper<0> { - template + template static void - def(char const* name, StubsT stubs, HolderT& holder, char const* doc) + def(char const* name, StubsT stubs, NameSpaceT& name_space, char const* doc) { // define the Oth stub function of stubs - define_stub_function<0>::define(name, stubs, holder, doc); + define_stub_function<0>::define(name, stubs, name_space, doc); // return } }; @@ -110,12 +164,12 @@ struct define_stub_function {}; // // 1. char const* name: function name that will be visible to python // 2. StubsT: a function stubs struct (see defaults_gen.hpp) -// 3. HolderT& holder: a python::class_ or python::module instance +// 3. NameSpaceT& name_space: a python::class_ or python::module instance // 4. SigT sig: Function signature typelist (see defaults_gen.hpp) // 5. char const* name: doc string // // This is the main entry point. This function recursively defines all -// stub functions of StubT (see defaults_gen.hpp) in HolderT holder which +// stub functions of StubT (see defaults_gen.hpp) in NameSpaceT name_space which // can be either a python::class_ or a python::module. The sig argument // is a typelist that specifies the return type, the class (for member // functions, and the arguments. Here are some SigT examples: @@ -125,12 +179,12 @@ struct define_stub_function {}; // void C::foo(int) mpl::type_list // /////////////////////////////////////////////////////////////////////////////// - template + template inline void define_with_defaults( char const* name, StubsT, - HolderT& holder, + NameSpaceT& name_space, SigT sig, char const* doc) { @@ -150,7 +204,7 @@ struct define_stub_function {}; typedef typename stubs_type::template gen gen_type; define_with_defaults_helper::def - (name, gen_type(), holder, doc); + (name, gen_type(), name_space, doc); } } // namespace detail @@ -163,24 +217,22 @@ struct define_stub_function {}; #else // defined(BOOST_PP_IS_ITERATING) // PP vertical iteration code + template <> struct define_stub_function { - - template - static void - define - ( + template + static void define( char const* name, StubsT, - HolderT& holder, + NameSpaceT& name_space, char const* doc ) { - holder.def( + detail::name_space_def(name_space, name, &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION()), default_call_policies(), - doc); + doc, &name_space); } }; diff --git a/include/boost/python/scope.hpp b/include/boost/python/scope.hpp index 298f1eaa..50047bd9 100644 --- a/include/boost/python/scope.hpp +++ b/include/boost/python/scope.hpp @@ -37,15 +37,15 @@ inline scope::scope(object const& new_scope) inline scope::scope() : object(detail::borrowed_reference( - current_scope + current_scope ? current_scope : Py_None )) - , m_previous_scope(python::incref(current_scope)) + , m_previous_scope(python::xincref(current_scope)) { } inline scope::~scope() { - python::decref(current_scope); + python::xdecref(current_scope); current_scope = m_previous_scope; } diff --git a/src/module.cpp b/src/module.cpp index 088773fc..2dd476d1 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace boost { namespace python { namespace detail { @@ -37,6 +38,14 @@ void module_base::setattr_doc(const char* name, python::object const& x, char co objects::function::add_to_namespace(python::object(m_module), name, x, doc); } +void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& x, char const* doc) +{ + // Use function::add_to_namespace to achieve overloading if + // appropriate. + scope current; + objects::function::add_to_namespace(current, name, x, doc); +} + void module_base::add(type_handle const& x) { this->setattr_doc(x->tp_name, python::object(x), 0); @@ -74,6 +83,6 @@ BOOST_PYTHON_DECL void init_module(char const* name, void(*init_function)()) namespace boost { namespace python { -BOOST_PYTHON_DECL PyObject* scope::current_scope = Py_None; +BOOST_PYTHON_DECL PyObject* scope::current_scope = 0; }} diff --git a/src/object/life_support.cpp b/src/object/life_support.cpp index a1a62bfd..ae414bbe 100644 --- a/src/object/life_support.cpp +++ b/src/object/life_support.cpp @@ -37,7 +37,7 @@ extern "C" } PyTypeObject life_support_type = { - PyObject_HEAD_INIT(&PyType_Type) + PyObject_HEAD_INIT(0)//(&PyType_Type) 0, "Boost.Python.life_support", sizeof(life_support), @@ -84,8 +84,11 @@ PyObject* make_nurse_and_patient(PyObject* nurse, PyObject* patient) if (nurse == Py_None) return incref(nurse); - if ((life_support_type.tp_flags & Py_TPFLAGS_READY) == 0) + if (life_support_type.ob_type == 0) + { + life_support_type.ob_type = &PyType_Type; PyType_Ready(&life_support_type); + } life_support* system = PyObject_New(life_support, &life_support_type); if (!system) diff --git a/test/back_reference.cpp b/test/back_reference.cpp index 22477646..73990640 100644 --- a/test/back_reference.cpp +++ b/test/back_reference.cpp @@ -4,7 +4,8 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #include -#include +#include +#include #include #include #include @@ -88,24 +89,23 @@ bool y_equality(back_reference y1, Y const& y2) BOOST_PYTHON_MODULE_INIT(back_reference_ext) { - module("back_reference_ext") - .def("copy_Y", copy_Y, return_value_policy()) - .def("copy_Z", copy_Z, return_value_policy()) - .def("x_instances", &X::count) - .add( - class_("Y", args()) - .def("value", &Y::value) - .def("set", &Y::set) - ) - - .add( - class_ >("Z", args()) - .def("value", &Z::value) - .def("set", &Z::set) - ) - .def("y_identity", y_identity) - .def("y_equality", y_equality) + def("copy_Y", copy_Y, return_value_policy()); + def("copy_Z", copy_Z, return_value_policy()); + def("x_instances", &X::count); + + class_("Y", args()) + .def("value", &Y::value) + .def("set", &Y::set) ; + + class_ >("Z", args()) + .def("value", &Z::value) + .def("set", &Z::set) + ; + + def("y_identity", y_identity); + def("y_equality", y_equality); + } #include "module_tail.cpp" diff --git a/test/bienstman1.cpp b/test/bienstman1.cpp index 5e035d68..b4acf059 100644 --- a/test/bienstman1.cpp +++ b/test/bienstman1.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include #include #include diff --git a/test/bienstman2.cpp b/test/bienstman2.cpp index 79c4dfb0..dd7ba532 100644 --- a/test/bienstman2.cpp +++ b/test/bienstman2.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include struct C {}; diff --git a/test/bienstman3.cpp b/test/bienstman3.cpp index 9b2985e1..f1dc212d 100644 --- a/test/bienstman3.cpp +++ b/test/bienstman3.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include struct V diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp index 22ed6b6f..ef1c94c5 100644 --- a/test/bienstman4.cpp +++ b/test/bienstman4.cpp @@ -4,7 +4,8 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include #include #include diff --git a/test/bienstman5.cpp b/test/bienstman5.cpp index 57b36f21..983b7804 100644 --- a/test/bienstman5.cpp +++ b/test/bienstman5.cpp @@ -4,7 +4,8 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include #include #include diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 230d1a3e..700c190a 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -3,7 +3,8 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include //#include #include #include @@ -114,36 +115,35 @@ int X::counter; BOOST_PYTHON_MODULE_INIT(callbacks_ext) { - boost::python::module("callbacks_ext") - .def("apply_object_object", apply_object_object) - .def("apply_to_own_type", apply_to_own_type) - .def("apply_int_int", apply_int_int) - .def("apply_void_int", apply_void_int) - .def("apply_X_X", apply_X_X) - .def("apply_void_X_ref", apply_void_X_ref) - .def("apply_void_X_cref", apply_void_X_cref) - .def("apply_void_X_ptr", apply_void_X_ptr) - .def("apply_void_X_deep_ptr", apply_void_X_deep_ptr) + def("apply_object_object", apply_object_object); + def("apply_to_own_type", apply_to_own_type); + def("apply_int_int", apply_int_int); + def("apply_void_int", apply_void_int); + def("apply_X_X", apply_X_X); + def("apply_void_X_ref", apply_void_X_ref); + def("apply_void_X_cref", apply_void_X_cref); + def("apply_void_X_ptr", apply_void_X_ptr); + def("apply_void_X_deep_ptr", apply_void_X_deep_ptr); - .def("apply_X_ptr_handle_cref", apply_X_ptr_handle_cref - , return_value_policy()) + def("apply_X_ptr_handle_cref", apply_X_ptr_handle_cref + , return_value_policy()); - .def("apply_X_ref_handle", apply_X_ref_handle - , return_value_policy()) + def("apply_X_ref_handle", apply_X_ref_handle + , return_value_policy()); - .def("apply_cstring_cstring", apply_cstring_cstring) - .def("apply_cstring_pyobject", apply_cstring_pyobject) - .def("apply_char_char", apply_char_char) - .def("apply_to_string_literal", apply_to_string_literal) + def("apply_cstring_cstring", apply_cstring_cstring); + def("apply_cstring_pyobject", apply_cstring_pyobject); + def("apply_char_char", apply_char_char); + def("apply_to_string_literal", apply_to_string_literal); - .add( - class_("X", args()) - .def_init(args()) - .def("value", &X::value) - .def("set", &X::set) - ) - .def("x_count", &X::count) + + class_("X", args()) + .def_init(args()) + .def("value", &X::value) + .def("set", &X::set) ; + + def("x_count", &X::count); } #include "module_tail.cpp" diff --git a/test/cltree.cpp b/test/cltree.cpp index 8b96aad3..03e1be47 100755 --- a/test/cltree.cpp +++ b/test/cltree.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include #include diff --git a/test/data_members.cpp b/test/data_members.cpp index 2ee9c45d..5ab73438 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -4,7 +4,8 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #include -#include +#include +#include #include "test_class.hpp" #if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 diff --git a/test/defaults.cpp b/test/defaults.cpp index fab13d5f..80988bd5 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -3,10 +3,13 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include + +#include +#include #include #include #include +#include #if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 # include // works around a KCC intermediate code generation bug @@ -115,11 +118,15 @@ BOOST_PYTHON_MEM_FUN_GENERATOR(X_foo_3_stubs, foo, 2, 3) BOOST_PYTHON_MODULE_INIT(defaults_ext) { - module("defaults_ext") - .def("foo", foo, foo_stubs()) - .def("bar", (object(*)(int, char, std::string, double))0, bar_stubs()) - ; + def("foo", foo, foo_stubs()); + def("bar", (object(*)(int, char, std::string, double))0, bar_stubs()); + // Show that this works with the old obsolete module version of def(). + module("defaults_ext") + .def("foobar", foo, foo_stubs()) + .def("barfoo", (object(*)(int, char, std::string, double))0, bar_stubs()) + ; + class_("X") # if (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 245) \ diff --git a/test/dict.cpp b/test/dict.cpp index d693658c..0850c6be 100644 --- a/test/dict.cpp +++ b/test/dict.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include #include #include @@ -69,14 +70,12 @@ void test_templates(object print) BOOST_PYTHON_MODULE_INIT(dict_ext) { - module("dict_ext") - .def("new_dict", new_dict) - .def("data_dict", data_dict) - .def("dict_keys", dict_keys) - .def("dict_values", dict_values) - .def("dict_items", dict_items) - .def("dict_from_sequence", dict_from_sequence) - .def("work_with_dict", work_with_dict) - .def("test_templates", test_templates) - ; + def("new_dict", new_dict); + def("data_dict", data_dict); + def("dict_keys", dict_keys); + def("dict_values", dict_values); + def("dict_items", dict_items); + def("dict_from_sequence", dict_from_sequence); + def("work_with_dict", work_with_dict); + def("test_templates", test_templates); } diff --git a/test/docstring.cpp b/test/docstring.cpp index 9642c636..01bacfba 100644 --- a/test/docstring.cpp +++ b/test/docstring.cpp @@ -6,7 +6,9 @@ #include #include #include -#include +#include +#include +#include #include #include "test_class.hpp" @@ -30,32 +32,28 @@ unsigned long fact(unsigned long n) BOOST_PYTHON_MODULE_INIT(docstring_ext) { - module("docstring_ext", - - "A simple test module for documentation strings\n" - "Exercised by docstring.py" - ) - - .add( - class_("X", - "A simple class wrapper around a C++ int\n" - "includes some error-checking" - - , args(), - "this is the __init__ function\n" - "its documentation has two lines." - - ) - - .def("value", &X::value, - "gets the value of the object") - ) - - .def("create", create, return_value_policy(), - "creates a new X object") - - .def("fact", fact, "compute the factorial") + scope().attr("__doc__") = + "A simple test module for documentation strings\n" + "Exercised by docstring.py" ; + + class_("X", + "A simple class wrapper around a C++ int\n" + "includes some error-checking" + + , args(), + "this is the __init__ function\n" + "its documentation has two lines." + + ) + .def("value", &X::value, + "gets the value of the object") + ; + + def("create", create, return_value_policy(), + "creates a new X object"); + + def("fact", fact, "compute the factorial"); } #include "module_tail.cpp" diff --git a/test/exception_translator.cpp b/test/exception_translator.cpp index 58512ef2..8a6428fd 100644 --- a/test/exception_translator.cpp +++ b/test/exception_translator.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include struct error {}; @@ -17,9 +18,8 @@ void throw_error() BOOST_PYTHON_MODULE_INIT(exception_translator_ext) { using namespace boost::python; - register_exception_translator(&translate); - module("exception_translator_ext") - .def("throw_error", throw_error); + + def("throw_error", throw_error); } diff --git a/test/extract.cpp b/test/extract.cpp index 946f5ba1..17640f2f 100644 --- a/test/extract.cpp +++ b/test/extract.cpp @@ -7,7 +7,8 @@ #include "test_class.hpp" #include #include -#include +#include +#include #include #include #include @@ -98,29 +99,28 @@ std::string x_rep(X const& x) BOOST_PYTHON_MODULE_INIT(extract_ext) { implicitly_convertible(); - - module("extract_ext") - .def("extract_bool", extract_bool) - .def("extract_list", extract_list) - .def("extract_cstring", extract_cstring) - .def("extract_string", extract_string) - .def("extract_string_cref", extract_string_cref, return_value_policy()) - .def("extract_X", extract_X) - .def("extract_X_ptr", extract_X_ptr, return_value_policy()) - .def("extract_X_ref", extract_X_ref, return_value_policy()) - .def("check_bool", check_bool) - .def("check_list", check_list) - .def("check_cstring", check_cstring) - .def("check_string", check_string) - .def("check_string_cref", check_string_cref) - .def("check_X", check_X) - .def("check_X_ptr", check_X_ptr) - .def("check_X_ref", check_X_ref) + def("extract_bool", extract_bool); + def("extract_list", extract_list); + def("extract_cstring", extract_cstring); + def("extract_string", extract_string); + def("extract_string_cref", extract_string_cref, return_value_policy()); + def("extract_X", extract_X); + def("extract_X_ptr", extract_X_ptr, return_value_policy()); + def("extract_X_ref", extract_X_ref, return_value_policy()); - .def("double_X", double_X) + def("check_bool", check_bool); + def("check_list", check_list); + def("check_cstring", check_cstring); + def("check_string", check_string); + def("check_string_cref", check_string_cref); + def("check_X", check_X); + def("check_X_ptr", check_X_ptr); + def("check_X_ref", check_X_ref); - .def("count_Xs", &X::count) + def("double_X", double_X); + + def("count_Xs", &X::count); ; object x_class( diff --git a/test/implicit.cpp b/test/implicit.cpp index ca250b9e..cbf34027 100644 --- a/test/implicit.cpp +++ b/test/implicit.cpp @@ -5,7 +5,8 @@ // to its suitability for any purpose. #include #include -#include +#include +#include #include "test_class.hpp" using namespace boost::python; @@ -22,15 +23,15 @@ X make_x(int n) { return X(n); } BOOST_PYTHON_MODULE_INIT(implicit_ext) { implicitly_convertible(); - module("implicit_ext") - .def("x_value", x_value) - .def("make_x", make_x) - .add( - class_("X", args()) - .def("value", &X::value) - .def("set", &X::set) - ) + + def("x_value", x_value); + def("make_x", make_x); + + class_("X", args()) + .def("value", &X::value) + .def("set", &X::set) ; + implicitly_convertible(); } diff --git a/test/input_iterator.cpp b/test/input_iterator.cpp index 0eb5c109..19b50f77 100644 --- a/test/input_iterator.cpp +++ b/test/input_iterator.cpp @@ -3,7 +3,8 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include #include #include #include @@ -36,15 +37,12 @@ list_range2 range2(list_int& x) // the same module with the others. BOOST_PYTHON_MODULE_INIT(input_iterator) { - module("input_iterator") - .def("range2", &::range2) - .add( - class_("list_range2") - - // We can wrap InputIterators which return by-value - .def("__iter__" - , range(&list_range2::first, &list_range2::second)) - ) + def("range2", &::range2); + + class_("list_range2") + // We can wrap InputIterators which return by-value + .def("__iter__" + , range(&list_range2::first, &list_range2::second)) ; } diff --git a/test/iterator.cpp b/test/iterator.cpp index 8f59d4b7..7aaae77c 100644 --- a/test/iterator.cpp +++ b/test/iterator.cpp @@ -3,7 +3,8 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include #include #include #include @@ -72,9 +73,7 @@ private: BOOST_PYTHON_MODULE_INIT(iterator_ext) { - module("iterator_ext") - .def("range", &::range) - ; + def("range", &::range); class_("list_int") .def("push_back", push_back) diff --git a/test/list.cpp b/test/list.cpp index 2e6c2ee7..b3bce4a2 100644 --- a/test/list.cpp +++ b/test/list.cpp @@ -4,7 +4,8 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include #include #include #include @@ -126,20 +127,19 @@ void exercise(list x, object y, object print) BOOST_PYTHON_MODULE_INIT(list_ext) { - module("list_ext") - .def("new_list", new_list) - .def("listify", listify) - .def("listify_string", listify_string) - .def("apply_object_list", apply_object_list) - .def("apply_list_list", apply_list_list) + def("new_list", new_list); + def("listify", listify); + def("listify_string", listify_string); + def("apply_object_list", apply_object_list); + def("apply_list_list", apply_list_list); - .def("append_object", append_object) - .def("append_list", append_list) + def("append_object", append_object); + def("append_list", append_list); - .def("exercise", exercise) - - .add(class_("X", args()) - .def( "__repr__", x_rep)) + def("exercise", exercise); + + class_("X", args()) + .def( "__repr__", x_rep) ; } diff --git a/test/long.cpp b/test/long.cpp index 2a139de8..32d3164a 100644 --- a/test/long.cpp +++ b/test/long.cpp @@ -4,7 +4,8 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include #include #include @@ -40,12 +41,11 @@ int is_long2(char const*) BOOST_PYTHON_MODULE_INIT(long_ext) { - module("long_ext") - .def("new_long", new_long) - .def("longify", longify) - .def("longify_string", longify_string) - .def("is_long", is_long1) - .def("is_long", is_long2) + def("new_long", new_long); + def("longify", longify); + def("longify_string", longify_string); + def("is_long", is_long1); + def("is_long", is_long2); ; } diff --git a/test/m1.cpp b/test/m1.cpp index 34832dfa..a6cb7439 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -7,7 +7,8 @@ #include "simple_type.hpp" #include "complicated.hpp" -#include +#include +#include #include #include #include @@ -215,37 +216,35 @@ BOOST_PYTHON_MODULE_INIT(m1) lvalue_from_pytype,&SimpleType>(); - module("m1") - // Insert the metaclass for all extension classes - .setattr("xclass", boost::python::objects::class_metatype()) + // Insert the metaclass for all extension classes + scope().attr("xclass") = boost::python::objects::class_metatype(); // Insert the base class for all extension classes - .setattr("xinst", boost::python::objects::class_type()) + scope().attr("xinst") = boost::python::objects::class_type(); - .def("new_noddy", new_noddy) - .def("new_simple", new_simple) + def("new_noddy", new_noddy); + def("new_simple", new_simple); // Expose f() in all its variations - .def("f", f) - .def("f_mutable_ref", f_mutable_ref) - .def("f_mutable_ptr", f_mutable_ptr) - .def("f_const_ptr", f_const_ptr) + def("f", f); + def("f_mutable_ref", f_mutable_ref); + def("f_mutable_ptr", f_mutable_ptr); + def("f_const_ptr", f_const_ptr); - .def("f2", f2) + def("f2", f2); // Expose g() - .def("g", g , return_value_policy() - ) + def("g", g , return_value_policy() + ); - .def("take_a", take_a) - .def("take_b", take_b) - .def("take_c", take_c) - .def("take_d", take_d) + def("take_a", take_a); + def("take_b", take_b); + def("take_c", take_c); + def("take_d", take_d); - .def("take_d_shared_ptr", take_d_shared_ptr) - .def("d_factory", d_factory) - ; + def("take_d_shared_ptr", take_d_shared_ptr); + def("d_factory", d_factory); class_ >("A") .def("name", &A::name) diff --git a/test/m2.cpp b/test/m2.cpp index afffb27d..5eee1a89 100644 --- a/test/m2.cpp +++ b/test/m2.cpp @@ -7,7 +7,8 @@ // This module exercises the converters exposed in m1 at a low level // by exposing raw Python extension functions that use wrap<> and // unwrap<> objects. -#include +#include +#include #include #include #include @@ -65,35 +66,34 @@ BOOST_PYTHON_MODULE_INIT(m2) using boost::python::return_value_policy; using boost::python::copy_const_reference; using boost::python::copy_non_const_reference; + using boost::python::def; - boost::python::module("m2") - .def("unwrap_int", unwrap_int) - .def("unwrap_int_ref", unwrap_int_ref) - .def("unwrap_int_const_ref", unwrap_int_const_ref) - .def("unwrap_simple", unwrap_simple) - .def("unwrap_simple_ref", unwrap_simple_ref) - .def("unwrap_simple_const_ref", unwrap_simple_const_ref) + def("unwrap_int", unwrap_int); + def("unwrap_int_ref", unwrap_int_ref); + def("unwrap_int_const_ref", unwrap_int_const_ref); + def("unwrap_simple", unwrap_simple); + def("unwrap_simple_ref", unwrap_simple_ref); + def("unwrap_simple_const_ref", unwrap_simple_const_ref); - .def("wrap_int", &rewrap::f) + def("wrap_int", &rewrap::f); - .def("wrap_int_ref", &rewrap::f - , return_value_policy() - ) + def("wrap_int_ref", &rewrap::f + , return_value_policy() + ); - .def("wrap_int_const_ref", &rewrap::f - , return_value_policy() - ) + def("wrap_int_const_ref", &rewrap::f + , return_value_policy() + ); - .def("wrap_simple", &rewrap::f) + def("wrap_simple", &rewrap::f); - .def("wrap_simple_ref", &rewrap::f - , return_value_policy() - ) + def("wrap_simple_ref", &rewrap::f + , return_value_policy() + ); - .def("wrap_simple_const_ref", &rewrap::f - , return_value_policy() - ) - ; + def("wrap_simple_const_ref", &rewrap::f + , return_value_policy() + ); } #include "module_tail.cpp" diff --git a/test/minimal.cpp b/test/minimal.cpp index d76922bf..be0fe6ec 100644 --- a/test/minimal.cpp +++ b/test/minimal.cpp @@ -3,7 +3,8 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include #if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 # include // works around a KCC intermediate code generation bug @@ -11,7 +12,6 @@ BOOST_PYTHON_MODULE_INIT(minimal_ext) { - boost::python::module m("minimal_ext"); } #include "module_tail.cpp" diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp index 562842a0..43e8bfb1 100644 --- a/test/multi_arg_constructor.cpp +++ b/test/multi_arg_constructor.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include struct A diff --git a/test/object.cpp b/test/object.cpp index 9bcf54a4..6a76aeb3 100755 --- a/test/object.cpp +++ b/test/object.cpp @@ -3,7 +3,8 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include #include using namespace boost::python; @@ -280,38 +281,37 @@ bool check_inplace(object l, object o) BOOST_PYTHON_MODULE_INIT(object_ext) { - module("object_ext") - .def("call_object_3", call_object_3) - .def("message", message) - .def("number", number) + def("call_object_3", call_object_3); + def("message", message); + def("number", number); - .def("obj_getattr", obj_getattr) - .def("obj_const_getattr", obj_const_getattr) - .def("obj_setattr", obj_setattr) - .def("obj_setattr42", obj_setattr42) - .def("obj_moveattr", obj_moveattr) + def("obj_getattr", obj_getattr); + def("obj_const_getattr", obj_const_getattr); + def("obj_setattr", obj_setattr); + def("obj_setattr42", obj_setattr42); + def("obj_moveattr", obj_moveattr); - .def("obj_getitem", obj_getitem) - .def("obj_getitem3", obj_getitem) - .def("obj_const_getitem", obj_const_getitem) - .def("obj_setitem", obj_setitem) - .def("obj_setitem42", obj_setitem42) - .def("obj_moveitem", obj_moveitem) - .def("obj_moveitem2", obj_moveitem2) + def("obj_getitem", obj_getitem); + def("obj_getitem3", obj_getitem); + def("obj_const_getitem", obj_const_getitem); + def("obj_setitem", obj_setitem); + def("obj_setitem42", obj_setitem42); + def("obj_moveitem", obj_moveitem); + def("obj_moveitem2", obj_moveitem2); - .def("test", test) - .def("test_not", test_not) + def("test", test); + def("test_not", test_not); - .def("test_attr", test_attr) - .def("test_not_attr", test_not_attr) + def("test_attr", test_attr); + def("test_not_attr", test_not_attr); - .def("test_item", test_item) - .def("test_not_item", test_not_item) + def("test_item", test_item); + def("test_not_item", test_not_item); - .def("check_binary_operators", check_binary_operators) - .def("check_inplace", check_inplace) - .def("check_string_slice", check_string_slice) + def("check_binary_operators", check_binary_operators); + def("check_inplace", check_inplace); + def("check_string_slice", check_string_slice); ; } diff --git a/test/operators.cpp b/test/operators.cpp index ae90f996..e21b5509 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -6,7 +6,8 @@ #include #include #include -#include +#include +#include #include "test_class.hpp" #if __GNUC__ != 2 # include diff --git a/test/pickle1.cpp b/test/pickle1.cpp index 647ef249..e1397d60 100644 --- a/test/pickle1.cpp +++ b/test/pickle1.cpp @@ -10,7 +10,8 @@ For more information refer to boost/libs/python/doc/pickle.html. */ -#include +#include +#include #include #include diff --git a/test/pickle2.cpp b/test/pickle2.cpp index f1bd8439..984d6380 100644 --- a/test/pickle2.cpp +++ b/test/pickle2.cpp @@ -22,7 +22,8 @@ #include -#include +#include +#include #include #include #include diff --git a/test/pickle3.cpp b/test/pickle3.cpp index 367b1d81..8911b24c 100644 --- a/test/pickle3.cpp +++ b/test/pickle3.cpp @@ -17,7 +17,8 @@ #include -#include +#include +#include #include #include #include diff --git a/test/str.cpp b/test/str.cpp index d9af0478..646f8676 100644 --- a/test/str.cpp +++ b/test/str.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include #include @@ -60,9 +61,7 @@ void work_with_string(object print) BOOST_PYTHON_MODULE_INIT(str_ext) { - module("str_ext") - .def("convert_to_string",convert_to_string) - .def("work_with_string",work_with_string) - ; + def("convert_to_string",convert_to_string); + def("work_with_string",work_with_string); } diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp index 63b71669..912f2dc5 100644 --- a/test/test_builtin_converters.cpp +++ b/test/test_builtin_converters.cpp @@ -4,7 +4,8 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #include -#include +#include +#include #include #include #include @@ -38,6 +39,7 @@ struct by_reference } }; +using boost::python::def; using boost::python::handle; using boost::python::object; using boost::python::borrowed; @@ -57,71 +59,68 @@ char const* rewrap_value_mutable_cstring(char* x) { return x; } BOOST_PYTHON_MODULE_INIT(builtin_converters) { - boost::python::module("builtin_converters") - .def("get_type", get_type) - .def("return_null_handle", return_null_handle) + def("get_type", get_type); + def("return_null_handle", return_null_handle); - .def("rewrap_value_bool", by_value::rewrap) - .def("rewrap_value_char", by_value::rewrap) - .def("rewrap_value_signed_char", by_value::rewrap) - .def("rewrap_value_unsigned_char", by_value::rewrap) - .def("rewrap_value_int", by_value::rewrap) - .def("rewrap_value_unsigned_int", by_value::rewrap) - .def("rewrap_value_short", by_value::rewrap) - .def("rewrap_value_unsigned_short", by_value::rewrap) - .def("rewrap_value_long", by_value::rewrap) - .def("rewrap_value_unsigned_long", by_value::rewrap) + def("rewrap_value_bool", by_value::rewrap); + def("rewrap_value_char", by_value::rewrap); + def("rewrap_value_signed_char", by_value::rewrap); + def("rewrap_value_unsigned_char", by_value::rewrap); + def("rewrap_value_int", by_value::rewrap); + def("rewrap_value_unsigned_int", by_value::rewrap); + def("rewrap_value_short", by_value::rewrap); + def("rewrap_value_unsigned_short", by_value::rewrap); + def("rewrap_value_long", by_value::rewrap); + def("rewrap_value_unsigned_long", by_value::rewrap); // using Python's macro instead of Boost's - we don't seem to get the // config right all the time. #ifdef HAVE_LONG_LONG - .def("rewrap_value_long_long", by_value::rewrap) - .def("rewrap_value_unsigned_long_long", by_value::rewrap) + def("rewrap_value_long_long", by_value::rewrap); + def("rewrap_value_unsigned_long_long", by_value::rewrap); #endif - .def("rewrap_value_float", by_value::rewrap) - .def("rewrap_value_double", by_value::rewrap) - .def("rewrap_value_long_double", by_value::rewrap) - .def("rewrap_value_complex_float", by_value >::rewrap) - .def("rewrap_value_complex_double", by_value >::rewrap) - .def("rewrap_value_complex_long_double", by_value >::rewrap) - .def("rewrap_value_string", by_value::rewrap) - .def("rewrap_value_cstring", by_value::rewrap) - .def("rewrap_value_handle", by_value >::rewrap) - .def("rewrap_value_object", by_value::rewrap) + def("rewrap_value_float", by_value::rewrap); + def("rewrap_value_double", by_value::rewrap); + def("rewrap_value_long_double", by_value::rewrap); + def("rewrap_value_complex_float", by_value >::rewrap); + def("rewrap_value_complex_double", by_value >::rewrap); + def("rewrap_value_complex_long_double", by_value >::rewrap); + def("rewrap_value_string", by_value::rewrap); + def("rewrap_value_cstring", by_value::rewrap); + def("rewrap_value_handle", by_value >::rewrap); + def("rewrap_value_object", by_value::rewrap); // Expose this to illustrate our failings ;-). See test_builtin_converters.py - .def("rewrap_value_mutable_cstring", rewrap_value_mutable_cstring) + def("rewrap_value_mutable_cstring", rewrap_value_mutable_cstring); - .def("rewrap_const_reference_bool", by_const_reference::rewrap) - .def("rewrap_const_reference_char", by_const_reference::rewrap) - .def("rewrap_const_reference_signed_char", by_const_reference::rewrap) - .def("rewrap_const_reference_unsigned_char", by_const_reference::rewrap) - .def("rewrap_const_reference_int", by_const_reference::rewrap) - .def("rewrap_const_reference_unsigned_int", by_const_reference::rewrap) - .def("rewrap_const_reference_short", by_const_reference::rewrap) - .def("rewrap_const_reference_unsigned_short", by_const_reference::rewrap) - .def("rewrap_const_reference_long", by_const_reference::rewrap) - .def("rewrap_const_reference_unsigned_long", by_const_reference::rewrap) + def("rewrap_const_reference_bool", by_const_reference::rewrap); + def("rewrap_const_reference_char", by_const_reference::rewrap); + def("rewrap_const_reference_signed_char", by_const_reference::rewrap); + def("rewrap_const_reference_unsigned_char", by_const_reference::rewrap); + def("rewrap_const_reference_int", by_const_reference::rewrap); + def("rewrap_const_reference_unsigned_int", by_const_reference::rewrap); + def("rewrap_const_reference_short", by_const_reference::rewrap); + def("rewrap_const_reference_unsigned_short", by_const_reference::rewrap); + def("rewrap_const_reference_long", by_const_reference::rewrap); + def("rewrap_const_reference_unsigned_long", by_const_reference::rewrap); // using Python's macro instead of Boost's - we don't seem to get the // config right all the time. #ifdef HAVE_LONG_LONG - .def("rewrap_const_reference_long_long", by_const_reference::rewrap) - .def("rewrap_const_reference_unsigned_long_long", by_const_reference::rewrap) + def("rewrap_const_reference_long_long", by_const_reference::rewrap); + def("rewrap_const_reference_unsigned_long_long", by_const_reference::rewrap); #endif - .def("rewrap_const_reference_float", by_const_reference::rewrap) - .def("rewrap_const_reference_double", by_const_reference::rewrap) - .def("rewrap_const_reference_long_double", by_const_reference::rewrap) - .def("rewrap_const_reference_complex_float", by_const_reference >::rewrap) - .def("rewrap_const_reference_complex_double", by_const_reference >::rewrap) - .def("rewrap_const_reference_complex_long_double", by_const_reference >::rewrap) - .def("rewrap_const_reference_string", by_const_reference::rewrap) - .def("rewrap_const_reference_cstring", by_const_reference::rewrap) - .def("rewrap_const_reference_handle", by_const_reference >::rewrap) - .def("rewrap_const_reference_object", by_const_reference::rewrap) + def("rewrap_const_reference_float", by_const_reference::rewrap); + def("rewrap_const_reference_double", by_const_reference::rewrap); + def("rewrap_const_reference_long_double", by_const_reference::rewrap); + def("rewrap_const_reference_complex_float", by_const_reference >::rewrap); + def("rewrap_const_reference_complex_double", by_const_reference >::rewrap); + def("rewrap_const_reference_complex_long_double", by_const_reference >::rewrap); + def("rewrap_const_reference_string", by_const_reference::rewrap); + def("rewrap_const_reference_cstring", by_const_reference::rewrap); + def("rewrap_const_reference_handle", by_const_reference >::rewrap); + def("rewrap_const_reference_object", by_const_reference::rewrap); - .def("rewrap_reference_object", by_reference::rewrap) - - ; + def("rewrap_reference_object", by_reference::rewrap); } diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index caefe4cb..b04e3496 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -3,7 +3,8 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include #include #include #include @@ -88,15 +89,13 @@ A* as_A(Base* b) BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) { - boost::python::module("test_pointer_adoption_ext") - .def("num_a_instances", num_a_instances) + def("num_a_instances", num_a_instances); // Specify the manage_new_object return policy to take // ownership of create's result - .def("create", create, return_value_policy()) + def("create", create, return_value_policy()); - .def("as_A", as_A, return_internal_reference<>()) - ; + def("as_A", as_A, return_internal_reference<>()); class_("Base") ; diff --git a/test/tuple.cpp b/test/tuple.cpp index 61b4d187..d5569185 100644 --- a/test/tuple.cpp +++ b/test/tuple.cpp @@ -1,4 +1,5 @@ -#include +#include +#include #include #include @@ -20,11 +21,9 @@ tuple mktuple2(char const* a1, int x) { return make_tuple(a1, x); } BOOST_PYTHON_MODULE_INIT(tuple_ext) { - module("tuple_ext") - .def("convert_to_tuple",convert_to_tuple) - .def("test_operators",test_operators) - .def("make_tuple", mktuple0) - .def("make_tuple", mktuple1) - .def("make_tuple", mktuple2) - ; + def("convert_to_tuple",convert_to_tuple); + def("test_operators",test_operators); + def("make_tuple", mktuple0); + def("make_tuple", mktuple1); + def("make_tuple", mktuple2); } diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp index 3864498a..73d47dc5 100644 --- a/test/virtual_functions.cpp +++ b/test/virtual_functions.cpp @@ -4,7 +4,8 @@ // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #include -#include +#include +#include #include #include #include From 73ffc4a13f2d06de84bc1ac7219d45cf2987a1e8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 3 Sep 2002 13:20:08 +0000 Subject: [PATCH 0695/1042] Support for free-function def() invocation (no module object) Fix bugs relying on initialization of objects in the Python DLL [SVN r15142] --- include/boost/python/def.hpp | 68 ++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 include/boost/python/def.hpp diff --git a/include/boost/python/def.hpp b/include/boost/python/def.hpp new file mode 100644 index 00000000..084b64a7 --- /dev/null +++ b/include/boost/python/def.hpp @@ -0,0 +1,68 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef DEF_DWA200292_HPP +# define DEF_DWA200292_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& obj, char const* doc); + + template + void + dispatch_def( + char const* name, + Fn fn, + CallPolicyOrDoc const& policy_or_doc, + char const* doc, + void const*) + { + typedef detail::def_helper helper; + + detail::scope_setattr_doc( + name, boost::python::make_function(fn, helper::get_policy(policy_or_doc)), + helper::get_doc(policy_or_doc, doc)); + } + + 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. + scope current; + detail::define_with_defaults(name, stubs, current, detail::get_signature(sig), doc); + } +} + +template +void def(char const* name, Fn fn) +{ + detail::scope_setattr_doc(name, boost::python::make_function(fn), 0); +} + +template +void def(char const* name, Arg1T arg1, Arg2T const& arg2, char const* doc = 0) +{ + detail::dispatch_def(name, arg1, arg2, doc, &arg2); +} + + +}} // namespace boost::python + +#endif // DEF_DWA200292_HPP From 5762eb9b3307adaa0016b3d75e733c3163931827 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 3 Sep 2002 16:57:17 +0000 Subject: [PATCH 0696/1042] Add missing #include [SVN r15145] --- include/boost/python/detail/type_list_utils.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/python/detail/type_list_utils.hpp b/include/boost/python/detail/type_list_utils.hpp index 9f87b9bf..a9352850 100644 --- a/include/boost/python/detail/type_list_utils.hpp +++ b/include/boost/python/detail/type_list_utils.hpp @@ -23,6 +23,8 @@ # include # include +# include + namespace boost { namespace python { namespace detail { # if (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 245) \ From fe02cae4f7be6871783f543c5d921dc398f3890d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 3 Sep 2002 18:20:59 +0000 Subject: [PATCH 0697/1042] Add missing #include [SVN r15146] --- include/boost/python/def.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/python/def.hpp b/include/boost/python/def.hpp index 084b64a7..5052644a 100644 --- a/include/boost/python/def.hpp +++ b/include/boost/python/def.hpp @@ -11,6 +11,7 @@ # include # include # include +# include namespace boost { namespace python { From 946a93164a4fff836038bf0afa56f2e17db26dee Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 3 Sep 2002 18:23:13 +0000 Subject: [PATCH 0698/1042] Remove colliding "MAX" macro [SVN r15147] --- include/boost/python/detail/type_list_utils.hpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/include/boost/python/detail/type_list_utils.hpp b/include/boost/python/detail/type_list_utils.hpp index a9352850..026fd92f 100644 --- a/include/boost/python/detail/type_list_utils.hpp +++ b/include/boost/python/detail/type_list_utils.hpp @@ -72,12 +72,11 @@ namespace boost { namespace python { namespace detail { #else // defined(BOOST_PP_IS_ITERATING) # define N BOOST_PP_ITERATION() -# define MAX BOOST_PYTHON_MAX_ARITY -# if (N < MAX-1) +# if (N < BOOST_PYTHON_MAX_ARITY-1) - template - struct type_at > + template + struct type_at > { typedef BOOST_PP_CAT(A, N) type; }; @@ -88,7 +87,7 @@ namespace boost { namespace python { namespace detail { // typedef boost::mpl::type_list sequence; // }; -# if (N > 0) +# if (N > 0) // template // struct pop_front > @@ -102,7 +101,7 @@ namespace boost { namespace python { namespace detail { // typedef boost::mpl::type_list sequence; // }; -# endif +# endif # endif template @@ -112,6 +111,5 @@ namespace boost { namespace python { namespace detail { }; # undef N -# undef MAX #endif // !defined(BOOST_PP_IS_ITERATING) From 0453e05bb26301884d055a07cdcf024aa9c3c20c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 3 Sep 2002 18:30:18 +0000 Subject: [PATCH 0699/1042] Suppress private inheritance warning [SVN r15148] --- include/boost/python/scope.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/python/scope.hpp b/include/boost/python/scope.hpp index 50047bd9..7262f8da 100644 --- a/include/boost/python/scope.hpp +++ b/include/boost/python/scope.hpp @@ -12,7 +12,8 @@ namespace boost { namespace python { -class BOOST_PYTHON_DECL scope : public object, noncopyable +class BOOST_PYTHON_DECL scope + : public object, private noncopyable { public: inline scope(object const&); From 7407a6b14483d214181bd5319f072709e1a69bb7 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 4 Sep 2002 07:33:35 +0000 Subject: [PATCH 0700/1042] use def_init() for compilers that don't support init<... optional<...> >; with this all tru64_cxx test pass; (I know this is not testing the default argument support, but a failing test isn't very inspiring for others, and the addition shows people what the alternative is.) [SVN r15154] --- test/defaults.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/defaults.cpp b/test/defaults.cpp index 80988bd5..e7df5e2a 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -132,10 +132,13 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) # if (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 245) \ && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) .def(init >()) +#else + .def_init(args()) + .def_init(args()) + .def_init(args()) + .def_init(args()) #endif - - - .def("get_state", &X::get_state) + .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) From ac02c763c7cd7388dfa2d5edf05d2efd955d2221 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 4 Sep 2002 16:28:24 +0000 Subject: [PATCH 0701/1042] Fixed to workaround init<...> only for intel compilers [SVN r15157] --- test/defaults.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/defaults.cpp b/test/defaults.cpp index e7df5e2a..64fdd5ca 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -126,18 +126,17 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) .def("foobar", foo, foo_stubs()) .def("barfoo", (object(*)(int, char, std::string, double))0, bar_stubs()) ; - + class_("X") -# if (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 245) \ - && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) +# if (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) .def(init >()) -#else +# else .def_init(args()) .def_init(args()) .def_init(args()) .def_init(args()) -#endif +# endif .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) From ba86f516d847b41ff0945d4214620223b4e83ea6 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 4 Sep 2002 21:58:21 +0000 Subject: [PATCH 0702/1042] Fixed case where member function has no arguments. [SVN r15160] --- include/boost/python/detail/defaults_gen.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 9a43ed9b..b131269d 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -107,7 +108,7 @@ struct func_stubs_base {}; #define BPL_IMPL_MEM_FUNC_WRAPPER_GEN(INDEX, DATA) \ static RT BOOST_PP_CAT(func_, INDEX) \ ( \ - ClassT& obj, \ + ClassT& obj BOOST_PP_COMMA_IF(INDEX) \ BOOST_PP_ENUM \ ( \ BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ From d274a8395b7d02082b0470a467e8015ba9685e99 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 4 Sep 2002 22:10:37 +0000 Subject: [PATCH 0703/1042] pardon, wrong commit. one more try. sorry. [SVN r15161] --- include/boost/python/detail/defaults_gen.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index b131269d..33cc13c8 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -108,7 +108,7 @@ struct func_stubs_base {}; #define BPL_IMPL_MEM_FUNC_WRAPPER_GEN(INDEX, DATA) \ static RT BOOST_PP_CAT(func_, INDEX) \ ( \ - ClassT& obj BOOST_PP_COMMA_IF(INDEX) \ + ClassT& obj, \ BOOST_PP_ENUM \ ( \ BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ From 4d53fb97b6378526cd7aac350b6181e06dab645e Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 4 Sep 2002 22:36:05 +0000 Subject: [PATCH 0704/1042] update to defaults gen that fixes member functions with zero arguments (added a test in defaults.cpp) [SVN r15162] --- include/boost/python/detail/defaults_gen.hpp | 3 ++- test/defaults.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 33cc13c8..d0e0cbb9 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -108,7 +108,8 @@ struct func_stubs_base {}; #define BPL_IMPL_MEM_FUNC_WRAPPER_GEN(INDEX, DATA) \ static RT BOOST_PP_CAT(func_, INDEX) \ ( \ - ClassT& obj, \ + ClassT& obj BOOST_PP_COMMA_IF( \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX)) \ BOOST_PP_ENUM \ ( \ BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ diff --git a/test/defaults.cpp b/test/defaults.cpp index 64fdd5ca..6f9e7c13 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -83,6 +83,13 @@ struct X { return format % make_tuple(a, b, c, d); } + object + bar2(int a = 0, char b = 'D', std::string c = "default", double d = 0.0) const + { + // tests zero arg member function + return format % make_tuple(a, b, c, d); + } + object foo(int a, bool b=false) const { @@ -111,6 +118,7 @@ struct X { }; BOOST_PYTHON_MEM_FUN_GENERATOR(X_bar_stubs, bar, 1, 4) +BOOST_PYTHON_MEM_FUN_GENERATOR(X_bar2_stubs, bar2, 0, 4) // tests zero arg member function BOOST_PYTHON_MEM_FUN_GENERATOR(X_foo_2_stubs, foo, 1, 2) BOOST_PYTHON_MEM_FUN_GENERATOR(X_foo_3_stubs, foo, 2, 3) From ce2e9de6fbb68bfd56369041811bdd9b9e88eafd Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 4 Sep 2002 23:51:24 +0000 Subject: [PATCH 0705/1042] fixed case where function has all default arguments, also added a test in defaults.cpp [SVN r15165] --- include/boost/python/detail/defaults_def.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index cc13d314..bf2a4fb9 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -199,7 +199,7 @@ struct define_stub_function {}; >::type stubs_type; BOOST_STATIC_ASSERT( - (stubs_type::max_args + 1) <= + (stubs_type::max_args) <= boost::python::detail::type_list_size::value); typedef typename stubs_type::template gen gen_type; From 5cda0581cdacde08a1123176304a6c638050de2e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 5 Sep 2002 13:59:46 +0000 Subject: [PATCH 0706/1042] bug fix (IRIX CC diagnostics) [SVN r15167] --- include/boost/python/module.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 012aee6d..cc8cb832 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -31,7 +31,7 @@ class module : public detail::module_base template module& setattr(const char* name, T const& x) { - this->module_base::setattr_doc(name, python::object(x), 0); + this->base::setattr_doc(name, python::object(x), 0); return *this; } From 9d520877d15075f15102675a8b43248caa4bf32d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 5 Sep 2002 14:00:57 +0000 Subject: [PATCH 0707/1042] adjustment for IRIX CC; also tested with gcc 3.0.4, VC7, cxx 6.5 [SVN r15168] --- src/object/function.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object/function.cpp b/src/object/function.cpp index 187becc9..8aa39dbf 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -299,13 +299,13 @@ extern "C" else return python::incref(f->name().ptr()); } +} static PyGetSetDef function_getsetlist[] = { {"__name__", (getter)function_get_name, 0 }, {"__doc__", (getter)function_get_doc, (setter)function_set_doc}, {NULL} /* Sentinel */ }; -} PyTypeObject function_type = { PyObject_HEAD_INIT(0) From b8d3c84d3c89a638d02a9f5c0394d21a857723de Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 5 Sep 2002 23:31:30 +0000 Subject: [PATCH 0708/1042] macro names changed to be more self-documenting [SVN r15172] --- include/boost/python/detail/defaults_gen.hpp | 14 +++++++++----- test/defaults.cpp | 12 ++++++------ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index d0e0cbb9..79144360 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -224,8 +224,8 @@ struct func_stubs_base {}; // // There are two versions: // -// 1. BOOST_PYTHON_FUNCTION_GENERATOR for free functions -// 2. BOOST_PYTHON_MEM_FUN_GENERATOR for member functions. +// 1. BOOST_PYTHON_FUNCTION_OVERLOADS for free functions +// 2. BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS for member functions. // // For instance, given a function: // @@ -237,7 +237,7 @@ struct func_stubs_base {}; // // The macro invocation: // -// BOOST_PYTHON_FUNCTION_GENERATOR(foo_stubs, foo, 1, 4) +// BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4) // // Generates this code: // @@ -284,7 +284,7 @@ struct func_stubs_base {}; // for the return type (void) and the lack of the return keyword. // /////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_FUNCTION_GENERATOR(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\ +#define BOOST_PYTHON_FUNCTION_OVERLOADS(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\ BPL_IMPL_GEN_FUNCTION_STUB \ ( \ FNAME, \ @@ -293,7 +293,7 @@ struct func_stubs_base {}; BOOST_PP_SUB(MAX_ARGS, MIN_ARGS) \ ) \ -#define BOOST_PYTHON_MEM_FUN_GENERATOR(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\ +#define BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS)\ BPL_IMPL_GEN_MEM_FUNCTION_STUB \ ( \ FNAME, \ @@ -302,6 +302,10 @@ struct func_stubs_base {}; BOOST_PP_SUB(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 diff --git a/test/defaults.cpp b/test/defaults.cpp index 6f9e7c13..06fb2bc2 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -49,7 +49,7 @@ bar(int a) return format % make_tuple(a, 'D', "default", 0.0); } -BOOST_PYTHON_FUNCTION_GENERATOR(bar_stubs, bar, 1, 4) +BOOST_PYTHON_FUNCTION_OVERLOADS(bar_stubs, bar, 1, 4) /////////////////////////////////////////////////////////////////////////////// // @@ -62,7 +62,7 @@ foo(int a, char b = 'D', std::string c = "default", double d = 0.0) return format % make_tuple(a, b, c, d); } -BOOST_PYTHON_FUNCTION_GENERATOR(foo_stubs, foo, 1, 4) +BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4) /////////////////////////////////////////////////////////////////////////////// // @@ -117,10 +117,10 @@ struct X { object state; }; -BOOST_PYTHON_MEM_FUN_GENERATOR(X_bar_stubs, bar, 1, 4) -BOOST_PYTHON_MEM_FUN_GENERATOR(X_bar2_stubs, bar2, 0, 4) // tests zero arg member function -BOOST_PYTHON_MEM_FUN_GENERATOR(X_foo_2_stubs, foo, 1, 2) -BOOST_PYTHON_MEM_FUN_GENERATOR(X_foo_3_stubs, foo, 2, 3) +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar_stubs, bar, 1, 4) +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar2_stubs, bar2, 0, 4) // tests zero arg member function +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_2_stubs, foo, 1, 2) +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_3_stubs, foo, 2, 3) /////////////////////////////////////////////////////////////////////////////// From 522a29241b3b91937eb5d33049d659c33a810372 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Fri, 6 Sep 2002 23:11:09 +0000 Subject: [PATCH 0709/1042] added call policies to the default stubs. [SVN r15190] --- include/boost/python/class.hpp | 53 ++++++++++++--- include/boost/python/def.hpp | 69 ++++++++++++++------ include/boost/python/detail/defaults_def.hpp | 53 +++++++++------ include/boost/python/init.hpp | 18 ++--- include/boost/python/module.hpp | 4 +- test/defaults.cpp | 4 +- 6 files changed, 141 insertions(+), 60 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 08a2c47d..4c7a1383 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -175,9 +175,37 @@ class class_ : public objects::class_base } template - self& def(char const* name, Arg1T arg1, Arg2T const& arg2, char const* doc = 0) + self& def(char const* name, Arg1T arg1, Arg2T const& arg2) { - dispatch_def(name, arg1, arg2, doc, &arg2); + // The arguments may be: + // arg1: function or signature + // arg2: policy or docstring or stubs + + dispatch_def(&arg2, name, arg1, arg2, (char*)0); + 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 + + 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; } @@ -302,30 +330,37 @@ class class_ : public objects::class_base template void dispatch_def( + void const*, char const* name, Fn fn, CallPolicyOrDoc const& policy_or_doc, - char const* doc, - void const*) + char const* doc) { typedef detail::def_helper helper; this->def_impl( - name, fn, helper::get_policy(policy_or_doc), helper::get_doc(policy_or_doc, doc), &fn); + name, fn, helper::get_policy(policy_or_doc), + helper::get_doc(policy_or_doc, doc), &fn); } - template + template void dispatch_def( + detail::func_stubs_base const*, char const* name, SigT sig, StubsT const& stubs, - char const* doc, - detail::func_stubs_base const*) + CallPolicyOrDoc const& policy_or_doc, + char const* doc = 0) { + 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, *this, detail::get_signature(sig), doc); + detail::define_with_defaults( + name, stubs, helper::get_policy(policy_or_doc), + *this, detail::get_signature(sig), + helper::get_doc(policy_or_doc, doc)); } }; diff --git a/include/boost/python/def.hpp b/include/boost/python/def.hpp index 5052644a..c6b8bb54 100644 --- a/include/boost/python/def.hpp +++ b/include/boost/python/def.hpp @@ -13,7 +13,7 @@ # include # include -namespace boost { namespace python { +namespace boost { namespace python { namespace detail { @@ -22,11 +22,11 @@ namespace detail template void dispatch_def( + void const*, char const* name, Fn fn, CallPolicyOrDoc const& policy_or_doc, - char const* doc, - void const*) + char const* doc) { typedef detail::def_helper helper; @@ -35,20 +35,26 @@ namespace detail helper::get_doc(policy_or_doc, doc)); } - 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. - scope current; - detail::define_with_defaults(name, stubs, current, detail::get_signature(sig), doc); - } + 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) + { + 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)); + } } template @@ -58,11 +64,36 @@ void def(char const* name, Fn fn) } template -void def(char const* name, Arg1T arg1, Arg2T const& arg2, char const* doc = 0) +void def(char const* name, Arg1T arg1, Arg2T const& arg2) { - detail::dispatch_def(name, arg1, arg2, doc, &arg2); + // The arguments may be: + // arg1: function or signature + // arg2: policy or docstring or stubs + + detail::dispatch_def(&arg2, name, arg1, arg2, (char*)0); } +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 + + 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); +} }} // namespace boost::python diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index bf2a4fb9..908fdbd9 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -34,7 +34,7 @@ namespace objects namespace detail { -template +template static void name_space_def( NameSpaceT& name_space, char const* name, @@ -48,7 +48,7 @@ static void name_space_def( name, f, policies, doc); } -template +template static void name_space_def( object& name_space, char const* name, @@ -59,12 +59,12 @@ static void name_space_def( ) { scope within(name_space); - + def(name, f, policies, doc); } // For backward compatibility -template +template static void name_space_def( NameSpaceT& name_space, char const* name, @@ -133,14 +133,19 @@ struct define_stub_function {}; template struct define_with_defaults_helper { - template + template static void - def(char const* name, StubsT stubs, NameSpaceT& name_space, char const* doc) + def( + char const* name, + StubsT stubs, + CallPolicies const& policies, + NameSpaceT& name_space, + char const* doc) { // define the NTH stub function of stubs - define_stub_function::define(name, stubs, name_space, doc); + define_stub_function::define(name, stubs, policies, name_space, doc); // call the next define_with_defaults_helper - define_with_defaults_helper::def(name, stubs, name_space, doc); + define_with_defaults_helper::def(name, stubs, policies, name_space, doc); } }; @@ -148,12 +153,17 @@ struct define_stub_function {}; template <> struct define_with_defaults_helper<0> { - template + template static void - def(char const* name, StubsT stubs, NameSpaceT& name_space, char const* doc) + def( + char const* name, + StubsT stubs, + CallPolicies const& policies, + NameSpaceT& name_space, + char const* doc) { // define the Oth stub function of stubs - define_stub_function<0>::define(name, stubs, name_space, doc); + define_stub_function<0>::define(name, stubs, policies, name_space, doc); // return } }; @@ -162,11 +172,12 @@ struct define_stub_function {}; // // define_with_defaults // -// 1. char const* name: function name that will be visible to python -// 2. StubsT: a function stubs struct (see defaults_gen.hpp) -// 3. NameSpaceT& name_space: a python::class_ or python::module instance -// 4. SigT sig: Function signature typelist (see defaults_gen.hpp) -// 5. char const* name: doc string +// 1. char const* name: function name that will be visible to python +// 2. StubsT: a function stubs struct (see defaults_gen.hpp) +// 3. CallPolicies& policies: Call policies +// 4. NameSpaceT& name_space: a python::class_ or python::module instance +// 5. SigT sig: Function signature typelist (see defaults_gen.hpp) +// 6. char const* name: doc string // // This is the main entry point. This function recursively defines all // stub functions of StubT (see defaults_gen.hpp) in NameSpaceT name_space which @@ -179,11 +190,12 @@ struct define_stub_function {}; // void C::foo(int) mpl::type_list // /////////////////////////////////////////////////////////////////////////////// - template + template inline void define_with_defaults( char const* name, StubsT, + CallPolicies const& policies, NameSpaceT& name_space, SigT sig, char const* doc) @@ -204,7 +216,7 @@ struct define_stub_function {}; typedef typename stubs_type::template gen gen_type; define_with_defaults_helper::def - (name, gen_type(), name_space, doc); + (name, gen_type(), policies, name_space, doc); } } // namespace detail @@ -220,10 +232,11 @@ struct define_stub_function {}; template <> struct define_stub_function { - template + template static void define( char const* name, StubsT, + CallPolicies const& policies, NameSpaceT& name_space, char const* doc ) @@ -231,7 +244,7 @@ struct define_stub_function { detail::name_space_def(name_space, name, &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION()), - default_call_policies(), + policies, doc, &name_space); } }; diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 5ea2fdbc..617ed30a 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -125,7 +125,7 @@ namespace detail { // Case 1: default case, just push T to the back of ListT - template + template struct apply { typedef typename boost::mpl::push_back::sequence sequence; @@ -134,7 +134,7 @@ namespace detail { struct append_to_init_helper2 { - template + template struct apply { // Case 2: optional case, T is an optional, append all @@ -153,14 +153,14 @@ namespace detail { // Case 3: nil case, we found a nil, do nothing - template + template struct apply { typedef ListT sequence; }; }; - template + template struct append_to_init { typedef typename boost::mpl::select_type @@ -192,7 +192,7 @@ namespace detail { template struct check_init_params_helper { - template + template struct apply { // case where size of sequence is not zero @@ -221,7 +221,7 @@ namespace detail { // case where size of sequence is zero - template + template struct apply { enum { is_ok = true }; @@ -252,20 +252,20 @@ namespace detail { // init >::value == 3 // /////////////////////////////////////////////////////////////////////////// - template + template struct count_optionals1 { BOOST_STATIC_CONSTANT(int, value = 0); }; - template + template struct count_optionals2 { BOOST_STATIC_CONSTANT( int, value = boost::mpl::size::value); }; - template + template struct count_optionals : boost::mpl::select_type < diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index cc8cb832..a455ca41 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -89,7 +89,9 @@ 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, *this, detail::get_signature(sig), doc); + detail::define_with_defaults( + name, stubs, default_call_policies(), + *this, detail::get_signature(sig), doc); } }; diff --git a/test/defaults.cpp b/test/defaults.cpp index 06fb2bc2..cacb6ef7 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -126,7 +126,7 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_3_stubs, foo, 2, 3) BOOST_PYTHON_MODULE_INIT(defaults_ext) { - def("foo", foo, foo_stubs()); + def("foo", foo, foo_stubs(), default_call_policies()); def("bar", (object(*)(int, char, std::string, double))0, bar_stubs()); // Show that this works with the old obsolete module version of def(). @@ -147,7 +147,7 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) # endif .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) - .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) + .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs(), default_call_policies()) .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs()) ; From acbb5be6ab4b88bb22776b91afa7d634495b8c41 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Sat, 7 Sep 2002 01:35:42 +0000 Subject: [PATCH 0710/1042] Added call policies to def(init<...>) and added tests to see that the call policies is working in default.cpp [SVN r15191] --- include/boost/python/class.hpp | 17 ++++++++++++-- include/boost/python/init.hpp | 20 ++++++++--------- test/defaults.cpp | 41 +++++++++++++++++++++++++++------- test/defaults.py | 11 ++++++++- 4 files changed, 68 insertions(+), 21 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 4c7a1383..d215f33f 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -168,9 +168,22 @@ class class_ : public objects::class_base } template - self& def(init const& i, char const* doc = 0) + self& def(init const& i) { - define_init(*this, i, doc); + 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)); return *this; } diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 617ed30a..b00bd2d5 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -352,12 +352,12 @@ namespace detail { template struct define_class_init_helper { - template - static void apply(ClassT& cl, ArgsT const& args, char const* doc) + template + static void apply(ClassT& cl, CallPoliciesT const& policies, ArgsT const& args, char const* doc) { - cl.def_init(args, default_call_policies(), doc); + cl.def_init(args, policies, doc); typename boost::mpl::pop_back::sequence next; - define_class_init_helper::apply(cl, next, doc); + define_class_init_helper::apply(cl, policies, next, doc); } }; @@ -374,10 +374,10 @@ namespace detail { template <> struct define_class_init_helper<0> { - template - static void apply(ClassT& cl, ArgsT const& args, char const* doc) + template + static void apply(ClassT& cl, CallPoliciesT const& policies, ArgsT const& args, char const* doc) { - cl.def_init(args, default_call_policies(), doc); + cl.def_init(args, policies, doc); } }; } @@ -403,13 +403,13 @@ namespace detail { // __init__(int) // /////////////////////////////////////////////////////////////////////////////// -template +template void -define_init(ClassT& cl, InitT const& i, char const* doc) +define_init(ClassT& cl, InitT const& i, CallPoliciesT const& policies, char const* doc) { enum { n_defaults_plus_1 = InitT::n_defaults + 1 }; typedef typename InitT::sequence args_t; - detail::define_class_init_helper::apply(cl, args_t(), doc); + detail::define_class_init_helper::apply(cl, policies, args_t(), doc); } }} // namespace boost::python diff --git a/test/defaults.cpp b/test/defaults.cpp index cacb6ef7..8cd3fe7b 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 # include // works around a KCC intermediate code generation bug @@ -69,6 +70,20 @@ BOOST_PYTHON_FUNCTION_OVERLOADS(foo_stubs, foo, 1, 4) // Overloaded member functions with default arguments // /////////////////////////////////////////////////////////////////////////////// +struct Y { + + Y() {} + + object + get_state() const + { + return format % make_tuple(a, b, c, d); + } + + int a; char b; std::string c; double d; +}; + + struct X { X() {} @@ -83,11 +98,15 @@ struct X { return format % make_tuple(a, b, c, d); } - object - bar2(int a = 0, char b = 'D', std::string c = "default", double d = 0.0) const + Y const& + bar2(int a = 0, char b = 'D', std::string c = "default", double d = 0.0) { - // tests zero arg member function - return format % make_tuple(a, b, c, d); + // tests zero arg member function and return_internal_reference policy + y.a = a; + y.b = b; + y.c = c; + y.d = d; + return y; } object @@ -114,11 +133,12 @@ struct X { return state; } + Y y; object state; }; BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar_stubs, bar, 1, 4) -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar2_stubs, bar2, 0, 4) // tests zero arg member function +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_bar_stubs2, bar2, 0, 4) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_2_stubs, foo, 1, 2) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_3_stubs, foo, 2, 3) @@ -126,7 +146,7 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_3_stubs, foo, 2, 3) BOOST_PYTHON_MODULE_INIT(defaults_ext) { - def("foo", foo, foo_stubs(), default_call_policies()); + def("foo", foo, foo_stubs()); def("bar", (object(*)(int, char, std::string, double))0, bar_stubs()); // Show that this works with the old obsolete module version of def(). @@ -135,6 +155,10 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) .def("barfoo", (object(*)(int, char, std::string, double))0, bar_stubs()) ; + class_("Y", no_init) + .def("get_state", &Y::get_state) + ; + class_("X") # if (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) @@ -145,9 +169,10 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) .def_init(args()) .def_init(args()) # endif - .def("get_state", &X::get_state) + .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) - .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs(), default_call_policies()) + .def("bar2", &X::bar2, X_bar_stubs2(), return_internal_reference<>()) + .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs()) ; diff --git a/test/defaults.py b/test/defaults.py index ac890de2..701ba386 100644 --- a/test/defaults.py +++ b/test/defaults.py @@ -56,7 +56,16 @@ >>> x = X(1, 'X', "Phoenix", 3.65) >>> x.get_state() 'int(1); char(X); string(Phoenix); double(3.65); ' - +>>> x.bar2().get_state() +'int(0); char(D); string(default); double(0.0); ' +>>> x.bar2(1).get_state() +'int(1); char(D); string(default); double(0.0); ' +>>> x.bar2(1, 'K').get_state() +'int(1); char(K); string(default); double(0.0); ' +>>> x.bar2(1, 'K', "Kim").get_state() +'int(1); char(K); string(Kim); double(0.0); ' +>>> x.bar2(1, 'K', "Kim", 9.9).get_state() +'int(1); char(K); string(Kim); double(9.9); ' """ def run(args = None): From 526d99f8322b10289754806fee4ee1ff35c5d3a8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 7 Sep 2002 04:44:17 +0000 Subject: [PATCH 0711/1042] Embed C++ objects directly in Python objects [SVN r15192] --- include/boost/python/class.hpp | 20 ++- include/boost/python/converter/smart_ptr.hpp | 70 --------- include/boost/python/instance_holder.hpp | 12 ++ include/boost/python/object.hpp | 1 + include/boost/python/object/class.hpp | 28 ++-- include/boost/python/object/class_detail.hpp | 20 +++ include/boost/python/object/class_wrapper.hpp | 41 +----- include/boost/python/object/instance.hpp | 45 ++++++ include/boost/python/object/iterator.hpp | 1 + include/boost/python/object/make_holder.hpp | 16 +- include/boost/python/object/make_instance.hpp | 72 +++++++++ .../boost/python/object/pickle_support.hpp | 1 - include/boost/python/object/select_holder.hpp | 50 +++++-- include/boost/python/object/value_holder.hpp | 2 +- include/boost/python/object_core.hpp | 6 +- include/boost/python/to_python_indirect.hpp | 38 ++--- src/object/class.cpp | 138 ++++++++++++++++-- src/object/function.cpp | 10 +- test/cltree.cpp | 4 +- test/defaults.cpp | 3 +- test/m1.cpp | 6 - test/select_holder.cpp | 3 +- 22 files changed, 375 insertions(+), 212 deletions(-) delete mode 100644 include/boost/python/converter/smart_ptr.hpp create mode 100644 include/boost/python/object/class_detail.hpp create mode 100644 include/boost/python/object/instance.hpp create mode 100644 include/boost/python/object/make_instance.hpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index d215f33f..918de0ec 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -21,6 +21,7 @@ # include # include # include +# include # include # include # include @@ -56,7 +57,7 @@ namespace detail static inline void register_copy_constructor(mpl::bool_t const&, SelectHolder const& , T* = 0) { typedef typename SelectHolder::type holder; - force_instantiate(objects::class_wrapper()); + force_instantiate(objects::class_wrapper >()); SelectHolder::register_(); } @@ -96,7 +97,7 @@ class class_ : public objects::class_base X3 >::type>::type>::type held_type; - typedef objects::class_id class_id; + typedef objects::select_holder holder_selector; typedef typename detail::select_bases(); // Write the rest of the elements into succeeding positions. - class_id* p = ids + 1; + type_info* p = ids + 1; mpl::for_each::execute(&p); } BOOST_STATIC_CONSTANT( std::size_t, size = mpl::size::value + 1); - class_id ids[size]; + type_info ids[size]; }; friend struct id_vector; @@ -146,6 +146,7 @@ class class_ : public objects::class_base { this->register_(); this->def_init(InitArgs()); + this->set_instance_size(holder_selector::additional_size()); } @@ -155,6 +156,7 @@ class class_ : public objects::class_base { this->register_(); this->def_init(InitArgs(), initdoc); + this->set_instance_size(holder_selector::additional_size()); } // Wrap a member function or a non-member function which can take @@ -237,7 +239,7 @@ class class_ : public objects::class_base return this->def("__init__", python::make_constructor( // Using runtime type selection works around a CWPro7 bug. - objects::select_holder((held_type*)0).get() + holder_selector::execute((held_type*)0).get() ) ); } @@ -252,7 +254,7 @@ class class_ : public objects::class_base python::make_constructor( helper::get_policy(policy_or_doc) // Using runtime type selection works around a CWPro7 bug. - , objects::select_holder((held_type*)0).get() + , holder_selector::execute((held_type*)0).get() ) , helper::get_doc(policy_or_doc, doc) ); @@ -389,7 +391,7 @@ inline void class_::register_() const detail::register_copy_constructor( mpl::bool_t() - , objects::select_holder((held_type*)0) + , holder_selector::execute((held_type*)0) ); } @@ -402,6 +404,7 @@ inline class_::class_() this->register_(); detail::force_instantiate(sizeof(detail::assert_default_constructible(T()))); this->def_init(); + this->set_instance_size(holder_selector::additional_size()); } template @@ -419,6 +422,7 @@ inline class_::class_(char const* name, char const* doc) this->register_(); detail::force_instantiate(sizeof(detail::assert_default_constructible(T()))); this->def_init(); + this->set_instance_size(holder_selector::additional_size()); } template diff --git a/include/boost/python/converter/smart_ptr.hpp b/include/boost/python/converter/smart_ptr.hpp deleted file mode 100644 index bae4c2b8..00000000 --- a/include/boost/python/converter/smart_ptr.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef SMART_PTR_DWA2002123_HPP -# define SMART_PTR_DWA2002123_HPP - -# include -# include -namespace boost { namespace python { namespace converter { - -template -class smart_ptr_wrapper - : wrapper -{ - smart_ptr_wrapper(ref const& type_) - : m_class_object(type_) - { - assert(type_->ob_type == (PyTypeObject*)class_metatype().get()); - } - - PyObject* convert(Pointer x) const; - - private: - ref m_class_object; - - smart_ptr_converters(); -} - - -// -// implementations -// - -template -PyObject* smart_ptr_wrapper::convert(Pointer x) const -{ - if (x.operator->() == 0) - return detail::none(); - - // Don't call the type to do the construction, since that - // would require the registration of an __init__ copy - // constructor. Instead, just construct the object in place. - PyObject* raw_result = (PyObject*)PyObject_New( - instance, (PyTypeObject*)m_class_object.get()); - - if (raw_result == 0) - return 0; - - // Everything's OK; Bypass NULL checks but guard against - // exceptions. - ref result(raw_result, ref::allow_null()); - - // Build a value_holder to contain the object using the copy - // constructor - objects::pointer_holder* - p = new objects::pointer_holder(x); - - // Install it in the instance - p->install(raw_result); - - // Return the new result - return result.release(); -} - - -}}} // namespace boost::python::converter - -#endif // SMART_PTR_DWA2002123_HPP diff --git a/include/boost/python/instance_holder.hpp b/include/boost/python/instance_holder.hpp index ea368c1a..28aa02e8 100755 --- a/include/boost/python/instance_holder.hpp +++ b/include/boost/python/instance_holder.hpp @@ -8,6 +8,8 @@ # include # include +# include +# include namespace boost { namespace python { @@ -25,6 +27,16 @@ struct BOOST_PYTHON_DECL instance_holder : private noncopyable void install(PyObject* inst) throw(); + // These functions should probably be located elsewhere. + + // Allocate storage for an object of the given size at the given + // offset in the Python instance<> object if bytes are available + // there. Otherwise allocate size bytes of heap memory. + static void* allocate(PyObject*, std::size_t offset, std::size_t size); + + // Deallocate storage from the heap if it was not carved out of + // the given Python object by allocate(), above. + static void deallocate(PyObject*, void* storage) throw(); private: instance_holder* m_next; }; diff --git a/include/boost/python/object.hpp b/include/boost/python/object.hpp index b2e0c6b3..dbdb7c0a 100755 --- a/include/boost/python/object.hpp +++ b/include/boost/python/object.hpp @@ -11,6 +11,7 @@ # include # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index cd7c25f4..69bc5b20 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -9,21 +9,14 @@ # include # include # include -# include -# include # include # include # include namespace boost { namespace python { -class module; - namespace objects { -// To identify a class, we don't need cv/reference decorations -typedef type_info class_id; - struct BOOST_PYTHON_DECL class_base : python::api::object { // constructor @@ -33,6 +26,7 @@ struct BOOST_PYTHON_DECL class_base : python::api::object , std::size_t num_types // A list of class_ids. The first is the type , class_id const*const types // this is wrapping. The rest are the types of // any bases. + , char const* doc = 0 // Docstring, if any. ); @@ -41,21 +35,17 @@ struct BOOST_PYTHON_DECL class_base : python::api::object void add_property(char const* name, object const& fget, object const& fset); void setattr(char const* name, object const&); void enable_pickling(bool getstate_manages_dict); + + // Set a special attribute in the class which tells Boost.Python + // to allocate extra bytes for embedded C++ objects in Python + // instances. + void set_instance_size(std::size_t bytes); + + // Set an __init__ function which throws an appropriate exception + // for abstract classes. void def_no_init(); }; -BOOST_PYTHON_DECL type_handle registered_class_object(class_id id); - -// Each extension instance will be one of these -struct instance -{ - PyObject_HEAD - instance_holder* objects; -}; - -BOOST_PYTHON_DECL type_handle class_metatype(); -BOOST_PYTHON_DECL type_handle class_type(); - }}} // namespace boost::python::objects #endif // CLASS_DWA20011214_HPP diff --git a/include/boost/python/object/class_detail.hpp b/include/boost/python/object/class_detail.hpp new file mode 100644 index 00000000..f4d4d51e --- /dev/null +++ b/include/boost/python/object/class_detail.hpp @@ -0,0 +1,20 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef CLASS_DETAIL_DWA200295_HPP +# define CLASS_DETAIL_DWA200295_HPP + +# include +# include + +namespace boost { namespace python { namespace objects { + +BOOST_PYTHON_DECL type_handle registered_class_object(type_info id); +BOOST_PYTHON_DECL type_handle class_metatype(); +BOOST_PYTHON_DECL type_handle class_type(); + +}}} // namespace boost::python::object + +#endif // CLASS_DETAIL_DWA200295_HPP diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index 723126a4..61364d9d 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -6,56 +6,21 @@ #ifndef CLASS_WRAPPER_DWA20011221_HPP # define CLASS_WRAPPER_DWA20011221_HPP -# include # include -# include # include namespace boost { namespace python { namespace objects { -template -struct copy_construct_instance -{ - static Holder* execute(PyObject* instance, Src const& x) - { - return new Holder(instance, cref(x)); - } -}; - // Used to convert objects of type Src to wrapped C++ classes by // building a new instance object and installing a Holder constructed // from the Src object. -template > +template struct class_wrapper - : to_python_converter > + : to_python_converter > { static PyObject* convert(Src const& x) { - // Get the class object associated with the wrapped type - typedef typename Holder::value_type value_type; - PyTypeObject* class_object = converter::registered::converters.class_object; - - // Don't call the type directly to do the construction, since - // that would require the registration of an appropriate - // __init__ function. - PyObject* raw_result = class_object->tp_alloc(class_object, 0); - - if (raw_result == 0) - return 0; - - // Everything's OK; Bypass NULL checks but guard against - // exceptions. - handle<> result(python::allow_null(raw_result)); - - // Build a value_holder to contain the object using the copy - // constructor - Holder* p = MakeHolder::execute(raw_result, x); - - // Install it in the instance - p->install(raw_result); - - // Return the new result - return result.release(); + return MakeInstance::execute(cref(x)); } }; diff --git a/include/boost/python/object/instance.hpp b/include/boost/python/object/instance.hpp new file mode 100644 index 00000000..c64ce33d --- /dev/null +++ b/include/boost/python/object/instance.hpp @@ -0,0 +1,45 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef INSTANCE_DWA200295_HPP +# define INSTANCE_DWA200295_HPP + +# include +# include +# include + +namespace boost { namespace python { namespace objects { + +// Each extension instance will be one of these +template +struct instance +{ + PyObject_VAR_HEAD + PyObject* dict; + PyObject* weakrefs; + instance_holder* objects; + + BOOST_STATIC_CONSTANT(std::size_t, alignment = alignment_of::value); + typedef typename type_with_alignment::type align_t; + + union + { + align_t align; + char bytes[sizeof(Data)]; + } storage; +}; + +template +struct additional_instance_size +{ + typedef instance instance_data; + typedef instance instance_char; + BOOST_STATIC_CONSTANT( + std::size_t, value = sizeof(instance_data) - offsetof(instance_char,storage)); +}; + +}}} // namespace boost::python::object + +#endif // INSTANCE_DWA200295_HPP diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index b41ba621..74af64c9 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -8,6 +8,7 @@ # include # include +# include # include # include # include diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 58a185b0..1eab34e8 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -10,7 +10,6 @@ # define MAKE_HOLDER_DWA20011215_HPP # include -# include # include # include @@ -20,6 +19,8 @@ # include # include +# include + namespace boost { namespace python { namespace objects { template struct make_holder; @@ -57,8 +58,17 @@ struct make_holder PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, t, a)) { - (new Holder( - p BOOST_PP_REPEAT(N, BOOST_PYTHON_DO_FORWARD_ARG, nil)))->install(p); + typedef instance instance_t; + + void* memory = Holder::allocate(p, offsetof(instance_t, storage), sizeof(Holder)); + try { + (new (memory) Holder( + p BOOST_PP_REPEAT(N, BOOST_PYTHON_DO_FORWARD_ARG, nil)))->install(p); + } + catch(...) { + Holder::deallocate(p, memory); + throw; + } } }; }; diff --git a/include/boost/python/object/make_instance.hpp b/include/boost/python/object/make_instance.hpp new file mode 100644 index 00000000..d5e153b9 --- /dev/null +++ b/include/boost/python/object/make_instance.hpp @@ -0,0 +1,72 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MAKE_INSTANCE_DWA200296_HPP +# define MAKE_INSTANCE_DWA200296_HPP + +# include +# include + +namespace boost { namespace python { namespace objects { + +template +struct make_instance +{ + typedef objects::instance instance_t; + + template + static PyObject* execute(Arg& x) + { + BOOST_STATIC_ASSERT(is_class::value); + PyTypeObject* type = converter::registered::converters.class_object; + + PyObject* raw_result = type->tp_alloc( + type, objects::additional_instance_size::value); + + if (raw_result != 0) + { + instance_t* result = (instance_t*)raw_result; + try + { + // construct the new C++ object and install the pointer + // in the Python object. + construct(result, x)->install(raw_result); + } + catch(...) + { + Py_DECREF(raw_result); // reclaim the Python object + throw; + } + + // Note the position of the internally-stored Holder, + // for the sake of destruction + result->ob_size = offsetof(instance_t, storage); + } + return raw_result; + } + + private: + // Kind of a hack to support code re-use. The first form is used + // to construct holders around pointers or smart pointers. The + // second form is used to construct holders around by-value + // returns. We have to pass a pointer to the owning Python object + // to the second form in order to make it forward the 2nd argument + // on to the constructor of its embedded T object. + template + static Holder* construct(instance_t* result, Arg& x) + { + return new ((void*)&result->storage) Holder(x); + } + + static Holder* construct(instance_t* result, reference_wrapper x) + { + return new ((void*)&result->storage) Holder((PyObject*)result, x); + } +}; + + +}}} // namespace boost::python::object + +#endif // MAKE_INSTANCE_DWA200296_HPP diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp index 2e94faea..bae05138 100644 --- a/include/boost/python/object/pickle_support.hpp +++ b/include/boost/python/object/pickle_support.hpp @@ -6,7 +6,6 @@ #ifndef BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP #define BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP -#include #include #include diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index a2e50c69..6902f68d 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -12,10 +12,14 @@ # include # include # include +# include +# include # include # include # include +# include # include +# include namespace boost { namespace python { namespace objects { @@ -96,7 +100,7 @@ namespace detail objects::class_wrapper< Ptr , type - , construct_from_pointer>()); + , make_instance >()); python::detail::force_instantiate( instance_finder::registration); @@ -104,24 +108,40 @@ namespace detail }; } -template -inline detail::select_value_holder select_holder(python::detail::not_specified*, T* = 0, NotSpecified* = 0) -{ - return detail::select_value_holder(); -} - template -inline detail::select_value_holder select_holder(T*, Held* = 0) +struct select_holder { - return detail::select_value_holder(); -} + static inline std::size_t additional_size() + { + return additional_size_helper(execute((Held*)0)); + } + + static inline detail::select_value_holder + execute(python::detail::not_specified*) + { + return detail::select_value_holder(); + } + static inline detail::select_value_holder + execute(T*) + { + return detail::select_value_holder(); + } -template -detail::select_pointer_holder select_holder(void*, Ptr* = 0, T* = 0) -{ - return detail::select_pointer_holder(); -} + static inline detail::select_pointer_holder + execute(void*) + { + return detail::select_pointer_holder(); + } + + private: + template + static inline std::size_t additional_size_helper(Selector const&) + { + typedef typename Selector::type holder; + return additional_instance_size::value; + } +}; }}} // namespace boost::python::objects diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 05a5c782..50477e3d 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -10,7 +10,7 @@ # define VALUE_HOLDER_DWA20011215_HPP # include -# include +# include # include # include # include diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 29127fc9..98383c2f 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -9,7 +9,6 @@ # include # include -# include # include # include # include @@ -22,6 +21,11 @@ namespace boost { namespace python { +namespace converter +{ + template struct arg_to_python; +} + // Put this in an inner namespace so that the generalized operators won't take over namespace api { diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index 60b861b1..23ff8594 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -8,10 +8,12 @@ # include # include +# include # include # include # include # include +# include # include namespace boost { namespace python { @@ -32,7 +34,7 @@ namespace detail { struct make_owning_holder { - typedef instance_holder* result_type; + typedef PyObject* result_type; template static result_type execute(T* p) { @@ -41,20 +43,22 @@ namespace detail typedef boost::shared_ptr smart_pointer; # else typedef std::auto_ptr smart_pointer; -# endif - - return new objects::pointer_holder( - smart_pointer(p)); +# endif + typedef objects::pointer_holder holder_t; + + smart_pointer ptr(p); + return objects::make_instance::execute(ptr); } }; struct make_reference_holder { - typedef instance_holder* result_type; + typedef PyObject* result_type; template static result_type execute(T* p) { - return new objects::pointer_holder(p); + typedef objects::pointer_holder holder_t; + return objects::make_instance::execute(p); } }; @@ -99,26 +103,8 @@ inline PyObject* to_python_indirect::operator()(T x) const PyObject* const null_result = detail::null_pointer_to_none(x, 1L); if (null_result != 0) return null_result; - - PyObject* raw_result = type()->tp_alloc(type(), 0); - if (raw_result == 0) - return 0; - - // Everything's OK; Bypass NULL checks but guard against - // exceptions. - handle<> result(python::allow_null(raw_result)); - - // Build a value_holder to contain the object using the copy - // constructor - instance_holder* p = - detail::unwind_type(x); - - // Install it in the instance - p->install(raw_result); - - // Return the new result - return result.release(); + return detail::unwind_type(x); } template diff --git a/src/object/class.cpp b/src/object/class.cpp index 754ebe5a..8af51fc8 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -3,9 +3,11 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. +#include +#include +#include #include #include -#include #include #include #include @@ -17,6 +19,9 @@ #include #include #include +#include +#include +#include namespace boost { namespace python { @@ -98,8 +103,8 @@ static PyTypeObject class_metatype_object = { void instance_holder::install(PyObject* self) throw() { assert(self->ob_type->ob_type == &class_metatype_object); - m_next = ((objects::instance*)self)->objects; - ((objects::instance*)self)->objects = this; + m_next = ((objects::instance<>*)self)->objects; + ((objects::instance<>*)self)->objects = this; } @@ -121,25 +126,89 @@ namespace objects { static void instance_dealloc(PyObject* inst) { - instance* kill_me = (instance*)inst; + instance<>* kill_me = (instance<>*)inst; for (instance_holder* p = kill_me->objects, *next; p != 0; p = next) { next = p->next(); - delete p; + p->~instance_holder(); + instance_holder::deallocate(inst, dynamic_cast(p)); } + // Python 2.2.1 won't add weak references automatically when + // tp_itemsize > 0, so we need to manage that + // ourselves. Accordingly, we also have to clean up the + // weakrefs ourselves. + if (kill_me->weakrefs != NULL) + PyObject_ClearWeakRefs(inst); + + Py_XDECREF(kill_me->dict); + inst->ob_type->tp_free(inst); } + + static PyObject * + instance_new(PyTypeObject* type_, PyObject* args, PyObject *kw) + { + // Attempt to find the __instance_size__ attribute. If not present, no problem. + PyObject* d = type_->tp_dict; + PyObject* instance_size_obj = PyObject_GetAttrString(d, "__instance_size__"); + + long instance_size = 0; + if (instance_size != 0) + instance_size = PyInt_AsLong(instance_size_obj); + + if (instance_size < 0) + instance_size = 0; + PyErr_Clear(); // Clear any errors that may have occurred. + + instance<>* result = (instance<>*)type_->tp_alloc(type_, instance_size); + if (result) + { + // Guido says we can use ob_size for any purpose we + // like, so we'll store the total size of the object + // there. A negative number indicates that the extra + // instance memory is not yet allocated to any holders. + result->ob_size = -(offsetof(instance<>,storage) + instance_size); + } + return (PyObject*)result; + } + + static PyObject* instance_get_dict(PyObject* op, void*) + { + instance<>* inst = downcast >(op); + if (inst->dict == 0) + inst->dict = PyDict_New(); + return python::xincref(inst->dict); + } + + static int instance_set_dict(PyObject* op, PyObject* dict, void*) + { + instance<>* inst = downcast >(op); + python::xdecref(inst->dict); + inst->dict = python::incref(dict); + return 0; + } } +static PyGetSetDef instance_getsets[] = { + {"__dict__", instance_get_dict, instance_set_dict, NULL}, + {0} +}; + + +static PyMemberDef instance_members[] = { + {"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0}, + {0} +}; + static PyTypeObject class_type_object = { PyObject_HEAD_INIT(0) //&class_metatype_object) 0, "Boost.Python.instance", - sizeof(instance), - 0, + offsetof(instance<>,storage), /* tp_basicsize */ + 1, /* tp_itemsize */ instance_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ @@ -161,20 +230,20 @@ namespace objects 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ + offsetof(instance<>,weakrefs), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, //&PyBaseObject_Type, /* tp_base */ + instance_members, /* tp_members */ + instance_getsets, /* tp_getset */ + 0, //&PyBaseObject_Type, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ + offsetof(instance<>,dict), /* tp_dictoffset */ 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew + instance_new /* tp_new */ }; BOOST_PYTHON_DECL type_handle class_type() @@ -195,7 +264,7 @@ namespace objects if (inst->ob_type->ob_type != &class_metatype_object) return 0; - instance* self = reinterpret_cast(inst); + instance<>* self = reinterpret_cast*>(inst); for (instance_holder* match = self->objects; match != 0; match = match->next()) { @@ -302,6 +371,11 @@ namespace objects this->attr("__doc__") = doc; } + void class_base::set_instance_size(std::size_t instance_size) + { + this->attr("__instance_size__") = instance_size; + } + extern "C" { // This declaration needed due to broken Python 2.2 headers @@ -369,4 +443,40 @@ namespace objects } } // namespace objects + +void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size) +{ + assert(self_->ob_type->ob_type == &class_metatype_object); + objects::instance<>* self = (objects::instance<>*)self_; + + int total_size_needed = holder_offset + holder_size; + + if (-self->ob_size >= total_size_needed) + { + // holder_offset should at least point into the variable-sized part + assert(holder_offset >= offsetof(objects::instance<>,storage)); + + // Record the fact that the storage is occupied, noting where it starts + self->ob_size = holder_offset; + return (char*)self + holder_offset; + } + else + { + void* const result = PyMem_Malloc(holder_size); + if (result == 0) + throw std::bad_alloc(); + return result; + } +} + +void instance_holder::deallocate(PyObject* self_, void* storage) throw() +{ + assert(self_->ob_type->ob_type == &class_metatype_object); + objects::instance<>* self = (objects::instance<>*)self_; + if (storage != (char*)self + self->ob_size) + { + PyMem_Free(storage); + } +} + }} // namespace boost::python diff --git a/src/object/function.cpp b/src/object/function.cpp index 8aa39dbf..6d013b3a 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -301,11 +301,11 @@ extern "C" } } - static PyGetSetDef function_getsetlist[] = { - {"__name__", (getter)function_get_name, 0 }, - {"__doc__", (getter)function_get_doc, (setter)function_set_doc}, - {NULL} /* Sentinel */ - }; +static PyGetSetDef function_getsetlist[] = { + {"__name__", (getter)function_get_name, 0 }, + {"__doc__", (getter)function_get_doc, (setter)function_set_doc}, + {NULL} /* Sentinel */ +}; PyTypeObject function_type = { PyObject_HEAD_INIT(0) diff --git a/test/cltree.cpp b/test/cltree.cpp index 03e1be47..f7ea9eeb 100755 --- a/test/cltree.cpp +++ b/test/cltree.cpp @@ -52,7 +52,7 @@ public: BOOST_PYTHON_MODULE_INIT(cltree) { boost::python::class_("basic") - .def("__repr__",&basic::repr) + .def("__repr__",&basic::repr) ; boost::python::class_, boost::noncopyable>("constant") @@ -60,7 +60,7 @@ BOOST_PYTHON_MODULE_INIT(cltree) boost::python::class_("symbol") - ; + ; boost::python::class_, variable_wrapper>("variable") ; diff --git a/test/defaults.cpp b/test/defaults.cpp index 8cd3fe7b..b6d2a72f 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -17,7 +17,6 @@ #endif using namespace boost::python; -using namespace std; char const* const format = "int(%s); char(%s); string(%s); double(%s); "; @@ -169,7 +168,7 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) .def_init(args()) .def_init(args()) # endif - .def("get_state", &X::get_state) + .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) .def("bar2", &X::bar2, X_bar_stubs2(), return_internal_reference<>()) .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) diff --git a/test/m1.cpp b/test/m1.cpp index a6cb7439..f09e4a93 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -216,12 +216,6 @@ BOOST_PYTHON_MODULE_INIT(m1) lvalue_from_pytype,&SimpleType>(); - // Insert the metaclass for all extension classes - scope().attr("xclass") = boost::python::objects::class_metatype(); - - // Insert the base class for all extension classes - scope().attr("xinst") = boost::python::objects::class_type(); - def("new_noddy", new_noddy); def("new_simple", new_simple); diff --git a/test/select_holder.cpp b/test/select_holder.cpp index f6b22baa..febbeb2d 100644 --- a/test/select_holder.cpp +++ b/test/select_holder.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #define BOOST_INCLUDE_MAIN @@ -39,7 +40,7 @@ void assert_same(U* = 0, T* = 0) template void assert_holder(T* = 0, Held* = 0, Holder* = 0) { - assert_same(boost::python::objects::select_holder((Held*)0).get()); + assert_same(boost::python::objects::select_holder::execute((Held*)0).get()); } int test_main(int, char * []) From 26a0df8253c07b4b6b17f5e38171eebfb25ffcf2 Mon Sep 17 00:00:00 2001 From: Paul Mensonides Date: Sun, 8 Sep 2002 22:03:22 +0000 Subject: [PATCH 0712/1042] pp-lib update [SVN r15214] --- include/boost/python/call.hpp | 2 +- include/boost/python/call_method.hpp | 2 +- include/boost/python/detail/make_tuple.hpp | 2 +- include/boost/python/detail/preprocessor.hpp | 8 ++++---- include/boost/python/detail/returning.hpp | 4 ++-- include/boost/python/init.hpp | 2 +- include/boost/python/object/make_holder.hpp | 4 ++-- include/boost/python/object/pointer_holder.hpp | 2 +- include/boost/python/object/value_holder.hpp | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp index 45ab7712..71da14cf 100644 --- a/include/boost/python/call.hpp +++ b/include/boost/python/call.hpp @@ -22,7 +22,7 @@ namespace boost { namespace python { -# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(n, _) \ +# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(z, n, _) \ , converter::arg_to_python(a##n).get() # define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp index 26b295d9..8eec759d 100644 --- a/include/boost/python/call_method.hpp +++ b/include/boost/python/call_method.hpp @@ -21,7 +21,7 @@ namespace boost { namespace python { -# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(n, _) \ +# define BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET(z, n, _) \ , converter::arg_to_python(a##n).get() # define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) diff --git a/include/boost/python/detail/make_tuple.hpp b/include/boost/python/detail/make_tuple.hpp index bbb67e07..41fcaa37 100644 --- a/include/boost/python/detail/make_tuple.hpp +++ b/include/boost/python/detail/make_tuple.hpp @@ -10,7 +10,7 @@ #define N BOOST_PP_ITERATION() -#define BOOST_PYTHON_MAKE_TUPLE_ARG(N, ignored) \ +#define BOOST_PYTHON_MAKE_TUPLE_ARG(z, N, ignored) \ PyTuple_SET_ITEM( \ result.ptr() \ , N \ diff --git a/include/boost/python/detail/preprocessor.hpp b/include/boost/python/detail/preprocessor.hpp index d55d44e6..89d1d26d 100644 --- a/include/boost/python/detail/preprocessor.hpp +++ b/include/boost/python/detail/preprocessor.hpp @@ -45,16 +45,16 @@ // enumerators # define BOOST_PYTHON_UNARY_ENUM(c, text) BOOST_PP_REPEAT(c, BOOST_PYTHON_UNARY_ENUM_I, text) -# define BOOST_PYTHON_UNARY_ENUM_I(n, text) BOOST_PP_COMMA_IF(n) text ## n +# define BOOST_PYTHON_UNARY_ENUM_I(z, n, text) BOOST_PP_COMMA_IF(n) text ## n # define BOOST_PYTHON_BINARY_ENUM(c, a, b) BOOST_PP_REPEAT(c, BOOST_PYTHON_BINARY_ENUM_I, (a, b)) -# define BOOST_PYTHON_BINARY_ENUM_I(n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, _), n) +# define BOOST_PYTHON_BINARY_ENUM_I(z, n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, _), n) # define BOOST_PYTHON_ENUM_WITH_DEFAULT(c, text, def) BOOST_PP_REPEAT(c, BOOST_PYTHON_ENUM_WITH_DEFAULT_I, (text, def)) -# define BOOST_PYTHON_ENUM_WITH_DEFAULT_I(n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) = BOOST_PP_TUPLE_ELEM(2, 1, _) +# define BOOST_PYTHON_ENUM_WITH_DEFAULT_I(z, n, _) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, _), n) = BOOST_PP_TUPLE_ELEM(2, 1, _) // fixed text (no commas) -# define BOOST_PYTHON_FIXED(n, text) text +# define BOOST_PYTHON_FIXED(z, n, text) text // flags # define BOOST_PYTHON_FUNCTION_POINTER 0x0001 diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 84609493..e0732e6b 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -78,10 +78,10 @@ struct returning # define N BOOST_PP_ITERATION() -# define BOOST_PYTHON_CALL_ARGS(n, _) \ +# define BOOST_PYTHON_CALL_ARGS(z, n, _) \ BOOST_PP_COMMA_IF(n) c##n(PyTuple_GET_ITEM(args_, n)) -# define BOOST_PYTHON_CHECK_CONVERSION(n, _) \ +# define BOOST_PYTHON_CHECK_CONVERSION(z, n, _) \ arg_from_python c##n(PyTuple_GET_ITEM(args_, n)); \ if (!c##n.convertible()) \ return 0; diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index b00bd2d5..c931d701 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -298,7 +298,7 @@ namespace detail { // last in the list. // /////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_APPEND_TO_INIT(INDEX, D) \ +#define BOOST_PYTHON_APPEND_TO_INIT(z, INDEX, D) \ typedef typename detail::append_to_init \ < \ BOOST_PP_CAT(l, INDEX), \ diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 1eab34e8..caa8e09f 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -25,11 +25,11 @@ namespace boost { namespace python { namespace objects { template struct make_holder; -# define BOOST_PYTHON_FORWARD_ARG(index, _) \ +# define BOOST_PYTHON_FORWARD_ARG(z, index, _) \ typedef typename mpl::at::type t##index; \ typedef typename forward::type f##index; -# define BOOST_PYTHON_DO_FORWARD_ARG(index, _) , f##index(a##index) +# define BOOST_PYTHON_DO_FORWARD_ARG(z, index, _) , f##index(a##index) // specializations... # define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index d680df66..fa0d5384 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -30,7 +30,7 @@ namespace boost { namespace python { namespace objects { -# define BOOST_PYTHON_UNFORWARD_LOCAL(n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) +# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) template struct pointer_holder : instance_holder diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 50477e3d..8552ba47 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -24,7 +24,7 @@ namespace boost { namespace python { namespace objects { -# define BOOST_PYTHON_UNFORWARD_LOCAL(n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) +# define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) template struct value_holder : instance_holder From a26bb0390d9e67e5ddf404fe7f95ee9df45aea0c Mon Sep 17 00:00:00 2001 From: Paul Mensonides Date: Sun, 8 Sep 2002 23:20:16 +0000 Subject: [PATCH 0713/1042] BOOST_PP_LINE inclusion [SVN r15218] --- include/boost/python/args.hpp | 1 + include/boost/python/call.hpp | 1 + include/boost/python/call_method.hpp | 1 + include/boost/python/detail/arg_tuple_size.hpp | 1 + include/boost/python/detail/caller.hpp | 1 + include/boost/python/detail/defaults_def.hpp | 1 + include/boost/python/detail/member_function_cast.hpp | 1 + include/boost/python/detail/result.hpp | 1 + include/boost/python/detail/returning.hpp | 1 + include/boost/python/detail/target.hpp | 1 + include/boost/python/detail/type_list_utils.hpp | 1 + include/boost/python/object/make_holder.hpp | 1 + include/boost/python/object/pointer_holder.hpp | 1 + include/boost/python/object/value_holder.hpp | 1 + include/boost/python/object_core.hpp | 1 + include/boost/python/signature.hpp | 1 + 16 files changed, 16 insertions(+) diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index 841d70d2..dc00c96c 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -15,6 +15,7 @@ # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp index 71da14cf..6ce027ef 100644 --- a/include/boost/python/call.hpp +++ b/include/boost/python/call.hpp @@ -19,6 +19,7 @@ # include # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp index 8eec759d..7c8f0e90 100644 --- a/include/boost/python/call_method.hpp +++ b/include/boost/python/call_method.hpp @@ -18,6 +18,7 @@ # include # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index bd1933fa..183e957f 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -20,6 +20,7 @@ # include # include +# include namespace boost { namespace python { namespace detail { diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index 43366464..322e1342 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -25,6 +25,7 @@ # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index 908fdbd9..7efbcb70 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -21,6 +21,7 @@ #include #include #include +#include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp index c7ac4fa8..491e6711 100644 --- a/include/boost/python/detail/member_function_cast.hpp +++ b/include/boost/python/detail/member_function_cast.hpp @@ -16,6 +16,7 @@ # include # include +# include namespace boost { namespace python { namespace detail { diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp index aaad4b86..84f6a554 100755 --- a/include/boost/python/detail/result.hpp +++ b/include/boost/python/detail/result.hpp @@ -18,6 +18,7 @@ # include # include +# include namespace boost { namespace python { namespace detail { diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index e0732e6b..5f45ffab 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -24,6 +24,7 @@ # include # include # include +# include # include diff --git a/include/boost/python/detail/target.hpp b/include/boost/python/detail/target.hpp index ffda614b..bbaec740 100644 --- a/include/boost/python/detail/target.hpp +++ b/include/boost/python/detail/target.hpp @@ -16,6 +16,7 @@ # include # include # include +# include namespace boost { namespace python { namespace detail { diff --git a/include/boost/python/detail/type_list_utils.hpp b/include/boost/python/detail/type_list_utils.hpp index 026fd92f..d03203b9 100644 --- a/include/boost/python/detail/type_list_utils.hpp +++ b/include/boost/python/detail/type_list_utils.hpp @@ -22,6 +22,7 @@ # include # include # include +# include # include diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index caa8e09f..933159da 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -18,6 +18,7 @@ # include # include # include +# include # include diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index fa0d5384..9ead5d94 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -20,6 +20,7 @@ # include # include # include +# include # include # include diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 8552ba47..ea751edc 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -21,6 +21,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 98383c2f..5d95946c 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -18,6 +18,7 @@ # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index cef56f92..46d0dabb 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -19,6 +19,7 @@ #include #include #include +#include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { namespace detail { From 4c8bcd918bf0c1ec680fd6eed5f9a695f6de4441 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 9 Sep 2002 01:59:45 +0000 Subject: [PATCH 0714/1042] cope with recent PP lib changes [SVN r15221] --- include/boost/python/detail/defaults_gen.hpp | 108 +++++++++---------- include/boost/python/detail/returning.hpp | 12 +-- include/boost/python/signature.hpp | 2 +- 3 files changed, 57 insertions(+), 65 deletions(-) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 79144360..50b5ef73 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -35,27 +35,19 @@ struct func_stubs_base {}; }}} // namespace boost::python::detail -/////////////////////////////////////////////////////////////////////////////// -// Temporary BOOST_PP fix before the CVS stabalizes /*$$$ FIX ME $$$*/ - -#ifndef BOOST_PP_FIX_REPEAT_2ND -#define BOOST_PP_FIX_REPEAT_2ND(c, m, d) /* ... */ \ - BOOST_PP_CAT(BOOST_PP_R2_, c)(m, d) \ - /**/ -#endif /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_TYPEDEF_GEN(INDEX, DATA) \ +#define BPL_IMPL_TYPEDEF_GEN(z, INDEX, DATA) \ typedef typename boost::python::detail::type_at \ < \ BOOST_PP_ADD(INDEX, DATA), \ SigT \ >::type BOOST_PP_CAT(T, INDEX); \ -#define BPL_IMPL_ARGS_GEN(INDEX, DATA) \ +#define BPL_IMPL_ARGS_GEN(z, INDEX, DATA) \ BOOST_PP_CAT(T, INDEX) BOOST_PP_CAT(arg, INDEX) \ -#define BPL_IMPL_FUNC_WRAPPER_GEN(INDEX, DATA) \ +#define BPL_IMPL_FUNC_WRAPPER_GEN(z, INDEX, DATA) \ static RT BOOST_PP_CAT(func_, INDEX) \ ( \ BOOST_PP_ENUM \ @@ -88,14 +80,14 @@ struct func_stubs_base {}; \ typedef typename boost::python::detail::type_at<0, SigT>::type RT; \ \ - BOOST_PP_FIX_REPEAT_2ND \ + BOOST_PP_REPEAT_2ND \ ( \ N_ARGS, \ BPL_IMPL_TYPEDEF_GEN, \ 1 \ ) \ \ - BOOST_PP_FIX_REPEAT_2ND \ + BOOST_PP_REPEAT_2ND \ ( \ BOOST_PP_INC(N_DFLTS), \ BPL_IMPL_FUNC_WRAPPER_GEN, \ @@ -105,7 +97,7 @@ struct func_stubs_base {}; }; \ /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_MEM_FUNC_WRAPPER_GEN(INDEX, DATA) \ +#define BPL_IMPL_MEM_FUNC_WRAPPER_GEN(z, INDEX, DATA) \ static RT BOOST_PP_CAT(func_, INDEX) \ ( \ ClassT& obj BOOST_PP_COMMA_IF( \ @@ -129,34 +121,34 @@ struct func_stubs_base {}; ); \ } \ -#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::python::detail::type_at<0, SigT>::type RT; \ - typedef typename boost::python::detail::type_at<1, SigT>::type ClassT;\ - \ - BOOST_PP_FIX_REPEAT_2ND \ - ( \ - N_ARGS, \ - BPL_IMPL_TYPEDEF_GEN, \ - 2 \ - ) \ - \ - BOOST_PP_FIX_REPEAT_2ND \ - ( \ - BOOST_PP_INC(N_DFLTS), \ - BPL_IMPL_MEM_FUNC_WRAPPER_GEN, \ - (FNAME, BOOST_PP_SUB(N_ARGS, N_DFLTS), RETURN) \ - ) \ - }; \ - }; \ - \ +#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::python::detail::type_at<0, SigT>::type RT; \ + typedef typename boost::python::detail::type_at<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(N_ARGS, N_DFLTS), RETURN) \ + ) \ + }; \ + }; + /////////////////////////////////////////////////////////////////////////////// #if defined(BOOST_MSVC) @@ -284,23 +276,23 @@ 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(MAX_ARGS, MIN_ARGS) \ - ) \ +#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(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(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(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/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 5f45ffab..495a8564 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -74,7 +74,7 @@ struct returning # endif // RETURNING_DWA20011201_HPP // --------------- function pointers --------------- // -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_FUNCTION_POINTER +#elif BOOST_PP_ITERATION_DEPTH() == 1 && (BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_FUNCTION_POINTER) # line BOOST_PP_LINE(__LINE__, returning.hpp(function pointers)) # define N BOOST_PP_ITERATION() @@ -131,7 +131,7 @@ struct returning # undef BOOST_PYTHON_CHECK_CONVERSION // --------------- pointers to members --------------- // -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_POINTER_TO_MEMBER +#elif BOOST_PP_ITERATION_DEPTH() == 1 && (BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_POINTER_TO_MEMBER) // Outer iteration over cv-qualifications # define BOOST_PP_ITERATION_PARAMS_2 \ @@ -145,12 +145,12 @@ struct returning # define N BOOST_PP_ITERATION() # define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) -# define BOOST_PYTHON_CALL_ARGS(n, _) \ +# define BOOST_PYTHON_CALL_ARGS(z, n, _) \ BOOST_PP_COMMA_IF(n) c##n(PyTuple_GET_ITEM(args_, BOOST_PP_INC(n))) -# define BOOST_PYTHON_CHECK_CONVERSION(n, _) \ - arg_from_python c##n(PyTuple_GET_ITEM(args_, BOOST_PP_INC(n))); \ - if (!c##n.convertible()) \ +# define BOOST_PYTHON_CHECK_CONVERSION(z, n, _) \ + arg_from_python c##n(PyTuple_GET_ITEM(args_, BOOST_PP_INC(n))); \ + if (!c##n.convertible()) \ return 0; # if (BOOST_PP_RELATIVE_FLAGS(1) & BOOST_PYTHON_RETURNING_NON_VOID) diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index 46d0dabb..e960f122 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -53,7 +53,7 @@ namespace boost { namespace python { namespace detail { // and arguments of the input signature and stuffs them in an mpl::type_list. // /////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_TEMPLATE_GEN(INDEX, DATA) class BOOST_PP_CAT(T, INDEX) +#define BOOST_PYTHON_TEMPLATE_GEN(z, index, data) class BOOST_PP_CAT(T, index) /////////////////////////////////////////////////////////////////////////////// #define BOOST_PP_ITERATION_PARAMS_1 \ From dcf7e7cf0c0caac38ebe4da5ca7f13622a95ebe9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 9 Sep 2002 02:00:53 +0000 Subject: [PATCH 0715/1042] Added support for enums [SVN r15222] --- Jamfile | 1 + include/boost/python/enum.hpp | 75 +++++++++++++++++++++++++++++++++++ include/boost/python/str.hpp | 2 + src/object/class.cpp | 66 +++++++++++++++--------------- src/str.cpp | 4 ++ test/Jamfile | 1 + 6 files changed, 117 insertions(+), 32 deletions(-) create mode 100644 include/boost/python/enum.hpp diff --git a/Jamfile b/Jamfile index d4f30be5..4ff03b82 100644 --- a/Jamfile +++ b/Jamfile @@ -23,6 +23,7 @@ dll bpl src/converter/from_python.cpp src/converter/registry.cpp src/converter/type_id.cpp + src/object/enum.cpp src/object/class.cpp src/object/function.cpp src/object/inheritance.cpp diff --git a/include/boost/python/enum.hpp b/include/boost/python/enum.hpp new file mode 100644 index 00000000..b1ad0d9d --- /dev/null +++ b/include/boost/python/enum.hpp @@ -0,0 +1,75 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ENUM_DWA200298_HPP +# define ENUM_DWA200298_HPP + +# include +# include + +namespace boost { namespace python { + +template +struct enum_ : public objects::enum_base +{ + enum_(char const* name); + inline enum_& value(char const* name, T); + + private: + static PyObject* to_python(void const* x); + static void* convertible(PyObject* obj); + static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data); +}; + +template +inline enum_::enum_(char const* name) + : enum_base( + name + , &enum_::to_python + , &enum_::convertible + , &enum_::construct + , type_id()) +{ +} + +// This is the conversion function that gets registered for converting +template +PyObject* enum_::to_python(void const* x) +{ + return enum_base::to_python( + converter::registered::converters.class_object + , static_cast(*(T const*)x)); +} + +template +void* enum_::convertible(PyObject* obj) +{ + return PyObject_IsInstance( + obj + , upcast( + converter::registered::converters.class_object)) + + ? obj : 0; +} + +template +void enum_::construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data) +{ + T x = static_cast(PyInt_AS_LONG(obj)); + void* const storage = ((converter::rvalue_from_python_storage*)data)->storage.bytes; + new (storage) T(x); + data->convertible = storage; +} + +template +inline enum_& enum_::value(char const* name, T x) +{ + objects::enum_base::add_value(name, static_cast(x)); + return *this; +} + +}} // namespace boost::python + +#endif // ENUM_DWA200298_HPP diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index ad2689e9..fb8bfe58 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -18,6 +18,8 @@ namespace boost { namespace python { class str : public object { public: + BOOST_PYTHON_DECL str(); // new str + BOOST_PYTHON_DECL str(const char* s); // new str explicit BOOST_PYTHON_DECL str(object_cref other); diff --git a/src/object/class.cpp b/src/object/class.cpp index 8af51fc8..3cd62a37 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -192,16 +193,16 @@ namespace objects } -static PyGetSetDef instance_getsets[] = { - {"__dict__", instance_get_dict, instance_set_dict, NULL}, - {0} -}; + static PyGetSetDef instance_getsets[] = { + {"__dict__", instance_get_dict, instance_set_dict, NULL}, + {0} + }; -static PyMemberDef instance_members[] = { - {"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0}, - {0} -}; + static PyMemberDef instance_members[] = { + {"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0}, + {0} + }; static PyTypeObject class_type_object = { PyObject_HEAD_INIT(0) //&class_metatype_object) @@ -275,6 +276,20 @@ static PyMemberDef instance_members[] = { return 0; } + object module_prefix() + { + object result( + PyObject_IsInstance(scope().ptr(), upcast(&PyModule_Type)) + ? object(scope().attr("__name__")) + : api::getattr(scope(), "__module__", str()) + ); + + if (result) + result += '.'; + + return result; + } + namespace { // Find a registered class object corresponding to id. Return a @@ -303,21 +318,17 @@ static PyMemberDef instance_members[] = { } return result; } - } - // class_base constructor - // - // name - the name of the new Python class - // - // num_types - one more than the number of declared bases - // - // types - array of python::type_info, the first item - // corresponding to the class being created, and the - // rest corresponding to its declared bases. - // - - namespace - { + // class_base constructor + // + // name - the name of the new Python class + // + // num_types - one more than the number of declared bases + // + // types - array of python::type_info, the first item + // corresponding to the class being created, and the + // rest corresponding to its declared bases. + // inline object new_class(char const* name, std::size_t num_types, class_id const* const types) { @@ -336,17 +347,8 @@ static PyMemberDef instance_members[] = { PyTuple_SET_ITEM(bases.get(), i - 1, upcast(c.release())); } - object module_name( - PyObject_IsInstance(scope().ptr(), upcast(&PyModule_Type)) - ? object(scope().attr("__name__")) - : api::getattr(scope(), "__module__", object("")) - ); - - if (module_name) - module_name += '.'; - // Call the class metatype to create a new class - object result = object(class_metatype())(module_name + name, bases, dict()); + object result = object(class_metatype())(module_prefix() + name, bases, dict()); assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type)); if (scope().ptr() != Py_None) diff --git a/src/str.cpp b/src/str.cpp index 12031548..f36de233 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -10,6 +10,10 @@ BOOST_PYTHON_DECL detail::new_reference str::call(object const& arg_) arg_.ptr()); } +BOOST_PYTHON_DECL str::str() + : object(detail::new_reference(PyString_FromString(""))) +{} + BOOST_PYTHON_DECL str::str(const char* s) : object(detail::new_reference(PyString_FromString(s))) {} diff --git a/test/Jamfile b/test/Jamfile index 7dcd3351..511408e8 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -54,6 +54,7 @@ rule bpl-test ( name ? : files * ) boost-python-runtest $(name) : $(py) $(modules) ; } +bpl-test enum ; bpl-test minimal ; bpl-test docstring ; bpl-test exception_translator ; From ee1cc99c650be686cce9b4d25fadd7a8e9af3ea6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 9 Sep 2002 02:24:41 +0000 Subject: [PATCH 0716/1042] Added support for enums [SVN r15223] --- src/object/enum.cpp | 206 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 src/object/enum.cpp diff --git a/src/object/enum.cpp b/src/object/enum.cpp new file mode 100644 index 00000000..36d49801 --- /dev/null +++ b/src/object/enum.cpp @@ -0,0 +1,206 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace python { namespace objects { + +struct enum_object +{ + PyIntObject base_object; + PyObject* name; +}; + +static PyMemberDef enum_members[] = { + {"name", T_OBJECT_EX, offsetof(enum_object,name),READONLY}, + {0} +}; + + +extern "C" { + static int + enum_print(PyObject *v, std::FILE *fp, int flags) + { + PyObject* s + = (flags & Py_PRINT_RAW) ? v->ob_type->tp_str(v) : v->ob_type->tp_repr(v); + if (s == 0) + return -1; + + char const* text = PyString_AsString(s); + if (text == 0) + return -1; + + std::fprintf(fp, text); + return 0; + } + + /* flags -- not used but required by interface */ + static PyObject* enum_repr(PyObject* self_) + { + enum_object* self = downcast(self_); + if (!self->name) + { + return PyString_FromFormat("%s(%ld)", self_->ob_type->tp_name, PyInt_AS_LONG(self_)); + } + else + { + char* name = PyString_AsString(self->name); + if (name == 0) + return 0; + + return PyString_FromFormat("%s.%s", self_->ob_type->tp_name, name); + } + } + + static PyObject* enum_str(PyObject* self_) + { + enum_object* self = downcast(self_); + if (!self->name) + { + return PyInt_Type.tp_str(self_); + } + else + { + return incref(self->name); + } + } +} + +static PyTypeObject enum_type_object = { + PyObject_HEAD_INIT(0) // &PyType_Type + 0, + "Boost.Python.enum", + sizeof(enum_object), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + enum_print, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + enum_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + enum_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_CHECKTYPES + | Py_TPFLAGS_HAVE_GC + | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + enum_members, /* tp_members */ + 0, /* tp_getset */ + 0, //&PyInt_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0 /* tp_new */ +}; + +object module_prefix(); + +namespace +{ + object new_enum_type(char const* name) + { + if (enum_type_object.tp_dict == 0) + { + enum_type_object.ob_type = incref(&PyType_Type); + enum_type_object.tp_base = &PyInt_Type; + if (PyType_Ready(&enum_type_object)) + throw_error_already_set(); + } + + type_handle metatype(borrowed(&PyType_Type)); + type_handle base(borrowed(&enum_type_object)); + + // suppress the instance __dict__ in these enum objects. There + // may be a slicker way, but this'll do for now. + dict d; + d["__slots__"] = tuple(); + d["values"] = dict(); + + object result = (object(metatype))( + module_prefix() + name, make_tuple(base), d); + + scope().attr(name) = result; + + return result; + } +} + +enum_base::enum_base( + char const* name + , converter::to_python_function_t to_python + , converter::convertible_function convertible + , converter::constructor_function construct + , type_info id + ) + : object(new_enum_type(name)) +{ + converter::registration& converters + = const_cast( + converter::registry::lookup(id)); + + converters.class_object = downcast(this->ptr()); + converter::registry::insert(to_python, id); + converter::registry::insert(convertible, construct, id); +} + +void enum_base::add_value(char const* name_, long value) +{ + // Convert name to Python string + object name(name_); + + // Create a new enum instance by calling the class with a value + object x = (*this)(value); + + // Store the object in the enum class + (*this).attr(name_) = x; + + dict d = extract(this->attr("values"))(); + d[value] = x; + + // Set the name field in the new enum instanec + enum_object* p = downcast(x.ptr()); + Py_XDECREF(p->name); + p->name = incref(name.ptr()); +} + +PyObject* enum_base::to_python(PyTypeObject* type_, long x) +{ + object type(type_handle(borrowed(type_))); + + dict d = extract(type.attr("values"))(); + object v = d.get(x, object()); + return incref( + (v == object() ? type(x) : v).ptr()); +} + +}}} // namespace boost::python::object From f8490a8850bd0cbf58bffb427bc08a49f39b8405 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Mon, 9 Sep 2002 02:36:54 +0000 Subject: [PATCH 0717/1042] Fixed init<...> bug where there are no default arguments. Added a test case for this. [SVN r15224] --- include/boost/python/init.hpp | 5 ++--- test/defaults.cpp | 6 ++++++ test/defaults.py | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index c931d701..03625a1b 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -262,7 +262,7 @@ namespace detail { struct count_optionals2 { BOOST_STATIC_CONSTANT( - int, value = boost::mpl::size::value); + int, value = boost::mpl::size::value + 1); }; template @@ -407,9 +407,8 @@ template void define_init(ClassT& cl, InitT const& i, CallPoliciesT const& policies, char const* doc) { - enum { n_defaults_plus_1 = InitT::n_defaults + 1 }; typedef typename InitT::sequence args_t; - detail::define_class_init_helper::apply(cl, policies, args_t(), doc); + detail::define_class_init_helper::apply(cl, policies, args_t(), doc); } }} // namespace boost::python diff --git a/test/defaults.cpp b/test/defaults.cpp index b6d2a72f..0f552666 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -91,6 +91,10 @@ struct X { : state(format % make_tuple(a, b, c, d)) {} + X(std::string s, bool b) + : state("Got exactly two arguments from constructor: string(%s); bool(%s); " % make_tuple(s, b)) + {} + object bar(int a, char b = 'D', std::string c = "default", double d = 0.0) const { @@ -162,11 +166,13 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) # if (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) .def(init >()) + .def(init()) # else .def_init(args()) .def_init(args()) .def_init(args()) .def_init(args()) + .def_init(args()) # endif .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) diff --git a/test/defaults.py b/test/defaults.py index 701ba386..aa7602f2 100644 --- a/test/defaults.py +++ b/test/defaults.py @@ -66,6 +66,9 @@ 'int(1); char(K); string(Kim); double(0.0); ' >>> x.bar2(1, 'K', "Kim", 9.9).get_state() 'int(1); char(K); string(Kim); double(9.9); ' +>>> x = X("Phoenix", 1) +>>> x.get_state() +'Got exactly two arguments from constructor: string(Phoenix); bool(1); ' """ def run(args = None): From e76440e940b112af5c0d4c1385b38b6a707d836a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 9 Sep 2002 03:03:39 +0000 Subject: [PATCH 0718/1042] Work around PP lib bug with GCC [SVN r15225] --- include/boost/python/signature.hpp | 79 +++++++++++++++--------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index e960f122..3bef081e 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -9,17 +9,18 @@ /////////////////////////////////////////////////////////////////////////////// #if !defined(BOOST_PP_IS_ITERATING) -#ifndef SIGNATURE_JDG20020813_HPP -#define SIGNATURE_JDG20020813_HPP +# ifndef SIGNATURE_JDG20020813_HPP +# define SIGNATURE_JDG20020813_HPP -#include -#include -#include -#include -#include -#include -#include -#include +# include +# include +# include +# include +# include +# include +# include +# include +# include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { namespace detail { @@ -53,70 +54,68 @@ namespace boost { namespace python { namespace detail { // and arguments of the input signature and stuffs them in an mpl::type_list. // /////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_TEMPLATE_GEN(z, index, data) class BOOST_PP_CAT(T, index) /////////////////////////////////////////////////////////////////////////////// -#define BOOST_PP_ITERATION_PARAMS_1 \ +# define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, BOOST_PYTHON_MAX_ARITY-1, )) -#include BOOST_PP_ITERATE() -#undef BOOST_PYTHON_TEMPLATE_GEN +# include BOOST_PP_ITERATE() } }} // namespace boost::python /////////////////////////////////////////////////////////////////////////////// -#endif // SIGNATURE_JDG20020813_HPP +# endif // SIGNATURE_JDG20020813_HPP #else // defined(BOOST_PP_IS_ITERATING) -// PP vertical iteration code -/////////////////////////////////////////////////////////////////////////////// +# define N BOOST_PP_ITERATION() + template < - class RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM(BOOST_PP_ITERATION(), BOOST_PYTHON_TEMPLATE_GEN, BOOST_PP_EMPTY)> + class RT BOOST_PP_COMMA_IF(N) + BOOST_PYTHON_UNARY_ENUM(N, class T)> inline boost::mpl::type_list< - RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)> -get_signature(RT(*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))) + RT BOOST_PP_COMMA_IF(N) + BOOST_PP_ENUM_PARAMS(N, T)> +get_signature(RT(*)(BOOST_PP_ENUM_PARAMS(N, T))) { return boost::mpl::type_list< - RT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)>(); + RT BOOST_PP_COMMA_IF(N) + BOOST_PP_ENUM_PARAMS(N, T)>(); } /////////////////////////////////////////////////////////////////////////////// -#if BOOST_PP_ITERATION() <= (BOOST_PYTHON_MAX_ARITY - 2) +#if N <= (BOOST_PYTHON_MAX_ARITY - 2) template < - class RT, class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM(BOOST_PP_ITERATION(), BOOST_PYTHON_TEMPLATE_GEN, BOOST_PP_EMPTY)> + class RT, class ClassT BOOST_PP_COMMA_IF(N) + BOOST_PYTHON_UNARY_ENUM(N, class T)> inline boost::mpl::type_list< - RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)> -get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))) + RT, ClassT BOOST_PP_COMMA_IF(N) + BOOST_PP_ENUM_PARAMS(N, T)> +get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T))) { return boost::mpl::type_list< - RT, ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)>(); + RT, ClassT BOOST_PP_COMMA_IF(N) + BOOST_PP_ENUM_PARAMS(N, T)>(); } /////////////////////////////////////// template < - class RT, class ClassT BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM(BOOST_PP_ITERATION(), BOOST_PYTHON_TEMPLATE_GEN, BOOST_PP_EMPTY)> + class RT, class ClassT BOOST_PP_COMMA_IF(N) + BOOST_PYTHON_UNARY_ENUM(N, class T)> inline boost::mpl::type_list< - RT, ClassT const BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)> -get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const) + RT, ClassT const BOOST_PP_COMMA_IF(N) + BOOST_PP_ENUM_PARAMS(N, T)> +get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T)) const) { return boost::mpl::type_list< RT, ClassT const - BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) - BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)>(); + BOOST_PP_COMMA_IF(N) + BOOST_PP_ENUM_PARAMS(N, T)>(); } -#endif // BOOST_PP_ITERATION() < (BOOST_PYTHON_MAX_ARITY - 2) +#endif // N < (BOOST_PYTHON_MAX_ARITY - 2) #endif // !defined(BOOST_PP_IS_ITERATING) From 4117614861ab8f6fb6d1e6c66b7f92c9cebeeb9f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 9 Sep 2002 03:34:01 +0000 Subject: [PATCH 0719/1042] Workaround MSVC6 bug [SVN r15226] --- include/boost/python/enum.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/enum.hpp b/include/boost/python/enum.hpp index b1ad0d9d..d09c1b68 100644 --- a/include/boost/python/enum.hpp +++ b/include/boost/python/enum.hpp @@ -66,7 +66,7 @@ void enum_::construct(PyObject* obj, converter::rvalue_from_python_stage1_dat template inline enum_& enum_::value(char const* name, T x) { - objects::enum_base::add_value(name, static_cast(x)); + this->add_value(name, static_cast(x)); return *this; } From 060f59daa886c60ea7af1683d2a7d7e145e8b5da Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 9 Sep 2002 03:35:05 +0000 Subject: [PATCH 0720/1042] Fix declaration bug Workaround broken MSVC6 stdlib [SVN r15227] --- src/object/enum.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/object/enum.cpp b/src/object/enum.cpp index 36d49801..b09a70a8 100644 --- a/src/object/enum.cpp +++ b/src/object/enum.cpp @@ -29,9 +29,10 @@ static PyMemberDef enum_members[] = { }; -extern "C" { +extern "C" +{ static int - enum_print(PyObject *v, std::FILE *fp, int flags) + enum_print(PyObject *v, BOOST_CSTD_::FILE *fp, int flags) { PyObject* s = (flags & Py_PRINT_RAW) ? v->ob_type->tp_str(v) : v->ob_type->tp_repr(v); @@ -42,7 +43,7 @@ extern "C" { if (text == 0) return -1; - std::fprintf(fp, text); + BOOST_CSTD_::fprintf(fp, text); return 0; } @@ -195,7 +196,7 @@ void enum_base::add_value(char const* name_, long value) PyObject* enum_base::to_python(PyTypeObject* type_, long x) { - object type(type_handle(borrowed(type_))); + object type((type_handle(borrowed(type_)))); dict d = extract(type.attr("values"))(); object v = d.get(x, object()); From eeda8221966ee3d7332ff303cd188812c6838c95 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 9 Sep 2002 04:14:31 +0000 Subject: [PATCH 0721/1042] Workaround broken BOOST_PP_ENUM on GCC [SVN r15228] --- include/boost/python/detail/defaults_gen.hpp | 67 ++++++++------------ 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 50b5ef73..b1ed0125 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -10,6 +10,7 @@ #ifndef DEFAULTS_GEN_JDG20020807_HPP #define DEFAULTS_GEN_JDG20020807_HPP +#include #include #include #include @@ -44,30 +45,21 @@ struct func_stubs_base {}; SigT \ >::type BOOST_PP_CAT(T, INDEX); \ -#define BPL_IMPL_ARGS_GEN(z, INDEX, DATA) \ - BOOST_PP_CAT(T, INDEX) BOOST_PP_CAT(arg, INDEX) \ - -#define BPL_IMPL_FUNC_WRAPPER_GEN(z, INDEX, DATA) \ - static RT BOOST_PP_CAT(func_, INDEX) \ - ( \ - BOOST_PP_ENUM \ - ( \ - BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ - BPL_IMPL_ARGS_GEN, \ - BOOST_PP_EMPTY \ - ) \ - ) \ - { \ - BOOST_PP_TUPLE_ELEM(3, 2, DATA) \ - BOOST_PP_TUPLE_ELEM(3, 0, DATA) \ - ( \ - BOOST_PP_ENUM_PARAMS \ - ( \ - BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ - arg \ - ) \ - ); \ - } \ +#define BPL_IMPL_FUNC_WRAPPER_GEN(z, index, DATA) \ + static RT BOOST_PP_CAT(func_, index) ( \ + BOOST_PYTHON_BINARY_ENUM( \ + BOOST_PP_ADD(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(BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), \ + arg \ + ) \ + ); \ + } #define BPL_IMPL_GEN_FUNCTION(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS, RETURN) \ struct FSTUBS_NAME { \ @@ -97,29 +89,20 @@ struct func_stubs_base {}; }; \ /////////////////////////////////////////////////////////////////////////////// -#define BPL_IMPL_MEM_FUNC_WRAPPER_GEN(z, INDEX, DATA) \ - static RT BOOST_PP_CAT(func_, INDEX) \ - ( \ +#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(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX)) \ - BOOST_PP_ENUM \ - ( \ - BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), INDEX), \ - BPL_IMPL_ARGS_GEN, \ - BOOST_PP_EMPTY \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), index)) \ + BOOST_PYTHON_BINARY_ENUM( \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), 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(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( \ + BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), arg \ ) \ ); \ - } \ + } #define BPL_IMPL_GEN_MEM_FUNCTION(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS, RETURN) \ struct FSTUBS_NAME { \ From dcb6a88c639c9a8a1b11d038d6f823001e087489 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 9 Sep 2002 11:37:30 +0000 Subject: [PATCH 0722/1042] *** empty log message *** [SVN r15233] --- test/enum.cpp | 27 +++++++++++++++++++++++++++ test/enum.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 test/enum.cpp create mode 100644 test/enum.py diff --git a/test/enum.cpp b/test/enum.cpp new file mode 100644 index 00000000..d6147bc0 --- /dev/null +++ b/test/enum.cpp @@ -0,0 +1,27 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include + +using namespace boost::python; + +enum color { red = 1, green = 2, blue = 4 }; + +color identity_(color x) { return x; } + +BOOST_PYTHON_MODULE_INIT(enum_ext) +{ + enum_("color") + .value("red", red) + .value("green", green) + .value("blue", blue) + ; + + def("identity", identity_); +} + +#include "module_tail.cpp" diff --git a/test/enum.py b/test/enum.py new file mode 100644 index 00000000..e21f8eb8 --- /dev/null +++ b/test/enum.py @@ -0,0 +1,42 @@ +''' +>>> from enum_ext import * + +>>> identity(color.red) +enum_ext.color.red + +>>> identity(color.green) +enum_ext.color.green + +>>> identity(color.blue) +enum_ext.color.blue + +>>> identity(color(1)) +enum_ext.color.red + +>>> identity(color(2)) +enum_ext.color.green + +>>> identity(color(3)) +enum_ext.color(3) + +>>> identity(color(4)) +enum_ext.color.blue + +>>> try: identity(1) +... except TypeError: pass +... else: print 'expected a TypeError' + +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 33ee2a43c56eecf2503cb644274c242e5715e5a0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 9 Sep 2002 17:17:59 +0000 Subject: [PATCH 0723/1042] initial commit [SVN r15238] --- include/boost/python/object/enum_base.hpp | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 include/boost/python/object/enum_base.hpp diff --git a/include/boost/python/object/enum_base.hpp b/include/boost/python/object/enum_base.hpp new file mode 100644 index 00000000..60bd49b1 --- /dev/null +++ b/include/boost/python/object/enum_base.hpp @@ -0,0 +1,32 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ENUM_BASE_DWA200298_HPP +# define ENUM_BASE_DWA200298_HPP + +# include +# include +# include + +namespace boost { namespace python { namespace objects { + +struct BOOST_PYTHON_DECL enum_base : python::api::object +{ + protected: + enum_base( + char const* name + , converter::to_python_function_t + , converter::convertible_function + , converter::constructor_function + , type_info); + + void add_value(char const* name, long value); + + static PyObject* to_python(PyTypeObject* type, long x); +}; + +}}} // namespace boost::python::object + +#endif // ENUM_BASE_DWA200298_HPP From 75a0da31fbe71be938d7c9963dad55da1ea42990 Mon Sep 17 00:00:00 2001 From: uid30600 Date: Mon, 9 Sep 2002 20:05:17 +0000 Subject: [PATCH 0724/1042] Reduce header interdependencies [SVN r15242] --- include/boost/python/back_reference.hpp | 2 +- include/boost/python/class.hpp | 6 ++++-- include/boost/python/converter/arg_to_python.hpp | 3 ++- .../boost/python/converter/return_from_python.hpp | 3 ++- include/boost/python/detail/void_return.hpp | 2 ++ include/boost/python/enum.hpp | 1 + include/boost/python/extract.hpp | 1 + include/boost/python/object/class.hpp | 3 ++- include/boost/python/object/enum_base.hpp | 2 ++ include/boost/python/object/instance.hpp | 5 +++++ include/boost/python/object/make_holder.hpp | 2 ++ include/boost/python/object/pickle_support.hpp | 10 +++++++--- include/boost/python/object_core.hpp | 14 ++++++-------- include/boost/python/object_operators.hpp | 1 + include/boost/python/object_slices.hpp | 1 + src/object_operators.cpp | 6 +++++- test/data_members.cpp | 1 - test/object_manager.cpp | 1 + 18 files changed, 45 insertions(+), 19 deletions(-) diff --git a/include/boost/python/back_reference.hpp b/include/boost/python/back_reference.hpp index 29ad6163..75a14525 100644 --- a/include/boost/python/back_reference.hpp +++ b/include/boost/python/back_reference.hpp @@ -6,9 +6,9 @@ #ifndef BACK_REFERENCE_DWA2002510_HPP # define BACK_REFERENCE_DWA2002510_HPP -# include # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 918de0ec..918cf4d2 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -7,10 +7,12 @@ # define CLASS_DWA200216_HPP # include +# include # include # include -# include -# include + +# include + # include # include # include diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index c936b81d..7abb274c 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -10,7 +10,6 @@ # include # include # include -# include # include # include # include @@ -26,6 +25,8 @@ namespace boost { namespace python { namespace converter { +template struct is_object_manager; + namespace detail { BOOST_PYTHON_DECL void throw_no_class_registered(); diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 490d4bf7..f02f01d9 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -6,7 +6,6 @@ #ifndef RETURN_FROM_PYTHON_DWA200265_HPP # define RETURN_FROM_PYTHON_DWA200265_HPP -# include # include # include # include @@ -17,6 +16,8 @@ namespace boost { namespace python { namespace converter { +template struct is_object_manager; + namespace detail { template diff --git a/include/boost/python/detail/void_return.hpp b/include/boost/python/detail/void_return.hpp index 28e919d7..512aa636 100644 --- a/include/boost/python/detail/void_return.hpp +++ b/include/boost/python/detail/void_return.hpp @@ -6,6 +6,8 @@ #ifndef VOID_RETURN_DWA200274_HPP # define VOID_RETURN_DWA200274_HPP +# include + namespace boost { namespace python { namespace detail { struct void_return diff --git a/include/boost/python/enum.hpp b/include/boost/python/enum.hpp index d09c1b68..f7d06075 100644 --- a/include/boost/python/enum.hpp +++ b/include/boost/python/enum.hpp @@ -8,6 +8,7 @@ # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/extract.hpp b/include/boost/python/extract.hpp index 16efb3bf..fdcaac28 100644 --- a/include/boost/python/extract.hpp +++ b/include/boost/python/extract.hpp @@ -16,6 +16,7 @@ # include # include # include +# include namespace boost { namespace python { diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index 69bc5b20..e97f8edd 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -11,6 +11,7 @@ # include # include # include +# include # include namespace boost { namespace python { @@ -24,7 +25,7 @@ struct BOOST_PYTHON_DECL class_base : python::api::object char const* name // The name of the class , std::size_t num_types // A list of class_ids. The first is the type - , class_id const*const types // this is wrapping. The rest are the types of + , type_info const*const types // this is wrapping. The rest are the types of // any bases. , char const* doc = 0 // Docstring, if any. diff --git a/include/boost/python/object/enum_base.hpp b/include/boost/python/object/enum_base.hpp index 60bd49b1..37cd8f17 100644 --- a/include/boost/python/object/enum_base.hpp +++ b/include/boost/python/object/enum_base.hpp @@ -9,6 +9,8 @@ # include # include # include +# include +# include namespace boost { namespace python { namespace objects { diff --git a/include/boost/python/object/instance.hpp b/include/boost/python/object/instance.hpp index c64ce33d..94e526b2 100644 --- a/include/boost/python/object/instance.hpp +++ b/include/boost/python/object/instance.hpp @@ -10,6 +10,11 @@ # include # include +namespace boost { namespace python +{ + struct instance_holder; +}} // namespace boost::python + namespace boost { namespace python { namespace objects { // Each extension instance will be one of these diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 933159da..429704a3 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -9,6 +9,8 @@ # ifndef MAKE_HOLDER_DWA20011215_HPP # define MAKE_HOLDER_DWA20011215_HPP +# include + # include # include # include diff --git a/include/boost/python/object/pickle_support.hpp b/include/boost/python/object/pickle_support.hpp index bae05138..a5a67cc2 100644 --- a/include/boost/python/object/pickle_support.hpp +++ b/include/boost/python/object/pickle_support.hpp @@ -6,11 +6,15 @@ #ifndef BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP #define BOOST_PYTHON_OBJECT_PICKLE_SUPPORT_RWGK20020603_HPP -#include -#include - namespace boost { namespace python { +namespace api +{ + class object; +} +using api::object; +class tuple; + BOOST_PYTHON_DECL object const& make_instance_reduce_function(); struct pickle_suite; diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 5d95946c..6b07d659 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -8,13 +8,13 @@ # include -# include -# include +# include +# include # include # include # include # include -# include +# include # include # include @@ -222,7 +222,7 @@ namespace api } // Throw error_already_set() if the handle is null. - explicit object(handle<> const&); + BOOST_PYTHON_DECL explicit object(handle<> const&); public: // implementation detail -- for internal use only explicit object(detail::borrowed_reference); @@ -312,10 +312,6 @@ template struct extract; // implementation // -inline object::object(handle<> const& x) - : object_base(python::incref(python::expect_non_null(x.get()))) -{} - inline object::object() : object_base(python::incref(Py_None)) {} @@ -364,6 +360,8 @@ inline PyObject* api::object_base::ptr() const // namespace converter { + template struct object_manager_traits; + template <> struct object_manager_traits { diff --git a/include/boost/python/object_operators.hpp b/include/boost/python/object_operators.hpp index 801218e6..fb14d484 100644 --- a/include/boost/python/object_operators.hpp +++ b/include/boost/python/object_operators.hpp @@ -7,6 +7,7 @@ # define OBJECT_OPERATORS_DWA2002617_HPP # include +# include namespace boost { namespace python { namespace api { diff --git a/include/boost/python/object_slices.hpp b/include/boost/python/object_slices.hpp index a4348efc..eb8dcb0b 100644 --- a/include/boost/python/object_slices.hpp +++ b/include/boost/python/object_slices.hpp @@ -9,6 +9,7 @@ # include # include # include +# include # include namespace boost { namespace python { namespace api { diff --git a/src/object_operators.cpp b/src/object_operators.cpp index 471f01ad..b7c984ef 100644 --- a/src/object_operators.cpp +++ b/src/object_operators.cpp @@ -49,5 +49,9 @@ BOOST_PYTHON_INPLACE_OPERATOR(&, And) BOOST_PYTHON_INPLACE_OPERATOR(^, Xor) BOOST_PYTHON_INPLACE_OPERATOR(|, Or) #undef BOOST_PYTHON_INPLACE_OPERATOR - + +BOOST_PYTHON_DECL object::object(handle<> const& x) + : object_base(python::incref(python::expect_non_null(x.get()))) +{} + }}} // namespace boost::python diff --git a/test/data_members.cpp b/test/data_members.cpp index 5ab73438..99459dff 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -5,7 +5,6 @@ // to its suitability for any purpose. #include #include -#include #include "test_class.hpp" #if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 diff --git a/test/object_manager.cpp b/test/object_manager.cpp index 0f1851c5..44005aeb 100755 --- a/test/object_manager.cpp +++ b/test/object_manager.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace boost::python; using namespace boost::python::converter; From 07561794e91c7bc7e6aafe38bcae48ecdbba6328 Mon Sep 17 00:00:00 2001 From: uid30600 Date: Mon, 9 Sep 2002 20:31:51 +0000 Subject: [PATCH 0725/1042] Fix missing declaration problem [SVN r15243] --- include/boost/python/object_core.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 6b07d659..a0119503 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -8,6 +8,7 @@ # include +# include # include # include # include From e079006a4b075ad325a70f9f7670c8247a326c37 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 9 Sep 2002 21:55:14 +0000 Subject: [PATCH 0726/1042] work around broken Tru64/cxx offsetof macro [SVN r15245] --- include/boost/python/detail/config.hpp | 8 ++++++++ include/boost/python/object/instance.hpp | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 2a9ec35e..c3750902 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -106,4 +106,12 @@ class function; }}} #endif +#if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590014) +// Replace broken Tru64/cxx offsetof macro +# define BOOST_PYTHON_OFFSETOF(s_name, s_member) \ + ((size_t)__INTADDR__(&(((s_name *)0)->s_member))) +#else +# define BOOST_PYTHON_OFFSETOF offsetof +#endif + #endif // CONFIG_DWA052200_H_ diff --git a/include/boost/python/object/instance.hpp b/include/boost/python/object/instance.hpp index 94e526b2..4cddcc99 100644 --- a/include/boost/python/object/instance.hpp +++ b/include/boost/python/object/instance.hpp @@ -42,7 +42,8 @@ struct additional_instance_size typedef instance instance_data; typedef instance instance_char; BOOST_STATIC_CONSTANT( - std::size_t, value = sizeof(instance_data) - offsetof(instance_char,storage)); + std::size_t, value = sizeof(instance_data) + - BOOST_PYTHON_OFFSETOF(instance_char,storage)); }; }}} // namespace boost::python::object From 5113de875ecc77bcd76cd4f778aeb0d9eabfb93d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 9 Sep 2002 21:58:15 +0000 Subject: [PATCH 0727/1042] work around broken Python 2.2 include files [SVN r15246] --- include/boost/python/detail/python22_fixed.h | 140 +++++++++++++++++++ include/boost/python/detail/wrap_python.hpp | 6 +- 2 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 include/boost/python/detail/python22_fixed.h diff --git a/include/boost/python/detail/python22_fixed.h b/include/boost/python/detail/python22_fixed.h new file mode 100644 index 00000000..3caff6dd --- /dev/null +++ b/include/boost/python/detail/python22_fixed.h @@ -0,0 +1,140 @@ +// Copy of Python 2.2/2.2.1 Python.h . +// Changes marked with "Boost.Python modification" +#ifndef Py_PYTHON_H +#define Py_PYTHON_H +/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */ + + +/* Enable compiler features; switching on C lib defines doesn't work + here, because the symbols haven't necessarily been defined yet. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +/* Forcing SUSv2 compatibility still produces problems on some + platforms, True64 and SGI IRIX begin two of them, so for now the + define is switched off. */ +#if 0 +#ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 500 +#endif +#endif + +/* Include nearly all Python header files */ + +#include "patchlevel.h" +#include "pyconfig.h" + +#ifdef HAVE_LIMITS_H +#include +#endif + +/* pyconfig.h may or may not define DL_IMPORT */ +#ifndef DL_IMPORT /* declarations for DLL import/export */ +#define DL_IMPORT(RTYPE) RTYPE +#endif +#ifndef DL_EXPORT /* declarations for DLL import/export */ +#define DL_EXPORT(RTYPE) RTYPE +#endif + +#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE) +#define _SGI_MP_SOURCE +#endif + +#include +#ifndef NULL +# error "Python.h requires that stdio.h define NULL." +#endif + +#include +#include +#ifdef HAVE_STDLIB_H +#include +#endif +#if PY_MICRO_VERSION == 1 // Boost.Python modification: emulate Python 2.2 +#ifdef HAVE_UNISTD_H +#include +#endif +#endif // Boost.Python modification: emulate Python 2.2 + +/* CAUTION: Build setups should ensure that NDEBUG is defined on the + * compiler command line when building Python in release mode; else + * assert() calls won't be removed. + */ +#include + +#include "pyport.h" + +#include "pymem.h" + +#include "object.h" +#include "objimpl.h" + +#include "pydebug.h" + +#include "unicodeobject.h" +#include "intobject.h" +#include "longobject.h" +#include "floatobject.h" +#ifndef WITHOUT_COMPLEX +#include "complexobject.h" +#endif +#include "rangeobject.h" +#include "stringobject.h" +#include "bufferobject.h" +#include "tupleobject.h" +#include "listobject.h" +#include "dictobject.h" +#include "methodobject.h" +#include "moduleobject.h" +#include "funcobject.h" +#include "classobject.h" +#include "fileobject.h" +#include "cobject.h" +#include "traceback.h" +#include "sliceobject.h" +#include "cellobject.h" +extern "C" { // Boost.Python modification: provide missing extern "C" +#include "iterobject.h" +#include "descrobject.h" +} // Boost.Python modification: provide missing extern "C" +#include "weakrefobject.h" + +#include "codecs.h" +#include "pyerrors.h" + +#include "pystate.h" + +#include "modsupport.h" +#include "pythonrun.h" +#include "ceval.h" +#include "sysmodule.h" +#include "intrcheck.h" +#include "import.h" + +#include "abstract.h" + +#define PyArg_GetInt(v, a) PyArg_Parse((v), "i", (a)) +#define PyArg_NoArgs(v) PyArg_Parse(v, "") + +/* Convert a possibly signed character to a nonnegative int */ +/* XXX This assumes characters are 8 bits wide */ +#ifdef __CHAR_UNSIGNED__ +#define Py_CHARMASK(c) (c) +#else +#define Py_CHARMASK(c) ((c) & 0xff) +#endif + +#include "pyfpe.h" + +/* These definitions must match corresponding definitions in graminit.h. + There's code in compile.c that checks that they are the same. */ +#define Py_single_input 256 +#define Py_file_input 257 +#define Py_eval_input 258 + +#ifdef HAVE_PTH +/* GNU pth user-space thread support */ +#include +#endif +#endif /* !Py_PYTHON_H */ diff --git a/include/boost/python/detail/wrap_python.hpp b/include/boost/python/detail/wrap_python.hpp index e2392bc5..6cb8dee2 100644 --- a/include/boost/python/detail/wrap_python.hpp +++ b/include/boost/python/detail/wrap_python.hpp @@ -115,7 +115,11 @@ typedef int pid_t; #endif // _WIN32 -#include +#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 2 && PY_MICRO_VERSION < 2 +# include +#else +# include +#endif #ifdef BOOST_PYTHON_ULONG_MAX_UNDEFINED # undef ULONG_MAX From ada55bd9e266525efe79171bf604a85b96e9f4c3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 11 Sep 2002 05:35:41 +0000 Subject: [PATCH 0728/1042] mpl_v2 branch checkin [SVN r15258] --- Jamfile | 2 +- test/bienstman4.cpp | 3 ++- test/bienstman5.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Jamfile b/Jamfile index 4ff03b82..d5a9e729 100644 --- a/Jamfile +++ b/Jamfile @@ -4,7 +4,7 @@ subproject libs/python ; SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; -local bpl-ldflags ; +local bpl-linkflags ; if $(UNIX) && ( $(OS) = AIX ) { diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp index ef1c94c5..324af85a 100644 --- a/test/bienstman4.cpp +++ b/test/bienstman4.cpp @@ -8,6 +8,7 @@ #include #include #include +#include struct Type1 {}; @@ -18,7 +19,7 @@ struct Expression {void add(Term const&) {} }; BOOST_PYTHON_MODULE_INIT(bienstman4_ext) { using namespace boost::python; - using boost::mpl::type_list; + using boost::mpl::list; implicitly_convertible(); diff --git a/test/bienstman5.cpp b/test/bienstman5.cpp index 983b7804..007d12a9 100644 --- a/test/bienstman5.cpp +++ b/test/bienstman5.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include From d91b6e9a1bdda1a48cfd6e09a39d2613a9cf335f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 12 Sep 2002 23:58:15 +0000 Subject: [PATCH 0729/1042] Compile (but still can't link) with MinGW-2.0 (GCC-3.2) [SVN r15285] --- include/boost/python/dict.hpp | 38 +++++----- include/boost/python/list.hpp | 34 ++++----- include/boost/python/long.hpp | 12 ++-- include/boost/python/str.hpp | 124 ++++++++++++++++----------------- include/boost/python/tuple.hpp | 8 +-- src/dict.cpp | 36 +++++----- src/list.cpp | 32 ++++----- src/long.cpp | 10 +-- src/object_operators.cpp | 2 +- src/str.cpp | 118 +++++++++++++++---------------- src/tuple.cpp | 6 +- 11 files changed, 210 insertions(+), 210 deletions(-) diff --git a/include/boost/python/dict.hpp b/include/boost/python/dict.hpp index b593f902..58d4635d 100644 --- a/include/boost/python/dict.hpp +++ b/include/boost/python/dict.hpp @@ -8,15 +8,15 @@ namespace boost { namespace python { -class dict : public object +class BOOST_PYTHON_DECL dict : public object { public: // dict() -> new empty dictionary. // dict(mapping) -> new dictionary initialized from a mapping object's // (key, value) pairs. // dict(seq) -> new dictionary initialized as if via: - BOOST_PYTHON_DECL dict(); // new dict - explicit BOOST_PYTHON_DECL dict(object_cref data); + dict(); // new dict + explicit dict(object_cref data); template explicit dict(T const& data) @@ -25,13 +25,13 @@ class dict : public object } // D.clear() -> None. Remove all items from D. - BOOST_PYTHON_DECL void clear(); + void clear(); // D.copy() -> a shallow copy of D - BOOST_PYTHON_DECL dict copy(); + dict copy(); // D.get(k[,d]) -> D[k] if D.has_key(k), else d. d defaults to None. - BOOST_PYTHON_DECL object get(object_cref k) const; + object get(object_cref k) const; template object get(T const& k) const @@ -39,7 +39,7 @@ class dict : public object return this->get(object(k)); } - BOOST_PYTHON_DECL object get(object_cref k, object_cref d) const; + object get(object_cref k, object_cref d) const; template object get(T1 const& k, T2 const& d) const @@ -48,7 +48,7 @@ class dict : public object } // D.has_key(k) -> 1 if D has a key k, else 0 - BOOST_PYTHON_DECL bool has_key(object_cref k) const; + bool has_key(object_cref k) const; template bool has_key(T const& k) const @@ -57,26 +57,26 @@ class dict : public object } // D.items() -> list of D's (key, value) pairs, as 2-tuples - BOOST_PYTHON_DECL list items() const; + list items() const; // D.iteritems() -> an iterator over the (key, value) items of D - BOOST_PYTHON_DECL object iteritems() const; + object iteritems() const; // D.iterkeys() -> an iterator over the keys of D - BOOST_PYTHON_DECL object iterkeys() const; + object iterkeys() const; // D.itervalues() -> an iterator over the values of D - BOOST_PYTHON_DECL object itervalues() const; + object itervalues() const; // D.keys() -> list of D's keys - BOOST_PYTHON_DECL list keys() const; + list keys() const; // D.popitem() -> (k, v), remove and return some (key, value) pair as a // 2-tuple; but raise KeyError if D is empty - BOOST_PYTHON_DECL tuple popitem(); + tuple popitem(); // D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if not D.has_key(k) - BOOST_PYTHON_DECL object setdefault(object_cref k); + object setdefault(object_cref k); template object setdefault(T const& k) @@ -84,7 +84,7 @@ class dict : public object return this->setdefault(object(k)); } - BOOST_PYTHON_DECL object setdefault(object_cref k, object_cref d); + object setdefault(object_cref k, object_cref d); template object setdefault(T1 const& k, T2 const& d) @@ -93,7 +93,7 @@ class dict : public object } // D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k] - BOOST_PYTHON_DECL void update(object_cref E); + void update(object_cref E); template void update(T const& E) @@ -102,13 +102,13 @@ class dict : public object } // D.values() -> list of D's values - BOOST_PYTHON_DECL list values() const; + list values() const; public: // implementation detail -- for internal use only BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict) private: - static BOOST_PYTHON_DECL detail::new_reference call(object const&); + static detail::new_reference call(object const&); }; diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp index 501eeed5..f851a7f1 100644 --- a/include/boost/python/list.hpp +++ b/include/boost/python/list.hpp @@ -11,11 +11,11 @@ namespace boost { namespace python { -class list : public object +class BOOST_PYTHON_DECL list : public object { public: - BOOST_PYTHON_DECL list(); // new list - explicit BOOST_PYTHON_DECL list(object_cref sequence); // new list initialized from sequence's items + list(); // new list + explicit list(object_cref sequence); // new list initialized from sequence's items template explicit list(T const& sequence) @@ -23,7 +23,7 @@ class list : public object { } - BOOST_PYTHON_DECL void append(object_cref); // append object to end + void append(object_cref); // append object to end template void append(T const& x) @@ -31,7 +31,7 @@ class list : public object this->append(object(x)); } - BOOST_PYTHON_DECL long count(object_cref value) const; // return number of occurrences of value + long count(object_cref value) const; // return number of occurrences of value template long count(T const& value) const @@ -39,7 +39,7 @@ class list : public object return this->count(object(value)); } - BOOST_PYTHON_DECL void extend(object_cref sequence); // extend list by appending sequence elements + void extend(object_cref sequence); // extend list by appending sequence elements template void extend(T const& x) @@ -47,7 +47,7 @@ class list : public object this->extend(object(x)); } - BOOST_PYTHON_DECL long index(object_cref value) const; // return index of first occurrence of value + long index(object_cref value) const; // return index of first occurrence of value template long index(T const& x) const @@ -55,8 +55,8 @@ class list : public object return this->index(object(x)); } - BOOST_PYTHON_DECL void insert(int index, object_cref); // insert object before index - BOOST_PYTHON_DECL void insert(object const& index, object_cref); + void insert(int index, object_cref); // insert object before index + void insert(object const& index, object_cref); template void insert(int index, T const& x) // insert object before index @@ -70,11 +70,11 @@ class list : public object this->insert(index, object(x)); } - BOOST_PYTHON_DECL object pop(); // remove and return item at index (default last) - BOOST_PYTHON_DECL object pop(long index); - BOOST_PYTHON_DECL object pop(object const& index); + object pop(); // remove and return item at index (default last) + object pop(long index); + object pop(object const& index); - BOOST_PYTHON_DECL void remove(object_cref value); // remove first occurrence of value + void remove(object_cref value); // remove first occurrence of value template void remove(T const& value) @@ -82,10 +82,10 @@ class list : public object this->remove(object(value)); } - BOOST_PYTHON_DECL void reverse(); // reverse *IN PLACE* + void reverse(); // reverse *IN PLACE* - BOOST_PYTHON_DECL void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1 - BOOST_PYTHON_DECL void sort(object_cref cmpfunc); + void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1 + void sort(object_cref cmpfunc); template void sort(T const& value) @@ -97,7 +97,7 @@ class list : public object BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list) private: - static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&); + static detail::new_non_null_reference call(object const&); }; // diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp index 3ba4f434..690a630b 100644 --- a/include/boost/python/long.hpp +++ b/include/boost/python/long.hpp @@ -11,11 +11,11 @@ namespace boost { namespace python { -class long_ : public object +class BOOST_PYTHON_DECL long_ : public object { public: - BOOST_PYTHON_DECL long_(); // new long_ - explicit BOOST_PYTHON_DECL long_(object_cref rhs); + long_(); // new long_ + explicit long_(object_cref rhs); template explicit long_(T const& rhs) @@ -23,7 +23,7 @@ class long_ : public object { } - explicit BOOST_PYTHON_DECL long_(object_cref rhs, object_cref base); + explicit long_(object_cref rhs, object_cref base); template explicit long_(T const& rhs, U const& base) @@ -34,8 +34,8 @@ class long_ : public object BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_) private: - static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&); - static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&, object const&); + static detail::new_non_null_reference call(object const&); + static detail::new_non_null_reference call(object const&, object const&); }; // diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index fb8bfe58..2a0e0e97 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -15,13 +15,13 @@ namespace boost { namespace python { -class str : public object +class BOOST_PYTHON_DECL str : public object { public: - BOOST_PYTHON_DECL str(); // new str + str(); // new str - BOOST_PYTHON_DECL str(const char* s); // new str - explicit BOOST_PYTHON_DECL str(object_cref other); + str(const char* s); // new str + explicit str(object_cref other); template explicit str(T const& other) @@ -29,9 +29,9 @@ class str : public object { } - BOOST_PYTHON_DECL str capitalize() const ; + str capitalize() const ; - BOOST_PYTHON_DECL str center(object_cref width) const ; + str center(object_cref width) const ; template str center(T const& width) const @@ -39,7 +39,7 @@ class str : public object return this->center(object(width)); } - BOOST_PYTHON_DECL long count(object_cref sub) const; + long count(object_cref sub) const; template long count(T const& sub) const @@ -47,7 +47,7 @@ class str : public object return this->count(object(sub)); } - BOOST_PYTHON_DECL long count(object_cref sub, object_cref start) const; + long count(object_cref sub, object_cref start) const; template long count(T1 const& sub,T2 const& start) const @@ -55,7 +55,7 @@ class str : public object return this->count(object(sub), object(start)); } - BOOST_PYTHON_DECL long count(object_cref sub, object_cref start, object_cref end) const; + long count(object_cref sub, object_cref start, object_cref end) const; template long count(T1 const& sub,T2 const& start, T3 const& end) const @@ -63,8 +63,8 @@ class str : public object return this->count(object(sub), object(start)); } - BOOST_PYTHON_DECL object decode() const; - BOOST_PYTHON_DECL object decode(object_cref encoding) const; + object decode() const; + object decode(object_cref encoding) const; template object decode(T const& encoding) const @@ -72,7 +72,7 @@ class str : public object return this->decode(object(encoding)); } - BOOST_PYTHON_DECL object decode(object_cref encoding, object_cref errors) const; + object decode(object_cref encoding, object_cref errors) const; template object decode(T1 const& encoding, T2 const& errors) const @@ -80,8 +80,8 @@ class str : public object return this->decode(object(encoding),object(errors)); } - BOOST_PYTHON_DECL object encode() const; - BOOST_PYTHON_DECL object encode(object_cref encoding) const; + object encode() const; + object encode(object_cref encoding) const; template object encode(T const& encoding) const @@ -89,7 +89,7 @@ class str : public object return this->encode(object(encoding)); } - BOOST_PYTHON_DECL object encode(object_cref encoding, object_cref errors) const; + object encode(object_cref encoding, object_cref errors) const; template object encode(T1 const& encoding, T2 const& errors) const @@ -97,7 +97,7 @@ class str : public object return this->encode(object(encoding),object(errors)); } - BOOST_PYTHON_DECL bool endswith(object_cref suffix) const; + bool endswith(object_cref suffix) const; template bool endswith(T const& suffix) const @@ -105,7 +105,7 @@ class str : public object return this->endswith(object(suffix)); } - BOOST_PYTHON_DECL bool endswith(object_cref suffix, object_cref start) const; + bool endswith(object_cref suffix, object_cref start) const; template bool endswith(T1 const& suffix, T2 const& start) const @@ -113,7 +113,7 @@ class str : public object return this->endswith(object(suffix), object(start)); } - BOOST_PYTHON_DECL bool endswith(object_cref suffix, object_cref start, object_cref end) const; + bool endswith(object_cref suffix, object_cref start, object_cref end) const; template bool endswith(T1 const& suffix, T2 const& start, T3 const& end) const @@ -121,8 +121,8 @@ class str : public object return this->endswith(object(suffix), object(start), object(end)); } - BOOST_PYTHON_DECL str expandtabs() const; - BOOST_PYTHON_DECL str expandtabs(object_cref tabsize) const; + str expandtabs() const; + str expandtabs(object_cref tabsize) const; template str expandtabs(T const& tabsize) const @@ -130,7 +130,7 @@ class str : public object return this->expandtabs(object(tabsize)); } - BOOST_PYTHON_DECL long find(object_cref sub) const; + long find(object_cref sub) const; template long find(T const& sub) const @@ -138,7 +138,7 @@ class str : public object return this->find(object(sub)); } - BOOST_PYTHON_DECL long find(object_cref sub, object_cref start) const; + long find(object_cref sub, object_cref start) const; template long find(T1 const& sub, T2 const& start) const @@ -146,7 +146,7 @@ class str : public object return this->find(object(sub), object(start)); } - BOOST_PYTHON_DECL long find(object_cref sub, object_cref start, object_cref end) const; + long find(object_cref sub, object_cref start, object_cref end) const; template long find(T1 const& sub, T2 const& start, T3 const& end) const @@ -154,7 +154,7 @@ class str : public object return this->find(object(sub), object(start), object(end)); } - BOOST_PYTHON_DECL long index(object_cref sub) const; + long index(object_cref sub) const; template long index(T const& sub) const @@ -162,7 +162,7 @@ class str : public object return this->index(object(sub)); } - BOOST_PYTHON_DECL long index(object_cref sub, object_cref start) const; + long index(object_cref sub, object_cref start) const; template long index(T1 const& sub, T2 const& start) const @@ -170,7 +170,7 @@ class str : public object return this->index(object(sub), object(start)); } - BOOST_PYTHON_DECL long index(object_cref sub, object_cref start, object_cref end) const; + long index(object_cref sub, object_cref start, object_cref end) const; template long index(T1 const& sub, T2 const& start, T3 const& end) const @@ -178,15 +178,15 @@ class str : public object return this->index(object(sub), object(start), object(end)); } - BOOST_PYTHON_DECL bool isalnum() const; - BOOST_PYTHON_DECL bool isalpha() const; - BOOST_PYTHON_DECL bool isdigit() const; - BOOST_PYTHON_DECL bool islower() const; - BOOST_PYTHON_DECL bool isspace() const; - BOOST_PYTHON_DECL bool istitle() const; - BOOST_PYTHON_DECL bool isupper() const; + bool isalnum() const; + bool isalpha() const; + bool isdigit() const; + bool islower() const; + bool isspace() const; + bool istitle() const; + bool isupper() const; - BOOST_PYTHON_DECL str join(object_cref sequence) const; + str join(object_cref sequence) const; template str join(T const& sequence) const @@ -194,7 +194,7 @@ class str : public object return this->join(object(sequence)); } - BOOST_PYTHON_DECL str ljust(object_cref width) const; + str ljust(object_cref width) const; template str ljust(T const& width) const @@ -202,10 +202,10 @@ class str : public object return this->ljust(object(width)); } - BOOST_PYTHON_DECL str lower() const; - BOOST_PYTHON_DECL str lstrip() const; + str lower() const; + str lstrip() const; - BOOST_PYTHON_DECL str replace(object_cref old, object_cref new_) const ; + str replace(object_cref old, object_cref new_) const ; template str replace(T1 const& old, T2 const& new_) const @@ -213,7 +213,7 @@ class str : public object return this->replace(object(old),object(new_)); } - BOOST_PYTHON_DECL str replace(object_cref old, object_cref new_, object_cref maxsplit) const ; + str replace(object_cref old, object_cref new_, object_cref maxsplit) const ; template str replace(T1 const& old, T2 const& new_, T3 const& maxsplit) const @@ -221,7 +221,7 @@ class str : public object return this->replace(object(old),object(new_),object(maxsplit)); } - BOOST_PYTHON_DECL long rfind(object_cref sub) const; + long rfind(object_cref sub) const; template long rfind(T const& sub) const @@ -229,7 +229,7 @@ class str : public object return this->rfind(object(sub)); } - BOOST_PYTHON_DECL long rfind(object_cref sub, object_cref start) const; + long rfind(object_cref sub, object_cref start) const; template long rfind(T1 const& sub, T2 const& start) const @@ -237,7 +237,7 @@ class str : public object return this->rfind(object(sub), object(start)); } - BOOST_PYTHON_DECL long rfind(object_cref sub, object_cref start, object_cref end) const; + long rfind(object_cref sub, object_cref start, object_cref end) const; template long rfind(T1 const& sub, T2 const& start, T3 const& end) const @@ -245,7 +245,7 @@ class str : public object return this->rfind(object(sub), object(start), object(end)); } - BOOST_PYTHON_DECL long rindex(object_cref sub) const; + long rindex(object_cref sub) const; template long rindex(T const& sub) const @@ -253,7 +253,7 @@ class str : public object return this->rindex(object(sub)); } - BOOST_PYTHON_DECL long rindex(object_cref sub, object_cref start) const; + long rindex(object_cref sub, object_cref start) const; template long rindex(T1 const& sub, T2 const& start) const @@ -261,7 +261,7 @@ class str : public object return this->rindex(object(sub), object(start)); } - BOOST_PYTHON_DECL long rindex(object_cref sub, object_cref start, object_cref end) const; + long rindex(object_cref sub, object_cref start, object_cref end) const; template long rindex(T1 const& sub, T2 const& start, T3 const& end) const @@ -269,7 +269,7 @@ class str : public object return this->rindex(object(sub), object(start), object(end)); } - BOOST_PYTHON_DECL str rjust(object_cref width) const; + str rjust(object_cref width) const; template str rjust(T const& width) const @@ -277,10 +277,10 @@ class str : public object return this->rjust(object(width)); } - BOOST_PYTHON_DECL str rstrip() const; + str rstrip() const; - BOOST_PYTHON_DECL list split() const; - BOOST_PYTHON_DECL list split(object_cref sep) const; + list split() const; + list split(object_cref sep) const; template list split(T const& sep) const @@ -288,7 +288,7 @@ class str : public object return this->split(object(sep)); } - BOOST_PYTHON_DECL list split(object_cref sep, object_cref maxsplit) const; + list split(object_cref sep, object_cref maxsplit) const; template list split(T1 const& sep, T2 const& maxsplit) const @@ -296,8 +296,8 @@ class str : public object return this->split(object(sep), object(maxsplit)); } - BOOST_PYTHON_DECL list splitlines() const; - BOOST_PYTHON_DECL list splitlines(object_cref keepends) const; + list splitlines() const; + list splitlines(object_cref keepends) const; template list splitlines(T const& keepends) const @@ -305,7 +305,7 @@ class str : public object return this->splitlines(object(keepends)); } - BOOST_PYTHON_DECL bool startswith(object_cref prefix) const ; + bool startswith(object_cref prefix) const ; template bool startswith(T const& prefix) const @@ -313,7 +313,7 @@ class str : public object return this->startswith(object(prefix)); } - BOOST_PYTHON_DECL bool startswith(object_cref prefix, object_cref start) const ; + bool startswith(object_cref prefix, object_cref start) const ; template bool startswidth(T1 const& prefix, T2 const& start) const @@ -321,7 +321,7 @@ class str : public object return this->startswidth(object(prefix), object(start)); } - BOOST_PYTHON_DECL bool startswith(object_cref prefix, object_cref start, object_cref end) const ; + bool startswith(object_cref prefix, object_cref start, object_cref end) const ; template bool startswidth(T1 const& prefix, T2 const& start, T3 const& end) const @@ -329,11 +329,11 @@ class str : public object return this->startswidth(object(prefix), object(start), object(end)); } - BOOST_PYTHON_DECL str strip() const ; - BOOST_PYTHON_DECL str swapcase() const ; - BOOST_PYTHON_DECL str title() const ; + str strip() const ; + str swapcase() const ; + str title() const ; - BOOST_PYTHON_DECL str translate(object_cref table) const; + str translate(object_cref table) const; template str translate(T const& table) const @@ -341,7 +341,7 @@ class str : public object return this->translate(object(table)); } - BOOST_PYTHON_DECL str translate(object_cref table, object_cref deletechars) const; + str translate(object_cref table, object_cref deletechars) const; template str translate(T1 const& table, T2 const& deletechars) const @@ -349,13 +349,13 @@ class str : public object return this->translate(object(table), object(deletechars)); } - BOOST_PYTHON_DECL str upper() const; + str upper() const; public: // implementation detail -- for internal use only BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str) private: - static BOOST_PYTHON_DECL detail::new_reference call(object const&); + static detail::new_reference call(object const&); }; // diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp index 38547696..133bc49b 100644 --- a/include/boost/python/tuple.hpp +++ b/include/boost/python/tuple.hpp @@ -6,14 +6,14 @@ namespace boost { namespace python { -class tuple : public object +class BOOST_PYTHON_DECL tuple : public object { public: // tuple() -> an empty tuple - BOOST_PYTHON_DECL tuple(); + tuple(); // tuple(sequence) -> tuple initialized from sequence's items - BOOST_PYTHON_DECL tuple(object_cref sequence); + tuple(object_cref sequence); template explicit tuple(T const& sequence) @@ -25,7 +25,7 @@ class tuple : public object BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple) private: - static BOOST_PYTHON_DECL detail::new_reference call(object const&); + static detail::new_reference call(object const&); }; // diff --git a/src/dict.cpp b/src/dict.cpp index 6cd72c27..e24145d0 100644 --- a/src/dict.cpp +++ b/src/dict.cpp @@ -24,22 +24,22 @@ namespace } } -BOOST_PYTHON_DECL detail::new_reference dict::call(object const& arg_) +detail::new_reference dict::call(object const& arg_) { return (detail::new_reference)PyObject_CallFunction( (PyObject*)&PyDict_Type, "(O)", arg_.ptr()); } -BOOST_PYTHON_DECL dict::dict() +dict::dict() : object(detail::new_reference(PyDict_New())) {} -BOOST_PYTHON_DECL dict::dict(object_cref data) +dict::dict(object_cref data) : object(dict::call(data)) {} -BOOST_PYTHON_DECL void dict::clear() +void dict::clear() { if (check_exact(this)) PyDict_Clear(this->ptr()); @@ -47,7 +47,7 @@ BOOST_PYTHON_DECL void dict::clear() this->attr("clear")(); } -BOOST_PYTHON_DECL dict dict::copy() +dict dict::copy() { if (check_exact(this)) { @@ -62,7 +62,7 @@ BOOST_PYTHON_DECL dict dict::copy() } } -BOOST_PYTHON_DECL object dict::get(object_cref k) const +object dict::get(object_cref k) const { if (check_exact(this)) { @@ -75,17 +75,17 @@ BOOST_PYTHON_DECL object dict::get(object_cref k) const } } -BOOST_PYTHON_DECL object dict::get(object_cref k, object_cref d) const +object dict::get(object_cref k, object_cref d) const { return this->attr("get")(k,d); } -BOOST_PYTHON_DECL bool dict::has_key(object_cref k) const +bool dict::has_key(object_cref k) const { return extract(this->attr("has_key")(k)); } -BOOST_PYTHON_DECL list dict::items() const +list dict::items() const { if (check_exact(this)) { @@ -98,22 +98,22 @@ BOOST_PYTHON_DECL list dict::items() const } } -BOOST_PYTHON_DECL object dict::iteritems() const +object dict::iteritems() const { return this->attr("iteritems")(); } -BOOST_PYTHON_DECL object dict::iterkeys() const +object dict::iterkeys() const { return this->attr("iterkeys")(); } -BOOST_PYTHON_DECL object dict::itervalues() const +object dict::itervalues() const { return this->attr("itervalues")(); } -BOOST_PYTHON_DECL list dict::keys() const +list dict::keys() const { if (check_exact(this)) { @@ -126,24 +126,24 @@ BOOST_PYTHON_DECL list dict::keys() const } } -BOOST_PYTHON_DECL tuple dict::popitem() +tuple dict::popitem() { return tuple(detail::borrowed_reference( this->attr("popitem")().ptr() )); } -BOOST_PYTHON_DECL object dict::setdefault(object_cref k) +object dict::setdefault(object_cref k) { return this->attr("setdefault")(k); } -BOOST_PYTHON_DECL object dict::setdefault(object_cref k, object_cref d) +object dict::setdefault(object_cref k, object_cref d) { return this->attr("setdefault")(k,d); } -BOOST_PYTHON_DECL void dict::update(object_cref other) +void dict::update(object_cref other) { if (check_exact(this)) { @@ -156,7 +156,7 @@ BOOST_PYTHON_DECL void dict::update(object_cref other) } } -BOOST_PYTHON_DECL list dict::values() const +list dict::values() const { if (check_exact(this)) { diff --git a/src/list.cpp b/src/list.cpp index ee8bceb3..1f434320 100644 --- a/src/list.cpp +++ b/src/list.cpp @@ -7,7 +7,7 @@ namespace boost { namespace python { -BOOST_PYTHON_DECL detail::new_non_null_reference list::call(object const& arg_) +detail::new_non_null_reference list::call(object const& arg_) { return (detail::new_non_null_reference) (expect_non_null)( @@ -16,15 +16,15 @@ BOOST_PYTHON_DECL detail::new_non_null_reference list::call(object const& arg_) arg_.ptr())); } -BOOST_PYTHON_DECL list::list() +list::list() : object(detail::new_reference(PyList_New(0))) {} -BOOST_PYTHON_DECL list::list(object_cref sequence) +list::list(object_cref sequence) : object(list::call(sequence)) {} -BOOST_PYTHON_DECL void list::append(object_cref x) +void list::append(object_cref x) { if (PyList_CheckExact(this->ptr())) { @@ -37,7 +37,7 @@ BOOST_PYTHON_DECL void list::append(object_cref x) } } -BOOST_PYTHON_DECL long list::count(object_cref value) const +long list::count(object_cref value) const { object result_obj(this->attr("count")(value)); long result = PyInt_AsLong(result_obj.ptr()); @@ -46,12 +46,12 @@ BOOST_PYTHON_DECL long list::count(object_cref value) const return result; } -BOOST_PYTHON_DECL void list::extend(object_cref sequence) +void list::extend(object_cref sequence) { this->attr("extend")(sequence); } -BOOST_PYTHON_DECL long list::index(object_cref value) const +long list::index(object_cref value) const { object result_obj(this->attr("index")(value)); long result = PyInt_AsLong(result_obj.ptr()); @@ -60,7 +60,7 @@ BOOST_PYTHON_DECL long list::index(object_cref value) const return result; } -BOOST_PYTHON_DECL void list::insert(int index, object_cref item) +void list::insert(int index, object_cref item) { if (PyList_CheckExact(this->ptr())) { @@ -73,7 +73,7 @@ BOOST_PYTHON_DECL void list::insert(int index, object_cref item) } } -BOOST_PYTHON_DECL void list::insert(object const& index, object_cref x) +void list::insert(object const& index, object_cref x) { long index_ = PyInt_AsLong(index.ptr()); if (index_ == -1 && PyErr_Occurred()) @@ -81,27 +81,27 @@ BOOST_PYTHON_DECL void list::insert(object const& index, object_cref x) this->insert(index_, x); } -BOOST_PYTHON_DECL object list::pop() +object list::pop() { return this->attr("pop")(); } -BOOST_PYTHON_DECL object list::pop(long index) +object list::pop(long index) { return this->pop(object(index)); } -BOOST_PYTHON_DECL object list::pop(object const& index) +object list::pop(object const& index) { return this->attr("pop")(index); } -BOOST_PYTHON_DECL void list::remove(object_cref value) +void list::remove(object_cref value) { this->attr("remove")(value); } -BOOST_PYTHON_DECL void list::reverse() +void list::reverse() { if (PyList_CheckExact(this->ptr())) { @@ -114,7 +114,7 @@ BOOST_PYTHON_DECL void list::reverse() } } -BOOST_PYTHON_DECL void list::sort() +void list::sort() { if (PyList_CheckExact(this->ptr())) { @@ -127,7 +127,7 @@ BOOST_PYTHON_DECL void list::sort() } } -BOOST_PYTHON_DECL void list::sort(object_cref cmpfunc) +void list::sort(object_cref cmpfunc) { this->attr("sort")(cmpfunc); } diff --git a/src/long.cpp b/src/long.cpp index 2cf98610..e66d4bdd 100644 --- a/src/long.cpp +++ b/src/long.cpp @@ -7,32 +7,32 @@ namespace boost { namespace python { -BOOST_PYTHON_DECL detail::new_non_null_reference long_::call(object const& arg_) +detail::new_non_null_reference long_::call(object const& arg_) { return (detail::new_non_null_reference)PyObject_CallFunction( (PyObject*)&PyLong_Type, "(O)", arg_.ptr()); } -BOOST_PYTHON_DECL detail::new_non_null_reference long_::call(object const& arg_, object const& base) +detail::new_non_null_reference long_::call(object const& arg_, object const& base) { return (detail::new_non_null_reference)PyObject_CallFunction( (PyObject*)&PyLong_Type, "(OO)", arg_.ptr(), base.ptr()); } -BOOST_PYTHON_DECL long_::long_() +long_::long_() : object( detail::new_reference( PyObject_CallFunction((PyObject*)&PyLong_Type, "()")) ) {} -BOOST_PYTHON_DECL long_::long_(object_cref arg) +long_::long_(object_cref arg) : object(long_::call(arg)) {} -BOOST_PYTHON_DECL long_::long_(object_cref arg, object_cref base) +long_::long_(object_cref arg, object_cref base) : object(long_::call(arg, base)) {} diff --git a/src/object_operators.cpp b/src/object_operators.cpp index b7c984ef..40cdeba3 100644 --- a/src/object_operators.cpp +++ b/src/object_operators.cpp @@ -50,7 +50,7 @@ BOOST_PYTHON_INPLACE_OPERATOR(^, Xor) BOOST_PYTHON_INPLACE_OPERATOR(|, Or) #undef BOOST_PYTHON_INPLACE_OPERATOR -BOOST_PYTHON_DECL object::object(handle<> const& x) +object::object(handle<> const& x) : object_base(python::incref(python::expect_non_null(x.get()))) {} diff --git a/src/str.cpp b/src/str.cpp index f36de233..fff18221 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -3,22 +3,22 @@ namespace boost { namespace python { -BOOST_PYTHON_DECL detail::new_reference str::call(object const& arg_) +detail::new_reference str::call(object const& arg_) { return (detail::new_reference)PyObject_CallFunction( (PyObject*)&PyString_Type, "(O)", arg_.ptr()); } -BOOST_PYTHON_DECL str::str() +str::str() : object(detail::new_reference(PyString_FromString(""))) {} -BOOST_PYTHON_DECL str::str(const char* s) +str::str(const char* s) : object(detail::new_reference(PyString_FromString(s))) {} -BOOST_PYTHON_DECL str::str(object_cref other) +str::str(object_cref other) : object(str::call(other)) {} @@ -36,64 +36,64 @@ namespace return str(detail::borrowed_reference(o.ptr())); } } -BOOST_PYTHON_DECL str str::capitalize() const +str str::capitalize() const { return assume_str(this->attr("capitalize")()); } -BOOST_PYTHON_DECL str str::center(object_cref width) const +str str::center(object_cref width) const { return assume_str( this->attr("center")(width) ); } -BOOST_PYTHON_DECL long str::count(object_cref sub) const +long str::count(object_cref sub) const { return extract(this->attr("count")(sub)); } -BOOST_PYTHON_DECL long str::count(object_cref sub, object_cref start) const +long str::count(object_cref sub, object_cref start) const { return extract(this->attr("count")(sub,start)); } -BOOST_PYTHON_DECL long str::count(object_cref sub, object_cref start, object_cref end) const +long str::count(object_cref sub, object_cref start, object_cref end) const { return extract(this->attr("count")(sub,start,end)); } -BOOST_PYTHON_DECL object str::decode() const +object str::decode() const { return this->attr("decode")(); } -BOOST_PYTHON_DECL object str::decode(object_cref encoding) const +object str::decode(object_cref encoding) const { return this->attr("decode")(encoding); } -BOOST_PYTHON_DECL object str::decode(object_cref encoding, object_cref errors) const +object str::decode(object_cref encoding, object_cref errors) const { return this->attr("decode")(encoding,errors); } -BOOST_PYTHON_DECL object str::encode() const +object str::encode() const { return this->attr("encode")(); } -BOOST_PYTHON_DECL object str::encode(object_cref encoding) const +object str::encode(object_cref encoding) const { return this->attr("encode")(encoding); } -BOOST_PYTHON_DECL object str::encode(object_cref encoding, object_cref errors) const +object str::encode(object_cref encoding, object_cref errors) const { return this->attr("encode")(encoding,errors); } -BOOST_PYTHON_DECL bool str::endswith(object_cref suffix) const +bool str::endswith(object_cref suffix) const { bool result = PyInt_AsLong(this->attr("endswith")(suffix).ptr()); if (PyErr_Occurred()) @@ -101,17 +101,17 @@ BOOST_PYTHON_DECL bool str::endswith(object_cref suffix) const return result; } -BOOST_PYTHON_DECL str str::expandtabs() const +str str::expandtabs() const { return assume_str(this->attr("expandtabs")()); } -BOOST_PYTHON_DECL str str::expandtabs(object_cref tabsize) const +str str::expandtabs(object_cref tabsize) const { return assume_str(this->attr("expandtabs")(tabsize)); } -BOOST_PYTHON_DECL long str::find(object_cref sub) const +long str::find(object_cref sub) const { long result = PyInt_AsLong(this->attr("find")(sub).ptr()); if (PyErr_Occurred()) @@ -119,7 +119,7 @@ BOOST_PYTHON_DECL long str::find(object_cref sub) const return result; } -BOOST_PYTHON_DECL long str::find(object_cref sub, object_cref start) const +long str::find(object_cref sub, object_cref start) const { long result = PyInt_AsLong(this->attr("find")(sub,start).ptr()); if (PyErr_Occurred()) @@ -127,7 +127,7 @@ BOOST_PYTHON_DECL long str::find(object_cref sub, object_cref start) const return result; } -BOOST_PYTHON_DECL long str::find(object_cref sub, object_cref start, object_cref end) const +long str::find(object_cref sub, object_cref start, object_cref end) const { long result = PyInt_AsLong(this->attr("find")(sub,start,end).ptr()); if (PyErr_Occurred()) @@ -135,7 +135,7 @@ BOOST_PYTHON_DECL long str::find(object_cref sub, object_cref start, object_cref return result; } -BOOST_PYTHON_DECL long str::index(object_cref sub) const +long str::index(object_cref sub) const { long result = PyInt_AsLong(this->attr("index")(sub).ptr()); if (PyErr_Occurred()) @@ -143,7 +143,7 @@ BOOST_PYTHON_DECL long str::index(object_cref sub) const return result; } -BOOST_PYTHON_DECL long str::index(object_cref sub, object_cref start) const +long str::index(object_cref sub, object_cref start) const { long result = PyInt_AsLong(this->attr("index")(sub,start).ptr()); if (PyErr_Occurred()) @@ -151,7 +151,7 @@ BOOST_PYTHON_DECL long str::index(object_cref sub, object_cref start) const return result; } -BOOST_PYTHON_DECL long str::index(object_cref sub, object_cref start, object_cref end) const +long str::index(object_cref sub, object_cref start, object_cref end) const { long result = PyInt_AsLong(this->attr("index")(sub,start,end).ptr()); if (PyErr_Occurred()) @@ -159,7 +159,7 @@ BOOST_PYTHON_DECL long str::index(object_cref sub, object_cref start, object_cre return result; } -BOOST_PYTHON_DECL bool str::isalnum() const +bool str::isalnum() const { bool result = PyInt_AsLong(this->attr("isalnum")().ptr()); if (PyErr_Occurred()) @@ -167,7 +167,7 @@ BOOST_PYTHON_DECL bool str::isalnum() const return result; } -BOOST_PYTHON_DECL bool str::isalpha() const +bool str::isalpha() const { bool result = PyInt_AsLong(this->attr("isalpha")().ptr()); if (PyErr_Occurred()) @@ -175,7 +175,7 @@ BOOST_PYTHON_DECL bool str::isalpha() const return result; } -BOOST_PYTHON_DECL bool str::isdigit() const +bool str::isdigit() const { bool result = PyInt_AsLong(this->attr("isdigit")().ptr()); if (PyErr_Occurred()) @@ -183,7 +183,7 @@ BOOST_PYTHON_DECL bool str::isdigit() const return result; } -BOOST_PYTHON_DECL bool str::islower() const +bool str::islower() const { bool result = PyInt_AsLong(this->attr("islower")().ptr()); if (PyErr_Occurred()) @@ -191,7 +191,7 @@ BOOST_PYTHON_DECL bool str::islower() const return result; } -BOOST_PYTHON_DECL bool str::isspace() const +bool str::isspace() const { bool result = PyInt_AsLong(this->attr("isspace")().ptr()); if (PyErr_Occurred()) @@ -199,7 +199,7 @@ BOOST_PYTHON_DECL bool str::isspace() const return result; } -BOOST_PYTHON_DECL bool str::istitle() const +bool str::istitle() const { bool result = PyInt_AsLong(this->attr("istitle")().ptr()); if (PyErr_Occurred()) @@ -207,7 +207,7 @@ BOOST_PYTHON_DECL bool str::istitle() const return result; } -BOOST_PYTHON_DECL bool str::isupper() const +bool str::isupper() const { bool result = PyInt_AsLong(this->attr("isupper")().ptr()); if (PyErr_Occurred()) @@ -215,36 +215,36 @@ BOOST_PYTHON_DECL bool str::isupper() const return result; } -BOOST_PYTHON_DECL str str::join(object_cref sequence) const +str str::join(object_cref sequence) const { return assume_str(this->attr("join")(sequence)); } -BOOST_PYTHON_DECL str str::ljust(object_cref width) const +str str::ljust(object_cref width) const { return assume_str(this->attr("ljust")(width)); } -BOOST_PYTHON_DECL str str::lower() const +str str::lower() const { return assume_str(this->attr("lower")()); } -BOOST_PYTHON_DECL str str::lstrip() const +str str::lstrip() const { return assume_str(this->attr("lstrip")()); } -BOOST_PYTHON_DECL str str::replace(object_cref old, object_cref new_) const +str str::replace(object_cref old, object_cref new_) const { return assume_str(this->attr("replace")(old,new_)); } -BOOST_PYTHON_DECL str str::replace(object_cref old, object_cref new_, object_cref maxsplit) const { +str str::replace(object_cref old, object_cref new_, object_cref maxsplit) const { return assume_str(this->attr("replace")(old,new_,maxsplit)); } -BOOST_PYTHON_DECL long str::rfind(object_cref sub) const +long str::rfind(object_cref sub) const { long result = PyInt_AsLong(this->attr("rfind")(sub).ptr()); if (PyErr_Occurred()) @@ -252,7 +252,7 @@ BOOST_PYTHON_DECL long str::rfind(object_cref sub) const return result; } -BOOST_PYTHON_DECL long str::rfind(object_cref sub, object_cref start) const +long str::rfind(object_cref sub, object_cref start) const { long result = PyInt_AsLong(this->attr("rfind")(sub,start).ptr()); if (PyErr_Occurred()) @@ -260,7 +260,7 @@ BOOST_PYTHON_DECL long str::rfind(object_cref sub, object_cref start) const return result; } -BOOST_PYTHON_DECL long str::rfind(object_cref sub, object_cref start, object_cref end) const +long str::rfind(object_cref sub, object_cref start, object_cref end) const { long result = PyInt_AsLong(this->attr("rfind")(sub,start,end).ptr()); if (PyErr_Occurred()) @@ -268,7 +268,7 @@ BOOST_PYTHON_DECL long str::rfind(object_cref sub, object_cref start, object_cre return result; } -BOOST_PYTHON_DECL long str::rindex(object_cref sub) const +long str::rindex(object_cref sub) const { long result = PyInt_AsLong(this->attr("rindex")(sub).ptr()); if (PyErr_Occurred()) @@ -276,7 +276,7 @@ BOOST_PYTHON_DECL long str::rindex(object_cref sub) const return result; } -BOOST_PYTHON_DECL long str::rindex(object_cref sub, object_cref start) const +long str::rindex(object_cref sub, object_cref start) const { long result = PyInt_AsLong(this->attr("rindex")(sub,start).ptr()); if (PyErr_Occurred()) @@ -284,7 +284,7 @@ BOOST_PYTHON_DECL long str::rindex(object_cref sub, object_cref start) const return result; } -BOOST_PYTHON_DECL long str::rindex(object_cref sub, object_cref start, object_cref end) const +long str::rindex(object_cref sub, object_cref start, object_cref end) const { long result = PyInt_AsLong(this->attr("rindex")(sub,start,end).ptr()); if (PyErr_Occurred()) @@ -292,42 +292,42 @@ BOOST_PYTHON_DECL long str::rindex(object_cref sub, object_cref start, object_cr return result; } -BOOST_PYTHON_DECL str str::rjust(object_cref width) const +str str::rjust(object_cref width) const { return assume_str(this->attr("rjust")(width)); } -BOOST_PYTHON_DECL str str::rstrip() const +str str::rstrip() const { return assume_str(this->attr("rstrip")()); } -BOOST_PYTHON_DECL list str::split() const +list str::split() const { return list(this->attr("split")()); } -BOOST_PYTHON_DECL list str::split(object_cref sep) const +list str::split(object_cref sep) const { return list(this->attr("split")(sep)); } -BOOST_PYTHON_DECL list str::split(object_cref sep, object_cref maxsplit) const +list str::split(object_cref sep, object_cref maxsplit) const { return list(this->attr("split")(sep,maxsplit)); } -BOOST_PYTHON_DECL list str::splitlines() const +list str::splitlines() const { return list(this->attr("splitlines")()); } -BOOST_PYTHON_DECL list str::splitlines(object_cref keepends) const +list str::splitlines(object_cref keepends) const { return list(this->attr("splitlines")(keepends)); } -BOOST_PYTHON_DECL bool str::startswith(object_cref prefix) const +bool str::startswith(object_cref prefix) const { bool result = PyInt_AsLong(this->attr("startswith")(prefix).ptr()); if (PyErr_Occurred()) @@ -335,7 +335,7 @@ BOOST_PYTHON_DECL bool str::startswith(object_cref prefix) const return result; } -BOOST_PYTHON_DECL bool str::startswith(object_cref prefix, object_cref start) const +bool str::startswith(object_cref prefix, object_cref start) const { bool result = PyInt_AsLong(this->attr("startswith")(prefix,start).ptr()); if (PyErr_Occurred()) @@ -343,7 +343,7 @@ BOOST_PYTHON_DECL bool str::startswith(object_cref prefix, object_cref start) co return result; } -BOOST_PYTHON_DECL bool str::startswith(object_cref prefix, object_cref start, object_cref end) const +bool str::startswith(object_cref prefix, object_cref start, object_cref end) const { bool result = PyInt_AsLong(this->attr("startswith")(prefix,start,end).ptr()); if (PyErr_Occurred()) @@ -351,32 +351,32 @@ BOOST_PYTHON_DECL bool str::startswith(object_cref prefix, object_cref start, ob return result; } -BOOST_PYTHON_DECL str str::strip() const +str str::strip() const { return assume_str(this->attr("strip")()); } -BOOST_PYTHON_DECL str str::swapcase() const +str str::swapcase() const { return assume_str(this->attr("swapcase")()); } -BOOST_PYTHON_DECL str str::title() const +str str::title() const { return assume_str(this->attr("title")()); } -BOOST_PYTHON_DECL str str::translate(object_cref table) const +str str::translate(object_cref table) const { return assume_str(this->attr("translate")(table)); } -BOOST_PYTHON_DECL str str::translate(object_cref table, object_cref deletechars) const +str str::translate(object_cref table, object_cref deletechars) const { return assume_str(this->attr("translate")(table,deletechars)); } -BOOST_PYTHON_DECL str str::upper() const +str str::upper() const { return assume_str(this->attr("upper")()); } diff --git a/src/tuple.cpp b/src/tuple.cpp index d6a33a56..16b8e773 100644 --- a/src/tuple.cpp +++ b/src/tuple.cpp @@ -2,18 +2,18 @@ namespace boost { namespace python { -BOOST_PYTHON_DECL detail::new_reference tuple::call(object const& arg_) +detail::new_reference tuple::call(object const& arg_) { return (detail::new_reference)PyObject_CallFunction( (PyObject*)&PyTuple_Type, "(O)", arg_.ptr()); } -BOOST_PYTHON_DECL tuple::tuple() +tuple::tuple() : object(detail::new_reference(PyTuple_New(0))) {} -BOOST_PYTHON_DECL tuple::tuple(object_cref sequence) +tuple::tuple(object_cref sequence) : object(tuple::call(sequence)) {} From 2dbb0093c164e6a7caaa61bde54da0fe1b65cda9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 13 Sep 2002 01:48:50 +0000 Subject: [PATCH 0730/1042] PP usage speedups (mostly for EDG) [SVN r15286] --- include/boost/python/call.hpp | 4 ++-- include/boost/python/call_method.hpp | 4 ++-- include/boost/python/detail/defaults_gen.hpp | 20 +++++++++---------- include/boost/python/detail/make_tuple.hpp | 2 +- include/boost/python/detail/returning.hpp | 16 +++++++-------- include/boost/python/init.hpp | 4 ++-- include/boost/python/object/make_holder.hpp | 4 ++-- .../boost/python/object/pointer_holder.hpp | 4 ++-- include/boost/python/object/value_holder.hpp | 4 ++-- 9 files changed, 31 insertions(+), 31 deletions(-) diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp index 6ce027ef..4edceee3 100644 --- a/include/boost/python/call.hpp +++ b/include/boost/python/call.hpp @@ -54,8 +54,8 @@ call(PyObject* callable return converter( PyEval_CallFunction( callable - , const_cast("(" BOOST_PP_REPEAT(N, BOOST_PYTHON_FIXED, "O") ")") - BOOST_PP_REPEAT(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) + , const_cast("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")") + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) )); } diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp index 7c8f0e90..e8917c22 100644 --- a/include/boost/python/call_method.hpp +++ b/include/boost/python/call_method.hpp @@ -54,8 +54,8 @@ call_method(PyObject* self, char const* name PyEval_CallMethod( self , const_cast(name) - , const_cast("(" BOOST_PP_REPEAT(N, BOOST_PYTHON_FIXED, "O") ")") - BOOST_PP_REPEAT(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) + , const_cast("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")") + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) )); } diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index b1ed0125..3198baa2 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -41,21 +41,21 @@ struct func_stubs_base {}; #define BPL_IMPL_TYPEDEF_GEN(z, INDEX, DATA) \ typedef typename boost::python::detail::type_at \ < \ - BOOST_PP_ADD(INDEX, DATA), \ + 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(BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), T, arg) \ + 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(BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), \ + BOOST_PP_ADD_D(1, BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), \ arg \ ) \ ); \ @@ -83,7 +83,7 @@ struct func_stubs_base {}; ( \ BOOST_PP_INC(N_DFLTS), \ BPL_IMPL_FUNC_WRAPPER_GEN, \ - (FNAME, BOOST_PP_SUB(N_ARGS, N_DFLTS), RETURN) \ + (FNAME, BOOST_PP_SUB_D(1, N_ARGS, N_DFLTS), RETURN) \ ) \ }; \ }; \ @@ -92,14 +92,14 @@ struct func_stubs_base {}; #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(BOOST_PP_TUPLE_ELEM(3, 1, DATA), index)) \ + BOOST_PP_ADD_D(1, BOOST_PP_TUPLE_ELEM(3, 1, DATA), index)) \ BOOST_PYTHON_BINARY_ENUM( \ - BOOST_PP_ADD(BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), T, arg) \ + BOOST_PP_ADD_D(1, BOOST_PP_TUPLE_ELEM(3, 1, DATA), 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(BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), arg \ + BOOST_PP_ADD_D(1, BOOST_PP_TUPLE_ELEM(3, 1, DATA), index), arg \ ) \ ); \ } @@ -127,7 +127,7 @@ struct func_stubs_base {}; ( \ BOOST_PP_INC(N_DFLTS), \ BPL_IMPL_MEM_FUNC_WRAPPER_GEN, \ - (FNAME, BOOST_PP_SUB(N_ARGS, N_DFLTS), RETURN) \ + (FNAME, BOOST_PP_SUB_D(1, N_ARGS, N_DFLTS), RETURN) \ ) \ }; \ }; @@ -265,7 +265,7 @@ struct func_stubs_base {}; FNAME, \ GENERATOR_NAME, \ MAX_ARGS, \ - BOOST_PP_SUB(MAX_ARGS, MIN_ARGS) \ + BOOST_PP_SUB_D(1, MAX_ARGS, MIN_ARGS) \ ) #define BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(GENERATOR_NAME, FNAME, MIN_ARGS, MAX_ARGS) \ @@ -274,7 +274,7 @@ struct func_stubs_base {}; FNAME, \ GENERATOR_NAME, \ MAX_ARGS, \ - BOOST_PP_SUB(MAX_ARGS, MIN_ARGS) \ + BOOST_PP_SUB_D(1, MAX_ARGS, MIN_ARGS) \ ) // deprecated macro names (to be removed) diff --git a/include/boost/python/detail/make_tuple.hpp b/include/boost/python/detail/make_tuple.hpp index 41fcaa37..07cd9903 100644 --- a/include/boost/python/detail/make_tuple.hpp +++ b/include/boost/python/detail/make_tuple.hpp @@ -22,7 +22,7 @@ make_tuple(BOOST_PYTHON_BINARY_ENUM(N, A, const& a)) { tuple result((detail::new_reference)::PyTuple_New(N)); - BOOST_PP_REPEAT(N, BOOST_PYTHON_MAKE_TUPLE_ARG, _) + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_MAKE_TUPLE_ARG, _) return result; } diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 495a8564..9ab87c43 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -96,7 +96,7 @@ struct returning , PyObject*, P const* policies) { // check that each of the arguments is convertible - BOOST_PP_REPEAT(N, BOOST_PYTHON_CHECK_CONVERSION, nil) + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil) // find the result converter typedef typename P::result_converter result_converter; @@ -104,7 +104,7 @@ struct returning if (!cr.convertible() || !policies->precall(args_)) return 0; PyObject* result = cr( - (*pf)(BOOST_PP_REPEAT(N, BOOST_PYTHON_CALL_ARGS, nil)) + (*pf)(BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil)) ); return policies->postcall(args_, result); } @@ -117,11 +117,11 @@ struct returning , PyObject*, P const* policies) { // check that each of the arguments is convertible - BOOST_PP_REPEAT(N, BOOST_PYTHON_CHECK_CONVERSION, nil) + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil) if (!policies->precall(args_)) return 0; - (*pf)(BOOST_PP_REPEAT(N, BOOST_PYTHON_CALL_ARGS, nil)); + (*pf)(BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil)); return policies->postcall(args_, detail::none()); } # endif // returning void / non-void @@ -168,7 +168,7 @@ struct returning return 0; // unroll a loop for the rest of them - BOOST_PP_REPEAT(N, BOOST_PYTHON_CHECK_CONVERSION, nil) + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil) // find the result converter typedef typename P::result_converter result_converter; @@ -177,7 +177,7 @@ struct returning return 0; PyObject* result = cr( ((ct(PyTuple_GET_ITEM(args_, 0))).*pmf)( - BOOST_PP_REPEAT(N, BOOST_PYTHON_CALL_ARGS, nil)) + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil)) ); return policies->postcall(args_, result); } @@ -196,13 +196,13 @@ struct returning return 0; // unroll a loop for the rest of them - BOOST_PP_REPEAT(N, BOOST_PYTHON_CHECK_CONVERSION, nil) + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil) if (!policies->precall(args_)) return 0; ((ct(PyTuple_GET_ITEM(args_, 0))).*pmf)( - BOOST_PP_REPEAT(N, BOOST_PYTHON_CALL_ARGS, nil)); + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil)); return policies->postcall(args_, detail::none()); } # endif diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 03625a1b..567e480a 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -310,8 +310,8 @@ template struct init : detail::check_init_params { typedef boost::mpl::type_list l0; - BOOST_PP_REPEAT - (BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY), BOOST_PYTHON_APPEND_TO_INIT, 0) + BOOST_PP_REPEAT_1ST( + BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY), BOOST_PYTHON_APPEND_TO_INIT, 0) typedef BOOST_PP_CAT(l, BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY)) sequence; diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 429704a3..3073e83b 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -56,7 +56,7 @@ struct make_holder template struct apply { - BOOST_PP_REPEAT(N, BOOST_PYTHON_FORWARD_ARG, nil) + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FORWARD_ARG, nil) static void execute( PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, t, a)) @@ -66,7 +66,7 @@ struct make_holder void* memory = Holder::allocate(p, offsetof(instance_t, storage), sizeof(Holder)); try { (new (memory) Holder( - p BOOST_PP_REPEAT(N, BOOST_PYTHON_DO_FORWARD_ARG, nil)))->install(p); + p BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_DO_FORWARD_ARG, nil)))->install(p); } catch(...) { Holder::deallocate(p, memory); diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 9ead5d94..1fe20ef3 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -131,7 +131,7 @@ void* pointer_holder_back_reference::holds(type_info dst_t) # endif pointer_holder(PyObject* BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) : m_p(new Value( - BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) )) {} @@ -149,7 +149,7 @@ void* pointer_holder_back_reference::holds(type_info dst_t) pointer_holder_back_reference( PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) : m_p(new held_type( - p BOOST_PP_COMMA_IF(N) BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) + p BOOST_PP_COMMA_IF(N) BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) )) {} diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index ea751edc..d40d058d 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -101,7 +101,7 @@ void* value_holder_back_reference::holds( value_holder( PyObject* BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) : m_held( - BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) ) {} @@ -121,7 +121,7 @@ void* value_holder_back_reference::holds( PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) : m_held( p BOOST_PP_COMMA_IF(N) - BOOST_PP_REPEAT(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) + BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) ) { } From 14cca4610bcf41aa97bc318015b41bf40a870860 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 13 Sep 2002 05:46:46 +0000 Subject: [PATCH 0731/1042] workaround for older EDG compilers (IRIX CC) [SVN r15292] --- include/boost/python/enum.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/boost/python/enum.hpp b/include/boost/python/enum.hpp index f7d06075..072a0626 100644 --- a/include/boost/python/enum.hpp +++ b/include/boost/python/enum.hpp @@ -15,6 +15,8 @@ namespace boost { namespace python { template struct enum_ : public objects::enum_base { + typedef objects::enum_base base; + enum_(char const* name); inline enum_& value(char const* name, T); @@ -26,7 +28,7 @@ struct enum_ : public objects::enum_base template inline enum_::enum_(char const* name) - : enum_base( + : base( name , &enum_::to_python , &enum_::convertible @@ -39,7 +41,7 @@ inline enum_::enum_(char const* name) template PyObject* enum_::to_python(void const* x) { - return enum_base::to_python( + return base::to_python( converter::registered::converters.class_object , static_cast(*(T const*)x)); } From 5923e20b7e217cd2dfb9cbb2ef1d09ea88899922 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 13 Sep 2002 22:57:04 +0000 Subject: [PATCH 0732/1042] Roll back MinGW 2.0 "fix" that still doesn't work, and breaks MSVC6. [SVN r15313] --- include/boost/python/dict.hpp | 38 +++++----- include/boost/python/list.hpp | 34 ++++----- include/boost/python/long.hpp | 12 ++-- include/boost/python/str.hpp | 124 ++++++++++++++++----------------- include/boost/python/tuple.hpp | 8 +-- 5 files changed, 108 insertions(+), 108 deletions(-) diff --git a/include/boost/python/dict.hpp b/include/boost/python/dict.hpp index 58d4635d..b593f902 100644 --- a/include/boost/python/dict.hpp +++ b/include/boost/python/dict.hpp @@ -8,15 +8,15 @@ namespace boost { namespace python { -class BOOST_PYTHON_DECL dict : public object +class dict : public object { public: // dict() -> new empty dictionary. // dict(mapping) -> new dictionary initialized from a mapping object's // (key, value) pairs. // dict(seq) -> new dictionary initialized as if via: - dict(); // new dict - explicit dict(object_cref data); + BOOST_PYTHON_DECL dict(); // new dict + explicit BOOST_PYTHON_DECL dict(object_cref data); template explicit dict(T const& data) @@ -25,13 +25,13 @@ class BOOST_PYTHON_DECL dict : public object } // D.clear() -> None. Remove all items from D. - void clear(); + BOOST_PYTHON_DECL void clear(); // D.copy() -> a shallow copy of D - dict copy(); + BOOST_PYTHON_DECL dict copy(); // D.get(k[,d]) -> D[k] if D.has_key(k), else d. d defaults to None. - object get(object_cref k) const; + BOOST_PYTHON_DECL object get(object_cref k) const; template object get(T const& k) const @@ -39,7 +39,7 @@ class BOOST_PYTHON_DECL dict : public object return this->get(object(k)); } - object get(object_cref k, object_cref d) const; + BOOST_PYTHON_DECL object get(object_cref k, object_cref d) const; template object get(T1 const& k, T2 const& d) const @@ -48,7 +48,7 @@ class BOOST_PYTHON_DECL dict : public object } // D.has_key(k) -> 1 if D has a key k, else 0 - bool has_key(object_cref k) const; + BOOST_PYTHON_DECL bool has_key(object_cref k) const; template bool has_key(T const& k) const @@ -57,26 +57,26 @@ class BOOST_PYTHON_DECL dict : public object } // D.items() -> list of D's (key, value) pairs, as 2-tuples - list items() const; + BOOST_PYTHON_DECL list items() const; // D.iteritems() -> an iterator over the (key, value) items of D - object iteritems() const; + BOOST_PYTHON_DECL object iteritems() const; // D.iterkeys() -> an iterator over the keys of D - object iterkeys() const; + BOOST_PYTHON_DECL object iterkeys() const; // D.itervalues() -> an iterator over the values of D - object itervalues() const; + BOOST_PYTHON_DECL object itervalues() const; // D.keys() -> list of D's keys - list keys() const; + BOOST_PYTHON_DECL list keys() const; // D.popitem() -> (k, v), remove and return some (key, value) pair as a // 2-tuple; but raise KeyError if D is empty - tuple popitem(); + BOOST_PYTHON_DECL tuple popitem(); // D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if not D.has_key(k) - object setdefault(object_cref k); + BOOST_PYTHON_DECL object setdefault(object_cref k); template object setdefault(T const& k) @@ -84,7 +84,7 @@ class BOOST_PYTHON_DECL dict : public object return this->setdefault(object(k)); } - object setdefault(object_cref k, object_cref d); + BOOST_PYTHON_DECL object setdefault(object_cref k, object_cref d); template object setdefault(T1 const& k, T2 const& d) @@ -93,7 +93,7 @@ class BOOST_PYTHON_DECL dict : public object } // D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k] - void update(object_cref E); + BOOST_PYTHON_DECL void update(object_cref E); template void update(T const& E) @@ -102,13 +102,13 @@ class BOOST_PYTHON_DECL dict : public object } // D.values() -> list of D's values - list values() const; + BOOST_PYTHON_DECL list values() const; public: // implementation detail -- for internal use only BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict) private: - static detail::new_reference call(object const&); + static BOOST_PYTHON_DECL detail::new_reference call(object const&); }; diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp index f851a7f1..501eeed5 100644 --- a/include/boost/python/list.hpp +++ b/include/boost/python/list.hpp @@ -11,11 +11,11 @@ namespace boost { namespace python { -class BOOST_PYTHON_DECL list : public object +class list : public object { public: - list(); // new list - explicit list(object_cref sequence); // new list initialized from sequence's items + BOOST_PYTHON_DECL list(); // new list + explicit BOOST_PYTHON_DECL list(object_cref sequence); // new list initialized from sequence's items template explicit list(T const& sequence) @@ -23,7 +23,7 @@ class BOOST_PYTHON_DECL list : public object { } - void append(object_cref); // append object to end + BOOST_PYTHON_DECL void append(object_cref); // append object to end template void append(T const& x) @@ -31,7 +31,7 @@ class BOOST_PYTHON_DECL list : public object this->append(object(x)); } - long count(object_cref value) const; // return number of occurrences of value + BOOST_PYTHON_DECL long count(object_cref value) const; // return number of occurrences of value template long count(T const& value) const @@ -39,7 +39,7 @@ class BOOST_PYTHON_DECL list : public object return this->count(object(value)); } - void extend(object_cref sequence); // extend list by appending sequence elements + BOOST_PYTHON_DECL void extend(object_cref sequence); // extend list by appending sequence elements template void extend(T const& x) @@ -47,7 +47,7 @@ class BOOST_PYTHON_DECL list : public object this->extend(object(x)); } - long index(object_cref value) const; // return index of first occurrence of value + BOOST_PYTHON_DECL long index(object_cref value) const; // return index of first occurrence of value template long index(T const& x) const @@ -55,8 +55,8 @@ class BOOST_PYTHON_DECL list : public object return this->index(object(x)); } - void insert(int index, object_cref); // insert object before index - void insert(object const& index, object_cref); + BOOST_PYTHON_DECL void insert(int index, object_cref); // insert object before index + BOOST_PYTHON_DECL void insert(object const& index, object_cref); template void insert(int index, T const& x) // insert object before index @@ -70,11 +70,11 @@ class BOOST_PYTHON_DECL list : public object this->insert(index, object(x)); } - object pop(); // remove and return item at index (default last) - object pop(long index); - object pop(object const& index); + BOOST_PYTHON_DECL object pop(); // remove and return item at index (default last) + BOOST_PYTHON_DECL object pop(long index); + BOOST_PYTHON_DECL object pop(object const& index); - void remove(object_cref value); // remove first occurrence of value + BOOST_PYTHON_DECL void remove(object_cref value); // remove first occurrence of value template void remove(T const& value) @@ -82,10 +82,10 @@ class BOOST_PYTHON_DECL list : public object this->remove(object(value)); } - void reverse(); // reverse *IN PLACE* + BOOST_PYTHON_DECL void reverse(); // reverse *IN PLACE* - void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1 - void sort(object_cref cmpfunc); + BOOST_PYTHON_DECL void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1 + BOOST_PYTHON_DECL void sort(object_cref cmpfunc); template void sort(T const& value) @@ -97,7 +97,7 @@ class BOOST_PYTHON_DECL list : public object BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list) private: - static detail::new_non_null_reference call(object const&); + static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&); }; // diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp index 690a630b..3ba4f434 100644 --- a/include/boost/python/long.hpp +++ b/include/boost/python/long.hpp @@ -11,11 +11,11 @@ namespace boost { namespace python { -class BOOST_PYTHON_DECL long_ : public object +class long_ : public object { public: - long_(); // new long_ - explicit long_(object_cref rhs); + BOOST_PYTHON_DECL long_(); // new long_ + explicit BOOST_PYTHON_DECL long_(object_cref rhs); template explicit long_(T const& rhs) @@ -23,7 +23,7 @@ class BOOST_PYTHON_DECL long_ : public object { } - explicit long_(object_cref rhs, object_cref base); + explicit BOOST_PYTHON_DECL long_(object_cref rhs, object_cref base); template explicit long_(T const& rhs, U const& base) @@ -34,8 +34,8 @@ class BOOST_PYTHON_DECL long_ : public object BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_) private: - static detail::new_non_null_reference call(object const&); - static detail::new_non_null_reference call(object const&, object const&); + static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&); + static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&, object const&); }; // diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index 2a0e0e97..fb8bfe58 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -15,13 +15,13 @@ namespace boost { namespace python { -class BOOST_PYTHON_DECL str : public object +class str : public object { public: - str(); // new str + BOOST_PYTHON_DECL str(); // new str - str(const char* s); // new str - explicit str(object_cref other); + BOOST_PYTHON_DECL str(const char* s); // new str + explicit BOOST_PYTHON_DECL str(object_cref other); template explicit str(T const& other) @@ -29,9 +29,9 @@ class BOOST_PYTHON_DECL str : public object { } - str capitalize() const ; + BOOST_PYTHON_DECL str capitalize() const ; - str center(object_cref width) const ; + BOOST_PYTHON_DECL str center(object_cref width) const ; template str center(T const& width) const @@ -39,7 +39,7 @@ class BOOST_PYTHON_DECL str : public object return this->center(object(width)); } - long count(object_cref sub) const; + BOOST_PYTHON_DECL long count(object_cref sub) const; template long count(T const& sub) const @@ -47,7 +47,7 @@ class BOOST_PYTHON_DECL str : public object return this->count(object(sub)); } - long count(object_cref sub, object_cref start) const; + BOOST_PYTHON_DECL long count(object_cref sub, object_cref start) const; template long count(T1 const& sub,T2 const& start) const @@ -55,7 +55,7 @@ class BOOST_PYTHON_DECL str : public object return this->count(object(sub), object(start)); } - long count(object_cref sub, object_cref start, object_cref end) const; + BOOST_PYTHON_DECL long count(object_cref sub, object_cref start, object_cref end) const; template long count(T1 const& sub,T2 const& start, T3 const& end) const @@ -63,8 +63,8 @@ class BOOST_PYTHON_DECL str : public object return this->count(object(sub), object(start)); } - object decode() const; - object decode(object_cref encoding) const; + BOOST_PYTHON_DECL object decode() const; + BOOST_PYTHON_DECL object decode(object_cref encoding) const; template object decode(T const& encoding) const @@ -72,7 +72,7 @@ class BOOST_PYTHON_DECL str : public object return this->decode(object(encoding)); } - object decode(object_cref encoding, object_cref errors) const; + BOOST_PYTHON_DECL object decode(object_cref encoding, object_cref errors) const; template object decode(T1 const& encoding, T2 const& errors) const @@ -80,8 +80,8 @@ class BOOST_PYTHON_DECL str : public object return this->decode(object(encoding),object(errors)); } - object encode() const; - object encode(object_cref encoding) const; + BOOST_PYTHON_DECL object encode() const; + BOOST_PYTHON_DECL object encode(object_cref encoding) const; template object encode(T const& encoding) const @@ -89,7 +89,7 @@ class BOOST_PYTHON_DECL str : public object return this->encode(object(encoding)); } - object encode(object_cref encoding, object_cref errors) const; + BOOST_PYTHON_DECL object encode(object_cref encoding, object_cref errors) const; template object encode(T1 const& encoding, T2 const& errors) const @@ -97,7 +97,7 @@ class BOOST_PYTHON_DECL str : public object return this->encode(object(encoding),object(errors)); } - bool endswith(object_cref suffix) const; + BOOST_PYTHON_DECL bool endswith(object_cref suffix) const; template bool endswith(T const& suffix) const @@ -105,7 +105,7 @@ class BOOST_PYTHON_DECL str : public object return this->endswith(object(suffix)); } - bool endswith(object_cref suffix, object_cref start) const; + BOOST_PYTHON_DECL bool endswith(object_cref suffix, object_cref start) const; template bool endswith(T1 const& suffix, T2 const& start) const @@ -113,7 +113,7 @@ class BOOST_PYTHON_DECL str : public object return this->endswith(object(suffix), object(start)); } - bool endswith(object_cref suffix, object_cref start, object_cref end) const; + BOOST_PYTHON_DECL bool endswith(object_cref suffix, object_cref start, object_cref end) const; template bool endswith(T1 const& suffix, T2 const& start, T3 const& end) const @@ -121,8 +121,8 @@ class BOOST_PYTHON_DECL str : public object return this->endswith(object(suffix), object(start), object(end)); } - str expandtabs() const; - str expandtabs(object_cref tabsize) const; + BOOST_PYTHON_DECL str expandtabs() const; + BOOST_PYTHON_DECL str expandtabs(object_cref tabsize) const; template str expandtabs(T const& tabsize) const @@ -130,7 +130,7 @@ class BOOST_PYTHON_DECL str : public object return this->expandtabs(object(tabsize)); } - long find(object_cref sub) const; + BOOST_PYTHON_DECL long find(object_cref sub) const; template long find(T const& sub) const @@ -138,7 +138,7 @@ class BOOST_PYTHON_DECL str : public object return this->find(object(sub)); } - long find(object_cref sub, object_cref start) const; + BOOST_PYTHON_DECL long find(object_cref sub, object_cref start) const; template long find(T1 const& sub, T2 const& start) const @@ -146,7 +146,7 @@ class BOOST_PYTHON_DECL str : public object return this->find(object(sub), object(start)); } - long find(object_cref sub, object_cref start, object_cref end) const; + BOOST_PYTHON_DECL long find(object_cref sub, object_cref start, object_cref end) const; template long find(T1 const& sub, T2 const& start, T3 const& end) const @@ -154,7 +154,7 @@ class BOOST_PYTHON_DECL str : public object return this->find(object(sub), object(start), object(end)); } - long index(object_cref sub) const; + BOOST_PYTHON_DECL long index(object_cref sub) const; template long index(T const& sub) const @@ -162,7 +162,7 @@ class BOOST_PYTHON_DECL str : public object return this->index(object(sub)); } - long index(object_cref sub, object_cref start) const; + BOOST_PYTHON_DECL long index(object_cref sub, object_cref start) const; template long index(T1 const& sub, T2 const& start) const @@ -170,7 +170,7 @@ class BOOST_PYTHON_DECL str : public object return this->index(object(sub), object(start)); } - long index(object_cref sub, object_cref start, object_cref end) const; + BOOST_PYTHON_DECL long index(object_cref sub, object_cref start, object_cref end) const; template long index(T1 const& sub, T2 const& start, T3 const& end) const @@ -178,15 +178,15 @@ class BOOST_PYTHON_DECL str : public object return this->index(object(sub), object(start), object(end)); } - bool isalnum() const; - bool isalpha() const; - bool isdigit() const; - bool islower() const; - bool isspace() const; - bool istitle() const; - bool isupper() const; + BOOST_PYTHON_DECL bool isalnum() const; + BOOST_PYTHON_DECL bool isalpha() const; + BOOST_PYTHON_DECL bool isdigit() const; + BOOST_PYTHON_DECL bool islower() const; + BOOST_PYTHON_DECL bool isspace() const; + BOOST_PYTHON_DECL bool istitle() const; + BOOST_PYTHON_DECL bool isupper() const; - str join(object_cref sequence) const; + BOOST_PYTHON_DECL str join(object_cref sequence) const; template str join(T const& sequence) const @@ -194,7 +194,7 @@ class BOOST_PYTHON_DECL str : public object return this->join(object(sequence)); } - str ljust(object_cref width) const; + BOOST_PYTHON_DECL str ljust(object_cref width) const; template str ljust(T const& width) const @@ -202,10 +202,10 @@ class BOOST_PYTHON_DECL str : public object return this->ljust(object(width)); } - str lower() const; - str lstrip() const; + BOOST_PYTHON_DECL str lower() const; + BOOST_PYTHON_DECL str lstrip() const; - str replace(object_cref old, object_cref new_) const ; + BOOST_PYTHON_DECL str replace(object_cref old, object_cref new_) const ; template str replace(T1 const& old, T2 const& new_) const @@ -213,7 +213,7 @@ class BOOST_PYTHON_DECL str : public object return this->replace(object(old),object(new_)); } - str replace(object_cref old, object_cref new_, object_cref maxsplit) const ; + BOOST_PYTHON_DECL str replace(object_cref old, object_cref new_, object_cref maxsplit) const ; template str replace(T1 const& old, T2 const& new_, T3 const& maxsplit) const @@ -221,7 +221,7 @@ class BOOST_PYTHON_DECL str : public object return this->replace(object(old),object(new_),object(maxsplit)); } - long rfind(object_cref sub) const; + BOOST_PYTHON_DECL long rfind(object_cref sub) const; template long rfind(T const& sub) const @@ -229,7 +229,7 @@ class BOOST_PYTHON_DECL str : public object return this->rfind(object(sub)); } - long rfind(object_cref sub, object_cref start) const; + BOOST_PYTHON_DECL long rfind(object_cref sub, object_cref start) const; template long rfind(T1 const& sub, T2 const& start) const @@ -237,7 +237,7 @@ class BOOST_PYTHON_DECL str : public object return this->rfind(object(sub), object(start)); } - long rfind(object_cref sub, object_cref start, object_cref end) const; + BOOST_PYTHON_DECL long rfind(object_cref sub, object_cref start, object_cref end) const; template long rfind(T1 const& sub, T2 const& start, T3 const& end) const @@ -245,7 +245,7 @@ class BOOST_PYTHON_DECL str : public object return this->rfind(object(sub), object(start), object(end)); } - long rindex(object_cref sub) const; + BOOST_PYTHON_DECL long rindex(object_cref sub) const; template long rindex(T const& sub) const @@ -253,7 +253,7 @@ class BOOST_PYTHON_DECL str : public object return this->rindex(object(sub)); } - long rindex(object_cref sub, object_cref start) const; + BOOST_PYTHON_DECL long rindex(object_cref sub, object_cref start) const; template long rindex(T1 const& sub, T2 const& start) const @@ -261,7 +261,7 @@ class BOOST_PYTHON_DECL str : public object return this->rindex(object(sub), object(start)); } - long rindex(object_cref sub, object_cref start, object_cref end) const; + BOOST_PYTHON_DECL long rindex(object_cref sub, object_cref start, object_cref end) const; template long rindex(T1 const& sub, T2 const& start, T3 const& end) const @@ -269,7 +269,7 @@ class BOOST_PYTHON_DECL str : public object return this->rindex(object(sub), object(start), object(end)); } - str rjust(object_cref width) const; + BOOST_PYTHON_DECL str rjust(object_cref width) const; template str rjust(T const& width) const @@ -277,10 +277,10 @@ class BOOST_PYTHON_DECL str : public object return this->rjust(object(width)); } - str rstrip() const; + BOOST_PYTHON_DECL str rstrip() const; - list split() const; - list split(object_cref sep) const; + BOOST_PYTHON_DECL list split() const; + BOOST_PYTHON_DECL list split(object_cref sep) const; template list split(T const& sep) const @@ -288,7 +288,7 @@ class BOOST_PYTHON_DECL str : public object return this->split(object(sep)); } - list split(object_cref sep, object_cref maxsplit) const; + BOOST_PYTHON_DECL list split(object_cref sep, object_cref maxsplit) const; template list split(T1 const& sep, T2 const& maxsplit) const @@ -296,8 +296,8 @@ class BOOST_PYTHON_DECL str : public object return this->split(object(sep), object(maxsplit)); } - list splitlines() const; - list splitlines(object_cref keepends) const; + BOOST_PYTHON_DECL list splitlines() const; + BOOST_PYTHON_DECL list splitlines(object_cref keepends) const; template list splitlines(T const& keepends) const @@ -305,7 +305,7 @@ class BOOST_PYTHON_DECL str : public object return this->splitlines(object(keepends)); } - bool startswith(object_cref prefix) const ; + BOOST_PYTHON_DECL bool startswith(object_cref prefix) const ; template bool startswith(T const& prefix) const @@ -313,7 +313,7 @@ class BOOST_PYTHON_DECL str : public object return this->startswith(object(prefix)); } - bool startswith(object_cref prefix, object_cref start) const ; + BOOST_PYTHON_DECL bool startswith(object_cref prefix, object_cref start) const ; template bool startswidth(T1 const& prefix, T2 const& start) const @@ -321,7 +321,7 @@ class BOOST_PYTHON_DECL str : public object return this->startswidth(object(prefix), object(start)); } - bool startswith(object_cref prefix, object_cref start, object_cref end) const ; + BOOST_PYTHON_DECL bool startswith(object_cref prefix, object_cref start, object_cref end) const ; template bool startswidth(T1 const& prefix, T2 const& start, T3 const& end) const @@ -329,11 +329,11 @@ class BOOST_PYTHON_DECL str : public object return this->startswidth(object(prefix), object(start), object(end)); } - str strip() const ; - str swapcase() const ; - str title() const ; + BOOST_PYTHON_DECL str strip() const ; + BOOST_PYTHON_DECL str swapcase() const ; + BOOST_PYTHON_DECL str title() const ; - str translate(object_cref table) const; + BOOST_PYTHON_DECL str translate(object_cref table) const; template str translate(T const& table) const @@ -341,7 +341,7 @@ class BOOST_PYTHON_DECL str : public object return this->translate(object(table)); } - str translate(object_cref table, object_cref deletechars) const; + BOOST_PYTHON_DECL str translate(object_cref table, object_cref deletechars) const; template str translate(T1 const& table, T2 const& deletechars) const @@ -349,13 +349,13 @@ class BOOST_PYTHON_DECL str : public object return this->translate(object(table), object(deletechars)); } - str upper() const; + BOOST_PYTHON_DECL str upper() const; public: // implementation detail -- for internal use only BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str) private: - static detail::new_reference call(object const&); + static BOOST_PYTHON_DECL detail::new_reference call(object const&); }; // diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp index 133bc49b..38547696 100644 --- a/include/boost/python/tuple.hpp +++ b/include/boost/python/tuple.hpp @@ -6,14 +6,14 @@ namespace boost { namespace python { -class BOOST_PYTHON_DECL tuple : public object +class tuple : public object { public: // tuple() -> an empty tuple - tuple(); + BOOST_PYTHON_DECL tuple(); // tuple(sequence) -> tuple initialized from sequence's items - tuple(object_cref sequence); + BOOST_PYTHON_DECL tuple(object_cref sequence); template explicit tuple(T const& sequence) @@ -25,7 +25,7 @@ class BOOST_PYTHON_DECL tuple : public object BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple) private: - static detail::new_reference call(object const&); + static BOOST_PYTHON_DECL detail::new_reference call(object const&); }; // From 482006ed1ade988ae4b124224ece7f8fb95eb966 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 13 Sep 2002 23:55:46 +0000 Subject: [PATCH 0733/1042] Roll workaround forward to CWPro8.2 release [SVN r15314] --- include/boost/python/object_core.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index a0119503..ebdfeac1 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -180,7 +180,7 @@ namespace api // there is a confirmed CWPro8 codegen bug here. We prevent the // early destruction of a temporary by binding a named object // instead. -# if __MWERKS__ < 0x3000 || __MWERKS__ > 0x3001 +# if __MWERKS__ < 0x3000 || __MWERKS__ > 0x3002 typedef object const& object_cref2; # else typedef object const object_cref2; From af5176be70a73236cd75ac120d59549fb42352ea Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 14 Sep 2002 02:04:17 +0000 Subject: [PATCH 0734/1042] msvc6 (with STLPort) workaround [SVN r15316] --- include/boost/python/class.hpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 918cf4d2..b5ba650c 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -70,7 +70,15 @@ namespace detail SelectHolder::register_(); } - template int assert_default_constructible(T const&); + template + struct assert_default_constructible + { + static int check2(T const*); + static int check() + { + return sizeof(check2(&T())); + } + }; } // @@ -265,6 +273,7 @@ class class_ : public objects::class_base // Define the default constructor. self& def_init() { + detail::assert_default_constructible::check(); this->def_init(mpl::type_list<>::type()); return *this; } @@ -404,7 +413,6 @@ inline class_::class_() : base(typeid(T).name(), id_vector::size, id_vector().ids) { this->register_(); - detail::force_instantiate(sizeof(detail::assert_default_constructible(T()))); this->def_init(); this->set_instance_size(holder_selector::additional_size()); } @@ -422,7 +430,6 @@ 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()); } From 4a6762540dddea4eb2aa07690e175eedd37d4726 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 14 Sep 2002 16:19:22 +0000 Subject: [PATCH 0735/1042] bugfix [SVN r15324] --- include/boost/python/class.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index b5ba650c..cdc17104 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -73,10 +73,10 @@ namespace detail template struct assert_default_constructible { - static int check2(T const*); + static int check2(T const&); static int check() { - return sizeof(check2(&T())); + return sizeof(check2(T())); } }; } From 604928adc40fd935acb1081865548d9bf0b1eb0f Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Sun, 15 Sep 2002 21:13:12 +0000 Subject: [PATCH 0736/1042] new API changes [SVN r15344] --- test/defaults.cpp | 16 ++++++++-------- test/defaults.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/test/defaults.cpp b/test/defaults.cpp index 0f552666..2ebcd571 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -158,25 +158,25 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) .def("barfoo", (object(*)(int, char, std::string, double))0, bar_stubs()) ; - class_("Y", no_init) + class_("Y", init<>("doc of Y init")) // this should work .def("get_state", &Y::get_state) ; class_("X") # if (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) - .def(init >()) - .def(init()) + .def(init >("doc of init")) + .def(init()[default_call_policies()]) // what's a good policy here? # else - .def_init(args()) - .def_init(args()) - .def_init(args()) - .def_init(args()) + .def_init(args(), "doc of init") + .def_init(args(), "doc of init") + .def_init(args(), "doc of init") + .def_init(args(), "doc of init") .def_init(args()) # endif .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) - .def("bar2", &X::bar2, X_bar_stubs2(), return_internal_reference<>()) + .def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()]) .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs()) diff --git a/test/defaults.py b/test/defaults.py index aa7602f2..ee7a6588 100644 --- a/test/defaults.py +++ b/test/defaults.py @@ -3,73 +3,115 @@ >>> from defaults_ext import * >>> bar(1) 'int(1); char(D); string(default); double(0.0); ' + >>> bar(2, 'X') 'int(2); char(X); string(default); double(0.0); ' + >>> bar(3, 'Y', "Hello World") 'int(3); char(Y); string(Hello World); double(0.0); ' + >>> bar(4, 'Z', "Hi There", 3.3) 'int(4); char(Z); string(Hi There); double(3.3); ' + >>> foo(1) 'int(1); char(D); string(default); double(0.0); ' + >>> foo(2, 'X') 'int(2); char(X); string(default); double(0.0); ' + >>> foo(3, 'Y', "Hello World") 'int(3); char(Y); string(Hello World); double(0.0); ' + >>> foo(4, 'Z', "Hi There", 3.3) 'int(4); char(Z); string(Hi There); double(3.3); ' + >>> x = X() >>> x.bar(1) 'int(1); char(D); string(default); double(0.0); ' + >>> x.bar(2, 'X') 'int(2); char(X); string(default); double(0.0); ' + >>> x.bar(3, 'Y', "Hello World") 'int(3); char(Y); string(Hello World); double(0.0); ' + >>> x.bar(4, 'Z', "Hi There", 3.3) 'int(4); char(Z); string(Hi There); double(3.3); ' + >>> x.foo(5) 'int(5); bool(0); ' + >>> x.foo(6, 0) 'int(6); bool(0); ' + >>> x.foo(7, 1) 'int(7); bool(1); ' + >>> x.foo("A") 'string(A); bool(0); ' + >>> x.foo("B", False) 'string(B); bool(0); ' + >>> x.foo("C", True) 'string(C); bool(1); ' + >>> x.foo([0,1,2], [2,3,4]) 'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' + >>> x.foo([0,1,2], [2,3,4], False) 'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' + >>> x.foo([0,1,2], [2,3,4], True) 'list([0, 1, 2]); list([2, 3, 4]); bool(1); ' + >>> x = X(1) >>> x.get_state() 'int(1); char(D); string(constructor); double(0.0); ' + >>> x = X(1, 'X') >>> x.get_state() 'int(1); char(X); string(constructor); double(0.0); ' + >>> x = X(1, 'X', "Yabadabadoo") >>> x.get_state() 'int(1); char(X); string(Yabadabadoo); double(0.0); ' + >>> x = X(1, 'X', "Phoenix", 3.65) >>> x.get_state() 'int(1); char(X); string(Phoenix); double(3.65); ' + >>> x.bar2().get_state() 'int(0); char(D); string(default); double(0.0); ' + >>> x.bar2(1).get_state() 'int(1); char(D); string(default); double(0.0); ' + >>> x.bar2(1, 'K').get_state() 'int(1); char(K); string(default); double(0.0); ' + >>> x.bar2(1, 'K', "Kim").get_state() 'int(1); char(K); string(Kim); double(0.0); ' + >>> x.bar2(1, 'K', "Kim", 9.9).get_state() 'int(1); char(K); string(Kim); double(9.9); ' + >>> x = X("Phoenix", 1) >>> x.get_state() 'Got exactly two arguments from constructor: string(Phoenix); bool(1); ' +>>> def printdoc(x): +... print x.__doc__ + +>>> printdoc(X.__init__) +doc of init + +>>> printdoc(Y.__init__) +doc of Y init + +>>> printdoc(X.bar2) +doc of X::bar2 + """ def run(args = None): import sys From b37198106da916297d00c28815c469de363729dd Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Sun, 15 Sep 2002 21:42:49 +0000 Subject: [PATCH 0737/1042] Changed args<...> to init<...> and changed class_(no_init) to class_("name", no_init) [SVN r15345] --- test/back_reference.cpp | 4 ++-- test/bienstman3.cpp | 2 +- test/bienstman4.cpp | 2 +- test/bienstman5.cpp | 2 +- test/callbacks.cpp | 4 ++-- test/data_members.cpp | 4 ++-- test/defaults.cpp | 8 -------- test/docstring.cpp | 15 ++++++++------- test/extract.cpp | 2 +- test/implicit.cpp | 2 +- test/list.cpp | 2 +- test/m1.cpp | 4 ++-- test/multi_arg_constructor.cpp | 2 +- test/nested.cpp | 4 ++-- test/operators.cpp | 4 ++-- test/pickle1.cpp | 2 +- test/pickle2.cpp | 2 +- test/pickle3.cpp | 2 +- test/test_pointer_adoption.cpp | 24 ++++++++++++------------ test/virtual_functions.cpp | 6 +++--- 20 files changed, 45 insertions(+), 52 deletions(-) diff --git a/test/back_reference.cpp b/test/back_reference.cpp index 73990640..d5ae5ece 100644 --- a/test/back_reference.cpp +++ b/test/back_reference.cpp @@ -93,12 +93,12 @@ BOOST_PYTHON_MODULE_INIT(back_reference_ext) def("copy_Z", copy_Z, return_value_policy()); def("x_instances", &X::count); - class_("Y", args()) + class_("Y", init()) .def("value", &Y::value) .def("set", &Y::set) ; - class_ >("Z", args()) + class_ >("Z", init()) .def("value", &Z::value) .def("set", &Z::set) ; diff --git a/test/bienstman3.cpp b/test/bienstman3.cpp index f1dc212d..22c7638e 100644 --- a/test/bienstman3.cpp +++ b/test/bienstman3.cpp @@ -17,6 +17,6 @@ BOOST_PYTHON_MODULE_INIT(bienstman3_ext) using namespace boost::python; class_("V", no_init); - class_("B", args()); + class_("B", init()); } diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp index 324af85a..ee510f2d 100644 --- a/test/bienstman4.cpp +++ b/test/bienstman4.cpp @@ -30,7 +30,7 @@ BOOST_PYTHON_MODULE_INIT(bienstman4_ext) class_("T1") ; - class_("Term", args()) + class_("Term", init()) ; Type1 t1; diff --git a/test/bienstman5.cpp b/test/bienstman5.cpp index 007d12a9..75fbd8da 100644 --- a/test/bienstman5.cpp +++ b/test/bienstman5.cpp @@ -17,7 +17,7 @@ BOOST_PYTHON_MODULE_INIT(bienstman5_ext) { using namespace boost::python; - class_("M", args const&>()) + class_("M", init const&>()) ; } diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 700c190a..763dcda8 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -137,8 +137,8 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) def("apply_to_string_literal", apply_to_string_literal); - class_("X", args()) - .def_init(args()) + class_("X", init()) + .def(init()) .def("value", &X::value) .def("set", &X::set) ; diff --git a/test/data_members.cpp b/test/data_members.cpp index 99459dff..7a05d359 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -22,14 +22,14 @@ double get_fair_value(X const& x) { return x.value(); } BOOST_PYTHON_MODULE_INIT(data_members_ext) { - class_("X", args()) + class_("X", init()) .def("value", &X::value) .def("set", &X::set) .def_readonly("x", &X::x) .add_property("fair_value", &get_fair_value) ; - class_("Y", args()) + class_("Y", init()) .def("value", &Y::value) .def("set", &Y::set) .def_readwrite("x", &Y::x) diff --git a/test/defaults.cpp b/test/defaults.cpp index 2ebcd571..41341e72 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -164,16 +164,8 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) class_("X") -# if (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) .def(init >("doc of init")) .def(init()[default_call_policies()]) // what's a good policy here? -# else - .def_init(args(), "doc of init") - .def_init(args(), "doc of init") - .def_init(args(), "doc of init") - .def_init(args(), "doc of init") - .def_init(args()) -# endif .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) .def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()]) diff --git a/test/docstring.cpp b/test/docstring.cpp index 01bacfba..417a6635 100644 --- a/test/docstring.cpp +++ b/test/docstring.cpp @@ -36,23 +36,24 @@ BOOST_PYTHON_MODULE_INIT(docstring_ext) "A simple test module for documentation strings\n" "Exercised by docstring.py" ; - + class_("X", "A simple class wrapper around a C++ int\n" "includes some error-checking" - - , args(), - "this is the __init__ function\n" - "its documentation has two lines." + + , init( + "this is the __init__ function\n" + "its documentation has two lines." + ) ) .def("value", &X::value, "gets the value of the object") ; - + def("create", create, return_value_policy(), "creates a new X object"); - + def("fact", fact, "compute the factorial"); } diff --git a/test/extract.cpp b/test/extract.cpp index 17640f2f..749f265a 100644 --- a/test/extract.cpp +++ b/test/extract.cpp @@ -124,7 +124,7 @@ BOOST_PYTHON_MODULE_INIT(extract_ext) ; object x_class( - class_("X", args()) + class_("X", init()) .def( "__repr__", x_rep)); // Instantiate an X object through the Python interface diff --git a/test/implicit.cpp b/test/implicit.cpp index cbf34027..2637f5ca 100644 --- a/test/implicit.cpp +++ b/test/implicit.cpp @@ -27,7 +27,7 @@ BOOST_PYTHON_MODULE_INIT(implicit_ext) def("x_value", x_value); def("make_x", make_x); - class_("X", args()) + class_("X", init()) .def("value", &X::value) .def("set", &X::set) ; diff --git a/test/list.cpp b/test/list.cpp index b3bce4a2..83ea063b 100644 --- a/test/list.cpp +++ b/test/list.cpp @@ -138,7 +138,7 @@ BOOST_PYTHON_MODULE_INIT(list_ext) def("exercise", exercise); - class_("X", args()) + class_("X", init()) .def( "__repr__", x_rep) ; } diff --git a/test/m1.cpp b/test/m1.cpp index f09e4a93..434ab096 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -259,8 +259,8 @@ BOOST_PYTHON_MODULE_INIT(m1) ; class_("complicated", - args()) - .def_init(args()) + init()) + .def(init()) .def("get_n", &complicated::get_n) ; } diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp index 43e8bfb1..24bc4d9a 100644 --- a/test/multi_arg_constructor.cpp +++ b/test/multi_arg_constructor.cpp @@ -17,7 +17,7 @@ BOOST_PYTHON_MODULE_INIT(multi_arg_constructor_ext) class_ >( "A" - , args() + , init() ) ; diff --git a/test/nested.cpp b/test/nested.cpp index 9bc5be32..8cbe3d79 100644 --- a/test/nested.cpp +++ b/test/nested.cpp @@ -34,12 +34,12 @@ BOOST_PYTHON_MODULE_INIT(nested_ext) // Establish X as the current scope. scope x_class( - class_("X", args()) + class_("X", init()) .def(str(self)) ); // Y will now be defined in the current scope - class_("Y", args()) + class_("Y", init()) .def(str(self)) ; } diff --git a/test/operators.cpp b/test/operators.cpp index e21b5509..dc2313df 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -59,7 +59,7 @@ std::ostream& operator<<(std::ostream& s, X const& x) BOOST_PYTHON_MODULE_INIT(operators_ext) { - class_("X", args()) + class_("X", init()) .def("value", &X::value) .def(self - self) .def(self - int()) @@ -77,7 +77,7 @@ BOOST_PYTHON_MODULE_INIT(operators_ext) .def(pow(int(),self)) ; - class_ >("Z", args()) + class_ >("Z", init()) .def(int_(self)) .def(float_(self)) .def(complex_(self)) diff --git a/test/pickle1.cpp b/test/pickle1.cpp index e1397d60..1f9e5139 100644 --- a/test/pickle1.cpp +++ b/test/pickle1.cpp @@ -48,7 +48,7 @@ namespace { BOOST_PYTHON_MODULE_INIT(pickle1_ext) { using namespace boost::python; - class_("world", args()) + class_("world", init()) .def("greet", &world::greet) .def_pickle(world_pickle_suite()) ; diff --git a/test/pickle2.cpp b/test/pickle2.cpp index 984d6380..b8aacbd7 100644 --- a/test/pickle2.cpp +++ b/test/pickle2.cpp @@ -90,7 +90,7 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle2_ext) { boost::python::class_( - "world", boost::python::args()) + "world", boost::python::init()) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) diff --git a/test/pickle3.cpp b/test/pickle3.cpp index 8911b24c..5fae9e6c 100644 --- a/test/pickle3.cpp +++ b/test/pickle3.cpp @@ -98,7 +98,7 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle3_ext) { boost::python::class_( - "world", boost::python::args()) + "world", boost::python::init()) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index b04e3496..90b39ea7 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -26,7 +26,7 @@ struct inner { this->s = new_s; } - + std::string s; }; @@ -42,7 +42,7 @@ struct A : Base { ++a_instances; } - + ~A() { --a_instances; @@ -65,7 +65,7 @@ struct B { B() : x(0) {} B(A* x_) : x(x_) {} - + inner const* adopt(A* x) { this->x = x; return &x->get_inner(); } std::string a_content() @@ -96,29 +96,29 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) def("create", create, return_value_policy()); def("as_A", as_A, return_internal_reference<>()); - + class_("Base") ; - - class_ >(no_init) + + class_ >("A", no_init) .def("content", &A::content) .def("get_inner", &A::get_inner, return_internal_reference<>()) ; - - class_(no_init) + + class_("inner", no_init) .def("change", &inner::change) ; - + class_("B") - .def_init(args(), with_custodian_and_ward_postcall<1,2>()) - + .def(init()[with_custodian_and_ward_postcall<1,2>()]) + .def("adopt", &B::adopt // Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self") , return_internal_reference<2 // Meanwhile, self holds a reference to the 2nd argument. , with_custodian_and_ward<1,2> >() ) - + .def("a_content", &B::a_content) ; } diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp index 73d47dc5..f0bfd787 100644 --- a/test/virtual_functions.cpp +++ b/test/virtual_functions.cpp @@ -89,7 +89,7 @@ int X::counter; BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) { - class_("concrete", args()) + class_("concrete", init()) .def("value", &concrete::value) .def("set", &concrete::set) .def("call_f", &concrete::call_f) @@ -97,14 +97,14 @@ BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) ; class_ - >("abstract", args()) + >("abstract", init()) .def("value", &abstract::value) .def("call_f", &abstract::call_f) .def("set", &abstract::set) ; - class_("Y", args()) + class_("Y", init()) .def("value", &Y::value) .def("set", &Y::set) ; From 06f6f2ff21408ade443af720e2d9743a8f9bd3e7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 16 Sep 2002 04:03:39 +0000 Subject: [PATCH 0738/1042] Restore main trunk to health [SVN r15359] --- test/back_reference.cpp | 4 ++-- test/bienstman3.cpp | 2 +- test/bienstman4.cpp | 2 +- test/bienstman5.cpp | 2 +- test/callbacks.cpp | 4 ++-- test/data_members.cpp | 4 ++-- test/defaults.cpp | 16 ++++++++++++---- test/docstring.cpp | 15 +++++++-------- test/extract.cpp | 2 +- test/implicit.cpp | 2 +- test/list.cpp | 2 +- test/m1.cpp | 4 ++-- test/multi_arg_constructor.cpp | 2 +- test/nested.cpp | 4 ++-- test/operators.cpp | 4 ++-- test/pickle1.cpp | 2 +- test/pickle2.cpp | 2 +- test/pickle3.cpp | 2 +- test/test_pointer_adoption.cpp | 24 ++++++++++++------------ test/virtual_functions.cpp | 6 +++--- 20 files changed, 56 insertions(+), 49 deletions(-) diff --git a/test/back_reference.cpp b/test/back_reference.cpp index d5ae5ece..73990640 100644 --- a/test/back_reference.cpp +++ b/test/back_reference.cpp @@ -93,12 +93,12 @@ BOOST_PYTHON_MODULE_INIT(back_reference_ext) def("copy_Z", copy_Z, return_value_policy()); def("x_instances", &X::count); - class_("Y", init()) + class_("Y", args()) .def("value", &Y::value) .def("set", &Y::set) ; - class_ >("Z", init()) + class_ >("Z", args()) .def("value", &Z::value) .def("set", &Z::set) ; diff --git a/test/bienstman3.cpp b/test/bienstman3.cpp index 22c7638e..f1dc212d 100644 --- a/test/bienstman3.cpp +++ b/test/bienstman3.cpp @@ -17,6 +17,6 @@ BOOST_PYTHON_MODULE_INIT(bienstman3_ext) using namespace boost::python; class_("V", no_init); - class_("B", init()); + class_("B", args()); } diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp index ee510f2d..324af85a 100644 --- a/test/bienstman4.cpp +++ b/test/bienstman4.cpp @@ -30,7 +30,7 @@ BOOST_PYTHON_MODULE_INIT(bienstman4_ext) class_("T1") ; - class_("Term", init()) + class_("Term", args()) ; Type1 t1; diff --git a/test/bienstman5.cpp b/test/bienstman5.cpp index 75fbd8da..007d12a9 100644 --- a/test/bienstman5.cpp +++ b/test/bienstman5.cpp @@ -17,7 +17,7 @@ BOOST_PYTHON_MODULE_INIT(bienstman5_ext) { using namespace boost::python; - class_("M", init const&>()) + class_("M", args const&>()) ; } diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 763dcda8..700c190a 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -137,8 +137,8 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) def("apply_to_string_literal", apply_to_string_literal); - class_("X", init()) - .def(init()) + class_("X", args()) + .def_init(args()) .def("value", &X::value) .def("set", &X::set) ; diff --git a/test/data_members.cpp b/test/data_members.cpp index 7a05d359..99459dff 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -22,14 +22,14 @@ double get_fair_value(X const& x) { return x.value(); } BOOST_PYTHON_MODULE_INIT(data_members_ext) { - class_("X", init()) + class_("X", args()) .def("value", &X::value) .def("set", &X::set) .def_readonly("x", &X::x) .add_property("fair_value", &get_fair_value) ; - class_("Y", init()) + class_("Y", args()) .def("value", &Y::value) .def("set", &Y::set) .def_readwrite("x", &Y::x) diff --git a/test/defaults.cpp b/test/defaults.cpp index 41341e72..0f552666 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -158,17 +158,25 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) .def("barfoo", (object(*)(int, char, std::string, double))0, bar_stubs()) ; - class_("Y", init<>("doc of Y init")) // this should work + class_("Y", no_init) .def("get_state", &Y::get_state) ; class_("X") - .def(init >("doc of init")) - .def(init()[default_call_policies()]) // what's a good policy here? +# if (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) + .def(init >()) + .def(init()) +# else + .def_init(args()) + .def_init(args()) + .def_init(args()) + .def_init(args()) + .def_init(args()) +# endif .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) - .def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()]) + .def("bar2", &X::bar2, X_bar_stubs2(), return_internal_reference<>()) .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs()) diff --git a/test/docstring.cpp b/test/docstring.cpp index 417a6635..01bacfba 100644 --- a/test/docstring.cpp +++ b/test/docstring.cpp @@ -36,24 +36,23 @@ BOOST_PYTHON_MODULE_INIT(docstring_ext) "A simple test module for documentation strings\n" "Exercised by docstring.py" ; - + class_("X", "A simple class wrapper around a C++ int\n" "includes some error-checking" - - , init( - "this is the __init__ function\n" - "its documentation has two lines." - ) + + , args(), + "this is the __init__ function\n" + "its documentation has two lines." ) .def("value", &X::value, "gets the value of the object") ; - + def("create", create, return_value_policy(), "creates a new X object"); - + def("fact", fact, "compute the factorial"); } diff --git a/test/extract.cpp b/test/extract.cpp index 749f265a..17640f2f 100644 --- a/test/extract.cpp +++ b/test/extract.cpp @@ -124,7 +124,7 @@ BOOST_PYTHON_MODULE_INIT(extract_ext) ; object x_class( - class_("X", init()) + class_("X", args()) .def( "__repr__", x_rep)); // Instantiate an X object through the Python interface diff --git a/test/implicit.cpp b/test/implicit.cpp index 2637f5ca..cbf34027 100644 --- a/test/implicit.cpp +++ b/test/implicit.cpp @@ -27,7 +27,7 @@ BOOST_PYTHON_MODULE_INIT(implicit_ext) def("x_value", x_value); def("make_x", make_x); - class_("X", init()) + class_("X", args()) .def("value", &X::value) .def("set", &X::set) ; diff --git a/test/list.cpp b/test/list.cpp index 83ea063b..b3bce4a2 100644 --- a/test/list.cpp +++ b/test/list.cpp @@ -138,7 +138,7 @@ BOOST_PYTHON_MODULE_INIT(list_ext) def("exercise", exercise); - class_("X", init()) + class_("X", args()) .def( "__repr__", x_rep) ; } diff --git a/test/m1.cpp b/test/m1.cpp index 434ab096..f09e4a93 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -259,8 +259,8 @@ BOOST_PYTHON_MODULE_INIT(m1) ; class_("complicated", - init()) - .def(init()) + args()) + .def_init(args()) .def("get_n", &complicated::get_n) ; } diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp index 24bc4d9a..43e8bfb1 100644 --- a/test/multi_arg_constructor.cpp +++ b/test/multi_arg_constructor.cpp @@ -17,7 +17,7 @@ BOOST_PYTHON_MODULE_INIT(multi_arg_constructor_ext) class_ >( "A" - , init() + , args() ) ; diff --git a/test/nested.cpp b/test/nested.cpp index 8cbe3d79..9bc5be32 100644 --- a/test/nested.cpp +++ b/test/nested.cpp @@ -34,12 +34,12 @@ BOOST_PYTHON_MODULE_INIT(nested_ext) // Establish X as the current scope. scope x_class( - class_("X", init()) + class_("X", args()) .def(str(self)) ); // Y will now be defined in the current scope - class_("Y", init()) + class_("Y", args()) .def(str(self)) ; } diff --git a/test/operators.cpp b/test/operators.cpp index dc2313df..e21b5509 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -59,7 +59,7 @@ std::ostream& operator<<(std::ostream& s, X const& x) BOOST_PYTHON_MODULE_INIT(operators_ext) { - class_("X", init()) + class_("X", args()) .def("value", &X::value) .def(self - self) .def(self - int()) @@ -77,7 +77,7 @@ BOOST_PYTHON_MODULE_INIT(operators_ext) .def(pow(int(),self)) ; - class_ >("Z", init()) + class_ >("Z", args()) .def(int_(self)) .def(float_(self)) .def(complex_(self)) diff --git a/test/pickle1.cpp b/test/pickle1.cpp index 1f9e5139..e1397d60 100644 --- a/test/pickle1.cpp +++ b/test/pickle1.cpp @@ -48,7 +48,7 @@ namespace { BOOST_PYTHON_MODULE_INIT(pickle1_ext) { using namespace boost::python; - class_("world", init()) + class_("world", args()) .def("greet", &world::greet) .def_pickle(world_pickle_suite()) ; diff --git a/test/pickle2.cpp b/test/pickle2.cpp index b8aacbd7..984d6380 100644 --- a/test/pickle2.cpp +++ b/test/pickle2.cpp @@ -90,7 +90,7 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle2_ext) { boost::python::class_( - "world", boost::python::init()) + "world", boost::python::args()) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) diff --git a/test/pickle3.cpp b/test/pickle3.cpp index 5fae9e6c..8911b24c 100644 --- a/test/pickle3.cpp +++ b/test/pickle3.cpp @@ -98,7 +98,7 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle3_ext) { boost::python::class_( - "world", boost::python::init()) + "world", boost::python::args()) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index 90b39ea7..b04e3496 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -26,7 +26,7 @@ struct inner { this->s = new_s; } - + std::string s; }; @@ -42,7 +42,7 @@ struct A : Base { ++a_instances; } - + ~A() { --a_instances; @@ -65,7 +65,7 @@ struct B { B() : x(0) {} B(A* x_) : x(x_) {} - + inner const* adopt(A* x) { this->x = x; return &x->get_inner(); } std::string a_content() @@ -96,29 +96,29 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) def("create", create, return_value_policy()); def("as_A", as_A, return_internal_reference<>()); - + class_("Base") ; - - class_ >("A", no_init) + + class_ >(no_init) .def("content", &A::content) .def("get_inner", &A::get_inner, return_internal_reference<>()) ; - - class_("inner", no_init) + + class_(no_init) .def("change", &inner::change) ; - + class_("B") - .def(init()[with_custodian_and_ward_postcall<1,2>()]) - + .def_init(args(), with_custodian_and_ward_postcall<1,2>()) + .def("adopt", &B::adopt // Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self") , return_internal_reference<2 // Meanwhile, self holds a reference to the 2nd argument. , with_custodian_and_ward<1,2> >() ) - + .def("a_content", &B::a_content) ; } diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp index f0bfd787..73d47dc5 100644 --- a/test/virtual_functions.cpp +++ b/test/virtual_functions.cpp @@ -89,7 +89,7 @@ int X::counter; BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) { - class_("concrete", init()) + class_("concrete", args()) .def("value", &concrete::value) .def("set", &concrete::set) .def("call_f", &concrete::call_f) @@ -97,14 +97,14 @@ BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) ; class_ - >("abstract", init()) + >("abstract", args()) .def("value", &abstract::value) .def("call_f", &abstract::call_f) .def("set", &abstract::set) ; - class_("Y", init()) + class_("Y", args()) .def("value", &Y::value) .def("set", &Y::set) ; From 802a2f3fdb06c337a3eb1bd917d6706e44995c9f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 16 Sep 2002 04:15:53 +0000 Subject: [PATCH 0739/1042] Restore main trunk to health [SVN r15362] --- test/defaults.py | 42 ------------------------------------------ 1 file changed, 42 deletions(-) diff --git a/test/defaults.py b/test/defaults.py index ee7a6588..aa7602f2 100644 --- a/test/defaults.py +++ b/test/defaults.py @@ -3,115 +3,73 @@ >>> from defaults_ext import * >>> bar(1) 'int(1); char(D); string(default); double(0.0); ' - >>> bar(2, 'X') 'int(2); char(X); string(default); double(0.0); ' - >>> bar(3, 'Y', "Hello World") 'int(3); char(Y); string(Hello World); double(0.0); ' - >>> bar(4, 'Z', "Hi There", 3.3) 'int(4); char(Z); string(Hi There); double(3.3); ' - >>> foo(1) 'int(1); char(D); string(default); double(0.0); ' - >>> foo(2, 'X') 'int(2); char(X); string(default); double(0.0); ' - >>> foo(3, 'Y', "Hello World") 'int(3); char(Y); string(Hello World); double(0.0); ' - >>> foo(4, 'Z', "Hi There", 3.3) 'int(4); char(Z); string(Hi There); double(3.3); ' - >>> x = X() >>> x.bar(1) 'int(1); char(D); string(default); double(0.0); ' - >>> x.bar(2, 'X') 'int(2); char(X); string(default); double(0.0); ' - >>> x.bar(3, 'Y', "Hello World") 'int(3); char(Y); string(Hello World); double(0.0); ' - >>> x.bar(4, 'Z', "Hi There", 3.3) 'int(4); char(Z); string(Hi There); double(3.3); ' - >>> x.foo(5) 'int(5); bool(0); ' - >>> x.foo(6, 0) 'int(6); bool(0); ' - >>> x.foo(7, 1) 'int(7); bool(1); ' - >>> x.foo("A") 'string(A); bool(0); ' - >>> x.foo("B", False) 'string(B); bool(0); ' - >>> x.foo("C", True) 'string(C); bool(1); ' - >>> x.foo([0,1,2], [2,3,4]) 'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' - >>> x.foo([0,1,2], [2,3,4], False) 'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' - >>> x.foo([0,1,2], [2,3,4], True) 'list([0, 1, 2]); list([2, 3, 4]); bool(1); ' - >>> x = X(1) >>> x.get_state() 'int(1); char(D); string(constructor); double(0.0); ' - >>> x = X(1, 'X') >>> x.get_state() 'int(1); char(X); string(constructor); double(0.0); ' - >>> x = X(1, 'X', "Yabadabadoo") >>> x.get_state() 'int(1); char(X); string(Yabadabadoo); double(0.0); ' - >>> x = X(1, 'X', "Phoenix", 3.65) >>> x.get_state() 'int(1); char(X); string(Phoenix); double(3.65); ' - >>> x.bar2().get_state() 'int(0); char(D); string(default); double(0.0); ' - >>> x.bar2(1).get_state() 'int(1); char(D); string(default); double(0.0); ' - >>> x.bar2(1, 'K').get_state() 'int(1); char(K); string(default); double(0.0); ' - >>> x.bar2(1, 'K', "Kim").get_state() 'int(1); char(K); string(Kim); double(0.0); ' - >>> x.bar2(1, 'K', "Kim", 9.9).get_state() 'int(1); char(K); string(Kim); double(9.9); ' - >>> x = X("Phoenix", 1) >>> x.get_state() 'Got exactly two arguments from constructor: string(Phoenix); bool(1); ' ->>> def printdoc(x): -... print x.__doc__ - ->>> printdoc(X.__init__) -doc of init - ->>> printdoc(Y.__init__) -doc of Y init - ->>> printdoc(X.bar2) -doc of X::bar2 - """ def run(args = None): import sys From b084f8a616c04a9cdbbeb6725043c62153eb123e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 16 Sep 2002 12:46:26 +0000 Subject: [PATCH 0740/1042] Restore main trunk to health [SVN r15378] --- include/boost/python/args.hpp | 75 +--- include/boost/python/bases.hpp | 22 +- include/boost/python/class.hpp | 53 +-- .../python/converter/arg_from_python.hpp | 14 +- .../boost/python/converter/arg_to_python.hpp | 12 +- .../boost/python/converter/object_manager.hpp | 8 +- .../python/converter/return_from_python.hpp | 6 +- .../converter/rvalue_from_python_data.hpp | 2 + include/boost/python/copy_const_reference.hpp | 4 +- .../boost/python/copy_non_const_reference.hpp | 4 +- .../boost/python/default_call_policies.hpp | 4 +- include/boost/python/detail/borrowed_ptr.hpp | 4 +- include/boost/python/detail/caller.hpp | 2 - include/boost/python/detail/convertible.hpp | 4 +- include/boost/python/detail/defaults_def.hpp | 21 +- include/boost/python/detail/defaults_gen.hpp | 21 +- include/boost/python/detail/destroy.hpp | 4 +- .../boost/python/detail/indirect_traits.hpp | 28 +- .../python/detail/member_function_cast.hpp | 4 +- include/boost/python/detail/msvc_typeinfo.hpp | 6 +- include/boost/python/detail/preprocessor.hpp | 4 + .../boost/python/detail/referent_storage.hpp | 4 +- include/boost/python/detail/result.hpp | 4 +- include/boost/python/detail/type_list.hpp | 38 +- .../boost/python/detail/type_list_impl.hpp | 55 +++ .../python/detail/type_list_impl_no_pts.hpp | 101 +++++ .../boost/python/detail/type_list_utils.hpp | 118 +----- include/boost/python/extract.hpp | 6 +- include/boost/python/init.hpp | 392 ++++++------------ include/boost/python/manage_new_object.hpp | 4 +- .../boost/python/object/class_converters.hpp | 38 +- include/boost/python/object/forward.hpp | 5 +- include/boost/python/object/inheritance.hpp | 6 +- include/boost/python/object/make_holder.hpp | 11 +- .../boost/python/object/pointer_holder.hpp | 2 +- include/boost/python/object/select_holder.hpp | 20 +- include/boost/python/operators2.hpp | 14 +- include/boost/python/pointee.hpp | 1 + .../python/reference_existing_object.hpp | 4 +- .../python/return_internal_reference.hpp | 4 +- include/boost/python/signature.hpp | 72 ++-- include/boost/python/to_python_value.hpp | 4 +- 42 files changed, 554 insertions(+), 651 deletions(-) create mode 100644 include/boost/python/detail/type_list_impl.hpp create mode 100644 include/boost/python/detail/type_list_impl_no_pts.hpp diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index dc00c96c..941529f0 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -1,5 +1,3 @@ -#if !defined(BOOST_PP_IS_ITERATING) - // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided @@ -8,14 +6,8 @@ #ifndef ARGS_DWA2002323_HPP # define ARGS_DWA2002323_HPP # include - # include - -# include - -# include -# include -# include +# include namespace boost { namespace python { @@ -28,76 +20,15 @@ namespace detail } }} -# if !defined(__EDG_VERSION__) || __EDG_VERSION__ > 245 - namespace boost { namespace python { // A type list for specifying arguments -template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, boost::mpl::null_argument) > +template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, mpl::void_) > struct args : detail::args_base > - , boost::mpl::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A) >::type + , detail::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A) >::type {}; }} // namespace boost::python -# else // slow template instantiators need this other version with - // explicit specializations of mpl::size<> and - // mpl::at<>. Eventually, however, inheritance from mpl::list - // *should* be eliminated and the two versions unified, just in - // order to get true arity independence - -namespace boost { namespace python { - -template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, boost::mpl::null_argument) > -struct args : detail::args_base > -{}; - -}} // namespace boost::python - -namespace boost { namespace mpl { - -template struct size; -template struct at; - -# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY, , 1)) -# include BOOST_PP_ITERATE() - -# define BOOST_PP_ITERATION_PARAMS_1 (4, (0, BOOST_PYTHON_MAX_ARITY - 1, , 2)) -# include BOOST_PP_ITERATE() - - -}} // namespace boost::mpl - -# endif // __EDG_VERSION__ # endif // ARGS_DWA2002323_HPP - -/* ---------- size ---------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 1 -# line BOOST_PP_LINE(__LINE__, args.hpp(size)) - -# define N BOOST_PP_ITERATION() - -template -struct size > -{ - BOOST_STATIC_CONSTANT(long, value = N); -}; - -# undef N - -/* ---------- at ---------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == 2 -# line BOOST_PP_LINE(__LINE__, args.hpp(at)) - -# define N BOOST_PP_ITERATION() - -template -struct at > -{ - typedef BOOST_PP_CAT(A, N) type; -}; - -# undef N - -#endif diff --git a/include/boost/python/bases.hpp b/include/boost/python/bases.hpp index 468c6744..ec03dfba 100644 --- a/include/boost/python/bases.hpp +++ b/include/boost/python/bases.hpp @@ -6,14 +6,16 @@ #ifndef BASES_DWA2002321_HPP # define BASES_DWA2002321_HPP # include -# include -# include -# include +# include +# include +# include +# include namespace boost { namespace python { + // A type list for specifying bases - template < BOOST_MPL_LIST_DEFAULT_PARAMETERS(typename B, ::boost::mpl::null_argument) > - struct bases : ::boost::mpl::type_list< BOOST_MPL_LIST_PARAMETERS(B) >::type + template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_MAX_BASES, typename B, mpl::void_) > + struct bases : detail::type_list< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, B) >::type {}; namespace detail @@ -23,14 +25,14 @@ namespace boost { namespace python { { BOOST_STATIC_CONSTANT(bool, value = false); }; - template < BOOST_MPL_LIST_PARAMETERS(class B) > - struct specifies_bases< bases< BOOST_MPL_LIST_PARAMETERS(B) > > + template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class B) > + struct specifies_bases< bases< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, B) > > { BOOST_STATIC_CONSTANT(bool, value = true); }; # else - template < BOOST_MPL_LIST_PARAMETERS(class B) > - static char is_bases_helper(bases< BOOST_MPL_LIST_PARAMETERS(B) > const&); + template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class B) > + static char is_bases_helper(bases< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, B) > const&); static char (& is_bases_helper(...) )[256]; @@ -45,7 +47,7 @@ namespace boost { namespace python { # endif template > struct select_bases - : mpl::select_type< + : mpl::if_c< specifies_bases::value , T , Prev diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index cdc17104..7f769739 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -20,7 +20,7 @@ # include # include # include -# include +# include # include # include # include @@ -40,7 +40,22 @@ namespace boost { namespace python { namespace detail { - struct write_type_id; + // This function object is used with mpl::for_each to write the id + // of the type a pointer to which is passed as its 2nd compile-time + // argument. into the iterator pointed to by its runtime argument + struct write_type_id + { + write_type_id(type_info**p) : p(p) {} + + // Here's the runtime behavior + template + void operator()(T*) const + { + *(*p)++ = type_id(); + }; + + type_info** p; + }; template struct select_held_type; @@ -56,7 +71,7 @@ namespace detail // to the type of holder that must be created. The 3rd argument is a // reference to the Python type object to be created. template - static inline void register_copy_constructor(mpl::bool_t const&, SelectHolder const& , T* = 0) + static inline void register_copy_constructor(mpl::bool_c const&, SelectHolder const& , T* = 0) { typedef typename SelectHolder::type holder; force_instantiate(objects::class_wrapper >()); @@ -65,7 +80,7 @@ namespace detail // Tag dispatched to have no effect. template - static inline void register_copy_constructor(mpl::bool_t const&, SelectHolder const&, T* = 0) + static inline void register_copy_constructor(mpl::bool_c const&, SelectHolder const&, T* = 0) { SelectHolder::register_(); } @@ -126,7 +141,7 @@ class class_ : public objects::class_base // Write the rest of the elements into succeeding positions. type_info* p = ids + 1; - mpl::for_each::execute(&p); + mpl::for_each(detail::write_type_id(&p), (bases*)0, (add_pointer*)0); } BOOST_STATIC_CONSTANT( @@ -274,7 +289,7 @@ class class_ : public objects::class_base self& def_init() { detail::assert_default_constructible::check(); - this->def_init(mpl::type_list<>::type()); + this->def_init(mpl::list0<>::type()); return *this; } @@ -401,7 +416,7 @@ inline void class_::register_() const objects::register_class_from_python(); detail::register_copy_constructor( - mpl::bool_t() + mpl::bool_c() , holder_selector::execute((held_type*)0) ); } @@ -452,28 +467,6 @@ inline class_::class_(char const* name, char const* doc, no_init_t) namespace detail { - // This is an mpl BinaryMetaFunction object with a runtime behavior, - // which is to write the id of the type which is passed as its 2nd - // compile-time argument into the iterator pointed to by its runtime - // argument - struct write_type_id - { - // The first argument is Ignored because mpl::for_each is still - // currently an accumulate (reduce) implementation. - template struct apply - { - // also an artifact of accumulate-based for_each - typedef void type; - - // Here's the runtime behavior - static void execute(type_info** p) - { - *(*p)++ = type_id(); - } - }; - }; - - template struct has_noncopyable : type_traits::ice_or< @@ -485,7 +478,7 @@ namespace detail template struct select_held_type - : mpl::select_type< + : mpl::if_c< type_traits::ice_or< specifies_bases::value , is_same::value diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp index 585a30eb..1e3dfa26 100755 --- a/include/boost/python/converter/arg_from_python.hpp +++ b/include/boost/python/converter/arg_from_python.hpp @@ -12,7 +12,7 @@ # include # include # include -# include +# include # include # include # include @@ -165,22 +165,22 @@ struct select_arg_from_python bool, back_ref = boost::python::is_back_reference::value); - typedef typename mpl::select_type< + typedef typename mpl::if_c< obj_mgr , object_manager_value_arg_from_python - , typename mpl::select_type< + , typename mpl::if_c< obj_mgr_ref , object_manager_ref_arg_from_python - , typename mpl::select_type< + , typename mpl::if_c< ptr , pointer_arg_from_python - , typename mpl::select_type< + , typename mpl::if_c< ptr_cref , pointer_cref_arg_from_python - , typename mpl::select_type< + , typename mpl::if_c< ref , reference_arg_from_python - , typename mpl::select_type< + , typename mpl::if_c< back_ref , back_reference_arg_from_python , arg_rvalue_from_python diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index 7abb274c..deab7964 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -109,22 +109,22 @@ namespace detail typedef typename unwrap_reference::type unwrapped_referent; typedef typename unwrap_pointer::type unwrapped_ptr; - typedef typename mpl::select_type< + typedef typename mpl::if_c< is_string , arg_to_python - , typename mpl::select_type< + , typename mpl::if_c< function , function_arg_to_python - , typename mpl::select_type< + , typename mpl::if_c< manager , object_manager_arg_to_python - , typename mpl::select_type< + , typename mpl::if_c< ptr , pointer_deep_arg_to_python - , typename mpl::select_type< + , typename mpl::if_c< ptr_wrapper , pointer_shallow_arg_to_python - , typename mpl::select_type< + , typename mpl::if_c< ref_wrapper , reference_arg_to_python , value_arg_to_python diff --git a/include/boost/python/converter/object_manager.hpp b/include/boost/python/converter/object_manager.hpp index 431ef708..974c149b 100755 --- a/include/boost/python/converter/object_manager.hpp +++ b/include/boost/python/converter/object_manager.hpp @@ -10,7 +10,7 @@ # include # include # include -# include +# include # include // Facilities for dealing with types which always manage Python @@ -102,7 +102,7 @@ struct default_object_manager_traits template struct object_manager_traits - : mpl::select_type< + : mpl::if_c< is_handle::value , handle_object_manager_traits , default_object_manager_traits @@ -164,7 +164,7 @@ namespace detail template struct is_object_manager_help { - typedef typename mpl::select_type< + typedef typename mpl::if_c< is_object_manager::value , yes_reference_to_object_manager , no_reference_to_object_manager @@ -217,7 +217,7 @@ namespace detail template struct is_reference_to_object_manager { - typedef typename mpl::select_type< + typedef typename mpl::if_c< is_reference::value , detail::is_reference_to_object_manager_ref , detail::is_reference_to_object_manager_nonref diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index f02f01d9..58d182f0 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -63,13 +63,13 @@ namespace detail BOOST_STATIC_CONSTANT( bool, ref = is_reference::value); - typedef typename mpl::select_type< + typedef typename mpl::if_c< obj_mgr , return_object_manager_from_python - , typename mpl::select_type< + , typename mpl::if_c< ptr , return_pointer_from_python - , typename mpl::select_type< + , typename mpl::if_c< ref , return_reference_from_python , return_rvalue_from_python diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp index 72ea7bd7..16c9d44b 100644 --- a/include/boost/python/converter/rvalue_from_python_data.hpp +++ b/include/boost/python/converter/rvalue_from_python_data.hpp @@ -10,6 +10,8 @@ # include # include # include +# include +# include # include // Data management for potential rvalue conversions from Python to C++ diff --git a/include/boost/python/copy_const_reference.hpp b/include/boost/python/copy_const_reference.hpp index b2fdd61f..8eecd2ce 100644 --- a/include/boost/python/copy_const_reference.hpp +++ b/include/boost/python/copy_const_reference.hpp @@ -6,7 +6,7 @@ #ifndef COPY_CONST_REFERENCE_DWA2002131_HPP # define COPY_CONST_REFERENCE_DWA2002131_HPP # include -# include +# include # include namespace boost { namespace python { @@ -28,7 +28,7 @@ struct copy_const_reference template struct apply { - typedef typename mpl::select_type< + typedef typename mpl::if_c< detail::is_reference_to_const::value , to_python_value , detail::copy_const_reference_expects_a_const_reference_return_type diff --git a/include/boost/python/copy_non_const_reference.hpp b/include/boost/python/copy_non_const_reference.hpp index 6f53fbdc..53c576e0 100644 --- a/include/boost/python/copy_non_const_reference.hpp +++ b/include/boost/python/copy_non_const_reference.hpp @@ -6,7 +6,7 @@ #ifndef COPY_NON_CONST_REFERENCE_DWA2002131_HPP # define COPY_NON_CONST_REFERENCE_DWA2002131_HPP # include -# include +# include # include namespace boost { namespace python { @@ -28,7 +28,7 @@ struct copy_non_const_reference template struct apply { - typedef typename mpl::select_type< + typedef typename mpl::if_c< boost::python::detail::is_reference_to_non_const::value , to_python_value , detail::copy_non_const_reference_expects_a_non_const_reference_return_type diff --git a/include/boost/python/default_call_policies.hpp b/include/boost/python/default_call_policies.hpp index f0b69255..f964990f 100644 --- a/include/boost/python/default_call_policies.hpp +++ b/include/boost/python/default_call_policies.hpp @@ -6,7 +6,7 @@ #ifndef DEFAULT_CALL_POLICIES_DWA2002131_HPP # define DEFAULT_CALL_POLICIES_DWA2002131_HPP # include -# include +# include # include # include @@ -50,7 +50,7 @@ struct default_result_converter { BOOST_STATIC_CONSTANT(bool, is_illegal = is_reference::value || is_pointer::value); - typedef typename mpl::select_type< + typedef typename mpl::if_c< is_illegal , detail::specify_a_result_policy_to_wrap_functions_returning , boost::python::to_python_value< diff --git a/include/boost/python/detail/borrowed_ptr.hpp b/include/boost/python/detail/borrowed_ptr.hpp index dc50c634..6b35c862 100755 --- a/include/boost/python/detail/borrowed_ptr.hpp +++ b/include/boost/python/detail/borrowed_ptr.hpp @@ -8,7 +8,7 @@ # include # include -# include +# include # include # include # include @@ -77,7 +77,7 @@ typedef char (&no_borrowed_ptr_t)[2]; no_borrowed_ptr_t is_borrowed_ptr_test(...); template -typename mpl::select_type< +typename mpl::if_c< is_pointer::value , T , int diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index 322e1342..2ade2a11 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -21,8 +21,6 @@ # include # include -# // temp: include - # include # include # include diff --git a/include/boost/python/detail/convertible.hpp b/include/boost/python/detail/convertible.hpp index 4ab58d94..74440090 100755 --- a/include/boost/python/detail/convertible.hpp +++ b/include/boost/python/detail/convertible.hpp @@ -7,7 +7,7 @@ # define CONVERTIBLE_DWA2002614_HPP # if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 241 -# include +# include # include # endif @@ -26,7 +26,7 @@ struct convertible static inline yes_convertible check(Target) { return 0; } # else template - static inline typename mpl::select_type< + static inline typename mpl::if_c< is_convertible::value , yes_convertible , no_convertible diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index 7efbcb70..9c79d926 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -14,10 +14,10 @@ #include #include -#include +#include +#include #include #include -#include #include #include #include @@ -86,7 +86,7 @@ static void name_space_def( // template // inline void // define_stub_function( -// char const* name, StubsT s, NameSpaceT& name_space, boost::mpl::int_t) +// char const* name, StubsT s, NameSpaceT& name_space, mpl::int_c) // { // name_space.def(name, &StubsT::func_N); // } @@ -186,9 +186,9 @@ struct define_stub_function {}; // is a typelist that specifies the return type, the class (for member // functions, and the arguments. Here are some SigT examples: // -// int foo(int) mpl::type_list -// void bar(int, int) mpl::type_list -// void C::foo(int) mpl::type_list +// int foo(int) mpl::list +// void bar(int, int) mpl::list +// void C::foo(int) mpl::list // /////////////////////////////////////////////////////////////////////////////// template @@ -201,19 +201,18 @@ struct define_stub_function {}; SigT sig, char const* doc) { - typedef typename boost::python::detail::type_at<0, SigT>::type nth_type; + typedef typename mpl::front::type return_type; typedef typename StubsT::v_type v_type; typedef typename StubsT::nv_type nv_type; - typedef typename mpl::select_type< - boost::is_same::value + typedef typename mpl::if_c< + boost::is_same::value , v_type , nv_type >::type stubs_type; BOOST_STATIC_ASSERT( - (stubs_type::max_args) <= - boost::python::detail::type_list_size::value); + (stubs_type::max_args) <= mpl::size::value); typedef typename stubs_type::template gen gen_type; define_with_defaults_helper::def diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 3198baa2..78808424 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -23,7 +23,8 @@ #include #include #include -#include +#include +#include namespace boost { namespace python { namespace detail { @@ -39,7 +40,7 @@ struct func_stubs_base {}; /////////////////////////////////////////////////////////////////////////////// #define BPL_IMPL_TYPEDEF_GEN(z, INDEX, DATA) \ - typedef typename boost::python::detail::type_at \ + typedef typename ::boost::mpl::at_c \ < \ BOOST_PP_ADD_D(1, INDEX, DATA), \ SigT \ @@ -70,7 +71,7 @@ struct func_stubs_base {}; template \ struct gen { \ \ - typedef typename boost::python::detail::type_at<0, SigT>::type RT; \ + typedef typename ::boost::mpl::front::type RT; \ \ BOOST_PP_REPEAT_2ND \ ( \ @@ -113,8 +114,8 @@ struct func_stubs_base {}; template \ struct gen { \ \ - typedef typename boost::python::detail::type_at<0, SigT>::type RT; \ - typedef typename boost::python::detail::type_at<1, SigT>::type ClassT; \ + typedef typename ::boost::mpl::front::type RT; \ + typedef typename ::boost::mpl::at_c<1, SigT>::type ClassT; \ \ BOOST_PP_REPEAT_2ND \ ( \ @@ -224,11 +225,11 @@ struct func_stubs_base {}; // 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; +// 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; // // static RT func_0(T0 arg0) // { return foo(arg0); } diff --git a/include/boost/python/detail/destroy.hpp b/include/boost/python/detail/destroy.hpp index 89e82f73..7b107550 100644 --- a/include/boost/python/detail/destroy.hpp +++ b/include/boost/python/detail/destroy.hpp @@ -67,8 +67,8 @@ inline void destroy_referent_impl(void* p, T& (*)()) // note: cv-qualification needed for MSVC6 // must come *before* T for metrowerks value_destroyer< - (boost::is_array::value) - , (boost::has_trivial_destructor::value) + (boost::is_array::value) + ,(boost::has_trivial_destructor::value) >::execute((const volatile T*)p); } diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index faabecc2..c6f8bcc7 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -5,11 +5,17 @@ // to its suitability for any purpose. #ifndef INDIRECT_TRAITS_DWA2002131_HPP # define INDIRECT_TRAITS_DWA2002131_HPP -# include -# include -# include -# include -# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include namespace boost { namespace python { namespace detail { @@ -184,7 +190,7 @@ typedef char (&outer_no_type)[1]; template struct is_const_help { - typedef typename mpl::select_type< + typedef typename mpl::if_c< is_const::value , inner_yes_type , inner_no_type @@ -194,7 +200,7 @@ struct is_const_help template struct is_volatile_help { - typedef typename mpl::select_type< + typedef typename mpl::if_c< is_volatile::value , inner_yes_type , inner_no_type @@ -204,7 +210,7 @@ struct is_volatile_help template struct is_pointer_help { - typedef typename mpl::select_type< + typedef typename mpl::if_c< is_pointer::value , inner_yes_type , inner_no_type @@ -214,7 +220,7 @@ struct is_pointer_help template struct is_class_help { - typedef typename mpl::select_type< + typedef typename mpl::if_c< is_class::value , inner_yes_type , inner_no_type @@ -228,7 +234,7 @@ struct is_reference_to_function static T t; BOOST_STATIC_CONSTANT( bool, value - = sizeof(::boost::detail::is_function_tester(t)) == sizeof(::boost::type_traits::yes_type)); + = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)); # endif template @@ -237,7 +243,7 @@ struct is_pointer_to_function static T t; BOOST_STATIC_CONSTANT( bool, value - = sizeof(::boost::detail::is_function_tester(t)) == sizeof(::boost::type_traits::yes_type)); + = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)); }; struct false_helper1 diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp index 491e6711..f143abd0 100644 --- a/include/boost/python/detail/member_function_cast.hpp +++ b/include/boost/python/detail/member_function_cast.hpp @@ -11,7 +11,7 @@ # include -# include +# include # include # include @@ -71,7 +71,7 @@ struct member_function_cast # ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING : member_function_cast_impl # else - : mpl::select_type< + : mpl::if_c< is_member_function_pointer::value , member_function_cast_impl , non_member_function_cast_impl diff --git a/include/boost/python/detail/msvc_typeinfo.hpp b/include/boost/python/detail/msvc_typeinfo.hpp index 21e47389..b50922b7 100644 --- a/include/boost/python/detail/msvc_typeinfo.hpp +++ b/include/boost/python/detail/msvc_typeinfo.hpp @@ -8,8 +8,10 @@ #include #include -#include -#include +#include +#include +#include +#include // // Fix for MSVC's broken typeid() implementation which doesn't strip // decoration. This fix doesn't handle cv-qualified array types. It diff --git a/include/boost/python/detail/preprocessor.hpp b/include/boost/python/detail/preprocessor.hpp index 89d1d26d..45e307d4 100644 --- a/include/boost/python/detail/preprocessor.hpp +++ b/include/boost/python/detail/preprocessor.hpp @@ -30,6 +30,10 @@ # define BOOST_PYTHON_MAX_ARITY 15 # endif +# ifndef BOOST_PYTHON_MAX_BASES +# define BOOST_PYTHON_MAX_BASES 10 +# endif + # define BOOST_PYTHON_CV_QUALIFIER(i) \ BOOST_PYTHON_APPLY( \ BOOST_PP_TUPLE_ELEM(4, i, BOOST_PYTHON_CV_QUALIFIER_I) \ diff --git a/include/boost/python/detail/referent_storage.hpp b/include/boost/python/detail/referent_storage.hpp index aebacf64..b93d888f 100644 --- a/include/boost/python/detail/referent_storage.hpp +++ b/include/boost/python/detail/referent_storage.hpp @@ -5,7 +5,7 @@ // to its suitability for any purpose. #ifndef REFERENT_STORAGE_DWA200278_HPP # define REFERENT_STORAGE_DWA200278_HPP -# include +# include # include namespace boost { namespace python { namespace detail { @@ -16,7 +16,7 @@ typedef int (alignment_dummy::*member_ptr); typedef int (alignment_dummy::*member_function_ptr)(); # define BOOST_PYTHON_ALIGNER(T, n) \ - typename mpl::select_type< \ + typename mpl::if_c< \ sizeof(T) <= size, T, char>::type t##n // Storage for size bytes, aligned to all fundamental types no larger than size diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp index 84f6a554..6ec95fb7 100755 --- a/include/boost/python/detail/result.hpp +++ b/include/boost/python/detail/result.hpp @@ -14,7 +14,7 @@ # include # include -# include +# include # include # include @@ -60,7 +60,7 @@ struct void_type template struct result_result { - typedef typename mpl::select_type< + typedef typename mpl::if_c< is_class::value , get_result_type , void_type diff --git a/include/boost/python/detail/type_list.hpp b/include/boost/python/detail/type_list.hpp index 66ac3857..4a09c0be 100644 --- a/include/boost/python/detail/type_list.hpp +++ b/include/boost/python/detail/type_list.hpp @@ -3,14 +3,38 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef TYPE_LIST_DWA200222_HPP -# define TYPE_LIST_DWA200222_HPP -# include +#ifndef TYPE_LIST_DWA2002913_HPP +# define TYPE_LIST_DWA2002913_HPP -namespace boost { namespace python { namespace detail { +# include +# include +# include -struct empty_list : boost::mpl::type_list<>::type {}; +# if BOOST_PYTHON_MAX_ARITY + 2 > BOOST_PYTHON_MAX_BASES +# define BOOST_PYTHON_LIST_SIZE BOOST_PP_INC(BOOST_PP_INC(BOOST_PYTHON_MAX_ARITY)) +# else +# define BOOST_PYTHON_BASE_LIST_SIZE BOOST_PYTHON_MAX_BASES +# endif -}}} // namespace boost::python::detail +// Compute the MPL list header to use for lists up to BOOST_PYTHON_LIST_SIZE in length +# if BOOST_PYTHON_LIST_SIZE > 48 +# error Arities above 48 not supported by Boost.Python due to MPL internal limit +# elif BOOST_PYTHON_LIST_SIZE > 38 +# include +# elif BOOST_PYTHON_LIST_SIZE > 28 +# include +# elif BOOST_PYTHON_LIST_SIZE > 18 +# include +# elif BOOST_PYTHON_LIST_SIZE > 8 +# include +# else +# include +# endif -#endif // TYPE_LIST_DWA200222_HPP +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# include +# else +# include +# endif + +#endif // TYPE_LIST_DWA2002913_HPP diff --git a/include/boost/python/detail/type_list_impl.hpp b/include/boost/python/detail/type_list_impl.hpp new file mode 100644 index 00000000..2a02851f --- /dev/null +++ b/include/boost/python/detail/type_list_impl.hpp @@ -0,0 +1,55 @@ +#ifndef BOOST_PP_IS_ITERATING +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +# ifndef TYPE_LIST_IMPL_DWA2002913_HPP +# define TYPE_LIST_IMPL_DWA2002913_HPP + +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +template +struct type_list + : BOOST_PP_CAT(mpl::list,BOOST_PYTHON_LIST_SIZE) +{ +}; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PP_DEC(BOOST_PYTHON_LIST_SIZE), )) +# include BOOST_PP_ITERATE() + + +}}} // namespace boost::python::detail + +# endif // TYPE_LIST_IMPL_DWA2002913_HPP + +#else // BOOST_PP_IS_ITERATING + +# define N BOOST_PP_ITERATION() +# define BOOST_PYTHON_VOID_ARGS BOOST_PP_SUB_D(1,BOOST_PYTHON_LIST_SIZE,N) + +template < + BOOST_PP_ENUM_PARAMS(N, class T) + > +struct type_list< + BOOST_PP_ENUM_PARAMS(N, T) + BOOST_PP_COMMA_IF(N) + BOOST_PP_ENUM( + BOOST_PYTHON_VOID_ARGS, BOOST_PYTHON_FIXED, mpl::void_) + > + : BOOST_PP_CAT(mpl::list,N) +{ +}; + +# undef BOOST_PYTHON_VOID_ARGS +# undef N + +#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/type_list_impl_no_pts.hpp b/include/boost/python/detail/type_list_impl_no_pts.hpp new file mode 100644 index 00000000..1c4d392c --- /dev/null +++ b/include/boost/python/detail/type_list_impl_no_pts.hpp @@ -0,0 +1,101 @@ +#ifndef BOOST_PP_IS_ITERATING +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +# ifndef TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP +# define TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP + +# include +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +template< typename T > +struct is_list_arg +{ + enum { value = true }; +}; + +template<> +struct is_list_arg +{ + enum { value = false }; +}; + +template struct type_list_impl_chooser; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_LIST_SIZE, )) +# include BOOST_PP_ITERATE() + +# define BOOST_PYTHON_PLUS() + +# define BOOST_PYTHON_IS_LIST_ARG(z, n, data) \ + BOOST_PP_IF(n, BOOST_PYTHON_PLUS, BOOST_PP_EMPTY)() \ + is_list_arg< BOOST_PP_CAT(T,n) >::value + +template< + BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE, class T) + > +struct type_list_count_args +{ + enum { value = + BOOST_PP_REPEAT_1(BOOST_PYTHON_LIST_SIZE, BOOST_PYTHON_IS_LIST_ARG, _) + }; +}; + +# undef BOOST_PYTHON_IS_LIST_ARG +# undef BOOST_PYTHON_PLUS + +template< + BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE, class T) + > +struct type_list_impl +{ + typedef type_list_count_args< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE,T) > arg_num_; + typedef typename detail::type_list_impl_chooser< arg_num_::value > + ::template result_< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE,T) >::type type; +}; + +template< + BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_LIST_SIZE, class T, mpl::void_) + > +struct type_list + : detail::type_list_impl< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE,T) >::type +{ + typedef typename detail::type_list_impl< + BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE,T) + >::type type; +}; + +}}} // namespace boost::python::detail + +# endif // TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP + +#else // BOOST_PP_IS_ITERATING + +# define N BOOST_PP_ITERATION() + +template<> +struct type_list_impl_chooser +{ + template< + BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE, class T) + > + struct result_ + { + typedef BOOST_PP_CAT(mpl::list,N)< + BOOST_PP_ENUM_PARAMS(N, T) + > type; + }; +}; + +# undef N + +#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/type_list_utils.hpp b/include/boost/python/detail/type_list_utils.hpp index d03203b9..ebb5488b 100644 --- a/include/boost/python/detail/type_list_utils.hpp +++ b/include/boost/python/detail/type_list_utils.hpp @@ -1,116 +1,28 @@ -/////////////////////////////////////////////////////////////////////////////// -// +#error obsolete // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -// -/////////////////////////////////////////////////////////////////////////////// -#if !defined(BOOST_PP_IS_ITERATING) - #ifndef TYPE_LIST_UTILS_JDG20020826_HPP -#define TYPE_LIST_UTILS_JDG20020826_HPP +# define TYPE_LIST_UTILS_JDG20020826_HPP -# include -# include -//# include -//# include - -# include -# include -# include -# include -# include -# include - -# include +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION namespace boost { namespace python { namespace detail { -# if (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 245) \ - && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) +template< typename T > +struct is_list_arg +{ + enum { value = true }; +}; - template - struct type_at : public boost::mpl::at {}; - - template - struct type_list_size : public boost::mpl::size {}; - -// template -// struct pop_front : public boost::mpl::pop_front {}; -// -// template -// struct pop_back : public boost::mpl::pop_back {}; - -# else - - template - struct type_at {}; - - template - struct type_list_size {}; - -// template -// struct pop_front {}; -// -// template -// struct pop_back {}; - -// template -// struct push_back {}; - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -# endif - -}}} // namespace boost::python::detail +template<> +struct is_list_arg +{ + enum { value = false }; +}; +}}} +# endif #endif // TYPE_LIST_UTILS_JDG20020826_HPP - -#else // defined(BOOST_PP_IS_ITERATING) - -# define N BOOST_PP_ITERATION() - -# if (N < BOOST_PYTHON_MAX_ARITY-1) - - template - struct type_at > - { - typedef BOOST_PP_CAT(A, N) type; - }; - -// template -// struct push_back, T> -// { -// typedef boost::mpl::type_list sequence; -// }; - -# if (N > 0) - -// template -// struct pop_front > -// { -// typedef boost::mpl::type_list sequence; -// }; -// -// template -// struct pop_back > -// { -// typedef boost::mpl::type_list sequence; -// }; - -# endif -# endif - - template - struct type_list_size > - { - BOOST_STATIC_CONSTANT(long, value = N); - }; - -# undef N - -#endif // !defined(BOOST_PP_IS_ITERATING) diff --git a/include/boost/python/extract.hpp b/include/boost/python/extract.hpp index fdcaac28..598fe249 100644 --- a/include/boost/python/extract.hpp +++ b/include/boost/python/extract.hpp @@ -87,13 +87,13 @@ namespace converter BOOST_STATIC_CONSTANT( bool, ref = is_reference::value); - typedef typename mpl::select_type< + typedef typename mpl::if_c< obj_mgr , extract_object_manager - , typename mpl::select_type< + , typename mpl::if_c< ptr , extract_pointer - , typename mpl::select_type< + , typename mpl::if_c< ref , extract_reference , extract_rvalue diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 567e480a..733973b1 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -10,21 +10,29 @@ #ifndef INIT_JDG20020820_HPP #define INIT_JDG20020820_HPP -#include -#include -#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include + +#include #include #include #include +#include #include -#include -#include -#include /////////////////////////////////////////////////////////////////////////////// #define BOOST_PYTHON_TEMPLATE_TYPES_WITH_DEFAULT \ @@ -32,7 +40,7 @@ ( \ BOOST_PYTHON_MAX_ARITY, \ class T, \ - boost::mpl::null_argument \ + mpl::void_ \ ) \ #define BOOST_PYTHON_TEMPLATE_TYPES \ @@ -61,16 +69,6 @@ struct optional; // forward declaration namespace detail { - /////////////////////////////////////////////////////////////////////////// - // - // is_nil::value - // - // This metaprogram checks if T is nil - // - /////////////////////////////////////////////////////////////////////////// - template - struct is_nil : public boost::is_same {}; - /////////////////////////////////////////////////////////////////////////// // // is_optional::value @@ -95,291 +93,159 @@ namespace detail { BOOST_STATIC_CONSTANT( 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 }; /////////////////////////////////////// #else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template - struct is_optional { + struct is_optional_impl { BOOST_STATIC_CONSTANT(bool, value = false); }; template - struct is_optional > { + struct is_optional_impl > { BOOST_STATIC_CONSTANT(bool, value = true); }; - #endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - - /////////////////////////////////////////////////////////////////////////// - // - // append_to_init [ and helpers ] - // - // A metaprogram appends T to the initializer type list - // - /////////////////////////////////////////////////////////////////////////// - struct append_to_init_helper1 { - - // Case 1: default case, just push T to the back of ListT - - template - struct apply { - - typedef typename boost::mpl::push_back::sequence sequence; - }; - }; - - struct append_to_init_helper2 { - - template - struct apply { - - // Case 2: optional case, T is an optional, append all - // the contents of the optional T into back of ListT - - typedef typename boost::mpl::for_each - < - typename T::sequence, - ListT, - boost::mpl::push_back - >::state sequence; - }; - }; - - struct append_to_init_helper3 { - - // Case 3: nil case, we found a nil, do nothing - - template - struct apply { - - typedef ListT sequence; - }; - }; - - template - struct append_to_init { - - typedef typename boost::mpl::select_type - < - is_optional::value, // if - append_to_init_helper2, // then - typename boost::mpl::select_type // else - < - is_nil::value, // if - append_to_init_helper3, // then - append_to_init_helper1 // else - >::type - >::type helper; - - typedef typename helper::template apply::sequence sequence; - }; - - /////////////////////////////////////////////////////////////////////////// - // - // check_init_params [ and helpers ] - // - // Check the init template parameters. Detect illegal - // arguments such as: - // - // init, int> // BAD trailing int - // init, optional > // BAD optional used twice - // - /////////////////////////////////////////////////////////////////////////// - template - struct check_init_params_helper { - - template - struct apply { - - // case where size of sequence is not zero - - typedef typename boost::mpl::pop_front::sequence rest; - - enum { - - // if first is optional then there must be no more - // elements to its right. if not then recurse and check - // the rest of the type list - - first_is_optional = - is_optional::type>::value, - size_of_rest = boost::mpl::size::value, - rest_is_nil = (size_of_rest == 0), - is_ok = first_is_optional ? rest_is_nil : - check_init_params_helper - ::template apply::is_ok - }; - }; - }; - - template <> - struct check_init_params_helper<0> { - - // case where size of sequence is zero - - template - struct apply { - - enum { is_ok = true }; - }; - }; - - struct init_base {}; - - template - struct check_init_params : init_base { - - typedef boost::mpl::type_list params; - - BOOST_STATIC_ASSERT - ( - check_init_params_helper::value> - ::template apply::is_ok - ); - }; - - /////////////////////////////////////////////////////////////////////////// - // - // count_optional_types [ and helpers ] - // - // count_optional_types::value computes the number of - // optional types (see init and optional below). For example: - // - // init >::value == 3 - // - /////////////////////////////////////////////////////////////////////////// template - struct count_optionals1 { - - BOOST_STATIC_CONSTANT(int, value = 0); - }; - - template - struct count_optionals2 { - - BOOST_STATIC_CONSTANT( - int, value = boost::mpl::size::value + 1); - }; - - template - struct count_optionals - : boost::mpl::select_type - < - is_optional::value, // if - count_optionals2, // then - count_optionals1 // else - >::type + struct is_optional : is_optional_impl { + typedef mpl::bool_c::value> type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T)) // needed for MSVC & Borland }; - - template - struct count_optional_types { - - BOOST_STATIC_CONSTANT(int, value = - count_optionals::value + - count_optionals::value + - count_optionals::value - ); - }; + #endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) } // namespace detail -/////////////////////////////////////////////////////////////////////////////// -// -// init -// -// init::sequence returns a typelist. One of T0..TN -// mat be an optional<...> see below. There should be only one -// optional in the input types and an optional should be the -// last in the list. -// -/////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_APPEND_TO_INIT(z, INDEX, D) \ - typedef typename detail::append_to_init \ - < \ - BOOST_PP_CAT(l, INDEX), \ - BOOST_PP_CAT(T, BOOST_PP_INC(INDEX)) \ - >::sequence BOOST_PP_CAT(l, BOOST_PP_INC(INDEX)); \ - template -struct init : detail::check_init_params +struct init //: detail::check_init_params { - typedef boost::mpl::type_list l0; - BOOST_PP_REPEAT_1ST( - BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY), BOOST_PYTHON_APPEND_TO_INIT, 0) + typedef detail::type_list signature_; + typedef typename mpl::end::type finish; - typedef BOOST_PP_CAT(l, BOOST_PP_DEC(BOOST_PYTHON_MAX_ARITY)) sequence; + // Find the optional<> element, if any + typedef typename mpl::find_if< + signature_, detail::is_optional + >::type opt; - BOOST_STATIC_CONSTANT(int, n_arguments = boost::mpl::size::value); - BOOST_STATIC_CONSTANT(int, n_defaults = - (detail::count_optional_types::value) - ); + // Check to make sure the optional<> element, if any, is the last one + typedef typename mpl::apply_if< + is_same + , mpl::identity + , mpl::next + >::type expected_finish; + BOOST_STATIC_ASSERT((is_same::value)); + + typedef typename mpl::apply_if< + is_same + , mpl::list0<> + , opt + >::type optional_args; + + // Count the number of default args + BOOST_STATIC_CONSTANT(int, n_defaults = mpl::size::value); + + typedef typename mpl::iterator_range< + typename mpl::begin::type + , opt + >::type required_args; + + // Build a reverse image of all the args, including optionals + typedef typename mpl::fold< + required_args + , mpl::list0<> + , mpl::push_front + >::type reversed_required; + + typedef typename mpl::fold< + optional_args + , reversed_required + , mpl::push_front + >::type reversed_args; + + // Count the maximum number of arguments + BOOST_STATIC_CONSTANT(int, n_arguments = mpl::size::value); }; /////////////////////////////////////////////////////////////////////////////// // // optional // -// optional::sequence returns a typelist. +// optional::type returns a typelist. // /////////////////////////////////////////////////////////////////////////////// template -struct optional { - - typedef boost::mpl::type_list sequence; +struct optional + : detail::type_list +{ }; -namespace detail { +namespace detail +{ + template + void def_init_reversed(ClassT& cl, ReversedArgs const&, CallPoliciesT const& policies, char const* doc) + { + typedef typename mpl::fold< + ReversedArgs + , mpl::list0<> + , mpl::push_front + >::type args; + + cl.def_init(args(), policies, doc); + } + + /////////////////////////////////////////////////////////////////////////////// + // + // define_class_init_helper::apply + // + // General case + // + // Accepts a class_ and an arguments list. Defines a constructor + // for the class given the arguments and recursively calls + // define_class_init_helper::apply with one less arguments (the + // rightmost argument is shaved off) + // + /////////////////////////////////////////////////////////////////////////////// + template + struct define_class_init_helper { - /////////////////////////////////////////////////////////////////////////////// - // - // define_class_init_helper::apply - // - // General case - // - // Accepts a class_ and an arguments list. Defines a constructor - // for the class given the arguments and recursively calls - // define_class_init_helper::apply with one less arguments (the - // rightmost argument is shaved off) - // - /////////////////////////////////////////////////////////////////////////////// - template - struct define_class_init_helper { + template + static void apply(ClassT& cl, CallPoliciesT const& policies, ReversedArgs const& args, char const* doc) + { + def_init_reversed(cl, args, policies, doc); - template - static void apply(ClassT& cl, CallPoliciesT const& policies, ArgsT const& args, char const* doc) - { - cl.def_init(args, policies, doc); - typename boost::mpl::pop_back::sequence next; - define_class_init_helper::apply(cl, policies, next, doc); - } - }; + typename mpl::pop_front::type next; + define_class_init_helper::apply(cl, policies, next, doc); + } + }; - /////////////////////////////////////////////////////////////////////////////// - // - // define_class_init_helper<0>::apply - // - // Terminal case - // - // Accepts a class_ and an arguments list. Defines a constructor - // for the class given the arguments. - // - /////////////////////////////////////////////////////////////////////////////// - template <> - struct define_class_init_helper<0> { + /////////////////////////////////////////////////////////////////////////////// + // + // define_class_init_helper<0>::apply + // + // Terminal case + // + // Accepts a class_ and an arguments list. Defines a constructor + // for the class given the arguments. + // + /////////////////////////////////////////////////////////////////////////////// + template <> + struct define_class_init_helper<0> { - template - static void apply(ClassT& cl, CallPoliciesT const& policies, ArgsT const& args, char const* doc) - { - cl.def_init(args, policies, doc); - } - }; + template + static void apply(ClassT& cl, CallPoliciesT const& policies, ReversedArgs const& args, char const* doc) + { + def_init_reversed(cl, args, policies, doc); + } + }; } /////////////////////////////////////////////////////////////////////////////// @@ -407,8 +273,8 @@ template void define_init(ClassT& cl, InitT const& i, CallPoliciesT const& policies, char const* doc) { - typedef typename InitT::sequence args_t; - detail::define_class_init_helper::apply(cl, policies, args_t(), doc); + typedef typename InitT::reversed_args reversed_args; + detail::define_class_init_helper::apply(cl, policies, reversed_args(), doc); } }} // namespace boost::python diff --git a/include/boost/python/manage_new_object.hpp b/include/boost/python/manage_new_object.hpp index e19035b7..0acbbec8 100644 --- a/include/boost/python/manage_new_object.hpp +++ b/include/boost/python/manage_new_object.hpp @@ -6,7 +6,7 @@ #ifndef MANAGE_NEW_OBJECT_DWA200222_HPP # define MANAGE_NEW_OBJECT_DWA200222_HPP # include -# include +# include # include # include @@ -27,7 +27,7 @@ struct manage_new_object template struct apply { - typedef typename mpl::select_type< + typedef typename mpl::if_c< boost::is_pointer::value , to_python_indirect , detail::manage_new_object_requires_a_pointer_return_type diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index 14e79a9d..79119ef7 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -13,6 +13,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -45,29 +46,22 @@ struct do_nothing template struct register_base_of { - // Ignored is needed because mpl::for_each is still actually - // accumulate. We're not using any state so it just sits there. - template - struct apply + // Here's the runtime part: + template + void operator()(Base*) const { - typedef void type; // 'type' needs to be defined for the same reasons + // Register the Base class + register_dynamic_id(); + // Register the up-cast + register_conversion(false); - // Here's the runtime part: - static void execute() - { - // Register the Base class - register_dynamic_id(); - // Register the up-cast - register_conversion(false); - - // Register the down-cast, if appropriate. - mpl::select_type< - is_polymorphic::value - , register_downcast - , do_nothing - >::type::execute(); - } - }; + // Register the down-cast, if appropriate. + mpl::if_c< + is_polymorphic::value + , register_downcast + , do_nothing + >::type::execute(); + } }; // Brings into existence all converters associated with a class Bases @@ -82,7 +76,7 @@ inline void register_class_from_python(Derived* = 0, Bases* = 0) register_dynamic_id(); // register each base in the sequence - mpl::for_each >::execute(); + mpl::for_each(register_base_of(), (Bases*)0, (add_pointer*)0); } }}} // namespace boost::python::object diff --git a/include/boost/python/object/forward.hpp b/include/boost/python/object/forward.hpp index cc23e94c..93c1ed21 100644 --- a/include/boost/python/object/forward.hpp +++ b/include/boost/python/object/forward.hpp @@ -6,10 +6,11 @@ #ifndef FORWARD_DWA20011215_HPP # define FORWARD_DWA20011215_HPP -# include +# include # include # include # include +# include # include namespace boost { namespace python { namespace objects { @@ -30,7 +31,7 @@ struct reference_to_value // is T. template struct forward - : mpl::select_type< + : mpl::if_c< is_scalar::value , T , reference_to_value > diff --git a/include/boost/python/object/inheritance.hpp b/include/boost/python/object/inheritance.hpp index 5129e35e..88b556ff 100644 --- a/include/boost/python/object/inheritance.hpp +++ b/include/boost/python/object/inheritance.hpp @@ -8,7 +8,7 @@ # include # include -# include +# include # include namespace boost { namespace python { namespace objects { @@ -80,7 +80,7 @@ struct non_polymorphic_id_generator template struct dynamic_id_generator { - typedef typename mpl::select_type< + typedef typename mpl::if_c< is_polymorphic::value , polymorphic_id_generator , non_polymorphic_id_generator >::type type; @@ -133,7 +133,7 @@ struct cast_generator is_base_and_derived::value )); - typedef typename mpl::select_type< + typedef typename mpl::if_c< is_upcast # if defined(__MWERKS__) && __MWERKS__ <= 0x2406 // grab a few more implicit_cast cases for CodeWarrior diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 3073e83b..2a9e4e58 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -15,7 +15,9 @@ # include # include -# include +# include +# include +# include # include # include @@ -29,8 +31,10 @@ namespace boost { namespace python { namespace objects { template struct make_holder; # define BOOST_PYTHON_FORWARD_ARG(z, index, _) \ - typedef typename mpl::at::type t##index; \ - typedef typename forward::type f##index; + typedef typename iter##index::type t##index; \ + typedef typename forward::type f##index; \ + typedef typename mpl::next::type \ + BOOST_PP_CAT(iter,BOOST_PP_INC(index)); # define BOOST_PYTHON_DO_FORWARD_ARG(z, index, _) , f##index(a##index) @@ -56,6 +60,7 @@ struct make_holder template struct apply { + typedef typename mpl::begin::type iter0; BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FORWARD_ARG, nil) static void execute( PyObject* p diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 1fe20ef3..0dca4ae3 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -22,7 +22,7 @@ # include # include -# include +# include # include # include diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index 6902f68d..3535fd29 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -15,10 +15,10 @@ # include # include # include -# include +# include # include # include -# include +# include # include namespace boost { namespace python { namespace objects { @@ -30,7 +30,7 @@ namespace detail { BOOST_STATIC_CONSTANT(bool, selector = (!is_same::value) | has_back_reference::value); - typedef typename mpl::select_type< + typedef typename mpl::if_c< selector , value_holder_back_reference , value_holder @@ -38,18 +38,18 @@ namespace detail static inline void register_() { - select_value_holder::register_(mpl::bool_t()); + select_value_holder::register_(mpl::bool_c()); } static type* get() { return 0; } private: - static inline void register_(mpl::bool_t) + static inline void register_(mpl::bool_c) { python::detail::force_instantiate(instance_finder::registration); } - static inline void register_(mpl::bool_t) + static inline void register_(mpl::bool_c) { } }; @@ -60,7 +60,7 @@ namespace detail typedef typename python::pointee::type pointee; BOOST_STATIC_CONSTANT(bool, selector = (!is_same::value) | has_back_reference::value); - typedef typename mpl::select_type< + typedef typename mpl::if_c< selector , pointer_holder_back_reference , pointer_holder @@ -68,13 +68,13 @@ namespace detail static inline void register_() { - select_pointer_holder::register_(mpl::bool_t()); + select_pointer_holder::register_(mpl::bool_c()); } static type* get() { return 0; } private: - static inline void register_(mpl::bool_t) + static inline void register_(mpl::bool_c) { // not implemented at least until we solve the back // reference issue mentioned in pointer_holder.hpp. @@ -94,7 +94,7 @@ namespace detail } }; - static inline void register_(mpl::bool_t) + static inline void register_(mpl::bool_c) { python::detail::force_instantiate( objects::class_wrapper< diff --git a/include/boost/python/operators2.hpp b/include/boost/python/operators2.hpp index 8c56abf7..3f06eb46 100755 --- a/include/boost/python/operators2.hpp +++ b/include/boost/python/operators2.hpp @@ -11,7 +11,7 @@ # include # include # include -# include +# include # include # include # include @@ -120,15 +120,15 @@ namespace detail // self_t template struct operator_ - : mpl::select_type< - (is_same::value) - , typename mpl::select_type< - (is_same::value) + : mpl::if_< + is_same + , typename mpl::if_< + is_same , binary_op , binary_op_l::type> >::type - , typename mpl::select_type< - (is_same::value) + , typename mpl::if_< + is_same , unary_op , binary_op_r::type> >::type diff --git a/include/boost/python/pointee.hpp b/include/boost/python/pointee.hpp index 52d65d67..d62bab54 100644 --- a/include/boost/python/pointee.hpp +++ b/include/boost/python/pointee.hpp @@ -7,6 +7,7 @@ # define POINTEE_DWA2002323_HPP # include +# include namespace boost { namespace python { diff --git a/include/boost/python/reference_existing_object.hpp b/include/boost/python/reference_existing_object.hpp index 1f8a43d8..e16dcf18 100644 --- a/include/boost/python/reference_existing_object.hpp +++ b/include/boost/python/reference_existing_object.hpp @@ -6,7 +6,7 @@ #ifndef REFERENCE_EXISTING_OBJECT_DWA200222_HPP # define REFERENCE_EXISTING_OBJECT_DWA200222_HPP # include -# include +# include # include # include @@ -32,7 +32,7 @@ struct reference_existing_object BOOST_STATIC_CONSTANT( bool, ok = is_pointer::value || is_reference::value); - typedef typename mpl::select_type< + typedef typename mpl::if_c< ok , to_python_indirect , detail::reference_existing_object_requires_a_pointer_or_reference_return_type diff --git a/include/boost/python/return_internal_reference.hpp b/include/boost/python/return_internal_reference.hpp index 3a968f45..7e350d77 100644 --- a/include/boost/python/return_internal_reference.hpp +++ b/include/boost/python/return_internal_reference.hpp @@ -9,7 +9,7 @@ # include # include # include -# include +# include namespace boost { namespace python { @@ -30,7 +30,7 @@ struct return_internal_reference private: BOOST_STATIC_CONSTANT(bool, legal = owner_arg > 0); public: - typedef typename mpl::select_type< + typedef typename mpl::if_c< legal , reference_existing_object , detail::return_internal_reference_owner_arg_must_be_greater_than_zero diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index 3bef081e..bd4b26df 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -19,8 +19,19 @@ # include # include # include -# include +# include + # include +# include +# include +# include + +# define BOOST_PYTHON_FUNCTION_SIGNATURE_LIST(n) \ + BOOST_PP_CAT(mpl::list, BOOST_PP_INC(n)) + +# define BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(n) \ + BOOST_PP_CAT(mpl::list, BOOST_PP_INC(BOOST_PP_INC(n))) + /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { namespace detail { @@ -30,28 +41,28 @@ namespace boost { namespace python { namespace detail { // The following macros generate expansions for: // // template -// inline boost::mpl::type_list +// inline mpl::list // get_signature(RT(*)(T0...TN)) // { -// return boost::mpl::type_list(); +// return mpl::list(); // } // // template -// inline boost::mpl::type_list +// inline mpl::list // get_signature(RT(ClassT::*)(T0...TN))) // { -// return boost::mpl::type_list(); +// return mpl::list(); // } // // template -// inline boost::mpl::type_list +// inline mpl::list // get_signature(RT(ClassT::*)(T0...TN) const)) // { -// return boost::mpl::type_list(); +// return mpl::list(); // } // // These functions extract the return type, class (for member functions) -// and arguments of the input signature and stuffs them in an mpl::type_list. +// and arguments of the input signature and stuffs them in an mpl::list. // /////////////////////////////////////////////////////////////////////////////// @@ -65,6 +76,10 @@ namespace boost { namespace python { namespace detail { }} // namespace boost::python + +# undef BOOST_PYTHON_FUNCTION_SIGNATURE_LIST +# undef BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST + /////////////////////////////////////////////////////////////////////////////// # endif // SIGNATURE_JDG20020813_HPP @@ -73,47 +88,38 @@ namespace boost { namespace python { namespace detail { # define N BOOST_PP_ITERATION() template < - class RT BOOST_PP_COMMA_IF(N) - BOOST_PYTHON_UNARY_ENUM(N, class T)> -inline boost::mpl::type_list< - RT BOOST_PP_COMMA_IF(N) - BOOST_PP_ENUM_PARAMS(N, T)> + class RT BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> +inline BOOST_PYTHON_FUNCTION_SIGNATURE_LIST(N)< + RT BOOST_PP_ENUM_TRAILING_PARAMS(N, T)> get_signature(RT(*)(BOOST_PP_ENUM_PARAMS(N, T))) { - return boost::mpl::type_list< - RT BOOST_PP_COMMA_IF(N) - BOOST_PP_ENUM_PARAMS(N, T)>(); + return BOOST_PYTHON_FUNCTION_SIGNATURE_LIST(N)< + RT BOOST_PP_ENUM_TRAILING_PARAMS(N, T) + >(); } /////////////////////////////////////////////////////////////////////////////// #if N <= (BOOST_PYTHON_MAX_ARITY - 2) template < - class RT, class ClassT BOOST_PP_COMMA_IF(N) - BOOST_PYTHON_UNARY_ENUM(N, class T)> -inline boost::mpl::type_list< - RT, ClassT BOOST_PP_COMMA_IF(N) - BOOST_PP_ENUM_PARAMS(N, T)> + class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> +inline BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< + RT, ClassT BOOST_PP_ENUM_TRAILING_PARAMS(N, T)> get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T))) { - return boost::mpl::type_list< - RT, ClassT BOOST_PP_COMMA_IF(N) - BOOST_PP_ENUM_PARAMS(N, T)>(); + return BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< + RT, ClassT BOOST_PP_ENUM_TRAILING_PARAMS(N, T)>(); } /////////////////////////////////////// template < - class RT, class ClassT BOOST_PP_COMMA_IF(N) - BOOST_PYTHON_UNARY_ENUM(N, class T)> -inline boost::mpl::type_list< - RT, ClassT const BOOST_PP_COMMA_IF(N) - BOOST_PP_ENUM_PARAMS(N, T)> + class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> +inline BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< + RT, ClassT const BOOST_PP_ENUM_TRAILING_PARAMS(N, T)> get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T)) const) { - return boost::mpl::type_list< - RT, ClassT const - BOOST_PP_COMMA_IF(N) - BOOST_PP_ENUM_PARAMS(N, T)>(); + return BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< + RT, ClassT const BOOST_PP_ENUM_TRAILING_PARAMS(N, T)>(); } #endif // N < (BOOST_PYTHON_MAX_ARITY - 2) diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp index b85eaf68..3b9cd76c 100644 --- a/include/boost/python/to_python_value.hpp +++ b/include/boost/python/to_python_value.hpp @@ -11,7 +11,7 @@ # include # include # include -# include +# include # include # include # include @@ -46,7 +46,7 @@ namespace detail template struct to_python_value - : mpl::select_type< + : mpl::if_c< boost::type_traits::ice_or< converter::is_object_manager::value , converter::is_reference_to_object_manager::value From 7fe5fb92b4868a91e86f4757d36fa10d43676541 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 16 Sep 2002 15:26:20 +0000 Subject: [PATCH 0741/1042] Patch for KCC bug [SVN r15381] --- include/boost/python/detail/aix_init_module.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/boost/python/detail/aix_init_module.hpp b/include/boost/python/detail/aix_init_module.hpp index 6eda62ea..06071c1f 100644 --- a/include/boost/python/detail/aix_init_module.hpp +++ b/include/boost/python/detail/aix_init_module.hpp @@ -8,6 +8,9 @@ # ifdef _AIX # include # include +# ifdef __KCC +# include // this works around a problem in KCC 4.0f +# endif namespace boost { namespace python { namespace detail { From 7cc01e155c2eb44629cf80eafced5ba4d3df4c29 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 17 Sep 2002 02:05:11 +0000 Subject: [PATCH 0742/1042] Kill extra ; [SVN r15395] --- include/boost/python/class.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 7f769739..c990e3bf 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -52,7 +52,7 @@ namespace detail void operator()(T*) const { *(*p)++ = type_id(); - }; + } type_info** p; }; From 34aead4d493312e6d0e30732c14883b854bd131d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 17 Sep 2002 03:47:10 +0000 Subject: [PATCH 0743/1042] Older EDG workaround [SVN r15396] --- include/boost/python/init.hpp | 119 +++++++++++++++++++++++++++------- 1 file changed, 95 insertions(+), 24 deletions(-) diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 733973b1..d9f0e5c3 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,16 +117,62 @@ 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; // Find the optional<> element, if any typedef typename mpl::find_if< - signature_, detail::is_optional + signature_, detail::is_optional >::type opt; @@ -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<> @@ -162,17 +202,47 @@ struct init //: detail::check_init_params typedef typename mpl::fold< required_args , mpl::list0<> - , mpl::push_front + , mpl::push_front<> >::type reversed_required; typedef typename mpl::fold< optional_args , reversed_required - , mpl::push_front + , mpl::push_front<> >::type reversed_args; // 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; }; /////////////////////////////////////////////////////////////////////////////// @@ -196,12 +266,12 @@ namespace detail typedef typename mpl::fold< ReversedArgs , mpl::list0<> - , mpl::push_front + , 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 From 0f559f3f970dba57eb0eb655f2901f4f43d8879f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 17 Sep 2002 03:55:29 +0000 Subject: [PATCH 0744/1042] Older EDG workaround [SVN r15397] --- include/boost/python/init.hpp | 113 +++++++--------------------------- 1 file changed, 21 insertions(+), 92 deletions(-) diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index d9f0e5c3..385fb385 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -36,20 +36,26 @@ /////////////////////////////////////////////////////////////////////////////// #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 { @@ -88,7 +94,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 }; @@ -117,62 +123,16 @@ 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 : public init_base > +struct init //: detail::check_init_params { - 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; // Find the optional<> element, if any typedef typename mpl::find_if< - signature_, detail::is_optional + signature_, detail::is_optional >::type opt; @@ -183,7 +143,7 @@ struct init : public init_base > , mpl::next >::type expected_finish; BOOST_STATIC_ASSERT((is_same::value)); - + typedef typename mpl::apply_if< is_same , mpl::list0<> @@ -213,36 +173,6 @@ struct init : public init_base > // 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; }; /////////////////////////////////////////////////////////////////////////////// @@ -268,10 +198,10 @@ namespace detail , mpl::list0<> , mpl::push_front<> >::type args; - + cl.def_init(args(), policies, doc); } - + /////////////////////////////////////////////////////////////////////////////// // // define_class_init_helper::apply @@ -339,13 +269,12 @@ namespace detail // __init__(int) // /////////////////////////////////////////////////////////////////////////////// -template +template void -define_init(ClassT& cl, InitT const& i) +define_init(ClassT& cl, InitT const& i, CallPoliciesT const& policies, char const* doc) { typedef typename InitT::reversed_args reversed_args; - detail::define_class_init_helper::apply( - cl, i.call_policies(), reversed_args(), i.doc_string()); + detail::define_class_init_helper::apply(cl, policies, reversed_args(), doc); } }} // namespace boost::python From bff10e571174b1dbf2bb946224721038d2608517 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 17 Sep 2002 17:37:59 +0000 Subject: [PATCH 0745/1042] Suppress warnings for old EDGs [SVN r15415] --- .../boost/python/converter/obj_mgr_arg_from_python.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/boost/python/converter/obj_mgr_arg_from_python.hpp b/include/boost/python/converter/obj_mgr_arg_from_python.hpp index 75b0ae43..0ad709c0 100644 --- a/include/boost/python/converter/obj_mgr_arg_from_python.hpp +++ b/include/boost/python/converter/obj_mgr_arg_from_python.hpp @@ -79,7 +79,13 @@ inline T object_manager_value_arg_from_python::operator()(PyObject* x) const template inline object_manager_ref_arg_from_python::object_manager_ref_arg_from_python(PyObject* x) { - python::detail::construct_referent(&m_result.bytes, python::detail::borrowed_reference(x)); +# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 241 + // needed for warning suppression + python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x); + python::detail::construct_referent(&m_result.bytes, x_); +# else + python::detail::construct_referent(&m_result.bytes, (python::detail::borrowed_reference)x); +# endif } template From b1796c0acbd49399c22ef52d1254b1b1bd45923c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 17 Sep 2002 19:32:50 +0000 Subject: [PATCH 0746/1042] Work around recent changes to bind which cause bound data members to be returned by const& [SVN r15417] --- include/boost/python/object/iterator.hpp | 49 ++++++++++++++++++------ 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 74af64c9..01bef3f1 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -7,7 +7,7 @@ # define ITERATOR_DWA2002510_HPP # include -# include +# include # include # include # include @@ -19,6 +19,8 @@ # include # include # include +# include +# include namespace boost { namespace python { namespace objects { @@ -155,7 +157,7 @@ namespace detail , PyObject* args_, PyObject* /*kw*/) { // Make sure the Python class is instantiated. - demand_iterator_class("iterator"); + detail::demand_iterator_class("iterator", (Iterator*)0, NextPolicies()); to_python_value > cr; @@ -177,6 +179,30 @@ namespace detail , get_start(x), get_finish(x))); } }; + + template + inline object make_iterator_function( + Accessor1 const& get_start, Accessor2 const& get_finish, Iterator const& (*)(), boost::type*, NextPolicies*, int) + { + return + objects::function_object( + boost::bind( + &make_iterator_help< + Target,Iterator,Accessor1,Accessor2,NextPolicies + >::create + , get_start, get_finish, _1, _2) + , 1 ); + } + + template + inline object make_iterator_function( + Accessor1 const& get_start, Accessor2 const& get_finish, Iterator& (*)(), boost::type*, NextPolicies*, ...) + { + return make_iterator_function( + get_start, get_finish, (Iterator const&(*)())0 + , (boost::type*)0, (NextPolicies*)0, 0); + } + } // Create a Python callable object which accepts a single argument @@ -190,16 +216,17 @@ inline object make_iterator_function( Accessor1 const& get_start, Accessor2 const& get_finish , boost::type* = 0, NextPolicies* = 0) { - typedef typename Accessor1::result_type result_type; + typedef typename Accessor1::result_type iterator; + typedef typename add_const::type iterator_const; + typedef typename add_reference::type iterator_cref; - return - objects::function_object( - boost::bind( - &detail::make_iterator_help< - Target,result_type,Accessor1,Accessor2,NextPolicies - >::create - , get_start, get_finish, _1, _2) - , 1 ); + return detail::make_iterator_function( + get_start, get_finish + , (iterator_cref(*)())0 + , (boost::type*)0 + , (NextPolicies*)0 + , 0 + ); } // From eb3e237e47909dde9c86ee86c15cff88c3bc84a6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 17 Sep 2002 20:36:17 +0000 Subject: [PATCH 0747/1042] Added a compile-only test for functions returning non-const references [SVN r15420] --- test/iterator.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/iterator.cpp b/test/iterator.cpp index 7aaae77c..191bf693 100644 --- a/test/iterator.cpp +++ b/test/iterator.cpp @@ -38,6 +38,12 @@ int back(list_int& x) typedef std::pair list_range; +struct list_range2 : list_range +{ + list_int::iterator& begin() { return this->first; } + list_int::iterator& end() { return this->second; } +}; + list_range range(list_int& x) { return list_range(x.begin(), x.end()); @@ -88,6 +94,12 @@ BOOST_PYTHON_MODULE_INIT(iterator_ext) , range(&list_range::first, &list_range::second)) ; + class_("list_range2") + + // We can specify member functions returning a non-const reference + .def("__iter__", range(&list_range2::begin, &list_range2::end)) + ; + class_("two_lists") // We can spcify member functions From 0b75a8e94edda3704caec6d7311cccbba5bbc411 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 17 Sep 2002 20:43:46 +0000 Subject: [PATCH 0748/1042] Adjust version number for old EDG workaround [SVN r15421] --- include/boost/python/converter/obj_mgr_arg_from_python.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/converter/obj_mgr_arg_from_python.hpp b/include/boost/python/converter/obj_mgr_arg_from_python.hpp index 0ad709c0..dfda753d 100644 --- a/include/boost/python/converter/obj_mgr_arg_from_python.hpp +++ b/include/boost/python/converter/obj_mgr_arg_from_python.hpp @@ -79,7 +79,7 @@ inline T object_manager_value_arg_from_python::operator()(PyObject* x) const template inline object_manager_ref_arg_from_python::object_manager_ref_arg_from_python(PyObject* x) { -# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 241 +# if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243 // needed for warning suppression python::detail::borrowed_reference x_ = python::detail::borrowed_reference(x); python::detail::construct_referent(&m_result.bytes, x_); From 7f9826527241993a1f62e760c2b7960a9615893b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 18 Sep 2002 02:20:39 +0000 Subject: [PATCH 0749/1042] Merge Joel's changes to trunk! [SVN r15430] --- include/boost/python/class.hpp | 137 +++---- include/boost/python/def.hpp | 69 ++-- include/boost/python/detail/def_helper.hpp | 24 +- include/boost/python/detail/defaults_def.hpp | 21 +- include/boost/python/detail/defaults_gen.hpp | 377 +++++++++++-------- include/boost/python/init.hpp | 111 +++++- include/boost/python/module.hpp | 5 +- test/back_reference.cpp | 4 +- test/bienstman3.cpp | 2 +- test/bienstman4.cpp | 2 +- test/bienstman5.cpp | 2 +- test/callbacks.cpp | 4 +- test/data_members.cpp | 4 +- test/defaults.cpp | 16 +- test/defaults.py | 42 +++ test/docstring.cpp | 15 +- test/extract.cpp | 2 +- test/implicit.cpp | 2 +- test/iterator.cpp | 1 + test/list.cpp | 2 +- test/m1.cpp | 7 +- test/multi_arg_constructor.cpp | 2 +- test/nested.cpp | 4 +- test/operators.cpp | 4 +- test/pickle1.cpp | 2 +- test/pickle2.cpp | 2 +- test/pickle3.cpp | 2 +- test/test_pointer_adoption.cpp | 24 +- test/virtual_functions.cpp | 6 +- 29 files changed, 526 insertions(+), 369 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index c990e3bf..76646b41 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,26 @@ 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) + // def(name, function, doc_string, policy) 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 +255,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; } @@ -369,39 +335,46 @@ class class_ : public objects::class_base inline void register_() const; + template + void dispatch_def( + detail::overloads_base const*, + char const* name, + SigT sig, + StubsT const& stubs) + { + // 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)); + } + template void dispatch_def( void const*, char const* name, Fn fn, - CallPolicyOrDoc const& policy_or_doc, - char const* doc) + CallPolicyOrDoc const& policy_or_doc) { typedef detail::def_helper helper; - this->def_impl( name, fn, helper::get_policy(policy_or_doc), - helper::get_doc(policy_or_doc, doc), &fn); + helper::get_doc(policy_or_doc, 0), &fn); } - template + template void dispatch_def( - detail::func_stubs_base const*, + void const*, char const* name, - SigT sig, - StubsT const& stubs, - CallPolicyOrDoc const& policy_or_doc, - char const* doc = 0) + Fn fn, + CallPolicyOrDoc1 const& policy_or_doc1, + CallPolicyOrDoc2 const& policy_or_doc2) { - typedef detail::def_helper helper; + 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)); + this->def_impl( + name, fn, helper::get_policy(policy_or_doc1, policy_or_doc2), + helper::get_doc(policy_or_doc1, policy_or_doc2), &fn); } }; @@ -421,30 +394,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..1ade4fd1 100644 --- a/include/boost/python/def.hpp +++ b/include/boost/python/def.hpp @@ -25,35 +25,44 @@ namespace detail void const*, char const* name, Fn fn, - CallPolicyOrDoc const& policy_or_doc, - char const* doc) + CallPolicyOrDoc const& policy_or_doc) { typedef detail::def_helper helper; detail::scope_setattr_doc( name, boost::python::make_function(fn, helper::get_policy(policy_or_doc)), - helper::get_doc(policy_or_doc, doc)); + helper::get_doc(policy_or_doc, 0)); + } + + template + void dispatch_def( + void const*, + char const* name, + Fn fn, + CallPolicyOrDoc1 const& policy_or_doc1, + CallPolicyOrDoc2 const& policy_or_doc2) + { + typedef detail::def_helper helper; + + detail::scope_setattr_doc( + name, boost::python::make_function( + fn, helper::get_policy(policy_or_doc1, policy_or_doc2)), + helper::get_doc(policy_or_doc1, policy_or_doc2)); } - template + template void dispatch_def( - detail::func_stubs_base const*, + detail::overloads_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 +76,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/def_helper.hpp b/include/boost/python/detail/def_helper.hpp index 1222f71b..b9931cfe 100644 --- a/include/boost/python/detail/def_helper.hpp +++ b/include/boost/python/detail/def_helper.hpp @@ -32,17 +32,33 @@ template struct def_helper_impl { template - static P const& get_policy(P const& x) { return x; } + static P const& + get_policy(P const& x) { return x; } + + template + static P1 const& + get_policy(P1 const& x, P2 const&) { return x; } // select left template - static char const* get_doc(P const&, char const* doc) { return doc; } + static char const* + get_doc(P const&, char const* doc) { return doc; } // select right }; template <> struct def_helper_impl { - static python::default_call_policies get_policy(char const*) { return default_call_policies(); } - static char const* get_doc(char const* doc, char const*) { return doc; } + static python::default_call_policies + get_policy(char const*) + { return default_call_policies(); } + + template + static P2 const& + get_policy(P1 const&, P2 const& y) { return y; } // select right + + template + static char const* + get_doc(char const* doc, P const&) // select left + { return doc; } }; template diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index 9c79d926..721fc37f 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -191,24 +191,22 @@ 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; - typedef typename StubsT::nv_type nv_type; + typedef typename StubsT::void_return_type void_return_type; + typedef typename StubsT::non_void_return_type non_void_return_type; typedef typename mpl::if_c< boost::is_same::value - , v_type - , nv_type + , void_return_type + , non_void_return_type >::type stubs_type; BOOST_STATIC_ASSERT( @@ -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..f2d48897 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,224 @@ #include #include -namespace boost { namespace python { namespace detail { +namespace boost { namespace python { + +// overloads_base is used as a base class for all function +// stubs. This class holds the doc_string of the stubs. + +namespace detail +{ + struct overloads_base + { + overloads_base(char const* doc_) + : doc(doc_) {} + + char const* doc_string() const + { return doc; } + + char const* doc; + }; +} + +// overloads_proxy is generated by the overloads_common operator[] (see +// below). This class holds a user defined call policies of the stubs. + +template +struct overloads_proxy + : public detail::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) + : detail::overloads_base(doc), 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 +struct overloads_common +: public detail::overloads_base { + + overloads_common(char const* doc) + : detail::overloads_base(doc) {} + + default_call_policies + call_policies() const + { return default_call_policies(); } + + template + ::boost::python::overloads_proxy + operator[](CallPoliciesT const& policies) const + { + return overloads_proxy + (policies, doc); + } +}; + +}} // namespace boost::python /////////////////////////////////////////////////////////////////////////////// -// -// func_stubs_base is used as a base class for all function stubs. -// -/////////////////////////////////////////////////////////////////////////////// -struct func_stubs_base {}; +#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); \ -}}} // 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 \ - ) \ - ); \ +#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 BPL_IMPL_GEN_FUNCTION(FNAME, FSTUBS_NAME, N_ARGS, N_DFLTS, RETURN) \ - struct FSTUBS_NAME { \ +#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) +#if defined(BOOST_NO_VOID_RETURNS) -#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 \ - : 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; \ +#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::overloads_common \ + { \ + typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \ + typedef BOOST_PP_CAT(fstubs_name, _V) void_return_type; \ + \ + fstubs_name(char const* doc = 0) \ + : boost::python:: \ + overloads_common(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 \ - : public boost::python::detail::func_stubs_base { \ +#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::overloads_common \ + { \ + typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \ + typedef BOOST_PP_CAT(fstubs_name, _V) void_return_type; \ \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _V) v_type; \ + fstubs_name(char const* doc = 0) \ + : boost::python:: \ + overloads_common(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 \ - : public boost::python::detail::func_stubs_base { \ +#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::overloads_common \ + { \ + typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \ + typedef BOOST_PP_CAT(fstubs_name, _NV) void_return_type; \ \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) v_type; \ + fstubs_name(char const* doc = 0) \ + : boost::python:: \ + overloads_common(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 \ - : public boost::python::detail::func_stubs_base { \ +#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::overloads_common \ + { \ + typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \ + typedef BOOST_PP_CAT(fstubs_name, _NV) void_return_type; \ \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) nv_type; \ - typedef BOOST_PP_CAT(FSTUBS_NAME, _NV) v_type; \ + fstubs_name(char const* doc = 0) \ + : boost::python:: \ + overloads_common(doc) {} \ }; \ #endif // defined(BOOST_MSVC) @@ -192,11 +252,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 +285,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); } @@ -246,37 +312,42 @@ struct func_stubs_base {}; // }; // // struct foo_stubs -// : public boost::python::detail::func_stubs_base { +// : public boost::python::overloads_common // -// typedef foo_stubs_NV nv_type; -// typedef foo_stubs_NV v_type; +// typedef foo_stubs_NV non_void_return_type; +// typedef foo_stubs_NV void_return_type; +// +// fstubs_name(char const* doc = 0) +// : boost::python:: +// overloads_common(doc) {} // }; // -// 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. +// 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_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. +// +// See the overloads_common above for a description of the foo_stubs' +// base class. // /////////////////////////////////////////////////////////////////////////////// -#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 385fb385..ed913124 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..2bf923c0 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -85,13 +85,12 @@ class module : public detail::module_base SigT sig, StubsT const& stubs, char const* doc, - detail::func_stubs_base const*) + detail::overloads_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, default_call_policies(), - *this, detail::get_signature(sig), doc); + name, stubs, *this, detail::get_signature(sig)); } }; diff --git a/test/back_reference.cpp b/test/back_reference.cpp index 73990640..d5ae5ece 100644 --- a/test/back_reference.cpp +++ b/test/back_reference.cpp @@ -93,12 +93,12 @@ BOOST_PYTHON_MODULE_INIT(back_reference_ext) def("copy_Z", copy_Z, return_value_policy()); def("x_instances", &X::count); - class_("Y", args()) + class_("Y", init()) .def("value", &Y::value) .def("set", &Y::set) ; - class_ >("Z", args()) + class_ >("Z", init()) .def("value", &Z::value) .def("set", &Z::set) ; diff --git a/test/bienstman3.cpp b/test/bienstman3.cpp index f1dc212d..22c7638e 100644 --- a/test/bienstman3.cpp +++ b/test/bienstman3.cpp @@ -17,6 +17,6 @@ BOOST_PYTHON_MODULE_INIT(bienstman3_ext) using namespace boost::python; class_("V", no_init); - class_("B", args()); + class_("B", init()); } diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp index 324af85a..ee510f2d 100644 --- a/test/bienstman4.cpp +++ b/test/bienstman4.cpp @@ -30,7 +30,7 @@ BOOST_PYTHON_MODULE_INIT(bienstman4_ext) class_("T1") ; - class_("Term", args()) + class_("Term", init()) ; Type1 t1; diff --git a/test/bienstman5.cpp b/test/bienstman5.cpp index 007d12a9..75fbd8da 100644 --- a/test/bienstman5.cpp +++ b/test/bienstman5.cpp @@ -17,7 +17,7 @@ BOOST_PYTHON_MODULE_INIT(bienstman5_ext) { using namespace boost::python; - class_("M", args const&>()) + class_("M", init const&>()) ; } diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 700c190a..763dcda8 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -137,8 +137,8 @@ BOOST_PYTHON_MODULE_INIT(callbacks_ext) def("apply_to_string_literal", apply_to_string_literal); - class_("X", args()) - .def_init(args()) + class_("X", init()) + .def(init()) .def("value", &X::value) .def("set", &X::set) ; diff --git a/test/data_members.cpp b/test/data_members.cpp index 99459dff..7a05d359 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -22,14 +22,14 @@ double get_fair_value(X const& x) { return x.value(); } BOOST_PYTHON_MODULE_INIT(data_members_ext) { - class_("X", args()) + class_("X", init()) .def("value", &X::value) .def("set", &X::set) .def_readonly("x", &X::x) .add_property("fair_value", &get_fair_value) ; - class_("Y", args()) + class_("Y", init()) .def("value", &Y::value) .def("set", &Y::set) .def_readwrite("x", &Y::x) diff --git a/test/defaults.cpp b/test/defaults.cpp index 0f552666..41341e72 100644 --- a/test/defaults.cpp +++ b/test/defaults.cpp @@ -158,25 +158,17 @@ BOOST_PYTHON_MODULE_INIT(defaults_ext) .def("barfoo", (object(*)(int, char, std::string, double))0, bar_stubs()) ; - class_("Y", no_init) + class_("Y", init<>("doc of Y init")) // this should work .def("get_state", &Y::get_state) ; class_("X") -# if (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) - .def(init >()) - .def(init()) -# else - .def_init(args()) - .def_init(args()) - .def_init(args()) - .def_init(args()) - .def_init(args()) -# endif + .def(init >("doc of init")) + .def(init()[default_call_policies()]) // what's a good policy here? .def("get_state", &X::get_state) .def("bar", &X::bar, X_bar_stubs()) - .def("bar2", &X::bar2, X_bar_stubs2(), return_internal_reference<>()) + .def("bar2", &X::bar2, X_bar_stubs2("doc of X::bar2")[return_internal_reference<>()]) .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs()) diff --git a/test/defaults.py b/test/defaults.py index aa7602f2..ee7a6588 100644 --- a/test/defaults.py +++ b/test/defaults.py @@ -3,73 +3,115 @@ >>> from defaults_ext import * >>> bar(1) 'int(1); char(D); string(default); double(0.0); ' + >>> bar(2, 'X') 'int(2); char(X); string(default); double(0.0); ' + >>> bar(3, 'Y', "Hello World") 'int(3); char(Y); string(Hello World); double(0.0); ' + >>> bar(4, 'Z', "Hi There", 3.3) 'int(4); char(Z); string(Hi There); double(3.3); ' + >>> foo(1) 'int(1); char(D); string(default); double(0.0); ' + >>> foo(2, 'X') 'int(2); char(X); string(default); double(0.0); ' + >>> foo(3, 'Y', "Hello World") 'int(3); char(Y); string(Hello World); double(0.0); ' + >>> foo(4, 'Z', "Hi There", 3.3) 'int(4); char(Z); string(Hi There); double(3.3); ' + >>> x = X() >>> x.bar(1) 'int(1); char(D); string(default); double(0.0); ' + >>> x.bar(2, 'X') 'int(2); char(X); string(default); double(0.0); ' + >>> x.bar(3, 'Y', "Hello World") 'int(3); char(Y); string(Hello World); double(0.0); ' + >>> x.bar(4, 'Z', "Hi There", 3.3) 'int(4); char(Z); string(Hi There); double(3.3); ' + >>> x.foo(5) 'int(5); bool(0); ' + >>> x.foo(6, 0) 'int(6); bool(0); ' + >>> x.foo(7, 1) 'int(7); bool(1); ' + >>> x.foo("A") 'string(A); bool(0); ' + >>> x.foo("B", False) 'string(B); bool(0); ' + >>> x.foo("C", True) 'string(C); bool(1); ' + >>> x.foo([0,1,2], [2,3,4]) 'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' + >>> x.foo([0,1,2], [2,3,4], False) 'list([0, 1, 2]); list([2, 3, 4]); bool(0); ' + >>> x.foo([0,1,2], [2,3,4], True) 'list([0, 1, 2]); list([2, 3, 4]); bool(1); ' + >>> x = X(1) >>> x.get_state() 'int(1); char(D); string(constructor); double(0.0); ' + >>> x = X(1, 'X') >>> x.get_state() 'int(1); char(X); string(constructor); double(0.0); ' + >>> x = X(1, 'X', "Yabadabadoo") >>> x.get_state() 'int(1); char(X); string(Yabadabadoo); double(0.0); ' + >>> x = X(1, 'X', "Phoenix", 3.65) >>> x.get_state() 'int(1); char(X); string(Phoenix); double(3.65); ' + >>> x.bar2().get_state() 'int(0); char(D); string(default); double(0.0); ' + >>> x.bar2(1).get_state() 'int(1); char(D); string(default); double(0.0); ' + >>> x.bar2(1, 'K').get_state() 'int(1); char(K); string(default); double(0.0); ' + >>> x.bar2(1, 'K', "Kim").get_state() 'int(1); char(K); string(Kim); double(0.0); ' + >>> x.bar2(1, 'K', "Kim", 9.9).get_state() 'int(1); char(K); string(Kim); double(9.9); ' + >>> x = X("Phoenix", 1) >>> x.get_state() 'Got exactly two arguments from constructor: string(Phoenix); bool(1); ' +>>> def printdoc(x): +... print x.__doc__ + +>>> printdoc(X.__init__) +doc of init + +>>> printdoc(Y.__init__) +doc of Y init + +>>> printdoc(X.bar2) +doc of X::bar2 + """ def run(args = None): import sys diff --git a/test/docstring.cpp b/test/docstring.cpp index 01bacfba..417a6635 100644 --- a/test/docstring.cpp +++ b/test/docstring.cpp @@ -36,23 +36,24 @@ BOOST_PYTHON_MODULE_INIT(docstring_ext) "A simple test module for documentation strings\n" "Exercised by docstring.py" ; - + class_("X", "A simple class wrapper around a C++ int\n" "includes some error-checking" - - , args(), - "this is the __init__ function\n" - "its documentation has two lines." + + , init( + "this is the __init__ function\n" + "its documentation has two lines." + ) ) .def("value", &X::value, "gets the value of the object") ; - + def("create", create, return_value_policy(), "creates a new X object"); - + def("fact", fact, "compute the factorial"); } diff --git a/test/extract.cpp b/test/extract.cpp index 17640f2f..749f265a 100644 --- a/test/extract.cpp +++ b/test/extract.cpp @@ -124,7 +124,7 @@ BOOST_PYTHON_MODULE_INIT(extract_ext) ; object x_class( - class_("X", args()) + class_("X", init()) .def( "__repr__", x_rep)); // Instantiate an X object through the Python interface diff --git a/test/implicit.cpp b/test/implicit.cpp index cbf34027..2637f5ca 100644 --- a/test/implicit.cpp +++ b/test/implicit.cpp @@ -27,7 +27,7 @@ BOOST_PYTHON_MODULE_INIT(implicit_ext) def("x_value", x_value); def("make_x", make_x); - class_("X", args()) + class_("X", init()) .def("value", &X::value) .def("set", &X::set) ; diff --git a/test/iterator.cpp b/test/iterator.cpp index 191bf693..02e67546 100644 --- a/test/iterator.cpp +++ b/test/iterator.cpp @@ -94,6 +94,7 @@ BOOST_PYTHON_MODULE_INIT(iterator_ext) , range(&list_range::first, &list_range::second)) ; + // No runtime tests for this one yet class_("list_range2") // We can specify member functions returning a non-const reference diff --git a/test/list.cpp b/test/list.cpp index b3bce4a2..83ea063b 100644 --- a/test/list.cpp +++ b/test/list.cpp @@ -138,7 +138,7 @@ BOOST_PYTHON_MODULE_INIT(list_ext) def("exercise", exercise); - class_("X", args()) + class_("X", init()) .def( "__repr__", x_rep) ; } diff --git a/test/m1.cpp b/test/m1.cpp index f09e4a93..122ad04d 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -171,6 +171,9 @@ struct B : A int x; }; +#if BOOST_MSVC == 1200 +# define C C_ +#endif struct C : A { @@ -259,8 +262,8 @@ BOOST_PYTHON_MODULE_INIT(m1) ; class_("complicated", - args()) - .def_init(args()) + init()) + .def(init()) .def("get_n", &complicated::get_n) ; } diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp index 43e8bfb1..24bc4d9a 100644 --- a/test/multi_arg_constructor.cpp +++ b/test/multi_arg_constructor.cpp @@ -17,7 +17,7 @@ BOOST_PYTHON_MODULE_INIT(multi_arg_constructor_ext) class_ >( "A" - , args() + , init() ) ; diff --git a/test/nested.cpp b/test/nested.cpp index 9bc5be32..8cbe3d79 100644 --- a/test/nested.cpp +++ b/test/nested.cpp @@ -34,12 +34,12 @@ BOOST_PYTHON_MODULE_INIT(nested_ext) // Establish X as the current scope. scope x_class( - class_("X", args()) + class_("X", init()) .def(str(self)) ); // Y will now be defined in the current scope - class_("Y", args()) + class_("Y", init()) .def(str(self)) ; } diff --git a/test/operators.cpp b/test/operators.cpp index e21b5509..dc2313df 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -59,7 +59,7 @@ std::ostream& operator<<(std::ostream& s, X const& x) BOOST_PYTHON_MODULE_INIT(operators_ext) { - class_("X", args()) + class_("X", init()) .def("value", &X::value) .def(self - self) .def(self - int()) @@ -77,7 +77,7 @@ BOOST_PYTHON_MODULE_INIT(operators_ext) .def(pow(int(),self)) ; - class_ >("Z", args()) + class_ >("Z", init()) .def(int_(self)) .def(float_(self)) .def(complex_(self)) diff --git a/test/pickle1.cpp b/test/pickle1.cpp index e1397d60..1f9e5139 100644 --- a/test/pickle1.cpp +++ b/test/pickle1.cpp @@ -48,7 +48,7 @@ namespace { BOOST_PYTHON_MODULE_INIT(pickle1_ext) { using namespace boost::python; - class_("world", args()) + class_("world", init()) .def("greet", &world::greet) .def_pickle(world_pickle_suite()) ; diff --git a/test/pickle2.cpp b/test/pickle2.cpp index 984d6380..b8aacbd7 100644 --- a/test/pickle2.cpp +++ b/test/pickle2.cpp @@ -90,7 +90,7 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle2_ext) { boost::python::class_( - "world", boost::python::args()) + "world", boost::python::init()) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) diff --git a/test/pickle3.cpp b/test/pickle3.cpp index 8911b24c..5fae9e6c 100644 --- a/test/pickle3.cpp +++ b/test/pickle3.cpp @@ -98,7 +98,7 @@ namespace { // Avoid cluttering the global namespace. BOOST_PYTHON_MODULE_INIT(pickle3_ext) { boost::python::class_( - "world", boost::python::args()) + "world", boost::python::init()) .def("greet", &world::greet) .def("get_secret_number", &world::get_secret_number) .def("set_secret_number", &world::set_secret_number) diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp index b04e3496..90b39ea7 100644 --- a/test/test_pointer_adoption.cpp +++ b/test/test_pointer_adoption.cpp @@ -26,7 +26,7 @@ struct inner { this->s = new_s; } - + std::string s; }; @@ -42,7 +42,7 @@ struct A : Base { ++a_instances; } - + ~A() { --a_instances; @@ -65,7 +65,7 @@ struct B { B() : x(0) {} B(A* x_) : x(x_) {} - + inner const* adopt(A* x) { this->x = x; return &x->get_inner(); } std::string a_content() @@ -96,29 +96,29 @@ BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext) def("create", create, return_value_policy()); def("as_A", as_A, return_internal_reference<>()); - + class_("Base") ; - - class_ >(no_init) + + class_ >("A", no_init) .def("content", &A::content) .def("get_inner", &A::get_inner, return_internal_reference<>()) ; - - class_(no_init) + + class_("inner", no_init) .def("change", &inner::change) ; - + class_("B") - .def_init(args(), with_custodian_and_ward_postcall<1,2>()) - + .def(init()[with_custodian_and_ward_postcall<1,2>()]) + .def("adopt", &B::adopt // Adopt returns a pointer referring to a subobject of its 2nd argument (1st being "self") , return_internal_reference<2 // Meanwhile, self holds a reference to the 2nd argument. , with_custodian_and_ward<1,2> >() ) - + .def("a_content", &B::a_content) ; } diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp index 73d47dc5..f0bfd787 100644 --- a/test/virtual_functions.cpp +++ b/test/virtual_functions.cpp @@ -89,7 +89,7 @@ int X::counter; BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) { - class_("concrete", args()) + class_("concrete", init()) .def("value", &concrete::value) .def("set", &concrete::set) .def("call_f", &concrete::call_f) @@ -97,14 +97,14 @@ BOOST_PYTHON_MODULE_INIT(virtual_functions_ext) ; class_ - >("abstract", args()) + >("abstract", init()) .def("value", &abstract::value) .def("call_f", &abstract::call_f) .def("set", &abstract::set) ; - class_("Y", args()) + class_("Y", init()) .def("value", &Y::value) .def("set", &Y::set) ; From 4320c73336cbe1ea12b9de0b225934173428a0ec Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 18 Sep 2002 04:05:32 +0000 Subject: [PATCH 0750/1042] Apply more preprocessor optimizations [SVN r15432] --- include/boost/python/bases.hpp | 13 +++--- include/boost/python/call.hpp | 6 ++- include/boost/python/call_method.hpp | 6 ++- .../boost/python/detail/arg_tuple_size.hpp | 14 ++++--- include/boost/python/detail/caller.hpp | 3 +- include/boost/python/detail/defaults_gen.hpp | 4 +- .../python/detail/member_function_cast.hpp | 3 +- include/boost/python/detail/result.hpp | 5 ++- include/boost/python/detail/returning.hpp | 9 +++-- include/boost/python/detail/target.hpp | 8 ++-- .../boost/python/detail/type_list_impl.hpp | 9 +++-- .../python/detail/type_list_impl_no_pts.hpp | 23 ++++++----- include/boost/python/init.hpp | 40 +++++++++---------- include/boost/python/signature.hpp | 32 +++++++++------ 14 files changed, 102 insertions(+), 73 deletions(-) diff --git a/include/boost/python/bases.hpp b/include/boost/python/bases.hpp index ec03dfba..503301c3 100644 --- a/include/boost/python/bases.hpp +++ b/include/boost/python/bases.hpp @@ -13,9 +13,11 @@ namespace boost { namespace python { +# define BOOST_PYTHON_BASE_PARAMS BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, B) + // A type list for specifying bases template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_MAX_BASES, typename B, mpl::void_) > - struct bases : detail::type_list< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, B) >::type + struct bases : detail::type_list< BOOST_PYTHON_BASE_PARAMS >::type {}; namespace detail @@ -25,14 +27,14 @@ namespace boost { namespace python { { BOOST_STATIC_CONSTANT(bool, value = false); }; - template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class B) > - struct specifies_bases< bases< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, B) > > + template < BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, class B) > + struct specifies_bases< bases< BOOST_PYTHON_BASE_PARAMS > > { BOOST_STATIC_CONSTANT(bool, value = true); }; # else - template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class B) > - static char is_bases_helper(bases< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, B) > const&); + template < BOOST_PYTHON_BASE_PARAMS > + static char is_bases_helper(bases< BOOST_PYTHON_BASE_PARAMS > const&); static char (& is_bases_helper(...) )[256]; @@ -55,6 +57,7 @@ namespace boost { namespace python { { }; } +# undef BOOST_PYTHON_BASE_PARAMS }} // namespace boost::python #endif // BASES_DWA2002321_HPP diff --git a/include/boost/python/call.hpp b/include/boost/python/call.hpp index 4edceee3..d80cba3c 100644 --- a/include/boost/python/call.hpp +++ b/include/boost/python/call.hpp @@ -20,6 +20,8 @@ # include # include # include +# include +# include namespace boost { namespace python { @@ -42,11 +44,11 @@ namespace boost { namespace python { template < class R - BOOST_PP_COMMA_IF(N) BOOST_PYTHON_UNARY_ENUM(N, class A) + BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) > typename detail::returnable::type call(PyObject* callable - BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, const& a) + BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a) , boost::type* = 0 ) { diff --git a/include/boost/python/call_method.hpp b/include/boost/python/call_method.hpp index e8917c22..347f866c 100644 --- a/include/boost/python/call_method.hpp +++ b/include/boost/python/call_method.hpp @@ -19,6 +19,8 @@ # include # include # include +# include +# include namespace boost { namespace python { @@ -41,11 +43,11 @@ namespace boost { namespace python { template < class R - BOOST_PP_COMMA_IF(N) BOOST_PYTHON_UNARY_ENUM(N, class A) + BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) > typename detail::returnable::type call_method(PyObject* self, char const* name - BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, const& a) + BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a) , boost::type* = 0 ) { diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index 183e957f..1d534ae8 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -21,6 +21,8 @@ # include # include # include +# include +# include namespace boost { namespace python { namespace detail { @@ -74,7 +76,7 @@ struct arg_tuple_size # if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) -template +template struct arg_tuple_size { BOOST_STATIC_CONSTANT(std::size_t, value = N); @@ -82,7 +84,7 @@ struct arg_tuple_size # else -template +template char_array arg_tuple_size_helper( R (*)(BOOST_PYTHON_UNARY_ENUM(N, A))); @@ -107,17 +109,17 @@ char_array arg_tuple_size_helper( # if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) -template -struct arg_tuple_size +template +struct arg_tuple_size { BOOST_STATIC_CONSTANT(std::size_t, value = N + 1U); }; # else -template +template char_array arg_tuple_size_helper( - R (T::*)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q); + R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q); # endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index 2ade2a11..99612b01 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -24,6 +24,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -88,7 +89,7 @@ PyObject* operator()( template < class P, class R, class T - BOOST_PP_COMMA_IF(N) BOOST_PYTHON_UNARY_ENUM(N, class A) + BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) > PyObject* operator()( R (T::*pmf)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index f2d48897..29c07610 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -128,7 +128,7 @@ struct overloads_common BOOST_PYTHON_TYPEDEF_GEN, \ 0) \ \ - BOOST_PP_REPEAT_FROM_TO( \ + 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, \ @@ -170,7 +170,7 @@ struct overloads_common BOOST_PYTHON_TYPEDEF_GEN, \ 0) \ \ - BOOST_PP_REPEAT_FROM_TO( \ + 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, \ diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp index f143abd0..a491494f 100644 --- a/include/boost/python/detail/member_function_cast.hpp +++ b/include/boost/python/detail/member_function_cast.hpp @@ -17,6 +17,7 @@ # include # include # include +# include namespace boost { namespace python { namespace detail { @@ -99,7 +100,7 @@ struct member_function_cast template < class S, class R - BOOST_PP_COMMA_IF(N) BOOST_PYTHON_UNARY_ENUM(N, class A) + BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) > static cast_helper stage1(R (S::*)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q) diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp index 6ec95fb7..315685e2 100755 --- a/include/boost/python/detail/result.hpp +++ b/include/boost/python/detail/result.hpp @@ -19,6 +19,7 @@ # include # include # include +# include namespace boost { namespace python { namespace detail { @@ -112,8 +113,8 @@ boost::type* result(R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)), int = 0) # define N BOOST_PP_ITERATION() # define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) -template -boost::type* result(R (T::*pmf)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q, int = 0) +template +boost::type* result(R (T::*pmf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q, int = 0) { return 0; } diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 9ab87c43..39941a39 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -25,6 +25,7 @@ # include # include # include +# include # include @@ -89,7 +90,7 @@ struct returning # if (BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_RETURNING_NON_VOID) - template + template static PyObject* call( R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)) , PyObject* args_ @@ -110,7 +111,7 @@ struct returning } # elif (BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_RETURNING_VOID) - template + template static PyObject* call( R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)) , PyObject* args_ @@ -155,7 +156,7 @@ struct returning # if (BOOST_PP_RELATIVE_FLAGS(1) & BOOST_PYTHON_RETURNING_NON_VOID) - template + template static PyObject* call( R (T::*pmf)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q , PyObject* args_ @@ -183,7 +184,7 @@ struct returning } # elif (BOOST_PP_RELATIVE_FLAGS(1) & BOOST_PYTHON_RETURNING_VOID) - template + template static PyObject* call( R (T::*pmf)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q , PyObject* args_ diff --git a/include/boost/python/detail/target.hpp b/include/boost/python/detail/target.hpp index bbaec740..d8983dae 100644 --- a/include/boost/python/detail/target.hpp +++ b/include/boost/python/detail/target.hpp @@ -17,6 +17,8 @@ # include # include # include +# include +# include namespace boost { namespace python { namespace detail { @@ -41,8 +43,8 @@ boost::type* target(R (T::*)) { return 0; } # define N BOOST_PP_ITERATION() -template -boost::type* target(R (*)(BOOST_PYTHON_UNARY_ENUM(N, A))) +template +boost::type* target(R (*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A))) { return 0; } @@ -63,7 +65,7 @@ boost::type* target(R (*)(BOOST_PYTHON_UNARY_ENUM(N, A # define N BOOST_PP_ITERATION() # define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) -template +template boost::type* target(R (T::*)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q) { return 0; diff --git a/include/boost/python/detail/type_list_impl.hpp b/include/boost/python/detail/type_list_impl.hpp index 2a02851f..831ca5c0 100644 --- a/include/boost/python/detail/type_list_impl.hpp +++ b/include/boost/python/detail/type_list_impl.hpp @@ -13,12 +13,13 @@ # include # include # include +# include namespace boost { namespace python { namespace detail { template struct type_list - : BOOST_PP_CAT(mpl::list,BOOST_PYTHON_LIST_SIZE) + : BOOST_PP_CAT(mpl::list,BOOST_PYTHON_LIST_SIZE) { }; @@ -37,15 +38,15 @@ struct type_list # define BOOST_PYTHON_VOID_ARGS BOOST_PP_SUB_D(1,BOOST_PYTHON_LIST_SIZE,N) template < - BOOST_PP_ENUM_PARAMS(N, class T) + BOOST_PP_ENUM_PARAMS_Z(1, N, class T) > struct type_list< - BOOST_PP_ENUM_PARAMS(N, T) + BOOST_PP_ENUM_PARAMS_Z(1, N, T) BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM( BOOST_PYTHON_VOID_ARGS, BOOST_PYTHON_FIXED, mpl::void_) > - : BOOST_PP_CAT(mpl::list,N) + : BOOST_PP_CAT(mpl::list,N) { }; diff --git a/include/boost/python/detail/type_list_impl_no_pts.hpp b/include/boost/python/detail/type_list_impl_no_pts.hpp index 1c4d392c..70a27d35 100644 --- a/include/boost/python/detail/type_list_impl_no_pts.hpp +++ b/include/boost/python/detail/type_list_impl_no_pts.hpp @@ -31,6 +31,9 @@ struct is_list_arg template struct type_list_impl_chooser; +# define BOOST_PYTHON_LIST_ACTUAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,T) +# define BOOST_PYTHON_LIST_FORMAL_PARAMS BOOST_PP_ENUM_PARAMS_Z(1,BOOST_PYTHON_LIST_SIZE,class T) + # define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, BOOST_PYTHON_LIST_SIZE, )) # include BOOST_PP_ITERATE() @@ -41,7 +44,7 @@ template struct type_list_impl_chooser; is_list_arg< BOOST_PP_CAT(T,n) >::value template< - BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE, class T) + BOOST_PYTHON_LIST_FORMAL_PARAMS > struct type_list_count_args { @@ -52,25 +55,27 @@ struct type_list_count_args # undef BOOST_PYTHON_IS_LIST_ARG # undef BOOST_PYTHON_PLUS - +# undef BOOST_PYTHON_LIST_FORMAL_PARAMS +# undef BOOST_PYTHON_LIST_ACTUAL_PARAMS + template< - BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE, class T) + BOOST_PYTHON_LIST_FORMAL_PARAMS > struct type_list_impl { - typedef type_list_count_args< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE,T) > arg_num_; + typedef type_list_count_args< BOOST_PYTHON_LIST_ACTUAL_PARAMS > arg_num_; typedef typename detail::type_list_impl_chooser< arg_num_::value > - ::template result_< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE,T) >::type type; + ::template result_< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type type; }; template< BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_LIST_SIZE, class T, mpl::void_) > struct type_list - : detail::type_list_impl< BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE,T) >::type + : detail::type_list_impl< BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type { typedef typename detail::type_list_impl< - BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE,T) + BOOST_PYTHON_LIST_ACTUAL_PARAMS >::type type; }; @@ -86,12 +91,12 @@ template<> struct type_list_impl_chooser { template< - BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_LIST_SIZE, class T) + BOOST_PYTHON_LIST_FORMAL_PARAMS > struct result_ { typedef BOOST_PP_CAT(mpl::list,N)< - BOOST_PP_ENUM_PARAMS(N, T) + BOOST_PYTHON_LIST_ACTUAL_PARAMS > type; }; }; diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index ed913124..75c5da84 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -35,30 +35,30 @@ #include /////////////////////////////////////////////////////////////////////////////// -#define BOOST_PYTHON_TEMPLATE_TYPES_WITH_DEFAULT \ +#define BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT \ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \ BOOST_PYTHON_MAX_ARITY, \ class T, \ mpl::void_) \ -#define BOOST_PYTHON_TEMPLATE_TYPES \ - BOOST_PP_ENUM_PARAMS( \ +#define BOOST_PYTHON_OVERLOAD_TYPES \ + BOOST_PP_ENUM_PARAMS_Z(1, \ BOOST_PYTHON_MAX_ARITY, \ class T) \ -#define BOOST_PYTHON_TEMPLATE_ARGS \ - BOOST_PP_ENUM_PARAMS( \ +#define BOOST_PYTHON_OVERLOAD_ARGS \ + BOOST_PP_ENUM_PARAMS_Z(1, \ BOOST_PYTHON_MAX_ARITY, \ T) \ /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { -template +template struct init; // forward declaration /////////////////////////////////////// -template +template struct optional; // forward declaration namespace detail { @@ -77,8 +77,8 @@ namespace detail { private: - template - static boost::type_traits::yes_type f(optional); + template + static boost::type_traits::yes_type f(optional); static boost::type_traits::no_type f(...); static T t(); @@ -101,8 +101,8 @@ namespace detail { BOOST_STATIC_CONSTANT(bool, value = false); }; - template - struct is_optional_impl > { + template + struct is_optional_impl > { BOOST_STATIC_CONSTANT(bool, value = true); }; @@ -147,10 +147,10 @@ struct init_with_call_policies char const* doc; }; -template -struct init : public init_base > +template +struct init : public init_base > { - typedef init self_t; + typedef init self_t; init(char const* doc_ = 0) : doc(doc_) {} @@ -167,7 +167,7 @@ struct init : public init_base > operator[](CallPoliciesT const& policies) const { return init_with_call_policies(policies, doc); } - typedef detail::type_list signature_; + typedef detail::type_list signature_; typedef typename mpl::end::type finish; // Find the optional<> element, if any @@ -252,9 +252,9 @@ struct init<> : public init_base > // optional::type returns a typelist. // /////////////////////////////////////////////////////////////////////////////// -template +template struct optional - : detail::type_list + : detail::type_list { }; @@ -350,9 +350,9 @@ define_init(ClassT& cl, InitT const& i) }} // namespace boost::python -#undef BOOST_PYTHON_TEMPLATE_TYPES_WITH_DEFAULT -#undef BOOST_PYTHON_TEMPLATE_TYPES -#undef BOOST_PYTHON_TEMPLATE_ARGS +#undef BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT +#undef BOOST_PYTHON_OVERLOAD_TYPES +#undef BOOST_PYTHON_OVERLOAD_ARGS #undef BOOST_PYTHON_IS_OPTIONAL_VALUE #undef BOOST_PYTHON_APPEND_TO_INIT diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index bd4b26df..be93ea4a 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -87,14 +87,18 @@ namespace boost { namespace python { namespace detail { # define N BOOST_PP_ITERATION() +# define BOOST_PYTHON_SIGNATURE_PARAMS BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T) +# define BOOST_PYTHON_SIGNATURE_TYPES BOOST_PP_ENUM_PARAMS_Z(1, N, T) +# define BOOST_PYTHON_TRAILING_SIGNATURE_TYPES BOOST_PP_COMMA_IF(N) BOOST_PYTHON_SIGNATURE_TYPES + template < - class RT BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> + class RT BOOST_PYTHON_SIGNATURE_PARAMS> inline BOOST_PYTHON_FUNCTION_SIGNATURE_LIST(N)< - RT BOOST_PP_ENUM_TRAILING_PARAMS(N, T)> -get_signature(RT(*)(BOOST_PP_ENUM_PARAMS(N, T))) + RT BOOST_PYTHON_TRAILING_SIGNATURE_TYPES> +get_signature(RT(*)(BOOST_PYTHON_SIGNATURE_TYPES)) { return BOOST_PYTHON_FUNCTION_SIGNATURE_LIST(N)< - RT BOOST_PP_ENUM_TRAILING_PARAMS(N, T) + RT BOOST_PYTHON_TRAILING_SIGNATURE_TYPES >(); } @@ -102,26 +106,30 @@ get_signature(RT(*)(BOOST_PP_ENUM_PARAMS(N, T))) #if N <= (BOOST_PYTHON_MAX_ARITY - 2) template < - class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> + class RT, class ClassT BOOST_PYTHON_SIGNATURE_PARAMS> inline BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< - RT, ClassT BOOST_PP_ENUM_TRAILING_PARAMS(N, T)> -get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T))) + RT, ClassT BOOST_PYTHON_TRAILING_SIGNATURE_TYPES > +get_signature(RT(ClassT::*)(BOOST_PYTHON_SIGNATURE_TYPES)) { return BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< - RT, ClassT BOOST_PP_ENUM_TRAILING_PARAMS(N, T)>(); + RT, ClassT BOOST_PYTHON_TRAILING_SIGNATURE_TYPES>(); } /////////////////////////////////////// template < - class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> + class RT, class ClassT BOOST_PYTHON_SIGNATURE_PARAMS> inline BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< - RT, ClassT const BOOST_PP_ENUM_TRAILING_PARAMS(N, T)> -get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS(N, T)) const) + RT, ClassT const BOOST_PYTHON_TRAILING_SIGNATURE_TYPES> +get_signature(RT(ClassT::*)(BOOST_PYTHON_SIGNATURE_TYPES) const) { return BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< - RT, ClassT const BOOST_PP_ENUM_TRAILING_PARAMS(N, T)>(); + RT, ClassT const BOOST_PYTHON_TRAILING_SIGNATURE_TYPES>(); } #endif // N < (BOOST_PYTHON_MAX_ARITY - 2) +# undef BOOST_PYTHON_SIGNATURE_PARAMS +# undef BOOST_PYTHON_SIGNATURE_TYPES +# undef BOOST_PYTHON_TRAILING_SIGNATURE_TYPES + #endif // !defined(BOOST_PP_IS_ITERATING) From ca5a222aec0e683f41157b5847ece92cbbb8afb9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 18 Sep 2002 04:07:20 +0000 Subject: [PATCH 0751/1042] quickie bugfix [SVN r15433] --- include/boost/python/detail/result.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp index 315685e2..2e955e23 100755 --- a/include/boost/python/detail/result.hpp +++ b/include/boost/python/detail/result.hpp @@ -19,6 +19,7 @@ # include # include # include +# include # include namespace boost { namespace python { namespace detail { From 065a53b997c9803498b39e833c42e41dd96d4693 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 18 Sep 2002 04:54:31 +0000 Subject: [PATCH 0752/1042] Apply more preprocessor optimizations [SVN r15435] --- include/boost/python/args.hpp | 5 ++-- .../boost/python/detail/arg_tuple_size.hpp | 4 +-- include/boost/python/detail/caller.hpp | 6 ++--- include/boost/python/detail/defaults_gen.hpp | 25 ++++++++++--------- include/boost/python/detail/make_tuple.hpp | 4 +-- .../python/detail/member_function_cast.hpp | 10 +++++--- include/boost/python/detail/result.hpp | 4 +-- include/boost/python/detail/returning.hpp | 8 +++--- include/boost/python/detail/target.hpp | 2 +- include/boost/python/object/make_holder.hpp | 3 ++- .../boost/python/object/pointer_holder.hpp | 12 +++++---- include/boost/python/object/value_holder.hpp | 12 ++++++--- include/boost/python/object_call.hpp | 6 ++--- include/boost/python/tuple.hpp | 2 ++ 14 files changed, 59 insertions(+), 44 deletions(-) diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index 941529f0..e488f3d8 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -8,6 +8,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -24,8 +25,8 @@ namespace boost { namespace python { // A type list for specifying arguments template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, mpl::void_) > -struct args : detail::args_base > - , detail::type_list< BOOST_PYTHON_UNARY_ENUM(BOOST_PYTHON_MAX_ARITY, A) >::type +struct args : detail::args_base > + , detail::type_list< BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_ARITY, A) >::type {}; }} // namespace boost::python diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index 1d534ae8..88900702 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -77,7 +77,7 @@ struct arg_tuple_size # if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template -struct arg_tuple_size +struct arg_tuple_size { BOOST_STATIC_CONSTANT(std::size_t, value = N); }; @@ -86,7 +86,7 @@ struct arg_tuple_size template char_array arg_tuple_size_helper( - R (*)(BOOST_PYTHON_UNARY_ENUM(N, A))); + R (*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A))); # endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index 99612b01..9d390dbd 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -61,10 +61,10 @@ struct caller template < class P, class R - BOOST_PP_COMMA_IF(N) BOOST_PYTHON_UNARY_ENUM(N, class A) + BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) > PyObject* operator()( - R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)) + R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) , PyObject* args , PyObject* keywords , P const& policies) const @@ -92,7 +92,7 @@ template < BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) > PyObject* operator()( - R (T::*pmf)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q + R (T::*pmf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q , PyObject* args, PyObject* keywords , P const& policies ) const diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 29c07610..d8b96d53 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -97,17 +98,17 @@ struct overloads_common 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_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) \ @@ -141,7 +142,7 @@ struct overloads_common 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_ENUM_BINARY_PARAMS_Z(1, index, T, arg) \ ) \ { \ BOOST_PP_TUPLE_ELEM(3, 2, data) obj.BOOST_PP_TUPLE_ELEM(3, 0, data)( \ diff --git a/include/boost/python/detail/make_tuple.hpp b/include/boost/python/detail/make_tuple.hpp index 07cd9903..cb5c6fc6 100644 --- a/include/boost/python/detail/make_tuple.hpp +++ b/include/boost/python/detail/make_tuple.hpp @@ -17,9 +17,9 @@ , python::incref(python::object(a##N).ptr()) \ ); - template + template tuple - make_tuple(BOOST_PYTHON_BINARY_ENUM(N, A, const& a)) + make_tuple(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a)) { tuple result((detail::new_reference)::PyTuple_New(N)); BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_MAKE_TUPLE_ARG, _) diff --git a/include/boost/python/detail/member_function_cast.hpp b/include/boost/python/detail/member_function_cast.hpp index a491494f..568c13cc 100644 --- a/include/boost/python/detail/member_function_cast.hpp +++ b/include/boost/python/detail/member_function_cast.hpp @@ -17,6 +17,8 @@ # include # include # include + +# include # include namespace boost { namespace python { namespace detail { @@ -97,17 +99,19 @@ struct member_function_cast # define N BOOST_PP_ITERATION() # define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) +# define P BOOST_PP_ENUM_PARAMS_Z(1, N, A) template < class S, class R BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) > - static cast_helper - stage1(R (S::*)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q) + static cast_helper + stage1(R (S::*)( P ) Q) { - return cast_helper(); + return cast_helper(); } +# undef P # undef N # undef Q diff --git a/include/boost/python/detail/result.hpp b/include/boost/python/detail/result.hpp index 2e955e23..bb66f13a 100755 --- a/include/boost/python/detail/result.hpp +++ b/include/boost/python/detail/result.hpp @@ -92,8 +92,8 @@ result(X const&, short = 0) { return 0; } # define N BOOST_PP_ITERATION() -template -boost::type* result(R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)), int = 0) +template +boost::type* result(R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)), int = 0) { return 0; } diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp index 39941a39..97338ff3 100644 --- a/include/boost/python/detail/returning.hpp +++ b/include/boost/python/detail/returning.hpp @@ -92,7 +92,7 @@ struct returning template static PyObject* call( - R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)) + R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) , PyObject* args_ , PyObject*, P const* policies) { @@ -113,7 +113,7 @@ struct returning template static PyObject* call( - R (*pf)(BOOST_PYTHON_UNARY_ENUM(N, A)) + R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) , PyObject* args_ , PyObject*, P const* policies) { @@ -158,7 +158,7 @@ struct returning template static PyObject* call( - R (T::*pmf)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q + R (T::*pmf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q , PyObject* args_ , PyObject*, P const* policies) { @@ -186,7 +186,7 @@ struct returning template static PyObject* call( - R (T::*pmf)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q + R (T::*pmf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q , PyObject* args_ , PyObject*, P const* policies) { diff --git a/include/boost/python/detail/target.hpp b/include/boost/python/detail/target.hpp index d8983dae..67007720 100644 --- a/include/boost/python/detail/target.hpp +++ b/include/boost/python/detail/target.hpp @@ -66,7 +66,7 @@ boost::type* target(R (*)(BOOST_PP_ENUM_PARAMS_Z(1, N, # define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) template -boost::type* target(R (T::*)(BOOST_PYTHON_UNARY_ENUM(N, A)) Q) +boost::type* target(R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q) { return 0; } diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index 2a9e4e58..ebcddc0d 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -23,6 +23,7 @@ # include # include # include +# include # include @@ -64,7 +65,7 @@ struct make_holder BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FORWARD_ARG, nil) static void execute( PyObject* p - BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, t, a)) + BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, t, a)) { typedef instance instance_t; diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 0dca4ae3..d0196941 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -20,7 +20,6 @@ # include # include # include -# include # include # include @@ -28,6 +27,9 @@ # include # include # include +# include +# include +# include namespace boost { namespace python { namespace objects { @@ -127,9 +129,9 @@ void* pointer_holder_back_reference::holds(type_info dst_t) # define N BOOST_PP_ITERATION() # if (N != 0) - template< BOOST_PYTHON_UNARY_ENUM(N, class A) > + template< BOOST_PP_ENUM_PARAMS_Z(1, N, class A) > # endif - pointer_holder(PyObject* BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) + pointer_holder(PyObject* BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) : m_p(new Value( BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) )) @@ -144,10 +146,10 @@ void* pointer_holder_back_reference::holds(type_info dst_t) # define N BOOST_PP_ITERATION() # if (N != 0) - template < BOOST_PYTHON_UNARY_ENUM(N, class A) > + template < BOOST_PP_ENUM_PARAMS_Z(1, N, class A) > # endif pointer_holder_back_reference( - PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) + PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) : m_p(new held_type( p BOOST_PP_COMMA_IF(N) BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) )) diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index d40d058d..95b58746 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -19,10 +19,14 @@ # include # include +# include # include # include # include +# include +# include + namespace boost { namespace python { namespace objects { # define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) @@ -96,10 +100,10 @@ void* value_holder_back_reference::holds( # define N BOOST_PP_ITERATION() # if (N != 0) - template + template # endif value_holder( - PyObject* BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) + PyObject* BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) : m_held( BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) ) @@ -115,10 +119,10 @@ void* value_holder_back_reference::holds( # define N BOOST_PP_ITERATION() # if (N != 0) - template + template # endif value_holder_back_reference( - PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PYTHON_BINARY_ENUM(N, A, a)) + PyObject* p BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, a)) : m_held( p BOOST_PP_COMMA_IF(N) BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil) diff --git a/include/boost/python/object_call.hpp b/include/boost/python/object_call.hpp index 31b2eff9..362446b2 100644 --- a/include/boost/python/object_call.hpp +++ b/include/boost/python/object_call.hpp @@ -10,13 +10,13 @@ #define N BOOST_PP_ITERATION() - template + template typename detail::dependent::type - operator()(BOOST_PYTHON_BINARY_ENUM(N, A, const& a)) const + operator()(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, A, const& a)) const { typedef typename detail::dependent::type obj; U const& self = *static_cast(this); - return call(get_managed_object(self, tag), BOOST_PYTHON_UNARY_ENUM(N, a)); + return call(get_managed_object(self, tag), BOOST_PP_ENUM_PARAMS_Z(1, N, a)); } #undef N diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp index 38547696..2ab4ad73 100644 --- a/include/boost/python/tuple.hpp +++ b/include/boost/python/tuple.hpp @@ -3,6 +3,8 @@ #include #include +#include +#include namespace boost { namespace python { From e8d2bbd2c9337cd72b49314fd8e6d9c7cbbbf97d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 18 Sep 2002 13:24:15 +0000 Subject: [PATCH 0753/1042] VC6 fixes [SVN r15438] --- include/boost/python/bases.hpp | 2 +- .../boost/python/detail/type_list_impl_no_pts.hpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/boost/python/bases.hpp b/include/boost/python/bases.hpp index 503301c3..6271e0fc 100644 --- a/include/boost/python/bases.hpp +++ b/include/boost/python/bases.hpp @@ -33,7 +33,7 @@ namespace boost { namespace python { BOOST_STATIC_CONSTANT(bool, value = true); }; # else - template < BOOST_PYTHON_BASE_PARAMS > + template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class B) > static char is_bases_helper(bases< BOOST_PYTHON_BASE_PARAMS > const&); static char (& is_bases_helper(...) )[256]; diff --git a/include/boost/python/detail/type_list_impl_no_pts.hpp b/include/boost/python/detail/type_list_impl_no_pts.hpp index 70a27d35..be537793 100644 --- a/include/boost/python/detail/type_list_impl_no_pts.hpp +++ b/include/boost/python/detail/type_list_impl_no_pts.hpp @@ -53,11 +53,6 @@ struct type_list_count_args }; }; -# undef BOOST_PYTHON_IS_LIST_ARG -# undef BOOST_PYTHON_PLUS -# undef BOOST_PYTHON_LIST_FORMAL_PARAMS -# undef BOOST_PYTHON_LIST_ACTUAL_PARAMS - template< BOOST_PYTHON_LIST_FORMAL_PARAMS > @@ -79,6 +74,11 @@ struct type_list >::type type; }; +# undef BOOST_PYTHON_IS_LIST_ARG +# undef BOOST_PYTHON_PLUS +# undef BOOST_PYTHON_LIST_FORMAL_PARAMS +# undef BOOST_PYTHON_LIST_ACTUAL_PARAMS + }}} // namespace boost::python::detail # endif // TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP @@ -96,7 +96,7 @@ struct type_list_impl_chooser struct result_ { typedef BOOST_PP_CAT(mpl::list,N)< - BOOST_PYTHON_LIST_ACTUAL_PARAMS + BOOST_PP_ENUM_PARAMS(N, T) > type; }; }; From 8e941417a5a6353c0cc5d0d0b56e2207da4c325f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 19 Sep 2002 16:11:34 +0000 Subject: [PATCH 0754/1042] Workaround slow Windows Intel C++ debug symbol generation [SVN r15452] --- test/Jamfile | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/test/Jamfile b/test/Jamfile index 511408e8..0a6914f0 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -11,7 +11,7 @@ local PYTHON_V1_PROPERTIES = $(PYTHON_PROPERTIES) ; local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) ; # Convenience rule makes declaring tests faster -rule bpl-test ( name ? : files * ) +rule bpl-test ( name ? : files * : requirements * ) { files ?= $(name).py $(name).cpp ; @@ -46,7 +46,7 @@ rule bpl-test ( name ? : files * ) m = $(m)_ext ; } } - extension $(m) : $(f) ../bpl ; + extension $(m) : $(f) ../bpl : $(requirements) ; modules += $(m) ; } } @@ -81,7 +81,24 @@ bpl-test data_members ; bpl-test bienstman1 ; bpl-test bienstman2 ; bpl-test bienstman3 ; -bpl-test multi_arg_constructor ; + +# A bug in the Win32 intel compilers causes compilation of one of our +# tests to take forever when debug symbols are enabled. This rule +# turns them off when added to the requirements section +rule turn-off-intel-debug-symbols ( toolset variant : properties * ) +{ + if $(NT) && [ MATCH (.*intel.*) : $(toolset) ] + { + properties = [ difference $(properties) : on ] off ; + } + return $(properties) ; +} + +bpl-test multi_arg_constructor + : # files + : # requirements + turn-off-intel-debug-symbols ; # debug symbols slow the build down too much + bpl-test iterator : iterator.py iterator.cpp input_iterator.cpp ; bpl-test extract ; From a75ee50533e173dcc92a9fd3eba2518df37b7dfd Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Sat, 21 Sep 2002 02:50:29 +0000 Subject: [PATCH 0755/1042] Removed def_init(...) from class_ [SVN r15468] --- include/boost/python/class.hpp | 43 ++++------------------------------ include/boost/python/init.hpp | 10 +++++++- 2 files changed, 14 insertions(+), 39 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 76646b41..59c1f30c 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -102,7 +102,7 @@ template < > class class_ : public objects::class_base { - private: // types + public: // types typedef objects::class_base base; typedef class_ self; @@ -116,12 +116,15 @@ class class_ : public objects::class_base typedef objects::select_holder holder_selector; + private: + 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 @@ -223,42 +226,6 @@ class class_ : public objects::class_base 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 - self& def_init(Args const&) - { - return this->def("__init__", - python::make_constructor( - // Using runtime type selection works around a CWPro7 bug. - holder_selector::execute((held_type*)0).get() - ) - ); - } - - template - 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( - helper::get_policy(policy_or_doc) - // Using runtime type selection works around a CWPro7 bug. - , holder_selector::execute((held_type*)0).get() - ) - , helper::get_doc(policy_or_doc, doc) - ); - } - - // Define the default constructor. - self& def_init() - { - this->def_init(mpl::list0<>::type()); - return *this; - } - // // Data member access // @@ -400,7 +367,7 @@ inline class_::class_(char const* name, char const* doc) { this->register_(); detail::force_instantiate(sizeof(detail::assert_default_constructible(T()))); - this->def_init(); + this->def(init<>()); this->set_instance_size(holder_selector::additional_size()); } diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 75c5da84..2efc1094 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -269,7 +269,15 @@ namespace detail , mpl::push_front<> >::type args; - cl.def_init(args(), policies, doc); + cl.def( + "__init__", + python::make_constructor( + policies + // Using runtime type selection works around a CWPro7 bug. + , ClassT::holder_selector::execute((ClassT::held_type*)0).get() + ) + , doc + ); } /////////////////////////////////////////////////////////////////////////////// From 88caf4f5b61a6e409e10a706176891541c9751a7 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Sat, 21 Sep 2002 08:01:24 +0000 Subject: [PATCH 0756/1042] added missing typename [SVN r15471] --- include/boost/python/init.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 2efc1094..5565caba 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -269,12 +269,15 @@ namespace detail , mpl::push_front<> >::type args; + typedef typename ClassT::holder_selector holder_selector_t; + typedef typename ClassT::held_type held_type_t; + cl.def( "__init__", python::make_constructor( policies // Using runtime type selection works around a CWPro7 bug. - , ClassT::holder_selector::execute((ClassT::held_type*)0).get() + , holder_selector_t::execute((held_type_t*)0).get() ) , doc ); From 3cb9ecae786f8eec49d95897afa80fcea043aaeb Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 25 Sep 2002 20:04:34 +0000 Subject: [PATCH 0757/1042] workaround for MIPSpro compiler bug is now in boost/function/function_base.hpp [SVN r15517] --- include/boost/python/detail/config.hpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index c3750902..16948010 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -97,15 +97,6 @@ # define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) struct ThIsTyPeNeVeRuSeD #endif -#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 -// Work around a compiler bug. -// boost::python::detail::function has to be seen by the compiler before the -// boost::function class template. -namespace boost { namespace python { namespace detail { -class function; -}}} -#endif - #if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590014) // Replace broken Tru64/cxx offsetof macro # define BOOST_PYTHON_OFFSETOF(s_name, s_member) \ From f4aa72373bb29c8de24c2f14c3dafe2bb2aac71d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 26 Sep 2002 00:11:30 +0000 Subject: [PATCH 0758/1042] Serious bugfix [SVN r15518] --- include/boost/python/converter/return_from_python.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 58d182f0..c487aa22 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -13,6 +13,7 @@ # include # include # include +# include namespace boost { namespace python { namespace converter { @@ -141,7 +142,7 @@ namespace detail inline T return_object_manager_from_python::operator()(PyObject* obj) const { return T( - object_manager_traits::adopt(obj) + object_manager_traits::adopt(expect_non_null(obj)) ); } } From 87d619e02af3ffa89179e08d0ea344a80ac5eae8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 26 Sep 2002 00:15:09 +0000 Subject: [PATCH 0759/1042] fixup comments [SVN r15519] --- src/converter/from_python.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index ade39a21..b6ce54ff 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -257,7 +257,7 @@ BOOST_PYTHON_DECL void void_result_from_python(PyObject* o) Py_DECREF(expect_non_null(o)); } -} +} // namespace boost::python::converter BOOST_PYTHON_DECL PyObject* pytype_check(PyTypeObject* type_, PyObject* source) @@ -277,4 +277,4 @@ pytype_check(PyTypeObject* type_, PyObject* source) return source; } -}} // namespace boost::python::converter +}} // namespace boost::python From 31a8be0434b6825350e1f07bc3e67bc07b32d867 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 26 Sep 2002 00:15:36 +0000 Subject: [PATCH 0760/1042] Patches for Intel C++ 7.0 beta [SVN r15520] --- include/boost/python/detail/msvc_typeinfo.hpp | 2 +- include/boost/python/type_id.hpp | 2 +- test/extract.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/detail/msvc_typeinfo.hpp b/include/boost/python/detail/msvc_typeinfo.hpp index b50922b7..92f0f56d 100644 --- a/include/boost/python/detail/msvc_typeinfo.hpp +++ b/include/boost/python/detail/msvc_typeinfo.hpp @@ -18,7 +18,7 @@ // could probably be done, but I haven't figured it out yet. // -# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 600 +# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(BOOST_INTEL_CXX_VERSION) && BOOST_INTEL_CXX_VERSION <= 700 namespace boost { namespace python { namespace detail { diff --git a/include/boost/python/type_id.hpp b/include/boost/python/type_id.hpp index cf818fe3..d44ce26a 100755 --- a/include/boost/python/type_id.hpp +++ b/include/boost/python/type_id.hpp @@ -54,7 +54,7 @@ template inline type_info type_id(boost::type* = 0) { return type_info( -# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 600) +# if (!defined(BOOST_MSVC) || BOOST_MSVC > 1300) && (!defined(BOOST_INTEL_CXX_VERSION) || BOOST_INTEL_CXX_VERSION > 700) typeid(T) # else // strip the decoration which msvc and Intel mistakenly leave in python::detail::msvc_typeid() diff --git a/test/extract.cpp b/test/extract.cpp index 749f265a..2faa27e9 100644 --- a/test/extract.cpp +++ b/test/extract.cpp @@ -51,14 +51,14 @@ std::string const& extract_string_cref(object x) #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 # pragma warning(push) # pragma warning(disable:4172) // msvc lies about returning a reference to temporary -#elif defined(_MSC_VER) && defined(__ICL) && __ICL <= 600 +#elif defined(_MSC_VER) && defined(__ICL) && __ICL <= 700 # pragma warning(push) # pragma warning(disable:473) // intel/win32 does too #endif return extract(x); -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 600 +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(_MSC_VER) && defined(__ICL) && __ICL <= 700 # pragma warning(pop) #endif } From 17879958ca67c787c0c661dfe525b0ddf55cfab6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 26 Sep 2002 00:16:16 +0000 Subject: [PATCH 0761/1042] NumPy (Numeric and numarray) support [SVN r15521] --- Jamfile | 2 + include/boost/python/dict.hpp | 2 +- include/boost/python/list.hpp | 2 +- include/boost/python/long.hpp | 2 +- include/boost/python/numeric.hpp | 230 ++++++++++++++++++++ include/boost/python/object_core.hpp | 14 +- include/boost/python/str.hpp | 2 +- include/boost/python/tuple.hpp | 2 +- src/numeric.cpp | 313 +++++++++++++++++++++++++++ test/Jamfile | 2 + test/numpy.cpp | 105 +++++++++ test/numpy.py | 175 +++++++++++++++ 12 files changed, 839 insertions(+), 12 deletions(-) create mode 100644 include/boost/python/numeric.hpp create mode 100644 src/numeric.cpp create mode 100644 test/numpy.cpp create mode 100644 test/numpy.py diff --git a/Jamfile b/Jamfile index d5a9e729..243e4829 100644 --- a/Jamfile +++ b/Jamfile @@ -13,6 +13,8 @@ if $(UNIX) && ( $(OS) = AIX ) dll bpl : + src/numeric.cpp + src/list.cpp src/long.cpp src/dict.cpp diff --git a/include/boost/python/dict.hpp b/include/boost/python/dict.hpp index b593f902..d78ccaf8 100644 --- a/include/boost/python/dict.hpp +++ b/include/boost/python/dict.hpp @@ -105,7 +105,7 @@ class dict : public object BOOST_PYTHON_DECL list values() const; public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict) + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict, object) private: static BOOST_PYTHON_DECL detail::new_reference call(object const&); diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp index 501eeed5..e6696878 100644 --- a/include/boost/python/list.hpp +++ b/include/boost/python/list.hpp @@ -94,7 +94,7 @@ class list : public object } public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list) + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list, object) private: static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&); diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp index 3ba4f434..b0cc6417 100644 --- a/include/boost/python/long.hpp +++ b/include/boost/python/long.hpp @@ -31,7 +31,7 @@ class long_ : public object { } public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_) + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_, object) private: static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&); diff --git a/include/boost/python/numeric.hpp b/include/boost/python/numeric.hpp new file mode 100644 index 00000000..1ef73439 --- /dev/null +++ b/include/boost/python/numeric.hpp @@ -0,0 +1,230 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef NUMARRAY_DWA2002922_HPP +# define NUMARRAY_DWA2002922_HPP + +# include +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace numeric { + +namespace aux +{ + struct BOOST_PYTHON_DECL array_base : object + { +# define BOOST_PP_LOCAL_MACRO(n) \ + array_base(BOOST_PP_ENUM_PARAMS(n, object const& x)); +# define BOOST_PP_LOCAL_LIMITS (1, 7) +# include BOOST_PP_LOCAL_ITERATE() + + object argmax(long axis=-1); + object argmin(long axis=-1); + object argsort(long axis=-1); + object astype(object const& type = object()); + void byteswap(); + object copy() const; + object diagonal(long offset = 0, long axis1 = 0, long axis2 = 1) const; + void info() const; + bool is_c_array() const; + bool isbyteswapped() const; + object new_(object type) const; + void sort(); + object trace(long offset = 0, long axis1 = 0, long axis2 = 1) const; + object type() const; + char typecode() const; + + object factory(object const& buffer=object() + , object const& type=object() + , object const& shape=object() + , bool copy = true + , bool savespace = false + , object typecode = object()); + + object getflat() const; + long getrank() const; + object getshape() const; + bool isaligned() const; + bool iscontiguous() const; + long itemsize() const; + long nelements() const; + object nonzero() const; + + void put(object const& indices, object const& values); + + void ravel(); + + object repeat(object const& repeats, long axis=0); + + void resize(object const& shape); + + void setflat(object const& flat); + void setshape(object const& shape); + + void swapaxes(long axis1, long axis2); + + object take(object const& sequence, long axis = 0) const; + + void tofile(object const& file) const; + + str tostring() const; + + void transpose(object const& axes = object()); + + object view() const; + + public: // implementation detail - do not touch. + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(array_base, object); + }; + + struct BOOST_PYTHON_DECL array_object_manager_traits + { + static bool check(PyObject* obj); + static detail::new_non_null_reference adopt(PyObject* obj); + }; +} // namespace aux + +class array : public aux::array_base +{ + typedef aux::array_base base; + public: + + object astype() { return base::astype(); } + + template + object astype(Type const& type_) + { + return base::astype(object(type_)); + } + + template + object new_(Type const& type_) const + { + return base::new_(object(type_)); + } + + template + void resize(Sequence const& x) + { + base::resize(object(x)); + } + +# define BOOST_PP_LOCAL_MACRO(n) \ + void resize(BOOST_PP_ENUM_PARAMS(n, long x)) \ + { \ + resize(make_tuple(BOOST_PP_ENUM_PARAMS(n, x))); \ + } +# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) +# include BOOST_PP_LOCAL_ITERATE() + + template + void setshape(Sequence const& x) + { + base::setshape(object(x)); + } + +# define BOOST_PP_LOCAL_MACRO(n) \ + void setshape(BOOST_PP_ENUM_PARAMS(n, long x)) \ + { \ + setshape(make_tuple(BOOST_PP_ENUM_PARAMS(n, x))); \ + } +# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) +# include BOOST_PP_LOCAL_ITERATE() + + template + void put(Indices const& indices, Values const& values) + { + base::put(object(indices), object(values)); + } + + template + object take(Sequence const& sequence, long axis = 0) + { + return base::take(object(sequence), axis); + } + + template + void tofile(File const& f) const + { + base::tofile(object(f)); + } + + object factory() + { + return base::factory(); + } + + template + object factory(Buffer const& buffer) + { + return base::factory(object(buffer)); + } + + template + object factory( + Buffer const& buffer + , Type const& type_) + { + return base::factory(object(buffer), object(type_)); + } + + template + object factory( + Buffer const& buffer + , Type const& type_ + , Shape const& shape + , bool copy = true + , bool savespace = false) + { + return base::factory(object(buffer), object(type_), object(shape), copy, savespace); + } + + template + object factory( + Buffer const& buffer + , Type const& type_ + , Shape const& shape + , bool copy + , bool savespace + , char typecode) + { + return base::factory(object(buffer), object(type_), object(shape), copy, savespace, object(typecode)); + } + +# define BOOST_PYTHON_ENUM_AS_OBJECT(z, n, x) object(BOOST_PP_CAT(x,n)) +# define BOOST_PP_LOCAL_MACRO(n) \ + template \ + explicit array(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& x)) \ + : array_base(BOOST_PP_ENUM(n, BOOST_PYTHON_ENUM_AS_OBJECT, x)) \ + {} +# define BOOST_PP_LOCAL_LIMITS (1, 7) +# include BOOST_PP_LOCAL_ITERATE() +# undef BOOST_PYTHON_AS_OBJECT + + static BOOST_PYTHON_DECL void set_module_and_type(char const* package_name = 0, char const* type_attribute_name = 0); + + public: // implementation detail -- for internal use only + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(array, array_base); +}; + +} // namespace boost::python::numeric + +namespace converter +{ + template <> + struct object_manager_traits< numeric::array > + : numeric::aux::array_object_manager_traits + { + BOOST_STATIC_CONSTANT(bool, is_specialized = true); + }; +} + +}} // namespace boost::python + +#endif // NUMARRAY_DWA2002922_HPP diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index ebdfeac1..2ee532a8 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -234,13 +234,13 @@ namespace api // Macros for forwarding constructors in classes derived from // object. Derived classes will usually want these as an // implementation detail -# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived) \ +# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \ inline explicit derived(python::detail::borrowed_reference p) \ - : object(p) {} \ + : base(p) {} \ inline explicit derived(python::detail::new_reference p) \ - : object(p) {} \ + : base(p) {} \ inline explicit derived(python::detail::new_non_null_reference p) \ - : object(p) {} + : base(p) {} # if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 # define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_ @@ -253,9 +253,9 @@ namespace api // runtime failure into an ambiguity error at compile-time due to // the lack of partial ordering, or at least a link-time error if no // generalized template constructor is declared. -# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived) \ - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived) \ - template \ +# define BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(derived, base) \ + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS_(derived, base) \ + template \ explicit derived(extract const&); # endif diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index fb8bfe58..ffb3c362 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -352,7 +352,7 @@ class str : public object BOOST_PYTHON_DECL str upper() const; public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str) + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str, object) private: static BOOST_PYTHON_DECL detail::new_reference call(object const&); diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp index 2ab4ad73..77c5e67c 100644 --- a/include/boost/python/tuple.hpp +++ b/include/boost/python/tuple.hpp @@ -24,7 +24,7 @@ class tuple : public object } public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple) + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple, object) private: static BOOST_PYTHON_DECL detail::new_reference call(object const&); diff --git a/src/numeric.cpp b/src/numeric.cpp new file mode 100644 index 00000000..7d06ec11 --- /dev/null +++ b/src/numeric.cpp @@ -0,0 +1,313 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace python { namespace numeric { + +namespace +{ + enum state_t { failed = -1, unknown, succeeded }; + state_t state = unknown; + std::string module_name; + std::string type_name; + + handle<> array_module; + object array_type; + object array_function; + + void throw_load_failure() + { + PyErr_Format( + PyExc_ImportError + , "No module named '%s' or its type '%s' did not follow the NumPy protocol" + , module_name.c_str(), type_name.c_str()); + throw_error_already_set(); + + } + + bool load(bool throw_on_error) + { + if (!state) + { + if (module_name.size() == 0) + { + module_name = "numarray"; + type_name = "NDArray"; + if (load(false)) + return true; + module_name = "Numeric"; + type_name = "ArrayType"; + } + + state = failed; + PyObject* module = ::PyImport_Import(object(module_name).ptr()); + if (module) + { + PyObject* type = ::PyObject_GetAttrString(module, const_cast(type_name.c_str())); + + if (type && PyType_Check(type)) + { + array_type = object(detail::new_non_null_reference(type)); + PyObject* function = ::PyObject_GetAttrString(module, const_cast("array")); + + if (function && PyCallable_Check(function)) + { + array_function = object(detail::new_reference(function)); + state = succeeded; + } + } + } + } + + if (state == succeeded) + return true; + + if (throw_on_error) + throw_load_failure(); + + PyErr_Clear(); + return false; + } + + object const& demand_array_function() + { + load(true); + return array_function; + } +} + +void array::set_module_and_type(char const* package_name, char const* type_attribute_name) +{ + state = unknown; + module_name = package_name ? package_name : "" ; + type_name = type_attribute_name ? type_attribute_name : "" ; +} + + +namespace aux +{ + bool array_object_manager_traits::check(PyObject* obj) + { + if (!load(false)) + return false; + return ::PyObject_IsInstance(obj, array_type.ptr()); + } + + python::detail::new_non_null_reference + array_object_manager_traits::adopt(PyObject* obj) + { + load(true); + return detail::new_non_null_reference( + pytype_check(downcast(array_type.ptr()), obj)); + } + + +# define BOOST_PYTHON_AS_OBJECT(z, n, _) object(x##n) +# define BOOST_PP_LOCAL_MACRO(n) \ + array_base::array_base(BOOST_PP_ENUM_PARAMS(n, object const& x)) \ + : object((load(true), array_function)(BOOST_PP_ENUM_PARAMS(n, x))) \ + {} +# define BOOST_PP_LOCAL_LIMITS (1, 6) +# include BOOST_PP_LOCAL_ITERATE() +# undef BOOST_PYTHON_AS_OBJECT + + array_base::array_base(BOOST_PP_ENUM_PARAMS(7, object const& x)) + : object((load(true), array_type)(BOOST_PP_ENUM_PARAMS(7, x))) + {} + + object array_base::argmax(long axis) + { + return attr("argmax")(axis); + } + + object array_base::argmin(long axis) + { + return attr("argmin")(axis); + } + + object array_base::argsort(long axis) + { + return attr("argsort")(axis); + } + + object array_base::astype(object const& type) + { + return attr("astype")(type); + } + + void array_base::byteswap() + { + attr("byteswap")(); + } + + object array_base::copy() const + { + return attr("copy")(); + } + + object array_base::diagonal(long offset, long axis1, long axis2) const + { + return attr("diagonal")(offset, axis1, axis2); + } + + void array_base::info() const + { + attr("info")(); + } + + bool array_base::is_c_array() const + { + return extract(attr("is_c_array")()); + } + + bool array_base::isbyteswapped() const + { + return extract(attr("isbyteswapped")()); + } + + object array_base::new_(object type) const + { + return attr("new")(type); + } + + void array_base::sort() + { + attr("sort")(); + } + + object array_base::trace(long offset, long axis1, long axis2) const + { + return attr("trace")(offset, axis1, axis2); + } + + object array_base::type() const + { + return attr("type")(); + } + + char array_base::typecode() const + { + return extract(attr("typecode")()); + } + + object array_base::factory(object const& buffer + , object const& type + , object const& shape + , bool copy + , bool savespace + , object typecode) + { + return attr("array")(buffer, type, shape, copy, savespace, typecode); + } + + object array_base::getflat() const + { + return attr("getflat")(); + } + + long array_base::getrank() const + { + return extract(attr("getrank")()); + } + + object array_base::getshape() const + { + return attr("getshape")(); + } + + bool array_base::isaligned() const + { + return extract(attr("isaligned")); + } + + bool array_base::iscontiguous() const + { + return extract(attr("isaligned")); + } + + long array_base::itemsize() const + { + return extract(attr("itemsize")); + } + + long array_base::nelements() const + { + return extract(attr("nelements")); + } + + object array_base::nonzero() const + { + return attr("nonzero")(); + } + + void array_base::put(object const& indices, object const& values) + { + attr("put")(indices, values); + } + + void array_base::ravel() + { + attr("ravel")(); + } + + object array_base::repeat(object const& repeats, long axis) + { + return attr("repeat")(repeats, axis); + } + + void array_base::resize(object const& shape) + { + attr("resize")(shape); + } + + void array_base::setflat(object const& flat) + { + attr("setflat")(flat); + } + + void array_base::setshape(object const& shape) + { + attr("setshape")(shape); + } + + void array_base::swapaxes(long axis1, long axis2) + { + attr("swapaxes")(axis1, axis2); + } + + object array_base::take(object const& sequence, long axis) const + { + return attr("take")(sequence, axis); + } + + void array_base::tofile(object const& file) const + { + attr("tofile")(file); + } + + str array_base::tostring() const + { + return str(attr("tostring")()); + } + + void array_base::transpose(object const& axes) + { + attr("transpose")(axes); + } + + object array_base::view() const + { + return attr("view")(); + } +} + +}}} // namespace boost::python::numeric diff --git a/test/Jamfile b/test/Jamfile index 0a6914f0..f8e3d631 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -54,6 +54,8 @@ rule bpl-test ( name ? : files * : requirements * ) boost-python-runtest $(name) : $(py) $(modules) ; } +bpl-test numpy ; + bpl-test enum ; bpl-test minimal ; bpl-test docstring ; diff --git a/test/numpy.cpp b/test/numpy.cpp new file mode 100644 index 00000000..36b9e070 --- /dev/null +++ b/test/numpy.cpp @@ -0,0 +1,105 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include + +using namespace boost::python; + +// See if we can invoke array() from C++ +object new_array() +{ + return numeric::array( + make_tuple( + make_tuple(1,2,3) + , make_tuple(4,5,6) + , make_tuple(7,8,9) + ) + ); +} + +// test argument conversion +void take_array(numeric::array x) +{ +} + +// A separate function to invoke the info() member. Must happen +// outside any doctests since this prints directly to stdout and the +// result text includes the address of the 'self' array. +void info(numeric::array const& z) +{ + z.info(); +} + +// Tests which work on both Numeric and numarray array objects. Of +// course all of the operators "just work" since numeric::array +// inherits that behavior from object. +void exercise(numeric::array& y, object check) +{ + y[make_tuple(2,1)] = 3; + check(y); + check(y.astype('D')); + check(y.copy()); + check(y.typecode()); +} + +// numarray-specific tests. check is a callable object which we can +// use to record intermediate results, which are later compared with +// the results of corresponding python operations. +void exercise_numarray(numeric::array& y, object check) +{ + check(y.astype()); + + check(y.argmax()); + check(y.argmax(0)); + + check(y.argmin()); + check(y.argmin(0)); + + check(y.argsort()); + check(y.argsort(1)); + + y.byteswap(); + check(y); + + check(y.diagonal()); + check(y.diagonal(1)); + check(y.diagonal(0, 1)); + check(y.diagonal(0, 1, 0)); + + check(y.is_c_array()); + check(y.isbyteswapped()); + + check(y.trace()); + check(y.trace(1)); + check(y.trace(0, 1)); + check(y.trace(0, 1, 0)); + + check(y.new_('D')); + y.sort(); + check(y); + check(y.type()); + + check(y.factory(make_tuple(1.2, 3.4))); + check(y.factory(make_tuple(1.2, 3.4), "Double")); + check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(1,2,1))); + check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(2,1,1), false)); + check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(2), true, true)); +} + +BOOST_PYTHON_MODULE_INIT(numpy_ext) +{ + def("new_array", new_array); + def("take_array", take_array); + def("exercise", exercise); + def("exercise_numarray", exercise_numarray); + def("set_module_and_type", &numeric::array::set_module_and_type); + def("info", info); +} + +#include "module_tail.cpp" diff --git a/test/numpy.py b/test/numpy.py new file mode 100644 index 00000000..ff0c6a8f --- /dev/null +++ b/test/numpy.py @@ -0,0 +1,175 @@ +def numeric_tests(): + ''' + >>> from numpy_ext import * + >>> x = new_array() + >>> x[1,1] = 0.0 + + >>> try: take_array(3) + ... except TypeError: pass + ... else: print 'expected a TypeError' + + >>> take_array(x) + + >>> print x + [[1 2 3] + [4 0 6] + [7 8 9]] + + >>> y = x.copy() + + + >>> p = _printer() + >>> check = p.check + >>> exercise(x, p) + >>> y[2,1] = 3 + >>> check(y); + + >>> check(y.astype('D')); + + >>> check(y.copy()); + + >>> check(y.typecode()); + + >>> p.results + [] + >>> del p + ''' + pass + +def _numarray_tests(): + ''' + >>> from numpy_ext import * + >>> x = new_array() + >>> y = x.copy() + >>> p = _printer() + >>> check = p.check + >>> exercise_numarray(x, p) + + >>> check(y.astype()); + + >>> check(y.argmax()); + >>> check(y.argmax(0)); + + >>> check(y.argmin()); + >>> check(y.argmin(0)); + + >>> check(y.argsort()); + >>> check(y.argsort(1)); + + >>> y.byteswap(); + >>> check(y); + + >>> check(y.diagonal()); + >>> check(y.diagonal(1)); + >>> check(y.diagonal(0, 1)); + >>> check(y.diagonal(0, 1, 0)); + + >>> check(y.is_c_array()); + >>> check(y.isbyteswapped()); + + >>> check(y.trace()); + >>> check(y.trace(1)); + >>> check(y.trace(0, 1)); + >>> check(y.trace(0, 1, 0)); + + >>> check(y.new('D')); + >>> y.sort(); + >>> check(y); + >>> check(y.type()); + + >>> check(y.array((1.2, 3.4))); + >>> check(y.array((1.2, 3.4), "Double")); + >>> check(y.array((1.2, 3.4), "Double", (1,2,1))); + >>> check(y.array((1.2, 3.4), "Double", (2,1,1), false)); + >>> check(y.array((1.2, 3.4), "Double", (2,), true, true)); + + >>> p.results + [] + >>> del p + ''' + pass + +false = 0; +true = 1; +class _printer(object): + def __init__(self): + self.results = []; + def __call__(self, *stuff): + self.results += [ str(x) for x in stuff ] + def check(self, x): + if self.results[0] == str(x): + del self.results[0] + else: + print ' Expected:\n %s\n but got:\n %s' % (x, self.results[0]) + +def _run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + + # See which of the numeric modules are installed + has_numeric = 0 + try: + import Numeric + m = Numeric + has_numeric = 1 + except ImportError: pass + + has_numarray = 0 + try: + import numarray + m = numarray + has_numarray = 1 + except ImportError: pass + + # Bail if neither one is installed + if not (has_numeric or has_numarray): + return 0 + + # test the info routine outside the doctest. See numpy.cpp for an + # explanation + import numpy_ext + if (has_numarray): + numpy_ext.info(m.array((1,2,3))) + + failures = 0 + + # + # Run tests 4 different ways if both modules are installed, just + # to show that set_module_and_type() is working properly + # + + # run all the tests with default module search + print 'testing default extension module' + failures += doctest.testmod(sys.modules.get(__name__))[0] + + # test against Numeric if installed + if has_numeric: + print 'testing Numeric module explicitly' + numpy_ext.set_module_and_type('Numeric', 'ArrayType') + failures += doctest.testmod(sys.modules.get(__name__))[0] + + global __test__ + if has_numarray: + # Add the _numarray_tests to the list of things to test in + # this case. + __test__ = { 'numarray_tests':_numarray_tests, + 'numeric_tests': numeric_tests } + print 'testing numarray module explicitly' + numpy_ext.set_module_and_type('numarray', 'NDArray') + failures += doctest.testmod(sys.modules.get(__name__))[0] + + # see that we can go back to the default + del __test__ + print 'testing default module again' + numpy_ext.set_module_and_type('', '') + failures += doctest.testmod(sys.modules.get(__name__))[0] + + return failures + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(_run()) From 173021377e9fde817cf6f6b7c6b6b1175e249e6f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 26 Sep 2002 03:29:59 +0000 Subject: [PATCH 0762/1042] Restore msvc-stlport workaround [SVN r15522] --- include/boost/python/class.hpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 59c1f30c..26400e3e 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -85,7 +85,23 @@ namespace detail SelectHolder::register_(); } - template int assert_default_constructible(T const&); + // A helpful compile-time assertion which gives a reasonable error + // message if T can't be default-constructed. + template + class assert_default_constructible + { + template + static int specify_init_arguments_or_no_init_for_class_(U const&); + public: + assert_default_constructible() + { + force_instantiate( + sizeof( + specify_init_arguments_or_no_init_for_class_(T()) + )); + + } + }; } // @@ -366,7 +382,7 @@ 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()))); + detail::assert_default_constructible(); this->def(init<>()); this->set_instance_size(holder_selector::additional_size()); } From 72e1c1a7f627cad897d09cfedecd2cf4a57e4c70 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 26 Sep 2002 12:00:04 +0000 Subject: [PATCH 0763/1042] bugfix [SVN r15525] --- test/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/numpy.py b/test/numpy.py index ff0c6a8f..b4c3ec62 100644 --- a/test/numpy.py +++ b/test/numpy.py @@ -160,9 +160,9 @@ def _run(args = None): print 'testing numarray module explicitly' numpy_ext.set_module_and_type('numarray', 'NDArray') failures += doctest.testmod(sys.modules.get(__name__))[0] + del __test__ # see that we can go back to the default - del __test__ print 'testing default module again' numpy_ext.set_module_and_type('', '') failures += doctest.testmod(sys.modules.get(__name__))[0] From 374b55be8ace4a4d0943e1e285caa490e0f59ad2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 26 Sep 2002 12:13:47 +0000 Subject: [PATCH 0764/1042] IRIX workarounds, eliminate dead header [SVN r15526] --- include/boost/python/class.hpp | 11 ++++++----- include/boost/python/class_fwd.hpp | 7 ------- include/boost/python/numeric.hpp | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 26400e3e..ceeb516c 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -9,7 +9,6 @@ # include # include # include -# include # include @@ -38,6 +37,8 @@ namespace boost { namespace python { +enum no_init_t { no_init }; + namespace detail { // This function object is used with mpl::for_each to write the id @@ -218,7 +219,7 @@ class class_ : public objects::class_base // def(name, function) // def(name, function, policy) // def(name, function, doc_string) - // def(name, signature, stubs) + // def(name, signature, overloads) dispatch_def(&arg2, name, arg1, arg2); return *this; @@ -318,17 +319,17 @@ class class_ : public objects::class_base inline void register_() const; - template + template void dispatch_def( detail::overloads_base const*, char const* name, SigT sig, - StubsT const& stubs) + OverloadsT const& overloads) { // 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)); + name, overloads, *this, detail::get_signature(sig)); } template diff --git a/include/boost/python/class_fwd.hpp b/include/boost/python/class_fwd.hpp index 87f3ba32..8aaec6a6 100644 --- a/include/boost/python/class_fwd.hpp +++ b/include/boost/python/class_fwd.hpp @@ -6,16 +6,9 @@ #ifndef CLASS_FWD_DWA200222_HPP # define CLASS_FWD_DWA200222_HPP # include -# include -# include namespace boost { namespace python { -namespace detail -{ - struct empty_list; -} - template < class T // class being wrapped // arbitrarily-ordered optional arguments. Full qualification needed for MSVC6 diff --git a/include/boost/python/numeric.hpp b/include/boost/python/numeric.hpp index 1ef73439..df92bfbf 100644 --- a/include/boost/python/numeric.hpp +++ b/include/boost/python/numeric.hpp @@ -210,7 +210,7 @@ class array : public aux::array_base static BOOST_PYTHON_DECL void set_module_and_type(char const* package_name = 0, char const* type_attribute_name = 0); public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(array, array_base); + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(array, base); }; } // namespace boost::python::numeric From 82ef6ec6597bc98bfbf56704a2f8f0cae8e4f1f7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 26 Sep 2002 13:09:57 +0000 Subject: [PATCH 0765/1042] more .IRIX workarounds [SVN r15527] --- include/boost/python/numeric.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/numeric.hpp b/include/boost/python/numeric.hpp index df92bfbf..59ccc2d8 100644 --- a/include/boost/python/numeric.hpp +++ b/include/boost/python/numeric.hpp @@ -201,7 +201,7 @@ class array : public aux::array_base # define BOOST_PP_LOCAL_MACRO(n) \ template \ explicit array(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& x)) \ - : array_base(BOOST_PP_ENUM(n, BOOST_PYTHON_ENUM_AS_OBJECT, x)) \ + : base(BOOST_PP_ENUM(n, BOOST_PYTHON_ENUM_AS_OBJECT, x)) \ {} # define BOOST_PP_LOCAL_LIMITS (1, 7) # include BOOST_PP_LOCAL_ITERATE() From bc91db64d701ccb0e70adc68e9200f8f7d86fee0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 26 Sep 2002 13:21:19 +0000 Subject: [PATCH 0766/1042] PP optimization [SVN r15528] --- include/boost/python/numeric.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/boost/python/numeric.hpp b/include/boost/python/numeric.hpp index 59ccc2d8..d74aad06 100644 --- a/include/boost/python/numeric.hpp +++ b/include/boost/python/numeric.hpp @@ -20,7 +20,7 @@ namespace aux struct BOOST_PYTHON_DECL array_base : object { # define BOOST_PP_LOCAL_MACRO(n) \ - array_base(BOOST_PP_ENUM_PARAMS(n, object const& x)); + array_base(BOOST_PP_ENUM_PARAMS_Z(1, n, object const& x)); # define BOOST_PP_LOCAL_LIMITS (1, 7) # include BOOST_PP_LOCAL_ITERATE() @@ -116,9 +116,9 @@ class array : public aux::array_base } # define BOOST_PP_LOCAL_MACRO(n) \ - void resize(BOOST_PP_ENUM_PARAMS(n, long x)) \ + void resize(BOOST_PP_ENUM_PARAMS_Z(1, n, long x)) \ { \ - resize(make_tuple(BOOST_PP_ENUM_PARAMS(n, x))); \ + resize(make_tuple(BOOST_PP_ENUM_PARAMS_Z(1, n, x))); \ } # define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) # include BOOST_PP_LOCAL_ITERATE() @@ -130,9 +130,9 @@ class array : public aux::array_base } # define BOOST_PP_LOCAL_MACRO(n) \ - void setshape(BOOST_PP_ENUM_PARAMS(n, long x)) \ + void setshape(BOOST_PP_ENUM_PARAMS_Z(1, n, long x)) \ { \ - setshape(make_tuple(BOOST_PP_ENUM_PARAMS(n, x))); \ + setshape(make_tuple(BOOST_PP_ENUM_PARAMS_Z(1, n, x))); \ } # define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) # include BOOST_PP_LOCAL_ITERATE() @@ -199,9 +199,9 @@ class array : public aux::array_base # define BOOST_PYTHON_ENUM_AS_OBJECT(z, n, x) object(BOOST_PP_CAT(x,n)) # define BOOST_PP_LOCAL_MACRO(n) \ - template \ - explicit array(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& x)) \ - : base(BOOST_PP_ENUM(n, BOOST_PYTHON_ENUM_AS_OBJECT, x)) \ + template \ + explicit array(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, n, T, const& x)) \ + : base(BOOST_PP_ENUM_1(n, BOOST_PYTHON_ENUM_AS_OBJECT, x)) \ {} # define BOOST_PP_LOCAL_LIMITS (1, 7) # include BOOST_PP_LOCAL_ITERATE() From 997e84f117ca32a9fbda434ceb8b22f45ae09875 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 28 Sep 2002 07:35:15 +0000 Subject: [PATCH 0767/1042] Keyword argument support [SVN r15533] --- include/boost/python/args.hpp | 122 +++++-- include/boost/python/class.hpp | 90 ++++-- include/boost/python/def.hpp | 64 ++-- include/boost/python/detail/def_helper.hpp | 192 +++++++---- include/boost/python/detail/defaults_def.hpp | 215 +++++++------ include/boost/python/detail/defaults_gen.hpp | 298 ++++++++++-------- .../boost/python/detail/indirect_traits.hpp | 9 +- .../python/detail/make_keyword_range_fn.hpp | 45 +++ include/boost/python/detail/scope.hpp | 15 + include/boost/python/init.hpp | 198 +++++++++--- include/boost/python/make_function.hpp | 15 + include/boost/python/module.hpp | 7 +- include/boost/python/object/function.hpp | 16 +- .../boost/python/object/function_object.hpp | 33 +- src/module.cpp | 6 +- src/object/function.cpp | 139 ++++++-- src/object/iterator.cpp | 1 - test/Jamfile | 6 +- test/args.cpp | 81 +++++ test/args.py | 161 ++++++++++ test/bienstman2.cpp | 3 + 21 files changed, 1261 insertions(+), 455 deletions(-) create mode 100644 include/boost/python/detail/make_keyword_range_fn.hpp create mode 100644 include/boost/python/detail/scope.hpp create mode 100644 test/args.cpp create mode 100644 test/args.py diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index e488f3d8..4e2e922b 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -3,33 +3,117 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#ifndef ARGS_DWA2002323_HPP -# define ARGS_DWA2002323_HPP -# include -# include -# include -# include +#ifndef KEYWORDS_DWA2002323_HPP +# define KEYWORDS_DWA2002323_HPP + +# include +# include +# include +# include +# include + +# include +# include +# include + +# include +# include +# include +# include + +# include +# include + +# include +# include + namespace boost { namespace python { -enum no_init_t { no_init }; - namespace detail { - template - struct args_base {}; + struct keyword + { + char const* name; + handle<> default_value; + }; + + template + struct keywords + { + BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords); + + keyword_range range() const + { + return keyword_range(elements, elements + nkeywords); + } + + keyword elements[nkeywords]; + }; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + struct is_keywords + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; + + template + struct is_keywords > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + template + struct is_reference_to_keywords + { + BOOST_STATIC_CONSTANT(bool, is_ref = is_reference::value); + typedef typename remove_reference::type deref; + typedef typename remove_cv::type key_t; + BOOST_STATIC_CONSTANT(bool, is_key = is_keywords::value); + BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key)); + + typedef mpl::bool_c type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) + }; +# else + typedef char (&yes_keywords_t)[1]; + typedef char (&no_keywords_t)[2]; + + no_keywords_t is_keywords_test(...); + + template + yes_keywords_t is_keywords_test(void (*)(keywords&)); + + template + yes_keywords_t is_keywords_test(void (*)(keywords const&)); + + template + class is_reference_to_keywords + { + public: + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof(detail::is_keywords_test( (void (*)(T))0 )) + == sizeof(detail::yes_keywords_t))); + + typedef mpl::bool_c type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) + }; +# endif } -}} -namespace boost { namespace python { - -// A type list for specifying arguments -template < BOOST_PYTHON_ENUM_WITH_DEFAULT(BOOST_PYTHON_MAX_ARITY, typename A, mpl::void_) > -struct args : detail::args_base > - , detail::type_list< BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_ARITY, A) >::type -{}; +# define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n; +# define BOOST_PP_LOCAL_MACRO(n) \ +inline detail::keywords args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \ +{ \ + detail::keywords result; \ + BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \ + return result; \ +} +# define BOOST_PP_LOCAL_LIMITS (1, BOOST_PYTHON_MAX_ARITY) +# include BOOST_PP_LOCAL_ITERATE() }} // namespace boost::python -# endif // ARGS_DWA2002323_HPP +# endif // KEYWORDS_DWA2002323_HPP diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index ceeb516c..2e0840b3 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -34,6 +34,7 @@ # include # include # include +# include namespace boost { namespace python { @@ -120,8 +121,9 @@ template < class class_ : public objects::class_base { public: // types - typedef objects::class_base base; - + typedef objects::class_base base; + typedef T wrapped_type; + typedef class_ self; BOOST_STATIC_CONSTANT(bool, is_copyable = (!detail::has_noncopyable::value)); @@ -201,7 +203,7 @@ class class_ : public objects::class_base template self& def(char const* name, F f) { - this->def_impl(name, f, default_call_policies(), 0, &f); + this->def_impl(name, f, detail::keywords<>(), default_call_policies(), 0, &f); return *this; } @@ -236,6 +238,13 @@ class class_ : public objects::class_base return *this; } + template + self& def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3, Arg4T const& arg4) + { + dispatch_def(&arg2, name, arg1, arg2, arg3, arg4); + return *this; + } + template self& def(detail::operator_ const& op) { @@ -297,22 +306,32 @@ class class_ : public objects::class_base private: // helper functions - template - inline void def_impl(char const* name, Fn fn, Policies const& policies - , char const* doc, ...) + template + inline void def_impl( + char const* name + , Fn fn + , Keywords const& keywords + , Policies const& policies + , char const* doc + , ...) { 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) + , policies, keywords) , doc); } template - inline void def_impl(char const* name, F f, default_call_policies const& - , char const* doc, object const*) + inline void def_impl( + char const* name + , F f + , detail::keywords<> const& + , default_call_policies const& + , char const* doc + , object const*) { objects::add_to_namespace(*this, name, f, doc); } @@ -332,33 +351,60 @@ class class_ : public objects::class_base name, overloads, *this, detail::get_signature(sig)); } - template + template void dispatch_def( void const*, char const* name, Fn fn, - CallPolicyOrDoc const& policy_or_doc) + A1 const& a1) { - typedef detail::def_helper helper; + detail::def_helper helper(a1); + this->def_impl( - name, fn, helper::get_policy(policy_or_doc), - helper::get_doc(policy_or_doc, 0), &fn); + name, fn + , helper.keywords() + , helper.policies() + , helper.doc() + , &fn); } - template + template void dispatch_def( void const*, char const* name, Fn fn, - CallPolicyOrDoc1 const& policy_or_doc1, - CallPolicyOrDoc2 const& policy_or_doc2) + A1 const& a1, + A2 const& a2) { - typedef detail::def_helper helper; - + detail::def_helper helper(a1,a2); + this->def_impl( - name, fn, helper::get_policy(policy_or_doc1, policy_or_doc2), - helper::get_doc(policy_or_doc1, policy_or_doc2), &fn); + name, fn + , helper.keywords() + , helper.policies() + , helper.doc() + , &fn); + } + + template + void dispatch_def( + void const*, + char const* name, + Fn fn, + A1 const& a1, + A2 const& a2, + A3 const& a3 + ) + { + detail::def_helper helper(a1,a2,a3); + + this->def_impl( + name, fn + , helper.keywords() + , helper.policies() + , helper.doc() + , &fn); } }; diff --git a/include/boost/python/def.hpp b/include/boost/python/def.hpp index 1ade4fd1..f6218886 100644 --- a/include/boost/python/def.hpp +++ b/include/boost/python/def.hpp @@ -12,43 +12,49 @@ # include # include # include +# include namespace boost { namespace python { namespace detail { - void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& obj, char const* doc); - - template + template void dispatch_def( void const*, char const* name, Fn fn, - CallPolicyOrDoc const& policy_or_doc) + A1 const& a1) { - typedef detail::def_helper helper; - + def_helper helper(a1); + detail::scope_setattr_doc( - name, boost::python::make_function(fn, helper::get_policy(policy_or_doc)), - helper::get_doc(policy_or_doc, 0)); + name, boost::python::make_function( + fn + , helper.policies() + , helper.keywords()) + , helper.doc() + ); } - template + template void dispatch_def( void const*, char const* name, Fn fn, - CallPolicyOrDoc1 const& policy_or_doc1, - CallPolicyOrDoc2 const& policy_or_doc2) + A1 const& a1, + A2 const& a2) { - typedef detail::def_helper helper; + def_helper helper(a1,a2); detail::scope_setattr_doc( - name, boost::python::make_function( - fn, helper::get_policy(policy_or_doc1, policy_or_doc2)), - helper::get_doc(policy_or_doc1, policy_or_doc2)); - } + name, python::make_function( + fn + , helper.policies() + , helper.keywords()) + , helper.doc() + ); + } template void dispatch_def( @@ -87,22 +93,22 @@ void def(char const* name, Arg1T arg1, Arg2T const& arg2) template void def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3) { - // 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, F f, A1 const& a1, A2 const& a2, A3 const& a3) +{ + detail::def_helper helper(a1,a2,a3); + + detail::scope_setattr_doc( + name, python::make_function( + f + , helper.policies() + , helper.keywords()) + , helper.doc() + ); +} }} // namespace boost::python diff --git a/include/boost/python/detail/def_helper.hpp b/include/boost/python/detail/def_helper.hpp index b9931cfe..4135af55 100644 --- a/include/boost/python/detail/def_helper.hpp +++ b/include/boost/python/detail/def_helper.hpp @@ -6,72 +6,146 @@ #ifndef DEF_HELPER_DWA200287_HPP # define DEF_HELPER_DWA200287_HPP +# include # include # include -# include +# include +# include +# include +# include +# include +# include +# include +# include -namespace boost { namespace python { namespace detail { +namespace boost { namespace python { -// -// def_helper -- -// -// A helper for def() functions which determines how to interpret -// an argument of type T which could be either CallPolicies or a -// string literal representing a docstring. -// -// Generates two static functions: -// -// get_policy(x), where x is of type T, returns a policies -// object: either a reference to x or default_call_policies() -// if x is a string literal. -// -// get_doc(x, s), where s convertible to char const*, returns x -// if x is a string literal, s otherwise. +struct default_call_policies; -template -struct def_helper_impl +namespace detail { - template - static P const& - get_policy(P const& x) { return x; } - - template - static P1 const& - get_policy(P1 const& x, P2 const&) { return x; } // select left - - template - static char const* - get_doc(P const&, char const* doc) { return doc; } // select right -}; - -template <> -struct def_helper_impl -{ - static python::default_call_policies - get_policy(char const*) - { return default_call_policies(); } - - template - static P2 const& - get_policy(P1 const&, P2 const& y) { return y; } // select right - - template - static char const* - get_doc(char const* doc, P const&) // select left - { return doc; } -}; + template + struct tuple_extract; -template -struct def_helper - : def_helper_impl< - type_traits::ice_or< - is_string_literal::value - , is_same::value - , is_same::value ->::value -> -{}; + template + struct tuple_extract_impl + { + template + struct apply + { + typedef typename Tuple::head_type result_type; + + static typename Tuple::head_type extract(Tuple const& x) + { + return x.get_head(); + } + }; + }; + + template <> + struct tuple_extract_impl + { + template + struct apply + : tuple_extract + { + // All of this forwarding would be unneeded if tuples were + // derived from their tails. + typedef tuple_extract base; + typedef typename base::result_type result_type; + static result_type extract(Tuple const& x) + { + return base::extract(x.get_tail()); + } + }; + }; -}}} // namespace boost::python::detail + template + struct tuple_extract_base_select + { + typedef typename Tuple::head_type head_type; + typedef typename mpl::apply1::type match_t; + BOOST_STATIC_CONSTANT(bool, match = match_t::value); + typedef typename tuple_extract_impl::template apply type; + }; + + template + struct tuple_extract + : tuple_extract_base_select< + Tuple + , typename mpl::lambda::type + >::type + { + }; + + template + struct doc_extract + : tuple_extract< + Tuple, + mpl::logical_not< + is_reference_to_class< + add_reference + > + > > + { + }; + + template + struct keyword_extract + : tuple_extract > > + { + }; + + template + struct policy_extract + : tuple_extract< + Tuple, + mpl::logical_and< + is_reference_to_class > + , mpl::logical_not > > + > + > + { + }; + +# define BOOST_PYTHON_DEF_HELPER_TAIL default_call_policies, keywords<0>, char const* + template + struct def_helper + { + typedef typename mpl::if_< + is_same + , boost::tuples::tuple + , typename mpl::if_< + is_same + , boost::tuples::tuple + , boost::tuples::tuple + >::type + >::type all_t; + + def_helper(T1 const& a1) : m_all(a1) {} + def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2) {} + def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3) {} + + char const* doc() const + { + return doc_extract::extract(m_all); + } + + typename keyword_extract::result_type keywords() const + { + return keyword_extract::extract(m_all); + } + + typename policy_extract::result_type policies() const + { + return policy_extract::extract(m_all); + } + + all_t m_all; + }; +# undef BOOST_PYTHON_DEF_HELPER_TAIL +} + +}} // namespace boost::python::detail #endif // DEF_HELPER_DWA200287_HPP diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index 721fc37f..d7262316 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -19,9 +19,11 @@ #include #include #include -#include #include #include +#include +#include +#include /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { @@ -33,78 +35,92 @@ namespace objects struct class_base; } -namespace detail { - -template -static void name_space_def( - NameSpaceT& name_space, - char const* name, - Func f, - CallPolicies const& policies, - char const* doc, - objects::class_base* - ) +namespace detail { - name_space.def( - name, f, policies, doc); -} + template struct member_function_cast; + + template + static void name_space_def( + NameSpaceT& name_space + , char const* name + , Func f + , keyword_range const& kw + , CallPolicies const& policies + , char const* doc + , objects::class_base* + ) + { + typedef typename NameSpaceT::wrapped_type wrapped_type; + + objects::add_to_namespace( + name_space, name, + make_keyword_range_function( + // This bit of nastiness casts F to a member function of T if possible. + member_function_cast::stage1(f).stage2((wrapped_type*)0).stage3(f) + , policies, kw) + , doc); + } -template -static void name_space_def( - object& name_space, - char const* name, - Func f, - CallPolicies const& policies, - char const* doc, - ... - ) -{ - scope within(name_space); + template + static void name_space_def( + object& name_space + , char const* name + , Func f + , keyword_range const& kw + , CallPolicies const& policies + , char const* doc + , ... + ) + { + scope within(name_space); - def(name, f, policies, doc); -} + detail::scope_setattr_doc( + name + , detail::make_keyword_range_function(f, policies, kw) + , doc); + } -// For backward compatibility -template -static void name_space_def( - NameSpaceT& name_space, - char const* name, - Func f, - CallPolicies const& policies, - char const* doc, - module* - ) -{ - name_space.def( - name, f, policies, doc); -} + // For backward compatibility + template + static void name_space_def( + NameSpaceT& name_space + , char const* name + , Func f + , keyword_range const& kw // ignored + , CallPolicies const& policies + , char const* doc + , module* + ) + { + name_space.def(name, f, policies, doc); + } -/////////////////////////////////////////////////////////////////////////////// -// -// This Boost PP code generates expansions for -// -// template -// inline void -// define_stub_function( -// char const* name, StubsT s, NameSpaceT& name_space, mpl::int_c) -// { -// name_space.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: function name that will be visible to python -// 2. StubsT: a function stubs struct (see defaults_gen.hpp) -// 3. NameSpaceT& name_space: a python::class_ or python::module instance -// 4. int_t: the Nth overloaded function (StubsT::func_N) -// (see defaults_gen.hpp) -// 5. char const* name: doc string -// -/////////////////////////////////////////////////////////////////////////////// -template -struct define_stub_function {}; + /////////////////////////////////////////////////////////////////////////////// + // + // This Boost PP code generates expansions for + // + // template + // inline void + // define_stub_function( + // char const* name, OverloadsT s, NameSpaceT& name_space, mpl::int_c) + // { + // name_space.def(name, &OverloadsT::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: function name that will be visible to python + // 2. OverloadsT: a function overloads struct (see defaults_gen.hpp) + // 3. NameSpaceT& name_space: a python::class_ or python::module instance + // 4. int_t: the Nth overloaded function (OverloadsT::func_N) + // (see defaults_gen.hpp) + // 5. char const* name: doc string + // + /////////////////////////////////////////////////////////////////////////////// + template + struct define_stub_function {}; #define BOOST_PP_ITERATION_PARAMS_1 \ (3, (0, BOOST_PYTHON_MAX_ARITY, )) @@ -120,10 +136,10 @@ struct define_stub_function {}; // terminal case define_with_defaults_helper<0>. The struct and its // specialization has a sole static member function def that expects: // -// 1. char const* name: function name that will be visible to python -// 2. StubsT: a function stubs struct (see defaults_gen.hpp) -// 3. NameSpaceT& name_space: a python::class_ or python::module instance -// 4. char const* name: doc string +// 1. char const* name: function name that will be visible to python +// 2. OverloadsT: a function overloads struct (see defaults_gen.hpp) +// 3. NameSpaceT& name_space: a python::class_ or python::module instance +// 4. char const* name: doc string // // The def static member function calls a corresponding // define_stub_function. The general case recursively calls @@ -139,14 +155,19 @@ struct define_stub_function {}; def( char const* name, StubsT stubs, + keyword_range kw, CallPolicies const& policies, NameSpaceT& name_space, char const* doc) { // define the NTH stub function of stubs - define_stub_function::define(name, stubs, policies, name_space, doc); + define_stub_function::define(name, stubs, kw, policies, name_space, doc); + + if (kw.second > kw.first) + --kw.second; + // call the next define_with_defaults_helper - define_with_defaults_helper::def(name, stubs, policies, name_space, doc); + define_with_defaults_helper::def(name, stubs, kw, policies, name_space, doc); } }; @@ -159,12 +180,13 @@ struct define_stub_function {}; def( char const* name, StubsT stubs, + keyword_range const& kw, CallPolicies const& policies, NameSpaceT& name_space, char const* doc) { // define the Oth stub function of stubs - define_stub_function<0>::define(name, stubs, policies, name_space, doc); + define_stub_function<0>::define(name, stubs, kw, policies, name_space, doc); // return } }; @@ -174,7 +196,7 @@ struct define_stub_function {}; // define_with_defaults // // 1. char const* name: function name that will be visible to python -// 2. StubsT: a function stubs struct (see defaults_gen.hpp) +// 2. OverloadsT: a function overloads struct (see defaults_gen.hpp) // 3. CallPolicies& policies: Call policies // 4. NameSpaceT& name_space: a python::class_ or python::module instance // 5. SigT sig: Function signature typelist (see defaults_gen.hpp) @@ -191,17 +213,17 @@ struct define_stub_function {}; // void C::foo(int) mpl::list // /////////////////////////////////////////////////////////////////////////////// - template + template inline void define_with_defaults( char const* name, - StubsT const& stubs, + OverloadsT const& overloads, NameSpaceT& name_space, SigT sig) { typedef typename mpl::front::type return_type; - typedef typename StubsT::void_return_type void_return_type; - typedef typename StubsT::non_void_return_type non_void_return_type; + typedef typename OverloadsT::void_return_type void_return_type; + typedef typename OverloadsT::non_void_return_type non_void_return_type; typedef typename mpl::if_c< boost::is_same::value @@ -213,8 +235,13 @@ struct define_stub_function {}; (stubs_type::max_args) <= mpl::size::value); typedef typename stubs_type::template gen gen_type; - define_with_defaults_helper::def - (name, gen_type(), stubs.call_policies(), name_space, stubs.doc_string()); + define_with_defaults_helper::def( + name + , gen_type() + , overloads.keywords() + , overloads.call_policies() + , name_space + , overloads.doc_string()); } } // namespace detail @@ -232,17 +259,21 @@ template <> struct define_stub_function { template static void define( - char const* name, - StubsT, - CallPolicies const& policies, - NameSpaceT& name_space, - char const* doc) + char const* name + , StubsT const& + , keyword_range const& kw + , CallPolicies const& policies + , NameSpaceT& name_space + , char const* doc) { - detail::name_space_def(name_space, - name, - &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION()), - policies, - doc, &name_space); + detail::name_space_def( + name_space + , name + , &StubsT::BOOST_PP_CAT(func_, BOOST_PP_ITERATION()) + , kw + , policies + , doc + , &name_space); } }; diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index d8b96d53..6106ce54 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -29,74 +29,96 @@ namespace boost { namespace python { -// overloads_base is used as a base class for all function -// stubs. This class holds the doc_string of the stubs. - 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_) - : doc(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 doc; } + { + return m_doc; + } - char const* 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. + // overloads_proxy is generated by the overloads_common operator[] (see + // below). This class holds a user defined call policies of the stubs. + template + 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; -template -struct overloads_proxy - : public detail::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_) + {} - overloads_proxy(CallPoliciesT const& policies_, char const* doc) - : detail::overloads_base(doc), policies(policies_) {} + CallPoliciesT + call_policies() const + { + return policies; + } - CallPoliciesT - call_policies() const - { return policies; } + CallPoliciesT 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 + struct overloads_common + : public overloads_base + { + overloads_common(char const* doc) + : overloads_base(doc) {} -// 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[] + overloads_common(char const* doc, keyword_range const& kw) + : overloads_base(doc, kw) {} -template -struct overloads_common -: public detail::overloads_base { + default_call_policies + call_policies() const + { + return default_call_policies(); + } - overloads_common(char const* doc) - : detail::overloads_base(doc) {} + template + overloads_proxy + operator[](CallPoliciesT const& policies) const + { + return overloads_proxy( + policies, this->doc_string(), this->keywords()); + } + }; - default_call_policies - call_policies() const - { return default_call_policies(); } +}}} // namespace boost::python::detail - template - ::boost::python::overloads_proxy - operator[](CallPoliciesT const& policies) const - { - return overloads_proxy - (policies, 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); \ + 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_, \ @@ -112,14 +134,14 @@ struct overloads_common } #define BOOST_PYTHON_GEN_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \ - struct fstubs_name { \ - \ + struct fstubs_name \ + { \ BOOST_STATIC_CONSTANT(int, n_funcs = BOOST_PP_INC(n_dflts)); \ BOOST_STATIC_CONSTANT(int, max_args = n_funcs); \ \ template \ - struct gen { \ - \ + struct gen \ + { \ typedef typename ::boost::mpl::begin::type rt_iter; \ typedef typename rt_iter::type RT; \ typedef typename rt_iter::next iter0; \ @@ -151,14 +173,14 @@ struct overloads_common } #define BOOST_PYTHON_GEN_MEM_FUNCTION(fname, fstubs_name, n_args, n_dflts, ret) \ - struct fstubs_name { \ - \ + 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 { \ - \ + struct gen \ + { \ typedef typename ::boost::mpl::begin::type rt_iter; \ typedef typename rt_iter::type RT; \ \ @@ -179,75 +201,82 @@ struct overloads_common }; \ }; -/////////////////////////////////////////////////////////////////////////////// -#if defined(BOOST_NO_VOID_RETURNS) - -#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::overloads_common \ - { \ - typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \ - typedef BOOST_PP_CAT(fstubs_name, _V) void_return_type; \ - \ - fstubs_name(char const* doc = 0) \ - : boost::python:: \ - overloads_common(doc) {} \ - }; \ - -/////////////////////////////////////////////////////////////////////////////// -#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::overloads_common \ +#define BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ + fstubs_name(char const* doc = 0) \ + : ::boost::python::detail::overloads_common(doc) {} \ + template \ + fstubs_name(char const* doc, Keywords const& keywords) \ + : ::boost::python::detail::overloads_common( \ + doc, keywords.range()) \ { \ - typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \ - typedef BOOST_PP_CAT(fstubs_name, _V) void_return_type; \ - \ - fstubs_name(char const* doc = 0) \ - : boost::python:: \ - overloads_common(doc) {} \ - }; \ - -#else - -/////////////////////////////////////////////////////////////////////////////// -#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::overloads_common \ + typedef typename ::boost::python::detail:: \ + error::more_keywords_than_function_arguments< \ + Keywords::size,(n_args+n_dflts)>::too_many_keywords assertion; \ + } \ + template \ + fstubs_name(Keywords const& keywords, char const* doc = 0) \ + : ::boost::python::detail::overloads_common( \ + doc, keywords.range()) \ { \ - typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \ - typedef BOOST_PP_CAT(fstubs_name, _NV) void_return_type; \ - \ - fstubs_name(char const* doc = 0) \ - : boost::python:: \ - overloads_common(doc) {} \ - }; \ + typedef typename ::boost::python::detail:: \ + error::more_keywords_than_function_arguments< \ + Keywords::size,(n_args+n_dflts)>::too_many_keywords assertion; \ + } -/////////////////////////////////////////////////////////////////////////////// -#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) \ +# if defined(BOOST_NO_VOID_RETURNS) + +# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ + BOOST_PYTHON_GEN_FUNCTION( \ + fname, BOOST_PP_CAT(fstubs_name, NonVoid), n_args, n_dflts, return) \ + BOOST_PYTHON_GEN_FUNCTION( \ + fname, BOOST_PP_CAT(fstubs_name, Void), n_args, n_dflts, ;) \ struct fstubs_name \ - : public boost::python::overloads_common \ + : public ::boost::python::detail::overloads_common \ { \ - typedef BOOST_PP_CAT(fstubs_name, _NV) non_void_return_type; \ - typedef BOOST_PP_CAT(fstubs_name, _NV) void_return_type; \ - \ - fstubs_name(char const* doc = 0) \ - : boost::python:: \ - overloads_common(doc) {} \ - }; \ + typedef BOOST_PP_CAT(fstubs_name, NonVoid) non_void_return_type; \ + typedef BOOST_PP_CAT(fstubs_name, Void) void_return_type; \ + BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ + }; -#endif // defined(BOOST_MSVC) +# 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, NonVoid), n_args, n_dflts, return) \ + BOOST_PYTHON_GEN_MEM_FUNCTION( \ + fname, BOOST_PP_CAT(fstubs_name, Void), n_args, n_dflts, ;) \ + struct fstubs_name \ + : public ::boost::python::detail::overloads_common \ + { \ + typedef BOOST_PP_CAT(fstubs_name, NonVoid) non_void_return_type; \ + typedef BOOST_PP_CAT(fstubs_name, Void) void_return_type; \ + BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ + }; + +# else // !defined(BOOST_NO_VOID_RETURNS) + +# define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts) \ + BOOST_PYTHON_GEN_FUNCTION( \ + fname, BOOST_PP_CAT(fstubs_name, NonVoid), n_args, n_dflts, return) \ + struct fstubs_name \ + : public ::boost::python::detail::overloads_common \ + { \ + typedef BOOST_PP_CAT(fstubs_name, NonVoid) non_void_return_type; \ + typedef BOOST_PP_CAT(fstubs_name, NonVoid) 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) \ + BOOST_PYTHON_GEN_MEM_FUNCTION( \ + fname, BOOST_PP_CAT(fstubs_name, NonVoid), n_args, n_dflts, return) \ + struct fstubs_name \ + : public ::boost::python::detail::overloads_common \ + { \ + typedef BOOST_PP_CAT(fstubs_name, NonVoid) non_void_return_type; \ + typedef BOOST_PP_CAT(fstubs_name, NonVoid) void_return_type; \ + BOOST_PYTHON_OVERLOAD_CONSTRUCTORS(fstubs_name, n_args, n_dflts) \ + }; + +# endif // !defined(BOOST_NO_VOID_RETURNS) /////////////////////////////////////////////////////////////////////////////// // @@ -278,14 +307,14 @@ struct overloads_common // // Generates this code: // -// struct foo_stubs_NV { -// +// struct foo_stubsNonVoid +// { // static const int n_funcs = 4; // static const int max_args = n_funcs; // // template -// struct gen { -// +// struct gen +// { // typedef typename ::boost::mpl::begin::type rt_iter; // typedef typename rt_iter::type RT; // typedef typename rt_iter::next iter0; @@ -312,28 +341,27 @@ struct overloads_common // }; // }; // -// struct foo_stubs -// : public boost::python::overloads_common +// struct foo_overloads +// : public boost::python::detail::overloads_common +// { +// typedef foo_overloadsNonVoid non_void_return_type; +// typedef foo_overloadsNonVoid void_return_type; // -// typedef foo_stubs_NV non_void_return_type; -// typedef foo_stubs_NV void_return_type; -// -// fstubs_name(char const* doc = 0) -// : boost::python:: -// overloads_common(doc) {} +// foo_overloads(char const* doc = 0) +// : boost::python::detail::overloads_common(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_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. +// 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_stubs' -// base class. +// 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) \ diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index c6f8bcc7..5d1a2697 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -16,6 +16,8 @@ # include # include # include +# include +# include namespace boost { namespace python { namespace detail { @@ -163,6 +165,8 @@ struct is_reference_to_class >::value >::value) ); + typedef mpl::bool_c type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) }; template @@ -343,7 +347,6 @@ struct is_reference_to_volatile { }; - template typename is_pointer_help::type reference_to_pointer_helper(V&); outer_no_type reference_to_pointer_helper(...); @@ -370,8 +373,10 @@ struct is_reference_to_class BOOST_STATIC_CONSTANT( bool, value = (is_reference::value - && sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type)) + & (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type))) ); + typedef mpl::bool_c type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) }; template diff --git a/include/boost/python/detail/make_keyword_range_fn.hpp b/include/boost/python/detail/make_keyword_range_fn.hpp new file mode 100644 index 00000000..e807f158 --- /dev/null +++ b/include/boost/python/detail/make_keyword_range_fn.hpp @@ -0,0 +1,45 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP +# define MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP + +# include +# include +# include +# include + +namespace boost { namespace python { namespace detail { + +template +object make_keyword_range_function(F f, Policies const& policies, keyword_range const& kw) +{ + enum { n_arguments = detail::arg_tuple_size::value }; + return objects::function_object( + ::boost::bind(detail::caller(), f, _1, _2, policies) + , n_arguments + , kw); +} + +template +object make_keyword_range_constructor( + Policies const& policies + , detail::keyword_range const& kw + , HolderGenerator* = 0 + , ArgList* = 0) +{ + enum { nargs = mpl::size::value }; + + return objects::function_object( + ::boost::bind(detail::caller(), + objects::make_holder + ::template apply::execute + , _1, _2, policies) + , nargs + 1, kw); +} + +}}} // namespace boost::python::detail + +#endif // MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP diff --git a/include/boost/python/detail/scope.hpp b/include/boost/python/detail/scope.hpp new file mode 100644 index 00000000..f8ece8f9 --- /dev/null +++ b/include/boost/python/detail/scope.hpp @@ -0,0 +1,15 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef SCOPE_DWA2002927_HPP +# define SCOPE_DWA2002927_HPP + +namespace boost { namespace python { namespace detail { + +void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& obj, char const* doc); + +}}} // namespace boost::python::detail + +#endif // SCOPE_DWA2002927_HPP diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 5565caba..1e3f23bb 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -11,6 +11,7 @@ #define INIT_JDG20020820_HPP #include +#include #include #include #include @@ -25,6 +26,7 @@ #include #include #include +#include #include @@ -34,6 +36,8 @@ #include #include +#include + /////////////////////////////////////////////////////////////////////////////// #define BOOST_PYTHON_OVERLOAD_TYPES_WITH_DEFAULT \ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( \ @@ -55,13 +59,22 @@ namespace boost { namespace python { template -struct init; // forward declaration +class init; // forward declaration + -/////////////////////////////////////// template struct optional; // forward declaration -namespace detail { +namespace detail +{ + namespace error + { + template + struct more_keywords_than_init_arguments + { + typedef char too_many_keywords[init_args - keywords >= 0 ? 1 : -1]; + }; + } /////////////////////////////////////////////////////////////////////////// // @@ -89,7 +102,7 @@ namespace detail { 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 + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T)) }; /////////////////////////////////////// @@ -111,61 +124,114 @@ namespace detail { struct is_optional : is_optional_impl { typedef mpl::bool_c::value> type; - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T)) // needed for MSVC & Borland + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T)) }; #endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) } // namespace detail template -struct init_base { - +struct init_base +{ + init_base(char const* doc_, detail::keyword_range const& keywords_) + : m_doc(doc_), m_keywords(keywords_) + {} + + init_base(char const* doc_) + : m_doc(doc_) + {} + DerivedT const& derived() const - { return *static_cast(this); } + { + return *static_cast(this); + } + + char const* doc_string() const + { + return m_doc; + } + + detail::keyword_range const& keywords() const + { + return m_keywords; + } + + static default_call_policies call_policies() + { + return default_call_policies(); + } + + private: // data members + char const* m_doc; + detail::keyword_range m_keywords; }; template -struct init_with_call_policies -: public init_base > +class init_with_call_policies + : public init_base > { + typedef init_base > base; + public: 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_) {} + init_with_call_policies( + CallPoliciesT const& policies_ + , char const* doc_ + , detail::keyword_range const& keywords + ) + : base(doc_, keywords) + , m_policies(policies_) + {} - char const* doc_string() const - { return doc; } - - CallPoliciesT - call_policies() const - { return policies; } - - CallPoliciesT policies; - char const* doc; + CallPoliciesT const& call_policies() const + { + return this->m_policies; + } + + private: // data members + CallPoliciesT m_policies; }; template -struct init : public init_base > +class init : public init_base > { + typedef init_base > base; + public: typedef init self_t; init(char const* doc_ = 0) - : doc(doc_) {} + : base(doc_) + { + } + + template + init(char const* doc_, Keywords const& kw) + : base(doc_, std::make_pair(kw.base(), kw.base() + Keywords::size)) + { + typedef typename detail::error::more_keywords_than_init_arguments< + Keywords::size, n_arguments + >::too_many_keywords assertion; + } - char const* doc_string() const - { return doc; } - - default_call_policies - call_policies() const - { return default_call_policies(); } + template + init(Keywords const& kw) + : base(0, kw.range()) + { + typedef typename detail::error::more_keywords_than_init_arguments< + Keywords::size, n_arguments + >::too_many_keywords assertion; + } template init_with_call_policies operator[](CallPoliciesT const& policies) const - { return init_with_call_policies(policies, doc); } + { + return init_with_call_policies( + policies, this->doc_string(), this->keywords()); + } typedef detail::type_list signature_; typedef typename mpl::end::type finish; @@ -213,37 +279,47 @@ struct init : public init_base > // Count the maximum number of arguments BOOST_STATIC_CONSTANT(int, n_arguments = mpl::size::value); - - char const* doc; }; +# if 1 template <> // specialization for zero args -struct init<> : public init_base > +class init<> : public init_base > { + typedef init_base > base; + public: typedef init<> self_t; init(char const* doc_ = 0) - : doc(doc_) {} + : base(doc_) + { + } + + template + init(char const* doc_, Keywords const& kw) + : base(doc_, std::make_pair(kw.base(), kw.base() + Keywords::size)) + { + } - char const* doc_string() const - { return doc; } - - default_call_policies - call_policies() const - { return default_call_policies(); } + template + init(Keywords const& kw) + : base(0, std::make_pair(kw.base(), kw.base() + Keywords::size)) + { + } template init_with_call_policies operator[](CallPoliciesT const& policies) const - { return init_with_call_policies(policies, doc); } + { + return init_with_call_policies( + policies, this->doc_string(), this->keywords()); + } BOOST_STATIC_CONSTANT(int, n_defaults = 0); BOOST_STATIC_CONSTANT(int, n_arguments = 0); typedef detail::type_list<> reversed_args; - - char const* doc; }; +# endif /////////////////////////////////////////////////////////////////////////////// // @@ -261,7 +337,13 @@ struct optional namespace detail { template - void def_init_reversed(ClassT& cl, ReversedArgs const&, CallPoliciesT const& policies, char const* doc) + void def_init_reversed( + ClassT& cl + , ReversedArgs const& + , CallPoliciesT const& policies + , char const* doc + , detail::keyword_range const& keywords_ + ) { typedef typename mpl::fold< ReversedArgs @@ -274,8 +356,9 @@ namespace detail cl.def( "__init__", - python::make_constructor( + detail::make_keyword_range_constructor( policies + , keywords_ // Using runtime type selection works around a CWPro7 bug. , holder_selector_t::execute((held_type_t*)0).get() ) @@ -299,12 +382,20 @@ namespace detail struct define_class_init_helper { template - static void apply(ClassT& cl, CallPoliciesT const& policies, ReversedArgs const& args, char const* doc) + static void apply( + ClassT& cl + , CallPoliciesT const& policies + , ReversedArgs const& args + , char const* doc + , detail::keyword_range keywords) { - def_init_reversed(cl, args, policies, doc); + def_init_reversed(cl, args, policies, doc, keywords); + if (keywords.second > keywords.first) + --keywords.second; + typename mpl::pop_front::type next; - define_class_init_helper::apply(cl, policies, next, doc); + define_class_init_helper::apply(cl, policies, next, doc, keywords); } }; @@ -322,9 +413,14 @@ namespace detail struct define_class_init_helper<0> { template - static void apply(ClassT& cl, CallPoliciesT const& policies, ReversedArgs const& args, char const* doc) + static void apply( + ClassT& cl + , CallPoliciesT const& policies + , ReversedArgs const& args + , char const* doc + , detail::keyword_range const& keywords) { - def_init_reversed(cl, args, policies, doc); + def_init_reversed(cl, args, policies, doc, keywords); } }; } @@ -356,7 +452,7 @@ define_init(ClassT& cl, InitT const& i) { typedef typename InitT::reversed_args reversed_args; detail::define_class_init_helper::apply( - cl, i.call_policies(), reversed_args(), i.doc_string()); + cl, i.call_policies(), reversed_args(), i.doc_string(), i.keywords()); } }} // namespace boost::python diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index decdf5b4..2277371f 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -7,6 +7,7 @@ # define MAKE_FUNCTION_DWA20011221_HPP # include +# include # include # include # include @@ -32,6 +33,20 @@ object make_function(F f, Policies const& policies) , detail::arg_tuple_size::value); } +template +object make_function(F f, Policies const& policies, Keywords const& keywords) +{ + enum { n_arguments = detail::arg_tuple_size::value }; + typedef typename detail::error::more_keywords_than_function_arguments< + Keywords::size, n_arguments + >::too_many_keywords assertion; + + return objects::function_object( + ::boost::bind(detail::caller(), f, _1, _2, policies) + , n_arguments + , keywords.range()); +} + template object make_constructor(HolderGenerator* = 0, ArgList* = 0) { diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp index 2bf923c0..69e9001d 100644 --- a/include/boost/python/module.hpp +++ b/include/boost/python/module.hpp @@ -71,11 +71,12 @@ class module : public detail::module_base char const* doc, void const*) { - typedef detail::def_helper helper; + detail::def_helper helper(policy_or_doc, doc); this->setattr_doc( - name, boost::python::make_function(fn, helper::get_policy(policy_or_doc)), - helper::get_doc(policy_or_doc, doc)); + name + , boost::python::make_function(fn, helper.policies()) + , helper.doc()); } template diff --git a/include/boost/python/object/function.hpp b/include/boost/python/object/function.hpp index c14f57e3..1a3c3f5f 100644 --- a/include/boost/python/object/function.hpp +++ b/include/boost/python/object/function.hpp @@ -7,6 +7,7 @@ # define FUNCTION_DWA20011214_HPP # include +# include # include # include # include @@ -17,7 +18,13 @@ namespace boost { namespace python { namespace objects { struct BOOST_PYTHON_DECL function : PyObject { - function(py_function const&, unsigned min_args, unsigned max_args = 0); + function( + py_function const& + , unsigned min_arity + , unsigned max_arity + , python::detail::keyword const* names_and_defaults + , unsigned num_keywords); + ~function(); PyObject* call(PyObject*, PyObject*) const; @@ -42,11 +49,12 @@ struct BOOST_PYTHON_DECL function : PyObject private: // data members py_function m_fn; - unsigned m_min_args; - unsigned m_max_args; + unsigned m_min_arity; + unsigned m_max_arity; handle m_overloads; object m_name; object m_doc; + object m_arg_names; }; // @@ -66,7 +74,7 @@ inline object const& function::name() const { return this->m_name; } - + }}} // namespace boost::python::objects #endif // FUNCTION_DWA20011214_HPP diff --git a/include/boost/python/object/function_object.hpp b/include/boost/python/object/function_object.hpp index 03535ec3..d3661563 100644 --- a/include/boost/python/object/function_object.hpp +++ b/include/boost/python/object/function_object.hpp @@ -8,17 +8,36 @@ # include # include # include +# include +# include -namespace boost { namespace python { namespace objects { +namespace boost { namespace python { -BOOST_PYTHON_DECL api::object function_object_impl(boost::function2 const& f, unsigned min_args, unsigned max_args = 0); +namespace objects +{ + BOOST_PYTHON_DECL api::object function_object( + py_function const& f + , unsigned min_arity, unsigned max_arity + , python::detail::keyword_range const&); -template -inline object function_object(F const& f, unsigned min_args, unsigned max_args = 0) -{ - return objects::function_object_impl(boost::function2(f), min_args, max_args); + BOOST_PYTHON_DECL api::object function_object( + py_function const& f + , unsigned arity + , python::detail::keyword_range const&); + + BOOST_PYTHON_DECL api::object function_object(py_function const& f, unsigned arity); + + // Add an attribute to the name_space with the given name. If it is + // a Boost.Python function object + // (boost/python/object/function.hpp), and an existing function is + // already there, add it as an overload. + BOOST_PYTHON_DECL void add_to_namespace( + object const& name_space, char const* name, object const& attribute); + + BOOST_PYTHON_DECL void add_to_namespace( + object const& name_space, char const* name, object const& attribute, char const* doc); } -}}} // namespace boost::python::objects +}} // namespace boost::python::objects #endif // FUNCTION_OBJECT_DWA2002725_HPP diff --git a/src/module.cpp b/src/module.cpp index 2dd476d1..d81e626a 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -6,8 +6,8 @@ // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. +#include #include -#include #include #include #include @@ -35,7 +35,7 @@ void module_base::setattr_doc(const char* name, python::object const& x, char co { // Use function::add_to_namespace to achieve overloading if // appropriate. - objects::function::add_to_namespace(python::object(m_module), name, x, doc); + objects::add_to_namespace(python::object(m_module), name, x, doc); } void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& x, char const* doc) @@ -43,7 +43,7 @@ void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& x, char // Use function::add_to_namespace to achieve overloading if // appropriate. scope current; - objects::function::add_to_namespace(current, name, x, doc); + objects::add_to_namespace(current, name, x, doc); } void module_base::add(type_handle const& x) diff --git a/src/object/function.cpp b/src/object/function.cpp index 6d013b3a..259bfb86 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -7,22 +7,54 @@ #include #include #include -#include #include #include +#include +#include +#include + #include #include -#include namespace boost { namespace python { namespace objects { extern PyTypeObject function_type; -function::function(py_function const& implementation, unsigned min_args, unsigned max_args) +function::function( + py_function const& implementation + , unsigned min_arity + , unsigned max_arity + , python::detail::keyword const* names_and_defaults + , unsigned num_keywords + ) : m_fn(implementation) - , m_min_args(min_args) - , m_max_args(std::max(max_args,min_args)) + , m_min_arity(min_arity) + // was using std::max here, but a problem with MinGW-2.95 and + // our directory prevents it. + , m_max_arity(max_arity > min_arity ? max_arity : min_arity) { + if (names_and_defaults != 0) + { + unsigned keyword_offset + = m_max_arity > num_keywords ? m_max_arity - num_keywords : 0; + + + m_arg_names = object(handle<>(PyTuple_New(m_max_arity))); + for (unsigned j = 0; j < keyword_offset; ++j) + PyTuple_SET_ITEM(m_arg_names.ptr(), j, incref(Py_None)); + + for (unsigned i = 0; i < num_keywords; ++i) + { + PyTuple_SET_ITEM( + m_arg_names.ptr() + , i + keyword_offset + , expect_non_null( + PyString_FromString(const_cast(names_and_defaults[i].name)) + ) + ); + } + } + PyObject* p = this; if (function_type.ob_type == 0) { @@ -39,14 +71,51 @@ function::~function() PyObject* function::call(PyObject* args, PyObject* keywords) const { std::size_t nargs = PyTuple_GET_SIZE(args); + std::size_t nkeywords = keywords ? PyDict_Size(keywords) : 0; + std::size_t total_args = nargs + nkeywords; + function const* f = this; do { // Check for a plausible number of arguments - if (nargs >= f->m_min_args && nargs <= f->m_max_args) + if (total_args >= f->m_min_arity && total_args <= f->m_max_arity) { + handle<> args2(allow_null(borrowed(args))); + if (nkeywords > 0) + { + if (!f->m_arg_names + || static_cast(PyTuple_Size(f->m_arg_names.ptr())) < total_args) + { + args2 = handle<>(); // signal failure + } + else + { + // build a new arg tuple + args2 = handle<>(PyTuple_New(total_args)); + + // Fill in the positional arguments + for (std::size_t i = 0; i < nargs; ++i) + PyTuple_SET_ITEM(args2.get(), i, incref(PyTuple_GET_ITEM(args, i))); + + // Grab remaining arguments by name from the keyword dictionary + for (std::size_t j = nargs; j < total_args; ++j) + { + PyObject* value = PyDict_GetItem( + keywords, PyTuple_GET_ITEM(f->m_arg_names.ptr(), j)); + + if (!value) + { + PyErr_Clear(); + args2 = handle<>(); + break; + } + PyTuple_SET_ITEM(args2.get(), j, incref(value)); + } + } + } + // Call the function - PyObject* result = f->m_fn(args, keywords); + PyObject* result = args2 ? f->m_fn(args2.get(), 0) : 0; // If the result is NULL but no error was set, m_fn failed // the argument-matching test. @@ -154,7 +223,10 @@ namespace handle not_implemented_function() { - static object keeper(function_object(¬_implemented_impl, 2, 3)); + static object keeper( + function_object(¬_implemented_impl, 2, 3 + , python::detail::keyword_range()) + ); return handle(borrowed(downcast(keeper.ptr()))); } } @@ -222,6 +294,19 @@ void function::add_to_namespace( } } +BOOST_PYTHON_DECL void add_to_namespace( + object const& name_space, char const* name, object const& attribute) +{ + function::add_to_namespace(name_space, name, attribute); +} + +BOOST_PYTHON_DECL void add_to_namespace( + object const& name_space, char const* name, object const& attribute, char const* doc) +{ + function::add_to_namespace(name_space, name, attribute, doc); +} + + namespace { struct bind_return @@ -350,31 +435,35 @@ PyTypeObject function_type = { 0 /* tp_new */ }; -object function_object_impl(py_function const& f, unsigned min_args, unsigned max_args) +object function_object( + py_function const& f, unsigned min_arity, unsigned max_arity + , python::detail::keyword_range const& keywords) { return python::object( python::detail::new_non_null_reference( - new function(f, min_args, max_args))); + new function( + f, min_arity, max_arity, keywords.first, keywords.second - keywords.first))); } -handle<> function_handle_impl(py_function const& f, unsigned min_args, unsigned max_args) +object function_object( + py_function const& f + , unsigned arity + , python::detail::keyword_range const& kw) +{ + return function_object(f, arity, arity, kw); +} + +object function_object(py_function const& f, unsigned arity) +{ + return function_object(f, arity, arity, python::detail::keyword_range()); +} + + +handle<> function_handle_impl(py_function const& f, unsigned min_arity, unsigned max_arity) { return python::handle<>( allow_null( - new function(f, min_args, max_args))); + new function(f, min_arity, max_arity, 0, 0))); } -BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute) -{ - function::add_to_namespace(name_space, name, attribute); -} - -BOOST_PYTHON_DECL void add_to_namespace( - object const& name_space, char const* name, object const& attribute, char const* doc) -{ - function::add_to_namespace(name_space, name, attribute, doc); -} - - }}} // namespace boost::python::objects diff --git a/src/object/iterator.cpp b/src/object/iterator.cpp index 384d6845..1718ee59 100644 --- a/src/object/iterator.cpp +++ b/src/object/iterator.cpp @@ -5,7 +5,6 @@ // to its suitability for any purpose. #include -#include #include #include diff --git a/test/Jamfile b/test/Jamfile index f8e3d631..6e305b42 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -54,10 +54,10 @@ rule bpl-test ( name ? : files * : requirements * ) boost-python-runtest $(name) : $(py) $(modules) ; } -bpl-test numpy ; - -bpl-test enum ; bpl-test minimal ; +bpl-test args ; +bpl-test numpy ; +bpl-test enum ; bpl-test docstring ; bpl-test exception_translator ; bpl-test pearu1 : test_cltree.py cltree.cpp ; diff --git a/test/args.cpp b/test/args.cpp new file mode 100644 index 00000000..9727b902 --- /dev/null +++ b/test/args.cpp @@ -0,0 +1,81 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include +#include +#include "test_class.hpp" + +using namespace boost::python; + +tuple f(int x = 1, double y = 4.25, char const* z = "wow") +{ + return make_tuple(x, y, z); +} + +BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3) + +typedef test_class<> Y; + +struct X +{ + X(int a0 = 0, int a1 = 1) : inner0(a0), inner1(a1) {} + tuple f(int x = 1, double y = 4.25, char const* z = "wow") + { + return make_tuple(x, y, z); + } + + Y const& inner(bool n) const { return n ? inner1 : inner0; } + + Y inner0; + Y inner1; +}; + +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3) + +BOOST_PYTHON_MODULE_INIT(args_ext) +{ + def("f", f, args("x", "y", "z") + , "This is f's docstring" + ); + +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 + // MSVC6 gives a fatal error LNK1179: invalid or corrupt file: + // duplicate comdat error if we try to re-use the exact type of f + // here, so substitute long for int. + tuple (*f)(long,double,char const*) = 0; +#endif + def("f1", f, f_overloads("f1's docstring", args("x", "y", "z"))); + def("f2", f, f_overloads(args("x", "y", "z"))); + def("f3", f, f_overloads(args("x", "y", "z"), "f3's docstring")); + + class_("Y", init()) + .def("value", &Y::value) + ; + + class_("X", "This is X's docstring") + .def(init >(args("a0", "a1"))) + .def("f", &X::f + , "This is X.f's docstring" + , args("x", "y", "z")) + + // Just to prove that all the different argument combinations work + .def("inner0", &X::inner, return_internal_reference<>(), args("n"), "docstring") + .def("inner1", &X::inner, return_internal_reference<>(), "docstring", args("n")) + + .def("inner2", &X::inner, args("n"), return_internal_reference<>(), "docstring") + .def("inner3", &X::inner, "docstring", return_internal_reference<>(), args("n")) + + .def("inner4", &X::inner, args("n"), "docstring", return_internal_reference<>()) + .def("inner5", &X::inner, "docstring", args("n"), return_internal_reference<>()) + + .def("f1", &X::f, X_f_overloads(args("x", "y", "z"))) + ; + + def("inner", &X::inner, "docstring", args("self", "n"), return_internal_reference<>()); +} diff --git a/test/args.py b/test/args.py new file mode 100644 index 00000000..665fae41 --- /dev/null +++ b/test/args.py @@ -0,0 +1,161 @@ +""" +>>> from args_ext import * + +>>> f(x= 1, y = 3, z = 'hello') +(1, 3.0, 'hello') + +>>> f(z = 'hello', x = 3, y = 2.5) +(3, 2.5, 'hello') + +>>> f(1, z = 'hi', y = 3) +(1, 3.0, 'hi') + +>>> try: f(1, 2, 'hello', bar = 'baz') +... except TypeError: pass +... else: print 'expected an exception: unknown keyword' + + + Exercise the functions using default stubs + +>>> f1(z = 'nix', y = .125, x = 2) +(2, 0.125, 'nix') +>>> f1(y = .125, x = 2) +(2, 0.125, 'wow') +>>> f1(x = 2) +(2, 4.25, 'wow') +>>> f1() +(1, 4.25, 'wow') + +>>> f2(z = 'nix', y = .125, x = 2) +(2, 0.125, 'nix') +>>> f2(y = .125, x = 2) +(2, 0.125, 'wow') +>>> f2(x = 2) +(2, 4.25, 'wow') +>>> f2() +(1, 4.25, 'wow') + +>>> f3(z = 'nix', y = .125, x = 2) +(2, 0.125, 'nix') +>>> f3(y = .125, x = 2) +(2, 0.125, 'wow') +>>> f3(x = 2) +(2, 4.25, 'wow') +>>> f3() +(1, 4.25, 'wow') + + Member function tests + +>>> q = X() +>>> q.f(x= 1, y = 3, z = 'hello') +(1, 3.0, 'hello') + +>>> q.f(z = 'hello', x = 3, y = 2.5) +(3, 2.5, 'hello') + +>>> q.f(1, z = 'hi', y = 3) +(1, 3.0, 'hi') + +>>> try: q.f(1, 2, 'hello', bar = 'baz') +... except TypeError: pass +... else: print 'expected an exception: unknown keyword' + + Exercise member functions using default stubs + +>>> q.f1(z = 'nix', y = .125, x = 2) +(2, 0.125, 'nix') +>>> q.f1(y = .125, x = 2) +(2, 0.125, 'wow') +>>> q.f1(x = 2) +(2, 4.25, 'wow') +>>> q.f1() +(1, 4.25, 'wow') + +>>> X.f.__doc__ +"This is X.f's docstring" + +>>> xfuncs = (X.inner0, X.inner1, X.inner2, X.inner3, X.inner4, X.inner5) +>>> for f in xfuncs: +... print f(q,1).value(), +... print f(q, n = 1).value(), +... print f(q, n = 0).value(), +... print f.__doc__ +1 1 0 docstring +1 1 0 docstring +1 1 0 docstring +1 1 0 docstring +1 1 0 docstring +1 1 0 docstring + +>>> x = X(a1 = 44, a0 = 22) +>>> x.inner0(0).value() +22 +>>> x.inner0(1).value() +44 + +>>> x = X(a0 = 7) +>>> x.inner0(0).value() +7 +>>> x.inner0(1).value() +1 + +>>> inner(n = 1, self = q).value() +1 +""" +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/bienstman2.cpp b/test/bienstman2.cpp index dd7ba532..7e4f951c 100644 --- a/test/bienstman2.cpp +++ b/test/bienstman2.cpp @@ -2,6 +2,9 @@ #include #include +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 // works around a name lookup bug +# define C C_ +#endif struct C {}; struct D {}; From 3158d28264ca66de7cc6caee5c96ec13079a2db0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 28 Sep 2002 07:48:27 +0000 Subject: [PATCH 0768/1042] Keyword argument support [SVN r15534] --- include/boost/python/args_fwd.hpp | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 include/boost/python/args_fwd.hpp diff --git a/include/boost/python/args_fwd.hpp b/include/boost/python/args_fwd.hpp new file mode 100644 index 00000000..b8ca0c7d --- /dev/null +++ b/include/boost/python/args_fwd.hpp @@ -0,0 +1,41 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef ARGS_FWD_DWA2002927_HPP +# define ARGS_FWD_DWA2002927_HPP + +# include +# include +# include + +namespace boost { namespace python { + +namespace detail +{ + struct keyword; + template struct keywords; + + typedef std::pair keyword_range; + + template <> + struct keywords<0> + { + BOOST_STATIC_CONSTANT(std::size_t, size = 0); + static keyword_range range() { return keyword_range(); } + }; + + namespace error + { + template + struct more_keywords_than_function_arguments + { + typedef char too_many_keywords[keywords > function_args ? -1 : 1]; + }; + } +} + +}} // namespace boost::python + +#endif // ARGS_FWD_DWA2002927_HPP From 6bfbeb3dfa76c190230ca1de4b93567212ac9690 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 28 Sep 2002 13:26:12 +0000 Subject: [PATCH 0769/1042] make minimal a more-useful test [SVN r15540] --- test/minimal.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/minimal.py b/test/minimal.py index fe5788f5..fde9840a 100644 --- a/test/minimal.py +++ b/test/minimal.py @@ -1,2 +1,4 @@ +print "IMPORTING minimal_ext" import minimal_ext +print "DONE IMPORTING minimal_ext" From a0ff708d29331d561db3c96130413989a5c85c63 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 28 Sep 2002 13:27:00 +0000 Subject: [PATCH 0770/1042] Fixes for AIX [SVN r15541] --- src/numeric.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/numeric.cpp b/src/numeric.cpp index 7d06ec11..7d275ff0 100644 --- a/src/numeric.cpp +++ b/src/numeric.cpp @@ -21,8 +21,8 @@ namespace std::string type_name; handle<> array_module; - object array_type; - object array_function; + handle<> array_type; + handle<> array_function; void throw_load_failure() { @@ -56,12 +56,12 @@ namespace if (type && PyType_Check(type)) { - array_type = object(detail::new_non_null_reference(type)); + array_type = handle<>(type); PyObject* function = ::PyObject_GetAttrString(module, const_cast("array")); if (function && PyCallable_Check(function)) { - array_function = object(detail::new_reference(function)); + array_function = handle<>(function); state = succeeded; } } @@ -78,10 +78,10 @@ namespace return false; } - object const& demand_array_function() + object demand_array_function() { load(true); - return array_function; + return object(array_function); } } @@ -99,7 +99,7 @@ namespace aux { if (!load(false)) return false; - return ::PyObject_IsInstance(obj, array_type.ptr()); + return ::PyObject_IsInstance(obj, array_type.get()); } python::detail::new_non_null_reference @@ -107,21 +107,21 @@ namespace aux { load(true); return detail::new_non_null_reference( - pytype_check(downcast(array_type.ptr()), obj)); + pytype_check(downcast(array_type.get()), obj)); } # define BOOST_PYTHON_AS_OBJECT(z, n, _) object(x##n) -# define BOOST_PP_LOCAL_MACRO(n) \ - array_base::array_base(BOOST_PP_ENUM_PARAMS(n, object const& x)) \ - : object((load(true), array_function)(BOOST_PP_ENUM_PARAMS(n, x))) \ +# define BOOST_PP_LOCAL_MACRO(n) \ + array_base::array_base(BOOST_PP_ENUM_PARAMS(n, object const& x)) \ + : object(demand_array_function()(BOOST_PP_ENUM_PARAMS(n, x))) \ {} # define BOOST_PP_LOCAL_LIMITS (1, 6) # include BOOST_PP_LOCAL_ITERATE() # undef BOOST_PYTHON_AS_OBJECT array_base::array_base(BOOST_PP_ENUM_PARAMS(7, object const& x)) - : object((load(true), array_type)(BOOST_PP_ENUM_PARAMS(7, x))) + : object(demand_array_function()(BOOST_PP_ENUM_PARAMS(7, x))) {} object array_base::argmax(long axis) From 94063f786238a3977601802364e4f5feab3ab9cc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 03:25:04 +0000 Subject: [PATCH 0771/1042] Keyword argument support tweak [SVN r15544] --- include/boost/python/init.hpp | 16 ++-------------- test/args.cpp | 2 +- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 1e3f23bb..35f2dc90 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -217,8 +217,8 @@ class init : public init_base > } template - init(Keywords const& kw) - : base(0, kw.range()) + init(Keywords const& kw, char const* doc_ = 0) + : base(doc_, kw.range()) { typedef typename detail::error::more_keywords_than_init_arguments< Keywords::size, n_arguments @@ -294,18 +294,6 @@ class init<> : public init_base > { } - template - init(char const* doc_, Keywords const& kw) - : base(doc_, std::make_pair(kw.base(), kw.base() + Keywords::size)) - { - } - - template - init(Keywords const& kw) - : base(0, std::make_pair(kw.base(), kw.base() + Keywords::size)) - { - } - template init_with_call_policies operator[](CallPoliciesT const& policies) const diff --git a/test/args.cpp b/test/args.cpp index 9727b902..ee79fcfa 100644 --- a/test/args.cpp +++ b/test/args.cpp @@ -54,7 +54,7 @@ BOOST_PYTHON_MODULE_INIT(args_ext) def("f2", f, f_overloads(args("x", "y", "z"))); def("f3", f, f_overloads(args("x", "y", "z"), "f3's docstring")); - class_("Y", init()) + class_("Y", init(args("value"), "Y's docstring")) .def("value", &Y::value) ; From 8cd3e16e2601babdaae477c161edacf29ffbe338 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 16:06:02 +0000 Subject: [PATCH 0772/1042] Documentation update [SVN r15548] --- doc/v2/CallPolicies.html | 242 +++++----- doc/v2/call_method.html | 171 +++---- doc/v2/class.html | 948 +++++++++++++++++++++++++-------------- doc/v2/definitions.html | 83 ++-- 4 files changed, 886 insertions(+), 558 deletions(-) diff --git a/doc/v2/CallPolicies.html b/doc/v2/CallPolicies.html index 3c2b98fd..9d582e7d 100644 --- a/doc/v2/CallPolicies.html +++ b/doc/v2/CallPolicies.html @@ -1,124 +1,152 @@ + + - - - -Boost.Python - CallPolicies Concept - - - + + + + + Boost.Python - CallPolicies Concept + + + +
      - - - - -
      -

      C++ Boost

      -
      -

      Boost.Python

      -

      CallPolicies Concept

      -
      -
      -
      -
      Introduction
      -
      CallPolicies Composition
      -
      Concept Requirements
      -
      -
      CallPolicies Concept
      -
      -
      + + +

      C++ Boost

      + -

      Introduction

      + +

      Boost.Python

      -

      Models of the CallPolicies concept are used to specialize the -behavior of Python callable objects generated by Boost.Python to -wrapped C++ objects like function and member function -pointers, providing three behaviors: -

        -
      1. precall - Python argument tuple management before -the wrapped object is invoked -
      2. result_converter - C++ return value handling -
      3. postcall - Python argument tuple and result -management after the wrapped object is invoked -
      +

      CallPolicies Concept

      + + + +
      -

      CallPolicies Composition

      +
      +
      Introduction
      -In order to allow the use of multiple models of CallPolicies in the -same callable object, Boost.Python's CallPolicies class templates -provide a chaining interface which allows them to be recursively -composed. This interface takes the form of an optional template -parameter, Base which defaults to -default_call_policies. By convention, the -precall function of the -Base is invoked after the precall -function supplied by the outer template, and the postcall -function of the Base is invoked before the -postcall function of the outer template. If a -result_converter is supplied by the outer template, it -replaces any result_converter supplied by the -Base. For an example, see -return_internal_reference. +
      CallPolicies Composition
      -

      Concept Requirements

      -

      CallPolicies Concept

      +
      Concept Requirements
      -

      In the table below, x denotes an object whose -type P is a model of CallPolicies, -a denotes a PyObject* pointing to -a Python argument tuple object, and r denotes a -PyObject* referring to a "preliminary" result -object. +

      +
      +
      CallPolicies Concept
      +
      +
      +
      - +

      Introduction

      - - - - - +

      Models of the CallPolicies concept are used to specialize the behavior + of Python callable objects generated by Boost.Python to wrapped C++ + objects like function and member function pointers, providing three + behaviors:

      - - - - - - -
      ExpressionTypeResult/Semantics
      x.precall(a)convertible to bool - returns false and PyErr_Occurred() != 0 - upon failure, true otherwise. +
        +
      1. precall - Python argument tuple management before the + wrapped object is invoked
      2. -
      P::result_converterA model of ResultConverterGenerator. - An MPL unarymetafunction object used produce the - "preliminary" result object. +
    • result_converter - C++ return value handling
    • -
      x.postcall(a, r)convertible to PyObject* - 0 0 and PyErr_Occurred() != 0 - upon failure. Must "conserve references" even in the - event of an exception. In other words, if r is not - returned, its reference count must be decremented; if another - existing object is returned, its reference count must be - incremented. -
      +
    • postcall - Python argument tuple and result management + after the wrapped object is invoked
    • + -Models of CallPolicies are required to be CopyConstructible. +

      CallPolicies Composition

      + In order to allow the use of multiple models of CallPolicies in the same + callable object, Boost.Python's CallPolicies class templates provide a + chaining interface which allows them to be recursively composed. This + interface takes the form of an optional template parameter, + Base which defaults to default_call_policies. + By convention, the precall function of the Base + is invoked after the precall function supplied by the + outer template, and the postcall function of the + Base is invoked before the postcall + function of the outer template. If a result_converter is + supplied by the outer template, it replaces any + result_converter supplied by the Base. For an + example, see return_internal_reference. + -
      -

      Revised - - 19 May, 2002 - -

      -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      Concept Requirements

      -

      Permission to copy, use, modify, sell - and distribute this software is granted provided this copyright notice appears - in all copies. This software is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose. - +

      CallPolicies Concept

      + +

      In the table below, x denotes an object whose type + P is a model of CallPolicies, a + denotes a PyObject* pointing to a Python argument tuple + object, and r denotes a PyObject* + referring to a "preliminary" result object.

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      ExpressionTypeResult/Semantics
      x.precall(a)convertible to boolreturns false and PyErr_Occurred() != 0 + upon failure, true otherwise.
      P::result_converterA model of ResultConverterGenerator.An MPL unary Metafunction + Class used produce the "preliminary" result object.
      x.postcall(a, r)convertible to PyObject*0 0 and PyErr_Occurred() != 0 + upon failure. Must "conserve references" even in the event of an + exception. In other words, if r is not returned, its + reference count must be decremented; if another existing object is + returned, its reference count must be incremented.
      + Models of CallPolicies are required to be CopyConstructible. +
      + +

      Revised + + 19 May, 2002 +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + +

      Permission to copy, use, modify, sell and distribute this software is + granted provided this copyright notice appears in all copies. This + software is provided "as is" without express or implied warranty, and + with no claim as to its suitability for any purpose.

      + + diff --git a/doc/v2/call_method.html b/doc/v2/call_method.html index f2c52a9b..3aae0e35 100644 --- a/doc/v2/call_method.html +++ b/doc/v2/call_method.html @@ -1,74 +1,89 @@ + + - - - -Boost.Python - <call_method.hpp> - - - + + + + + Boost.Python - <call_method.hpp> + + + +
      - - - - -
      -

      -

      -
      -

      Boost.Python

      -

      Header <call_method.hpp>

      -
      -
      -

      Contents

      -
      -
      Introduction
      -
      Functions
      -
      -
      call_method
      -
      + + +

      C++ Boost

      + -
      Example(s)
      + +

      Boost.Python

      -
      -
      -

      Introduction

      -

      - <boost/python/call_method.hpp> defines the call_method family of overloaded function - templates, used to invoke callable attributes of Python objects from C++. +

      Header <call_method.hpp>

      + + + +
      -

      Functions

      +

      Contents

      + +
      +
      Introduction
      + +
      Functions
      + +
      +
      +
      call_method
      +
      +
      + +
      Example(s)
      +
      +
      + +

      Introduction

      + +

      <boost/python/call_method.hpp> defines the call_method family of overloaded + function templates, used to invoke callable attributes of Python objects + from C++.

      + +

      Functions

      -template <class R, class A1, class A2, ... class An>
      +template <class R, class A1, class A2, ... class An>
       R call_method(PyObject* self, char const* method, A1 const&, A2 const&, ... An const&)
       
      -
      -
      Requires: R is a pointer type, reference - type, or a complete type with an accessible copy constructor
      -
      Effects: Invokes self.method(a1, a2, ...an) in - Python, where a1...an are the arguments to - call_method(), converted to Python objects. For a - complete semantic description, see this - page. +
      +
      Requires: R is a pointer type, reference type, + or a complete type with an accessible copy constructor
      -
      Returns: The result of the Python call, converted to the - C++ type R.
      +
      Effects: Invokes + self.method(a1, a2, ...an) in + Python, where a1...an are the + arguments to call_method(), converted to Python objects. + For a complete semantic description, see this + page.
      -
      -
      Rationale: call_method is critical to - implementing C++ virtual functions which are overridable in Python, - as shown by the example below. -
      -
      +
      Returns: The result of the Python call, converted to the C++ + type R.
      -

      Example(s)

      +
      Rationale: call_method is critical to + implementing C++ virtual functions which are overridable in Python, as + shown by the example below.
      + -The following C++ illustrates the use of call_method in -wrapping a class with a virtual function that can be overridden in -Python: +

      Example(s)

      + The following C++ illustrates the use of call_method in + wrapping a class with a virtual function that can be overridden in + Python: -

      C++ Module Definition

      +

      C++ Module Definition

       #include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
      @@ -79,13 +94,13 @@ Python:
       class Base
       {
        public:
      -   virtual char const* class_name() const { return "Base"; }
      +   virtual char const* class_name() const { return "Base"; }
          virtual ~Base();
       };
       
       bool is_base(Base* b)
       {
      -   return !std::strcmp(b->class_name(), "Base");
      +   return !std::strcmp(b->class_name(), "Base");
       }
       
       // Wrapper code begins here
      @@ -97,26 +112,25 @@ class Base_callback : public Base
        public:
          Base_callback(PyObject* self) : m_self(self) {}
       
      -   char const* class_name() const { return call_method(m_self, "class_name"); }
      +   char const* class_name() const { return call_method(m_self, "class_name"); }
          char const* Base_name() const { return Base::class_name(); }
        private:
      -   PyObject* m_self;
      +   PyObject* const m_self;
       };
       
       using namespace boost::python;
       BOOST_PYTHON_MODULE_INIT(my_module)
       {
      -   module("my_module")
      -      .def("is_base", is_base)
      -      .add(
      -         class_<Base,Base_callback, noncopyable>("Base")
      -             .def("class_name", Base_callback::Base_name);
      -         )
      -       ;
      +    def("is_base", is_base)
      +
      +    class_<Base,Base_callback, noncopyable>("Base")
      +        .def("class_name", &Base_callback::Base_name)
      +        ;
      +
       }
       
      -

      Python Code

      +

      Python Code

       >>> from my_module import *
       >>> class Derived(Base):
      @@ -130,12 +144,15 @@ BOOST_PYTHON_MODULE_INIT(my_module)
       >>> is_base(Derived())
       0
       
      -

      Revised - - 10 May, 2002 - -

      -

      © Copyright Dave Abrahams - 2002. All Rights Reserved.

      - + +

      Revised + + 28 Sept, 2002 +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + diff --git a/doc/v2/class.html b/doc/v2/class.html index 0496d2ca..240a1364 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -1,70 +1,108 @@ - + + + + Boost.Python - <boost/python/class.hpp>, <boost/python/class_fwd.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      Headers <boost/python/class.hpp>, <boost/python/class_fwd.hpp>

      +

      Contents

      -
      Introduction +
      Introduction
      -
      Classes +
      Classes
      -
      Class template class_ +
      Class template + class_
      Class class_ - synopsis + synopsis
      Class class_ - constructors + constructors
      Class class_ - modifier functions - -
      Class class_ - observer functions + modifier functions
      +
      -
      Class template bases +
      Class template + bases
      -
      Class bases - synopsis +
      Class template + bases synopsis
      +
      -
      Class template args +
      Class template init
      -
      Class args - synopsis +
      Class template + init synopsis
      + +
      Class init + constructors
      + +
      init-expressions
      +
      + +
      Class template + optional
      + +
      +
      +
      Class template + optional synopsis
      +
      +
      + +
      Class template + init_with_call_policies
      + +
      +
      +
      Class + template init_with_call_policies synopsis
      +
      +
      +
      -
      Example(s) +
      Example(s)

      @@ -72,168 +110,181 @@

      <boost/python/class.hpp> defines the interface through which users expose their C++ classes to Python. It declares the - class_ class template, which is parameterized on the - class type being exposed. It also exposes the args - and bases utility class templates, which are used in - conjunction with class_. + class_ class template, which is parameterized on the class + type being exposed. It also exposes the init, + optional and bases utility class templates, + which are used in conjunction with class_.

      <boost/python/class_fwd.hpp> contains a forward - declaration of the class_ class template. + declaration of the class_ class template.

      -

      Classes

      +

      Classes

      -

      Class template class_<T, Bases, HeldType, NonCopyable>

      +

      Class template + class_<T, Bases, HeldType, + NonCopyable>

      -

      Creates a Python class associated with the C++ type passed as - its first parameter. Although it has four template parameters, - only the first one is required. The three optional arguments can - actually be supplied in any - order; Boost.Python determines the role of the argument - from its type.
      +

      Creates a Python class associated with the C++ type passed as its + first parameter. Although it has four template parameters, only the first + one is required. The three optional arguments can actually be supplied + in any order; Boost.Python determines + the role of the argument from its type.

      +

      - - - - + - - - + - - - - + - - - - + - - - + +
      Template Parameter + Template ParameterRequirements + RequirementsSemantics + SemanticsDefault + Default
      T + TA class type. + A class type.The class being wrapped + The class being wrapped
      Bases + BasesA specialization of bases<...> which - specifies previously-exposed C++ base classes of T[1]. + A specialization of bases<...> which + specifies previously-exposed C++ base classes of T[1].Registers from_python conversions from - wrapped T instances to each of its exposed direct - and indirect bases. For each polymorphic base B, - registers conversions from indirectly-held wrapped - B instances to T. + Registers from_python conversions from wrapped + T instances to each of its exposed direct and indirect + bases. For each polymorphic base B, registers + conversions from indirectly-held wrapped B instances to + T.bases<> + bases<>
      HeldType + HeldTypeMust be T, a class derived - from T, or a Dereferenceable type for which - pointee<HeldType>::type - is T or a class derived from T. - + Must be T, a class derived from T, or a + Dereferenceable type for which + pointee<HeldType>::type + is T or a class derived from T.Specifies the type which is actually embedded in a Python - object wrapping a T instance. More details below. + Specifies the type which is actually embedded in a Python object + wrapping a T instance. More details below.T + T
      NonCopyable + NonCopyableIf supplied, must be boost::noncopyable. + If supplied, must be boost::noncopyable. Suppresses automatic registration of to_python - conversions which copy - T instances. Required when T has no - publicly-accessible copy constructor. - - An unspecified type other than boost::noncopyable. + Suppresses automatic registration of to_python + conversions which copy T instances. Required when + T has no publicly-accessible copy constructor.An unspecified type other than + boost::noncopyable.
      -

      HeldType Semantics

      +

      HeldType Semantics

      -
        -
      1. - If HeldType is derived from T, its - exposed constructor(s) must accept an initial - PyObject* argument which refers back to the Python - object that contains it, as shown in this example. This argument is - not included in the argument list type passed to def_init(), below, nor is - it passed explicitly by users when Python instances of - T are created. This is the idiom which allows C++ virtual - functions to be overridden in Python. Boost.Python automatically - registers additional converters which allow wrapped instances of - T to be passed to wrapped C++ functions expecting - HeldType arguments. +
          +
        1. If HeldType is derived from T, its exposed + constructor(s) must accept an initial PyObject* argument + which refers back to the Python object that contains the + HeldType instance, as shown in this example. This argument is not + included in the init-expression passed to def(init_expr), below, nor is + it passed explicitly by users when Python instances of T + are created. This idiom allows C++ virtual functions which will be + overridden in Python to access the Python object so the Python method + can be invoked. Boost.Python automatically registers additional + converters which allow wrapped instances of T to be passed + to wrapped C++ functions expecting HeldType + arguments.
        2. -
        3. Because Boost.Python will always allow - wrapped instances of T to be passed in place of - HeldType arguments, specifying a smart pointer for - HeldType allows users to pass Python - T instances where a smart pointer-to-T is - expected. Smart pointers such as std::auto_ptr<> - or boost::shared_ptr<> - which contain a nested type element_type designating - the referent type are automatically supported; additional smart - pointer types can be supported by specializing pointee<HeldType>. +
        4. Because Boost.Python will always allow wrapped instances of + T to be passed in place of HeldType + arguments, specifying a smart pointer for HeldType allows + users to pass Python T instances where a smart + pointer-to-T is expected. Smart pointers such as + std::auto_ptr<> or boost::shared_ptr<> + which contain a nested type element_type designating the + referent type are automatically supported; additional smart pointer + types can be supported by specializing pointee<HeldType>.
        5. -
        6. - As in case 1 above, when HeldType is a smart pointer to - a class derived from T, the initial - PyObject* argument must be supplied by all exposed - constructors. +
        7. As in case 1 above, when HeldType is a smart pointer + to a class derived from T, the initial + PyObject* argument must be supplied by all of + HeldType's exposed constructors.
        8. -
        9. - Except in cases 1 and 3, users may optionally specify that T itself - gets initialized with a similar initial PyObject* - argument by specializing has_back_reference. -
        +
      2. Except in cases 1 and 3, users may optionally specify that T itself + gets initialized with a similar initial PyObject* argument + by specializing has_back_reference<T>.
      3. +
      -

      Class template - class_ synopsis

      +

      Class template class_ + synopsis

       namespace boost { namespace python
       {
         template <class T
      -            , class Bases = bases<>
      +           , class Bases = bases<>
                   , class HeldType = T
                   , class NonCopyable = unspecified
                  >
      -  class class_
      +  class class_ : public object
         {
      -    class_();
      +    // Constructors with default __init__
           class_(char const* name);
      +    class_(char const* name, char const* docstring);
       
      -    // exposing constructors
      -    class_& def_init();
      +    // Constructors, specifying non-default __init__
      +    template <class Init>
      +    class_(char const* name, Init);
      +    template <class Init>
      +    class_(char const* name, char const* docstring, Init);
       
      -    template <class Args>
      -    class_& def_init(Args const& = Args());
      +    // Exposing additional __init__ functions
      +    template <class Init>
      +    class_& def(Init);
       
      -    template <class Args, class CallPolicy>
      -    class_& def_init(Args const&, CallPolicy policy);
      -
      -    // exposing member functions
      +    // defining methods
           template <class F>
           class_& def(char const* name, F f);
      -
      -    template <class Fn, class CallPolies>
      -    class_& def(char const* name, Fn fn, CallPolies);
      +    template <class Fn, class A1>
      +    class_& def(char const* name, Fn fn, A1 const&);
      +    template <class Fn, class A1, class A2>
      +    class_& def(char const* name, Fn fn, A1 const&, A2 const&);
      +    template <class Fn, class A1, class A2, class A3>
      +    class_& def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
       
           // exposing operators
           template <unspecified>
      -    class_& def(detail::operator_<unspecified>);
      +    class_& def(detail::operator_<unspecified>);
      +
      +    // Raw attribute modification
      +    template <class U>
      +    class_& setattr(char const* name, U const&);
       
           // exposing data members
           template <class D>
      @@ -242,287 +293,505 @@ namespace boost { namespace python
           template <class D>
           class_& def_readwrite(char const* name, D T::*pm);
       
      -    // Raw attribute modification
      -    class_& setattr(char const* name, ref const&);
      -
           // property creation
      -    void add_property(char const* name, ref const& fget);
      -    void add_property(char const* name, ref const& fget, ref const& fset);
      +    template <class Get>
      +    void add_property(char const* name, Get const& fget);
      +    template <class Get, class Set>
      +    void add_property(char const* name, Get const& fget, Set const& fset);
       
      -    // accessing the Python class object
      -    ref object() const;
      +    // pickle support
      +    void enable_pickling(bool getstate_manages_dict);
      +    template <typename PickleSuite>
      +    self& def_pickle(PickleSuite const&);
         };
       }}
       
      -

      Class template class_ constructors

      - -
      -class_();
      -
      - -
      -
      Requires: The platform's std::type_info::name() - implementation produces a string which corresponds to the type's - declaration in C++ - -
      Effects: Constructs a class_ object which - generates a Boost.Python extension class with the same name as - T. - -
      Rationale: Many platforms can generate reasonable names for - Python classes without user intervention. -
      +

      Class template class_ + constructors

       class_(char const* name);
      +class_(char const* name, char const* docstring);
      +template <class Init>
      +class_(char const* name, Init init_spec);
      +template <class Init>
      +class_(char const* name, char const* docstring, Init init_spec);
       
      -
      Requires: name is a ntbs which conforms to - Python's identifier - naming rules. +
      Requires: name is a ntbs which conforms to Python's identifier + naming rules. If docstring is supplied, it must be an + ntbs. If init_spec is + supplied, it must be either the special enumeration constant + no_init or an init-expression compatible with + T.
      -
      Effects: Constructs a class_ object which - generates a Boost.Python extension class named name. +
      Effects: Constructs a class_ object holding a + Boost.Python extension class named name. The + named attribute of the current scope is bound to the new + extension class.
      -
      Rationale: Gives the user full control over class naming. +
      +
        +
      • If supplied, the value of docstring is bound to + the __doc__ attribute of the extension class.
      • + +
      • If init_spec is no_init, a special + __init__ function is generated which always raises a + Python exception. Otherwise, this->def(init_spec) + is called.
      • + +
      • If init_spec is not supplied, + this->def(init<>()) is called.
      • +
      +
      + +
      Rationale:Allowing the user to specify constructor arguments + in the class_<> constructor helps her to avoid the + common run-time errors which result from invoking wrapped member + functions without having exposed an __init__ function + which creates the requisite T instance. Types which are + not default-constructible will cause a compile-time error unless + Init is supplied. The user must always supply + name as there is currently no portable method to derive + the text of the class name from its type.
      -

      Class template class_ - modifier functions

      - +

      Class template + class_ modifier functions

      -class_& def_init();
      -
      -template <class Args>
      -class_& def_init(Args const& argument_types);
      -
      -template <class Args, class CallPolicies>
      -class_& def_init(Args const& argument_types, CallPolicies policies);
      +template <class Init>
      +class_& def(Init init_expr);
       
      -
      Requires: Args is an MPL sequence of C++ argument - types (A1, A2,... AN) such that if - a1, a2... aN are objects of type - A1, A2,... AN respectively, the expression - T(a1, a2... aN) is valid. In the first form, - the expression T() must be valid. +
      Requires: init_expr is the result of an init-expression compatible with + T.
      -
      Effects: Adds the result of +
      Effects: For each valid + prefix P of Init, adds an + __init__(...) function overload to the + extension class accepting P as arguments. Each overload + generated constructs an object of HeldType according to + the semantics described above, using a copy of + init_expr's call policies. + If the longest valid prefix of Init contains N + types and init_expr holds M keywords, an initial + sequence of the keywords are used for all but the first + N - M arguments of each overload.
      -make_constructor<args<>,Holder>(), +
      Returns: *this
      -make_constructor<Args,Holder>(), or - -make_constructor<Args,Holder>(policies), - respectively, to the Boost.Python extension class being defined under the name - "__init__". Holder is a concrete subclass of instance_holder - which holds the HeldType. If the extension class - already has an "__init__" attribute, the usual overloading procedure applies. - -
      Returns: *this - -
      Rationale: Allows users to easily expose a class' constructor - to Python. +
      Rationale: Allows users to easily expose a class' + constructor to Python.
      - -
      - +
      +
       template <class F>
      -class_& def(char const* name, F f);
      -
      -template <class Fn, class CallPolicies>
      -class_& def(char const* name, Fn f, CallPolicies policies);
      +class_& def(char const* name, Fn fn);
      +template <class Fn, class A1>
      +class_& def(char const* name, Fn fn, A1 const& a1);
      +template <class Fn, class A1, class A2>
      +class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2);
      +template <class Fn, class A1, class A2, class A3>
      +class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3);
       
      -
      Requires: f is a non-null - pointer-to-function or pointer-to-member-function, or a callable - Python object passed as a PyObject* or ref. name - is a ntbs which conforms to Python's identifier - naming rules. In the first form, the return type of - f is not a reference and is not a pointer other - than char const* or PyObject*. In the - second form policies is a model of CallPolicies. +
      Requires: name is a ntbs which conforms to Python's identifier + naming rules.
      -
      Effects: Adds the result of make_function(f) or make_function(f, policies) to - the Boost.Python extension class being defined, with the given - name. If the extension class already has an attribute named - name, the usual overloading procedure applies. +
      +
        +
      • + If a1 is the result of an overload-dispatch-expression, + only the second is allowed and fn must be a pointer to [member] + function whose signature is compatible with A1. -
        Returns: *this +
        +
        Effects: For each valid prefix + P of A1, adds a + name(...) function overload + to the extension class. Each overload generated invokes + a1's call-expression with P, using a copy + of a1's call + policies. If the longest valid prefix of A1 + contains N types and a1 holds M + keywords, an initial sequence of the keywords are used for all + but the first N - M arguments of + each overload.
        +
        +
        +
      • + +
      • + Otherwise, a single method overload is built around fn, which + must not be null: + +
          +
        • If fn is a function pointer, its first argument must be of + the form U, cv&, + cv*, or + cv* const&, where + T* is convertible to U*, and + a1-a3, if supplied, may be selected + in any order from the table below.
        • + +
        • Otherwise, if fn is a member function pointer, its target + must be T or one of its public base classes, and + a1-a3, if supplied, may be selected + in any order from the table below.
        • + +
        • Otherwise, Fn must be [derived from] object, and + a1-a2, if supplied, may be selcted in any order + from the first two rows of the table below. To be useful, + fn should be + callable.
        • +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Memnonic NameRequirements/Type propertiesEffects
        docstringAny ntbs.Value will be bound to the __doc__ attribute + of the resulting method overload.
        policiesA model of CallPoliciesA copy will be used as the call policies of the resulting + method overload.
        keywordsThe result of a keyword-expression + specifying no more arguments than the arity of fn.A copy will be used as the call policies of the resulting + method overload.
        +
      • +
      +
      + +
      Returns: *this
      -
       template <unspecified>
      -class_& def(detail::operator_<unspecified>);
      +class_& def(detail::operator_<unspecified>);
       
      -
      Effects: Adds a Python special - method as described here. +
      Effects: Adds a Python special method as + described here.
      -
      Returns: *this +
      Returns: *this
      -
      -template <class F>
      -class_& setattr(char const* name, ref x);
      +template <class U>
      +class_& setattr(char const* name, U const& u);
       
      Requires: name is a ntbs which conforms to Python's identifier - naming rules. + "http://www.python.org/doc/current/ref/identifiers.html">identifier + naming rules.
      -
      Effects: PyObject_SetAttrString(this->object(), name, x.get()); +
      Effects: Converts u to Python and adds it to the attribute + dictionary of the extension class:
      -
      Returns: *this +
      +
      + PyObject_SetAttrString(this->ptr(), name, object(u).ptr()); +
      +
      + +
      Returns: *this
      - -
      - +
      +
      -void add_property(char const* name, ref const& fget);
      -void add_property(char const* name, ref const& fget, ref const& fset);
      -
      -
      - -
      Requires: name is a ntbs which conforms to - Python's identifier - naming rules. - -
      Effects: Creates a new Python property - class instance, passing fget.get() (and - fset.get() in the second form) to its constructor, - then adds that property to the Python class object under - construction with the given attribute name. - -
      Returns: *this - -
      Rationale: Allows users to easily expose a class' - data member such that it can be inspected from Python with a - natural syntax. -
      - -
      -
      -    template <class D>
      -    class_& def_readonly(char const* name, D T::*pm);
      +template <class Get>
      +void add_property(char const* name, Get const& fget);
      +template <class Get, class Set>
      +void add_property(char const* name, Get const& fget, Set const& fset);
       
      -
      Requires: name is a ntbs which conforms to Python's identifier - naming rules. + "http://www.python.org/doc/current/ref/identifiers.html">identifier + naming rules.
      -
      Effects: +
      Effects: Creates a new Python property + class instance, passing object(fget) (and object(fset) in the + second form) to its constructor, then adds that property to the Python + class object under construction with the given attribute + name.
      + +
      Returns: *this
      + +
      Rationale: Allows users to easily expose functions that can + be invoked from Python with attribute access syntax.
      +
      +
      -this->add_property(name, ref(make_getter(pm)));
      +template <class D>
      +class_& def_readonly(char const* name, D T::*pm);
       
      -
      Returns: *this +
      +
      Requires: name is a ntbs which conforms to + Python's identifier + naming rules.
      -
      Rationale: Allows users to easily expose a class' - data member such that it can be inspected from Python with a - natural syntax. +
      Effects:
      + +
      +
      +this->add_property(name, make_getter(pm));
      +
      +
      + +
      Returns: *this
      + +
      Rationale: Allows users to easily expose a class' data + member such that it can be inspected from Python with a natural + syntax.
      - -
      -
       template <class D>
       class_& def_readwrite(char const* name, D T::*pm);
       
      +
      Effects:
      -
      Effects: +
      -ref fget(make_getter(pm));
      -ref fset(make_setter(pm));
      -this->add_property(name, fget, fset);
      +this->add_property(name, make_getter(pm), make_setter(pm));
       
      +
      -
      Returns: *this +
      Returns: *this
      -
      Rationale: Allows users to easily expose a class' - data member such that it can be inspected and set from Python with a - natural syntax. - -

      Class template class_ - observer functions

      +
      Rationale: Allows users to easily expose a class' data + member such that it can be inspected and set from Python with a natural + syntax.
      +
      -ref object() const;
      +void enable_pickling(bool getstate_manages_dict);
       
      -
      Returns: A ref object which holds a reference to - the Boost.Python extension class object created by the - class_ constructor. +
      Requires: {{Ralf}}
      -
      Rationale: Mostly not needed by users, since module::add() uses this to insert the - extension class in the module. +
      Effects: {{Ralf}}
      + +
      Rationale: Allows users to easily expose functions that can + be invoked from Python with attribute access syntax.
      +
      +template <typename PickleSuite>
      +class_& def_pickle(PickleSuite const&);
      +
      -

      Class template - args<T1, T2,...TN>

      +
      +
      Requires: {{Ralf}}
      -

      A conveniently-named MPL sequence which - users pass to def_init calls to make - their code more readable. +

      Effects: {{Ralf}}
      -

      Class template args +
      Returns: *this
      + +
      Rationale: {{Ralf}}
      +

      +
      + + +

      Class template init<T1 = + unspecified, T2 = + unspecified,...Tn = + unspecified>

      + +

      A MPL sequence which + can be used to specify a family of one or more __init__ + functions. Only the last Ti supplied + may be an instantiation of optional<...>.

      + +

      Class template init synopsis

       namespace boost { namespace python
       {
      -  template <T1 = unspecified,...TN = unspecified>
      -  struct args
      -  {};
      +  template <T1 = unspecified,...Tn = unspecified>
      +  struct init
      +  {
      +      init(char const* doc = 0);
      +      template <class Keywords> init(Keywords const& kw, char const* doc = 0);
      +      template <class Keywords> init(char const* doc, Keywords const& kw);
      +
      +      template <class CallPolicies>
      +      unspecified operator[](CallPolicies const& policies) const
      +  };
      +}}
      +
      + +

      Class template init + constructors

      +
      +init(char const* doc = 0);
      +template <class Keywords> init(Keywords const& kw, char const* doc = 0);
      +template <class Keywords> init(char const* doc, Keywords const& kw);
      +
      + +
      +
      Requires: If supplied, doc is an ntbs. If supplied, kw is the + result of a
      + +
      Effects: The result is an init-expression whose + docstring is doc and whose keywords are + a reference to kw. If the first form is used, the + resulting expression's keywords are empty. The expression's + call policies are an instance of default_call_policies. + If Tn is optional<U1, U2,... + Um>, the + expression's valid prefixes are given by:
      + +
      +
      + (T1, T2,...Tn-1), + (T1, T2,...Tn-1 + , U1), + (T1, T2,...Tn-1 + , U1, U2), + ...(T1, T2,...Tn-1 + , U1, U2,...Um). +
      + Otherwise, the expression has one valid prefix given by the + the template arguments the user specified. +
      +
      + +

      Class template init + observer functions

      +
      +template <class Policies>
      +unspecified operator[](Policies const& policies) const
      +
      + +
      +
      Requires: Policies is a model of CallPolicies.
      + +
      Effects: Returns a new init-expression with all the same + properties as the init object except that its + callpolicies are replaced by a reference to + policies.
      +
      + +

      init-expressions

      + An init-expression is a transport vehicle for the following + properties, used to describe a family of __init__ methods to + be generated for an extension class: + +
      +
      docstring: An ntbs whose + value will bound to the method's __doc__ attribute
      + +
      keywords: A keyword-expression which will be + used to name (a trailing subset of) the arguments to the generated + __init__ function(s).
      + +
      call policies: An instance of a model of CallPolicies.
      + +
      argument types: An MPL sequence of C++ argument types which + will be used to construct the wrapped C++ object. An init expression + has one or more valid prefixes which are given by a sequence of + prefixes of its argument types.
      +
      + +

      Class template optional<T1 + = unspecified, T2 = + unspecified,...Tn = + unspecified>

      + +

      A MPL sequence which + can be used to specify the optional arguments to an __init__ + function.

      + +

      Class template + optional synopsis

      +
      +namespace boost { namespace python
      +{
      +  template <T1 = unspecified,...Tn = unspecified>
      +  struct optional {};
       }}
       

      Class template - bases<T1, T2,...TN>

      + bases<T1, T2,...TN> -

      An MPL sequence which - can be used in class_<...> - instantiations indicate a list of base classes. Although users - can pass any MPL sequence in place of args, above, the use of - bases to indicate base classes is mandatory. +

      An MPL sequence + which can be used in class_<...> + instantiations indicate a list of base classes.

      Class template bases synopsis

       namespace boost { namespace python
       {
      -  template <T1 = unspecified,...TN = unspecified>
      +  template <T1 = unspecified,...Tn = unspecified>
         struct bases
         {};
       }}
      @@ -530,12 +799,12 @@ namespace boost { namespace python
       
           

      Example(s)

      -

      Given a C++ class declaration: +

      Given a C++ class declaration:

       class Foo : public Bar, public Baz
       {
        public:
      -   Foo(int, char const*);
      +   Foo(int x, char const* y);
          Foo(double);
       
          std::string const& name() { return m_name; }
      @@ -546,44 +815,39 @@ class Foo : public Bar, public Baz
          ...
       };
       
      - - A corresponding Boost.Python extension class can be created with: + A corresponding Boost.Python extension class can be created with:
       using namespace boost::python;
       
      -ref foo = class_<Foo,bases<Bar,Baz> >()
      -   .def_init(args<int,char const*>())
      -   .def_init(args<double>())
      +class_<Foo,bases<Bar,Baz> >("Foo",
      +          "This is Foo's docstring."
      +          "It describes our Foo extension class",
      +
      +          init<int,char const*>(args("x","y"), "__init__ docstring")
      +          )
      +   .def(init<double>())
          .def("get_name", &Foo::get_name, return_internal_reference<>())
          .def("set_name", &Foo::set_name)
          .def_readwrite("value", &Foo::value)
      -   .object();
      +   ;
       
      - -
      - -[1] By "previously-exposed" we mean that the for each -B in bases, an instance of -class_<B> must have already been -constructed. Ensuring this in a portable manner when a class and its -bases are exposed in the same module entails using separate -full-expressions, rather than chaining consecutive definitions with -".add(...). - +
      + [1] By "previously-exposed" we mean that the for + each B in bases, an instance of + class_<B, ...> must have + already been constructed.
      -module m("module_name");
      -m.add(class_<Base>()
      -        .def_init());
      -m.add(class_<Derived, bases<Base>>()
      -        .def_init());
      +class_<Base>("Base");
      +class_<Derived, bases<Base> >("Derived");
       
      - Revised - 09 May, 2002 - + 29 Sept, 2002 -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + diff --git a/doc/v2/definitions.html b/doc/v2/definitions.html index 839608bc..4969f977 100644 --- a/doc/v2/definitions.html +++ b/doc/v2/definitions.html @@ -1,35 +1,54 @@ + + - - - -Boost.Python - Definitions - - - + + + + + Boost.Python - Definitions + + + +
      - - - - -
      -

      -

      -
      -

      Boost.Python

      -

      Definitions

      -
      -
      -
      -
      {{term}}: {{definition}}
      -
      {{term}}: {{definition}}
      -
      -
      -

      Revised - - 05 November, 2002 - -

      -

      © Copyright Dave Abrahams - 2002. All Rights Reserved.

      - + + +

      C++ Boost

      + + + +

      Boost.Python

      + +

      Definitions

      + + + +
      + +
      +
      arity: The number of arguments accepted + by a function or member function. Unless otherwise specified, the + hidden "this" argument to member functions is not counted + when specifying arity
      + +
      ntbs: Null-Terminated Byte String, or + `C'-string. C++ string literals are ntbses. An + ntbs must never be null.
      +
      +
      + +

      Revised + + 28 September, 2002 + +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From c860d74cba7def51c7628d89e34b5a51f5d7ea6b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 16:17:52 +0000 Subject: [PATCH 0773/1042] doc update [SVN r15549] --- doc/v2/copy_const_reference.html | 74 ++++++++++++++++------------ doc/v2/copy_non_const_reference.html | 70 +++++++++++++++----------- 2 files changed, 84 insertions(+), 60 deletions(-) diff --git a/doc/v2/copy_const_reference.html b/doc/v2/copy_const_reference.html index 70da135b..e8d02503 100644 --- a/doc/v2/copy_const_reference.html +++ b/doc/v2/copy_const_reference.html @@ -1,46 +1,58 @@ - + + + + - Boost.Python - <boost/python/copy_const_reference.hpp> + Boost.Python - + <boost/python/copy_const_reference.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      Header <boost/python/copy_const_reference.hpp>

      +

      Contents

      -
      Classes +
      Classes
      Class - copy_const_reference + copy_const_reference
      Class - copy_const_reference synopsis + copy_const_reference synopsis
      Class - copy_const_reference metafunctions + copy_const_reference metafunctions
      +
      +
      -
      Example +
      Example

      @@ -50,9 +62,10 @@ copy_const_reference

      copy_const_reference is a model of ResultConverterGenerator which can be - used to wrap C++ functions returning a reference-to-const type such that - the referenced value is copied into a new Python object. + "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator + which can be used to wrap C++ functions returning a reference-to-const + type such that the referenced value is copied into a new Python + object.

      Class copy_const_reference synopsis

      @@ -73,17 +86,17 @@ template <class T> struct apply
      -
      Requires: T is U const& for some - U. +
      Requires: T is U const& for + some U.
      Returns: typedef to_python_value<T> - type; + type;

      Example

      -

      C++ Module Definition

      +

      C++ Module Definition

       #include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
      @@ -104,20 +117,16 @@ struct Foo {
       using namespace boost::python;
       BOOST_PYTHON_MODULE_INIT(my_module)
       {
      -   module m("my_module")
      -      .add(
      -         class_<Bar>()
      -         )
      -      .add(
      -         class_<Foo>()
      -            .def_init(args<int>())
      -            .def("get_bar", &Foo::get_bar
      -                , return_value_policy<copy_const_reference>())
      -         )
      +    class_<Bar>("Bar");
      +
      +     class_<Foo>("Foo", init<int>())
      +        .def("get_bar", &Foo::get_bar
      +            , return_value_policy<copy_const_reference>())
              ;
       }
       
      -

      Python Code

      + +

      Python Code

       >>> from my_module import *
       >>> f = Foo(3)         # create a Foo object
      @@ -126,10 +135,13 @@ BOOST_PYTHON_MODULE_INIT(my_module)
       
           

      Revised - 15 February, 2002 + 29 September, 2002 +

      - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + diff --git a/doc/v2/copy_non_const_reference.html b/doc/v2/copy_non_const_reference.html index ffa728db..8f427016 100644 --- a/doc/v2/copy_non_const_reference.html +++ b/doc/v2/copy_non_const_reference.html @@ -1,47 +1,59 @@ - + + + + Boost.Python - <boost/python/copy_non_const_reference.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      Header <boost/python/copy_non_const_reference.hpp>

      +

      Contents

      -
      Classes +
      Classes
      Class - copy_non_const_reference + copy_non_const_reference
      Class - copy_non_const_reference synopsis + copy_non_const_reference synopsis
      -
      Class - copy_non_const_reference metafunctions +
      Class + copy_non_const_reference metafunctions
      +
      +
      -
      Example +
      Example

      @@ -51,9 +63,10 @@ copy_non_const_reference

      copy_non_const_reference is a model of ResultConverterGenerator which can be - used to wrap C++ functions returning a reference-to-non-const type such - that the referenced value is copied into a new Python object. + "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator + which can be used to wrap C++ functions returning a + reference-to-non-const type such that the referenced value is copied into + a new Python object.

      Class copy_non_const_reference synopsis

      @@ -75,16 +88,16 @@ template <class T> struct apply
      Requires: T is U& for some - non-const U. + non-const U.
      Returns: typedef to_python_value<T> - type; + type;

      Example

      -

      C++ code: +

      C++ code:

       #include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
      @@ -105,16 +118,12 @@ struct Foo {
       using namespace boost::python;
       BOOST_PYTHON_MODULE_INIT(my_module)
       {
      -   module("my_module")
      -      .add(
      -         class_<Bar>()
      -         )
      -      .add(
      -         class_<Foo>()
      -            .def_init(args<int>())
      -            .def("get_bar", &Foo::get_bar
      -                , return_value_policy<copy_non_const_reference>())
      -         );
      +    class_<Bar>("Bar");
      +
      +     class_<Foo>("Foo", init<int>())
      +        .def("get_bar", &Foo::get_bar
      +            , return_value_policy<copy_non_const_reference>())
      +       ;
       }
       
      Python Code: @@ -126,10 +135,13 @@ BOOST_PYTHON_MODULE_INIT(my_module)

      Revised - 05 November, 2001 + 29 September, 2001 +

      - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From 2f4e12916d8c1f7b801786c0ff68760efe1eff32 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 16:26:04 +0000 Subject: [PATCH 0774/1042] doc update [SVN r15550] --- doc/v2/data_members.html | 121 +++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 56 deletions(-) diff --git a/doc/v2/data_members.html b/doc/v2/data_members.html index 820bb1d4..5ec6ff01 100644 --- a/doc/v2/data_members.html +++ b/doc/v2/data_members.html @@ -1,109 +1,118 @@ - + + + + Boost.Python - <boost/python/data_members.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      -

      Header <boost/python/data_members.hpp>

      +

      Header + <boost/python/data_members.hpp>

      +

      Contents

      -
      Introduction +
      Introduction
      -
      Functions +
      Functions
      -
      make_getter +
      make_getter
      -
      make_setter +
      make_setter
      +
      -
      Example +
      Example

      Introduction

      make_getter() and - make_setter() are - the functions used internally by class_<>::make_setter() are the + functions used internally by class_<>::def_readonly and class_<>::def_readwrite to - produce Python callable objects which wrap C++ data members. + "class.html#class_-spec-modifiers">def_readwrite to produce + Python callable objects which wrap C++ data members.

      Functions

      -
       template <class C, class D>
      -objects::function* make_getter(D C::*pm);
      +object make_getter(D C::*pm);
       
       template <class C, class D, class Policies>
      -objects::function* make_getter(D C::*pm, Policies const& policies);
      +object make_getter(D C::*pm, Policies const& policies);
       
      -
      Requires: Policies is a model of CallPolicies. +
      Requires: Policies is a model of CallPolicies.
      -
      Effects: Creates a Python callable object which - accepts a single argument that can be converted - from_python to C*, and returns the - corresponding member D member of the C - object, converted to_python. If - policies is supplied, it will be applied to the - function as described here. +
      Effects: Creates a Python callable object which accepts a + single argument that can be converted from_python to + C*, and returns the corresponding member D + member of the C object, converted to_python. + If policies is supplied, it will be applied to the + function as described here.
      -
      Returns: A pointer convertible to PyObject* which - refers to the new Python callable object. +
      Returns: An instance of object which holds the new Python + callable object.
       template <class C, class D>
      -objects::function* make_setter(D C::*pm);
      +object make_setter(D C::*pm);
       
       template <class C, class D, class Policies>
      -objects::function* make_setter(D C::*pm, Policies const& policies);
      +object make_setter(D C::*pm, Policies const& policies);
       
      -
      Requires: Policies is a model of CallPolicies. +
      Requires: Policies is a model of CallPolicies.
      -
      Effects: Creates a Python callable object which, when - called from Python, expects two arguments which can be converted +
      Effects: Creates a Python callable object which, when called + from Python, expects two arguments which can be converted from_python to C* and D const&, respectively, and sets the - corresponding D member of the C - object. If policies is supplied, it will be applied - to the function as described here. + corresponding D member of the C object. If + policies is supplied, it will be applied to the function + as described here.
      -
      Returns: A pointer convertible to - PyObject* which refers to the new Python callable - object. +
      Returns: An instance of object which holds the new Python + callable object.

      Example

      -

      The code below uses make_getter and make_setter to expose a - data member as functions: - +

      The code below uses make_getter and make_setter to expose a data + member as functions:

       #include <boost/python/data_members.hpp>
       #include <boost/python/module.hpp>
      @@ -119,14 +128,10 @@ using namespace boost::python;
       
       BOOST_PYTHON_MODULE_INIT(data_members_example)
       {
      -    module("data_members_example")
      -        .add(
      -            class_<X>("X")
      -               .def_init(args<int>())
      -               .def("get", make_getter(&X::y))
      -               .def("set", make_setter(&X::y))
      -        )
      -        ;
      +    class_<X>("X", init<int>())
      +       .def("get", make_getter(&X::y))
      +       .def("set", make_setter(&X::y))
      +       ;
       }
       
      It can be used this way in Python: @@ -142,9 +147,13 @@ BOOST_PYTHON_MODULE_INIT(data_members_example)

      - 8 May 2002 + 29 September 2002 + +

      - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From 9ae0940e99d9b30de562ac07ea16f6deb54545ea Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 17:41:39 +0000 Subject: [PATCH 0775/1042] doc update [SVN r15551] --- doc/v2/errors.html | 174 ++++++++++++++++++++++++++++----------------- 1 file changed, 110 insertions(+), 64 deletions(-) diff --git a/doc/v2/errors.html b/doc/v2/errors.html index 6e364e8f..a87c308d 100644 --- a/doc/v2/errors.html +++ b/doc/v2/errors.html @@ -1,53 +1,68 @@ - + + + + Boost.Python - <boost/python/errors.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      Header <boost/python/errors.hpp>

      +

      Contents

      -
      Introduction +
      Introduction
      -
      Classes +
      Classes
      -
      Class error_already_set +
      Class + error_already_set
      Class - error_already_set synopsis + error_already_set synopsis
      +
      +
      -
      Functions +
      Functions
      -
      handle_exception +
      handle_exception
      -
      expect_non_null -
      throw_error_already_set +
      expect_non_null
      + +
      throw_error_already_set
      +
      -
      Examples +
      Examples

      @@ -56,20 +71,24 @@

      <boost/python/errors.hpp> provides types and functions for managing and translating between Python and C++ exceptions. This is relatively low-level functionality that is mostly used internally - by Boost.Python. Users should seldom need it. + by Boost.Python. Users should seldom need it.

      Classes

      Class error_already_set

      -

      error_already_set is an exception type which can be thrown - to indicate that a Python error has occurred. If thrown, the precondition - is that error_already_set is an exception type which can be + thrown to indicate that a Python error has occurred. If thrown, the + precondition is that PyErr_Occurred() - returns a value convertible to true. + returns a value convertible to true. Portable code shouldn't + throw this exception type directly, but should instead use throw_error_already_set(), + below.

      -

      Class error_already_set synopsis

      +

      Class error_already_set + synopsis

       namespace boost { namespace python
       {
      @@ -86,84 +105,100 @@ void handle_exception() throw();
       
      -
      Requires: The first form requires that the expression Requires: The first form requires that the expression + function0<void>(f) is valid. The second form requires that a C++ exception is currently - being handled (see section 15.1 in the C++ standard). + being handled (see section 15.1 in the C++ standard).
      Effects: The first form calls f() inside a - try block whose catch clauses set an - appropriate Python exception for the C++ exception caught, returning - true if an exception was caught, false - otherwise. The second form passes a function which rethrows the exception - currently being handled to the first form. + try block which first attempts to use all registered exception translators. If none of + those translates the exception, the catch clauses then set + an appropriate Python exception for the C++ exception caught, returning + true if an exception was thrown, false + otherwise. The second form passes a function which rethrows the + exception currently being handled to the first form.
      -
      Postconditions: No exception is being handled +
      Postconditions: No exception is being handled
      -
      Throws: nothing +
      Throws: nothing
      Rationale: At inter-language boundaries it is important to - ensure that no C++ exceptions escape, since the calling language usually - doesn't have the equipment neccessary to properly unwind the stack. Use - handle_exception to manage exception translation whenever - your C++ code is called directly from the Python API. This is done for - you automatically by the usual function wrapping facilities: make_function(), make_constructor(), module::def and class_::def). The second form can be more - convenient to use (see the example below), but - various compilers have problems when exceptions are rethrown from within - an enclosing try block. + ensure that no C++ exceptions escape, since the calling language + usually doesn't have the equipment neccessary to properly unwind the + stack. Use handle_exception to manage exception + translation whenever your C++ code is called directly from the Python + API. This is done for you automatically by the usual function wrapping + facilities: make_function(), + make_constructor(), + def() and class_::def(). The second form can be + more convenient to use (see the example below), + but various compilers have problems when exceptions are rethrown from + within an enclosing try block.
      -template <class T> T* expect_non_null(T* x);
      +template <class T> T* expect_non_null(T* x);
       
      -
      Returns: x +
      Returns: x
      Throws: error_already_set() iff x == - 0. + "#error_already_set-spec">error_already_set() iff x == + 0.
      -
      Rationale: Simplifies error-handling when calling many - functions in the Python/C API, which - return 0 on error. +
      Rationale: Simplifies error-handling when calling functions + in the Python/C + API which return 0 on error.
      -
       void throw_error_already_set();
       
      -
      Effects: throw error_already_set(); + "#error_already_set-spec">error_already_set();
      +
      + +
      +
      Rationale: Many platforms and compilers are not able to + consistently catch exceptions thrown across shared library boundaries. + Using this function from the Boost.Python library ensures that the + appropriate catch block in handle_exception() can catch the + exception.

      Examples

       #include <string>
       #include <boost/python/errors.hpp>
      -#include <boost/python/reference.hpp>
      +#include <boost/python/object.hpp>
      +#include <boost/python/handle.hpp>
       
       // Returns a std::string which has the same value as obj's "__name__"
       // attribute.
      -std::string get_name(boost::python::ref obj)
      +std::string get_name(boost::python::object obj)
       {
          // throws if there's no __name__ attribute
          PyObject* p = boost::python::expect_non_null(
      -      PyObject_GetAttrString(obj.get(), "__name__"));
      +      PyObject_GetAttrString(obj.ptr(), "__name__"));
      +
      +   char const* s = PyString_AsString(p);
      +   if (s != 0) 
      +        Py_DECREF(p);
       
          // throws if it's not a Python string
          std::string result(
             boost::python::expect_non_null(
                PyString_AsString(p)));
       
      -   Py_XDECREF(p); // Done with p
      +   Py_DECREF(p); // Done with p
          
          return result;
       }
      @@ -172,12 +207,19 @@ std::string get_name(boost::python::ref obj)
       // Demonstrate form 1 of handle_exception
       //
       
      -// Place a Python Int object whose value is 1 if a and b have
      +// Place into result a Python Int object whose value is 1 if a and b have
       // identical "__name__" attributes, 0 otherwise.
      -void same_name_impl(PyObject*& result, PyObject* a, PyObject* b)
      +void same_name_impl(PyObject*& result, boost::python::object a, boost::python::object b)
       {
          result = PyInt_FromLong(
      -      get_name(boost::python::ref(a1)) == get_name(boost::python::ref(a2)));
      +      get_name(a) == get_name(a2));
      +}
      +
      +object borrowed_object(PyObject* p)
      +{
      +   return boost::python::object(
      +        boost::python::handle<>(
      +             boost::python::borrowed(a1)));
       }
       
       // This is an example Python 'C' API interface function
      @@ -194,7 +236,7 @@ same_name(PyObject* args, PyObject* keywords)
          // Use boost::bind to make an object compatible with
          // boost::Function0<void>
          if (boost::python::handle_exception(
      -         boost::bind<void>(same_name_impl, boost::ref(result), a1, a2)))
      +         boost::bind<void>(same_name_impl, boost::ref(result), borrowed_object(a1), borrowed_object(a2))))
          {
             // an exception was thrown; the Python error was set by
             // handle_exception()
      @@ -217,9 +259,10 @@ same_name2(PyObject* args, PyObject* keywords)
       
          if (!PyArg_ParseTuple(args, const_cast<char*>("OO"), &a1, &a2))
             return 0;
      +
          try {
             return PyInt_FromLong(
      -         get_name(boost::python::ref(a1)) == get_name(boost::python::ref(a2)));
      +         get_name(borrowed_object(a1)) == get_name(borrowed_object(a2)));
          }
          catch(...)
          {
      @@ -232,10 +275,13 @@ same_name2(PyObject* args, PyObject* keywords)
       
           

      Revised - 17 November, 2002 + 29 September, 2002 +

      - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From 36d85eb02ebadfe62638e62db7e5790944ca0eba Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 17:51:31 +0000 Subject: [PATCH 0776/1042] doc update [SVN r15552] --- doc/v2/has_back_reference.html | 153 ++++++++++++++++----------------- 1 file changed, 75 insertions(+), 78 deletions(-) diff --git a/doc/v2/has_back_reference.html b/doc/v2/has_back_reference.html index a31cf448..c6d752dc 100644 --- a/doc/v2/has_back_reference.html +++ b/doc/v2/has_back_reference.html @@ -1,77 +1,82 @@ - - + + + + - Boost.Python - - <boost/python/has_back_reference.hpp> - + + - + +
      +
      -

      C++ Boost

      +

      C++ Boost

      +

      Boost.Python

      Header <boost/python/has_back_reference.hpp>

      +

      Contents

      -
      Introduction +
      Introduction
      -
      Classes +
      Classes
      Class template - has_back_reference + has_back_reference
      -
      Class template - has_back_reference synopsis +
      Class template + has_back_reference synopsis
      +
      -
      Example(s) +
      Example(s)
      +

      Introduction

      -

      <boost/python/has_back_reference.hpp> - defines the traits class template - has_back_reference<>, which can be - specialized by the user to indicate that a wrapped class - instance holds a PyObject* corresponding to a - Python object. +

      <boost/python/has_back_reference.hpp> defines the + traits class template has_back_reference<>, which can + be specialized by the user to indicate that a wrapped class instance + holds a PyObject* corresponding to a Python object.

      Classes

      Class template has_back_reference

      -

      A unary metafunction whose value is true iff - its argument is a pointer_wrapper<>. +

      A unary metafunction whose value is true iff its argument + is a pointer_wrapper<>.

      -

      Class - template has_back_reference synopsis

      +

      Class template + has_back_reference synopsis

       namespace boost { namespace python
       {
      @@ -82,36 +87,33 @@ namespace boost { namespace python
       }}
       
      -

      A "traits - class" which is inspected by Boost.Python to - determine how wrapped classes can be constructed. +

      A "traits + class" which is inspected by Boost.Python to determine how wrapped + classes can be constructed.

      - -
      value is an integral constant convertible - to bool of unspecified type. +
      value is an integral constant convertible to bool of + unspecified type.
      Specializations may substitute a value convertible to - true for value iff for each invocation of - class_<WrappedClass>::def_init(args<type-sequence...>()), - there exists a corresponding constructor - WrappedClass::WrappedClass(PyObject*, type-sequence...). If - such a specialization exists, the WrappedClass - constructors will be called with a "back reference" pointer - to the corresponding Python object whenever they are invoked from - Python. - + true for value iff for each invocation of + class_<WrappedClass>::def_init(args<type-sequence... + >()), there exists a corresponding constructor + WrappedClass::WrappedClass(PyObject*, type-sequence... + ). If such a specialization exists, the + WrappedClass constructors will be called with a "back + reference" pointer to the corresponding Python object whenever they are + invoked from Python.

      Example

      -

      C++ module definition

      - +

      C++ module definition

       #include <boost/python/class.hpp>
       #include <boost/python/module.hpp>
       #include <boost/python/has_back_reference.hpp>
      +#include <boost/python/handle.hpp>
       #include <boost/shared_ptr.hpp>
       
       using namespace boost::python;
      @@ -121,7 +123,7 @@ struct X
           X(PyObject* self) : m_self(self), m_x(0) {}
           X(PyObject* self, int x) : m_self(self), m_x(x) {}
           
      -    PyObject* self() { return m_self; }
      +    handle<> self() { return handle<>(borrowed(m_self)); }
           int get() { return m_x; }
           void set(int x) { m_x = x; }
       
      @@ -153,34 +155,27 @@ boost::shared_ptr<Y> Y_self(boost::shared_ptr<Y> self) const { retur
       
       BOOST_PYTHON_MODULE_INIT(back_references)
       {
      -    module("back_references")
      -        .add(
      -            class_<X>("X")
      -               .def_init()
      -               .def_init(args<int>())
      -               .def("self", &X::self)
      -               .def("get", &X::get)
      -               .def("set", &X::set)
      -            )
      -        .add(
      -            class_<Y, shared_ptr<Y> >("Y")
      -               .def_init()
      -               .def_init(args<int>())
      -               .def("get", &Y::get)
      -               .def("set", &Y::set)
      -               .def("self", Y_self)
      -            )
      -        ;
      +    class_<X>("X")
      +       .def(init<int>())
      +       .def("self", &X::self)
      +       .def("get", &X::get)
      +       .def("set", &X::set)
      +       ;
      +
      +    class_<Y, shared_ptr<Y> >("Y")
      +       .def(init<int>())
      +       .def("get", &Y::get)
      +       .def("set", &Y::set)
      +       .def("self", Y_self)
      +       ;
       }
       
      + The following Python session illustrates that x.self() + returns the same Python object on which it is invoked, while + y.self() must create a new Python object which refers to the + same Y instance. -The following Python session illustrates that x.self() -returns the same Python object on which it is invoked, while -y.self() must create a new Python object which refers to -the same Y instance. - -

      Python code

      - +

      Python code

       >>> from back_references import *
       >>> x = X(1)
      @@ -207,11 +202,13 @@ the same Y instance.
       
           

      Revised - 07 May, 2002 + 29 September, 2002 +

      - -

      © Copyright Dave Abrahams - 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From a27c2f7a80c0624301802348649674c75b69b47b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 18:47:48 +0000 Subject: [PATCH 0777/1042] doc update [SVN r15555] --- doc/v2/implicit.html | 106 ++++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 47 deletions(-) diff --git a/doc/v2/implicit.html b/doc/v2/implicit.html index 99ce9ad8..8b934691 100644 --- a/doc/v2/implicit.html +++ b/doc/v2/implicit.html @@ -1,51 +1,60 @@ - + + + + Boost.Python - <boost/python/implicit.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      Header <boost/python/implicit.hpp>

      +

      Contents

      -
      -
      Introduction +
      +
      Introduction
      - -
      Functions +
      Functions
      -
      -
      Function Template implicitly_convertible - +
      +
      Function Template + implicitly_convertible
      +
      -
      Example +
      Example

      Introduction

      - - implicitly_convertible allows Boost.Python to - implicitly take advantage of a C++ implicit or explicit conversion - when matching Python objects to C++ argument types. + implicitly_convertible allows Boost.Python to implicitly + take advantage of a C++ implicit or explicit conversion when matching + Python objects to C++ argument types.

      Functions

      -

      Function template implicitly_convertible

      +

      Function template + implicitly_convertible

       template <class Source, class Target>
       void implicitly_convertible();
      @@ -55,40 +64,42 @@ void implicitly_convertible();
             
               implicitly_convertible template parameters
      - - Parameter - Description - Source - The source type of the implicit conversion + Parameter + + Description + - Target - The target type of the implicit conversion + Source + + The source type of the implicit conversion + + + Target + + The target type of the implicit conversion +
      -
      Requires: The expression Target(s), - where s is of type Source, is valid. +
      Requires: The declaration Target t(s);, where + s is of type Source, is valid.
      Effects: registers an rvalue from_python converter to Target which can succeed for any - PyObject* p iff there exists any registered - converter which can produce Source rvalues + PyObject* p iff there exists any registered converter + which can produce Source rvalues
      -
      Rationale: C++ users expect to be able to take - advantage of the same sort of interoperability in Python as they - do in C++. +
      Rationale: C++ users expect to be able to take advantage of + the same sort of interoperability in Python as they do in C++.
      -

      Example

      - -

      C++ module definition

      - +

      C++ module definition

       #include <boost/python/class.hpp>
       #include <boost/python/implicit.hpp>
      @@ -112,21 +123,19 @@ X make_x(int n) { return X(n); }
       
       BOOST_PYTHON_MODULE_INIT(implicit_ext)
       {
      -    module("implicit_ext")
      -        .def("x_value", x_value)
      -        .def("make_x", make_x)
      -        .add(
      -            class_<X>("X")
      -            .def_init(args<int>())
      -            )
      +    def("x_value", x_value)
      +    def("make_x", make_x)
      +
      +    class_<X>("X", 
      +        init<int>())
               ;
      +
           implicitly_convertible<X,int>();
           implicitly_convertible<int,X>();
       }
       
      -

      Python code

      - +

      Python code

       >>> from implicit_ext import *
       >>> x_value(X(42))
      @@ -140,10 +149,13 @@ BOOST_PYTHON_MODULE_INIT(implicit_ext)
       
           

      Revised - 08 May, 2002 + 29 September, 2002 +

      - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From 0d1efb61e23d84f08e1a625c35970ffce1f85074 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 19:06:13 +0000 Subject: [PATCH 0778/1042] doc update [SVN r15556] --- doc/v2/call_method.html | 2 +- doc/v2/copy_const_reference.html | 2 +- doc/v2/copy_non_const_reference.html | 2 +- doc/v2/data_members.html | 2 +- doc/v2/has_back_reference.html | 2 +- doc/v2/implicit.html | 2 +- doc/v2/iterator.html | 407 +++++++++++++++------------ 7 files changed, 226 insertions(+), 193 deletions(-) diff --git a/doc/v2/call_method.html b/doc/v2/call_method.html index 3aae0e35..5323ab07 100644 --- a/doc/v2/call_method.html +++ b/doc/v2/call_method.html @@ -85,7 +85,7 @@ R call_method(PyObject* self, char const* method, A1 const&, A2 const&,

      C++ Module Definition

      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       #include <boost/python/class.hpp>
       #include <boost/utility.hpp>
       #include <cstring>
      diff --git a/doc/v2/copy_const_reference.html b/doc/v2/copy_const_reference.html
      index e8d02503..41a9b9ab 100644
      --- a/doc/v2/copy_const_reference.html
      +++ b/doc/v2/copy_const_reference.html
      @@ -98,7 +98,7 @@ template <class T> struct apply
       
           

      C++ Module Definition

      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/copy_const_reference.hpp>
       #include <boost/python/return_value_policy.hpp>
      diff --git a/doc/v2/copy_non_const_reference.html b/doc/v2/copy_non_const_reference.html
      index 8f427016..0169fff1 100644
      --- a/doc/v2/copy_non_const_reference.html
      +++ b/doc/v2/copy_non_const_reference.html
      @@ -99,7 +99,7 @@ template <class T> struct apply
       
           

      C++ code:

      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/copy_non_const_reference.hpp>
       #include <boost/python/return_value_policy.hpp>
      diff --git a/doc/v2/data_members.html b/doc/v2/data_members.html
      index 5ec6ff01..eabf8183 100644
      --- a/doc/v2/data_members.html
      +++ b/doc/v2/data_members.html
      @@ -115,7 +115,7 @@ template <class C, class D, class Policies>
           member as functions:

       #include <boost/python/data_members.hpp>
      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       #include <boost/python/class.hpp>
       
       struct X
      diff --git a/doc/v2/has_back_reference.html b/doc/v2/has_back_reference.html
      index c6d752dc..ed8b0342 100644
      --- a/doc/v2/has_back_reference.html
      +++ b/doc/v2/has_back_reference.html
      @@ -111,7 +111,7 @@ namespace boost { namespace python
           

      C++ module definition

       #include <boost/python/class.hpp>
      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       #include <boost/python/has_back_reference.hpp>
       #include <boost/python/handle.hpp>
       #include <boost/shared_ptr.hpp>
      diff --git a/doc/v2/implicit.html b/doc/v2/implicit.html
      index 8b934691..03832566 100644
      --- a/doc/v2/implicit.html
      +++ b/doc/v2/implicit.html
      @@ -103,7 +103,7 @@ void implicitly_convertible();
       
       #include <boost/python/class.hpp>
       #include <boost/python/implicit.hpp>
      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       
       using namespace boost::python;
       
      diff --git a/doc/v2/iterator.html b/doc/v2/iterator.html
      index 1e367cce..3388d913 100644
      --- a/doc/v2/iterator.html
      +++ b/doc/v2/iterator.html
      @@ -1,216 +1,239 @@
       
      -    
      +
      +
      +  
      +    
           
           
       
           Boost.Python - <boost/python/iterator.hpp>
      +  
       
      +  
           
      +      
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      Header <boost/python/iterator.hpp>

      +

      Contents

      -
      Introduction +
      Introduction
      -
      Classes +
      Classes
      -
      Class template iterator +
      Class template + iterator
      Class - iterator synopsis + iterator synopsis
      -
      Class template iterator - constructor +
      Class template + iterator constructor
      -
      +
      +
      -
      Class template iterators +
      Class template + iterators
      Class - iterators synopsis -
      Class template - iterators nested types -
      Class template - iterators static functions -
      -
      + iterators synopsis
      -
      Functions +
      Class template + iterators nested types
      + +
      Class template + iterators static functions
      +
      + + + + +
      Functions
      -
      range +
      range
      +
      -
      Examples +
      Examples

      Introduction

      -

      <boost/python/iterator.hpp> provides types - and functions for creating Python - iterators from C++ - Containers and <boost/python/iterator.hpp> provides types and + functions for creating Python + iterators from C++ Containers and Iterators. Note that if your class_ supports random-access iterators, - implementing - __getitem__ - (also known as the Sequence Protocol) may serve you better than - using this facility: Python will automatically create an iterator - type for you (see iter()), - and each access can be range-checked, leaving no possiblity of - accessing through an invalidated C++ iterator. + implementing __getitem__ + (also known as the Sequence Protocol) may serve you better than using + this facility: Python will automatically create an iterator type for you + (see iter()), + and each access can be range-checked, leaving no possiblity of accessing + through an invalidated C++ iterator.

      Classes

      Class Template iterator

      -

      Instances of iterator<C,P> hold a reference - to a callable Python object which, when invoked from Python, - expects a single argument c convertible to - C and creates a Python iterator that traverses - [c.begin(), - c.end()). The optional CallPolicies - P can be used to control how elements are returned - during iteration. +

      Instances of iterator<C,P> hold a reference to a + callable Python object which, when invoked from Python, expects a single + argument c convertible to C and creates a + Python iterator that traverses [c.begin(), + c.end()). The optional CallPolicies P can be used to + control how elements are returned during iteration.

      -

      In the table below, c is an instance of Container. +

      In the table below, c is an instance of + Container.

      - - - - + - - + + - - - + +
      Template Parameter + Template ParameterRequirements + RequirementsSemantics + SemanticsDefault + Default
      Container + Container[c.begin(),c.end()) is a valid Iterator - range. - - The result will convert its argument to - c and call - c.begin() and c.end() to acquire - iterators. To invoke Container's - const begin() and end() - functions, make it const. + [c.begin(),c.end()) is a valid Iterator range.The result will convert its argument to c and call + c.begin() and c.end() to acquire iterators. + To invoke Container's const + begin() and end() functions, make it + const.
      NextPolicies + NextPoliciesA default-constructible model of CallPolicies. + A default-constructible model of CallPolicies.Applied to the resulting iterators' next() method. - - An unspecified model of CallPolicies - which always makes a copy of the - result of deferencing the underlying C++ iterator + Applied to the resulting iterators' next() + method.An unspecified model of CallPolicies which + always makes a copy of the result of deferencing the underlying C++ + iterator
      -

      Class Template iterator synopsis

      +

      Class Template iterator + synopsis

       namespace boost { namespace python
       {
         template <class Container
                    , class NextPolicies = unspecified>
      -  struct iterator : reference<PyObject*>
      +  struct iterator : object
         {
             iterator();
         };
       }}
       
      -

      Class Template - iterator constructor

      +

      Class Template iterator + constructor

       iterator()
       
      -
      Effects: Initializes its base class with the result - of: +
      Effects:
      + +
      + Initializes its base class with the result of:
       range<NextPolicies>(&iterators<Container>::begin, &iterators<Container>::end)
       
      +
      -
      Postconditions: this->get() points to - a Python callable object which creates a Python iterator as - described above. +
      Postconditions: this->get() points to a + Python callable object which creates a Python iterator as described + above.
      -
      Rationale: Provides an easy way to create iterators - for the common case where a C++ class being wrapped provides - begin() and end(). +
      Rationale: Provides an easy way to create iterators for the + common case where a C++ class being wrapped provides + begin() and end().
      + - +

      Class Template + iterators

      -

      Class Template iterators

      +

      A utility class template which provides a way to reliably call its + argument's begin() and end() member functions. + Note that there is no portable way to take the address of a member + function of a C++ standard library container, so + iterators<> can be particularly helpful when wrapping + them.

      -

      A utility class template which provides a way to reliably call - its argument's begin() and end() member - functions. Note that there is no portable way to take the address - of a member function of a C++ standard library container, so - iterators<> can be particularly helpful when - wrapping them. - - -

      In the table below, x is an instance of C. +

      In the table below, x is an instance of + C.

      - - + - + + + - + +
      Required Valid Expression + Required Valid ExpressionType + Type
      x.begin() - - Convertible to C::const_iterator if C is a - const type; convertible to C::iterator otherwise. + x.begin()Convertible to C::const_iterator if C + is a const type; convertible to C::iterator + otherwise.
      x.end() - - Convertible to C::const_iterator if C is a - const type; convertible to C::iterator otherwise. + x.end()Convertible to C::const_iterator if C + is a const type; convertible to C::iterator + otherwise.
      -

      Class Template iterators synopsis

      +

      Class Template iterators + synopsis

       namespace boost { namespace python
       {
      @@ -224,141 +247,151 @@ namespace boost { namespace python
       }}
       
       
      -

      Class Template - iterators nested types

      -If C is a const type, +

      Class Template iterators nested + types

      + If C is a const type,
       typedef typename C::const_iterator iterator;
       
      -Otherwise: + Otherwise:
       typedef typename C::iterator iterator;
       
      -

      Class Template - iterators static functions

      - +

      Class Template iterators static + functions

       static iterator begin(C&);
       
      -
      Returns: x.begin() +
      Returns: x.begin()
      -
       static iterator end(C&);
       
      -
      Returns: x.end() +
      Returns: x.end()
      - - +

      Functions

       template <class NextPolicies, class Target, class Accessor1, class Accessor2>
      -reference<PyObject*> range(Accessor1 start, Accessor2 finish);
      +object range(Accessor1 start, Accessor2 finish);
       
       template <class NextPolicies, class Accessor1, class Accessor2>
      -reference<PyObject*> range(Accessor1 start, Accessor2 finish);
      +object range(Accessor1 start, Accessor2 finish);
       
       template <class Accessor1, class Accessor2>
      -reference<PyObject*> range(Accessor1 start, Accessor2 finish);
      +object range(Accessor1 start, Accessor2 finish);
       
      Requires: NextPolicies is a - default-constructible model of CallPolicies. + default-constructible model of CallPolicies.
      -
      Effects:
      +
      Effects:
      -The first form creates a Python callable - object which, when invoked, converts its argument to a - Target object - x, and creates a Python iterator which traverses - [bind(start,_1)(x)bind(finish,_1)(x)), - applying NextPolicies to the iterator's - next() function. -
      -
      The second form is identical to - the first, except that Target is deduced from - Accessor1 as follows: -
        -
      1. If Accessor1 is a function type, - Target is the type of its first argument. -
      2. If Accessor1 is a data member pointer of the - form R (T::*), Target is - identical to T. -
      3. If Accessor1 is a member function pointer of - the form - R (T::*)(arguments...) cv-opt, - where cv-opt is an optional cv-qualifier, - Target is identical to T. -
      -
      +
      +
      +
      The first form creates a Python callable object which, when + invoked, converts its argument to a Target object + x, and creates a Python iterator which traverses + [bind(start,_1)(x)bind(finish,_1)(x)), + applying NextPolicies to the iterator's + next() function.
      -
      The third form is identical to the second, except that - NextPolicies is an unspecified model of CallPolicies - which always makes a copy of the - result of deferencing the underlying C++ iterator
      -
      +
      The second form is identical to the first, except that + Target is deduced from Accessor1 as + follows:
      +
      +
        +
      1. If Accessor1 is a function type, + Target is the type of its first argument.
      2. -
        Rationale: The use of boost::bind() allows - C++ iterators to be accessed through functions, member functions - or data member pointers. Customization of - NextPolicies (e.g. using return_internal_reference) is useful when it is - expensive to copy sequence elements of a wrapped class - type. Customization of Target is useful when - Accessor1 is a function object, or when a base - class of the intended target type would otherwise be deduced. +
      3. If Accessor1 is a data member pointer of the + form R (T::*), Target is + identical to T.
      4. + +
      5. If Accessor1 is a member function pointer of + the form + R (T::*)(arguments...)  + cv-opt, where cv-opt is an optional + cv-qualifier, Target is identical to + T.
      6. +
      +
      + +
      The third form is identical to the second, except that + NextPolicies is an unspecified model of CallPolicies which + always makes a copy of the result of deferencing the underlying C++ + iterator
      +
      + + +
      Rationale: The use of boost::bind() allows C++ iterators + to be accessed through functions, member functions or data member + pointers. Customization of NextPolicies (e.g. using + return_internal_reference) + is useful when it is expensive to copy sequence elements of a wrapped + class type. Customization of Target is useful when + Accessor1 is a function object, or when a base class of + the intended target type would otherwise be deduced.

      Examples

      -
      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       #include <boost/python/class.hpp>
      -#include <boost/python/return_internal_reference.hpp>
      +
       #include <vector>
       
       using namespace boost::python;
       BOOST_PYTHON_MODULE_INIT(demo)
       {
      -   module("demo")
      -      .add(
      -         class_<std::vector<double> >("dvec")
      -            .def("__iter__", iterator<std::vector<double> >())
      -            ...
      -         )
      -      ;
      +    class_<std::vector<double> >("dvec")
      +        .def("__iter__", iterator<std::vector<double> >())
      +        ;
       }
       
      + A more comprehensive example can be found in: -A more comprehensive example can be found in: -
      -
      libs/python/test/iterator.cpp
      -
      libs/python/test/input_iterator.cpp
      -
      libs/python/test/input_iterator.py
      - +
      +
      libs/python/test/iterator.cpp
      -

      Revised - - 17 May, 2002 - +

      libs/python/test/input_iterator.cpp
      +
      libs/python/test/input_iterator.py
      -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      +

      Revised + + 29 September, 2002 + +

      + +

      © Copyright Dave Abrahams 2002. All + Rights Reserved.

      +
      +
      + + From d873aec9e6b36cce62b3d9b7775865e9569e27ee Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 19:15:53 +0000 Subject: [PATCH 0779/1042] doc update [SVN r15557] --- doc/v2/call_method.html | 2 +- doc/v2/implicit.html | 4 +- doc/v2/lvalue_from_pytype.html | 216 ++++++++++++++++++--------------- 3 files changed, 118 insertions(+), 104 deletions(-) diff --git a/doc/v2/call_method.html b/doc/v2/call_method.html index 5323ab07..e5cf7e6b 100644 --- a/doc/v2/call_method.html +++ b/doc/v2/call_method.html @@ -121,7 +121,7 @@ class Base_callback : public Base using namespace boost::python; BOOST_PYTHON_MODULE_INIT(my_module) { - def("is_base", is_base) + def("is_base", is_base); class_<Base,Base_callback, noncopyable>("Base") .def("class_name", &Base_callback::Base_name) diff --git a/doc/v2/implicit.html b/doc/v2/implicit.html index 03832566..aebe2b52 100644 --- a/doc/v2/implicit.html +++ b/doc/v2/implicit.html @@ -123,8 +123,8 @@ X make_x(int n) { return X(n); } BOOST_PYTHON_MODULE_INIT(implicit_ext) { - def("x_value", x_value) - def("make_x", make_x) + def("x_value", x_value); + def("make_x", make_x); class_<X>("X", init<int>()) diff --git a/doc/v2/lvalue_from_pytype.html b/doc/v2/lvalue_from_pytype.html index 8b3cb49e..57997b3a 100755 --- a/doc/v2/lvalue_from_pytype.html +++ b/doc/v2/lvalue_from_pytype.html @@ -1,128 +1,145 @@ - + + + + Boost.Python - <boost/python/lvalue_from_python.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      -

      Header <boost/python/lvalue_from_pytype.hpp>

      +

      Header + <boost/python/lvalue_from_pytype.hpp>

      +

      Contents

      -
      Introduction +
      Introduction
      - -
      Classes +
      Classes
      -
      Class Template lvalue_from_pytype +
      Class Template + lvalue_from_pytype
      -
      Class Template - lvalue_from_pytype synopsis + lvalue_from_pytype synopsis
      Class Template - lvalue_from_pytype constructor + lvalue_from_pytype constructor
      +
      -
      Class Template extract_identity +
      Class Template + extract_identity
      +
      -
      Class Template - extract_identity synopsis + extract_identity synopsis
      Class Template - extract_identity static functions + extract_identity static functions
      -
      Class Template extract_member +
      + +
      Class Template + extract_member
      +
      -
      Class Template - extract_member synopsis + extract_member synopsis
      Class Template - extract_member static functions + extract_member static functions
      +
      +
      -
      Example +
      Example

      Introduction

      - - <boost/python/lvalue_from_pytype.hpp> supplies - a facility for extracting C++ objects from within Python instances - of a given type. This is typically useful for dealing with - "traditional" Python extension types. + <boost/python/lvalue_from_pytype.hpp> supplies a + facility for extracting C++ objects from within Python instances of a + given type. This is typically useful for dealing with "traditional" + Python extension types.

      Classes

      -

      Class template lvalue_from_pytype

      +

      Class template + lvalue_from_pytype

      Class template lvalue_from_pytype will register - from_python converters which, given an object of the given Python - type, can extract references and pointers to a particular C++ - type. Its template arguments are: - -

      - + from_python converters which, given an object of the given Python type, + can extract references and pointers to a particular C++ type. Its + template arguments are:

      - - - - - + - - - + + + + + + + +
      lvalue_from_pytype Requirements
      - - In the table below, x denotes an object of type PythonObject& - + In the table below, x denotes an object of type + PythonObject&
      Parameter - - Requirements - - Semantics
      Extractor + Parametera model of Extractor whose - execute function returns a reference type. + RequirementsExtracts the lvalue from the Python object once its type has been confirmed + Semantics
      python_type + ExtractorA compile-time constant PyTypeObject* + a model of Extractor whose execute + function returns a reference type.The Python type of instances convertible by this - converter. Python subtypes are also convertible. + Extracts the lvalue from the Python object once its type has been + confirmed
      python_typeA compile-time constant PyTypeObject*The Python type of instances convertible by this converter. + Python subtypes are also convertible.
      -

      Class template lvalue_from_pytype synopsis

      +

      Class template + lvalue_from_pytype synopsis

       namespace boost { namespace python
       {
      @@ -134,25 +151,25 @@ namespace boost { namespace python
       }}
       
      -

      Class template lvalue_from_pytype constructor

      +

      Class template + lvalue_from_pytype constructor

       lvalue_from_pytype();
       
      - -
      Effects: Registers converters which can convert - Python objects of the given type to lvalues of the type returned - by Extractor::execute. - +
      Effects: Registers converters which can convert Python + objects of the given type to lvalues of the type returned by + Extractor::execute.
      -

      Class template extract_identity

      +

      Class template + extract_identity

      -

      extract_identity is a model of Extractor which can be - used in the common case where the C++ type to be extracted is the - same as the Python object type. +

      extract_identity is a model of Extractor which can be used in the + common case where the C++ type to be extracted is the same as the Python + object type.

      Class template extract_identity synopsis

      @@ -167,26 +184,26 @@ namespace boost { namespace python }}
      -

      Class template extract_identity static functions

      +

      Class template + extract_identity static functions

       InstanceType& execute(InstanceType& c);
       
      - -
      Returns: c - +
      Returns: c
      +

      Class template + extract_member

      -

      Class template extract_member

      +

      extract_member is a model of Extractor which can be used in the + common case in the common case where the C++ type to be extracted is a + member of the Python object.

      -

      extract_member is a model of Extractor which can be - used in the common case in the common case where the C++ - type to be extracted is a member of the Python object. - -

      Class template extract_member synopsis

      +

      Class template + extract_member synopsis

       namespace boost { namespace python
       {
      @@ -198,34 +215,31 @@ namespace boost { namespace python
       }}
       
      -

      Class template extract_member static functions

      +

      Class template + extract_member static functions

       static MemberType& execute(InstanceType& c);
       
      - -
      Returns: c.*member - +
      Returns: c.*member

      Example

      + This example presumes that someone has implemented the standard noddy example + module from the Python documentation, and we want to build a module + which manipulates Noddys. Since + noddy_NoddyObject is so simple that it carries no + interesting information, the example is a bit contrived: it assumes you + want to keep track of one particular object for some reason. This module + would have to be dynamically linked to the module which defines + noddy_NoddyType. -This example presumes that someone has implemented the standard noddy -example module from the Python documentation, and we want to build -a module which manipulates Noddys. Since -noddy_NoddyObject is so simple that it carries no -interesting information, the example is a bit contrived: it assumes -you want to keep track of one particular object for some reason. This -module would have to be dynamically linked to the module which defines -noddy_NoddyType. - -

      C++ module definition

      - +

      C++ module definition

       #include <boost/python/reference.hpp>
      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       
       // definition lifted from the Python docs
       typedef struct {
      @@ -247,18 +261,15 @@ void set_cache(noddy_NoddyObject* x)
       
       BOOST_PYTHON_MODULE_INIT(noddy_cache)
       {
      -   module noddy_cache("noddy_cache")
      -      .def("is_cached", is_cached)
      -      .def("set_cache", set_cache)
      -      ;
      +   def("is_cached", is_cached);
      +   def("set_cache", set_cache);
       
          // register Noddy lvalue converter
          lvalue_from_pytype<extract_identity<noddy_NoddyObject>,&noddy_NoddyType>();
       }
       
      -

      Python code

      - +

      Python code

       >>> import noddy
       >>> n = noddy.new_noddy()
      @@ -274,10 +285,13 @@ BOOST_PYTHON_MODULE_INIT(noddy_cache)
       
           

      Revised - 05 November, 2001 + 29 September, 2001 +

      - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From 6b5ea675c38f247f30a9a9742c5d835267b1376c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 20:18:04 +0000 Subject: [PATCH 0780/1042] doc update [SVN r15559] --- doc/v2/make_function.html | 139 ++++++++++++++++++++-------------- doc/v2/manage_new_object.html | 67 +++++++++------- 2 files changed, 123 insertions(+), 83 deletions(-) diff --git a/doc/v2/make_function.html b/doc/v2/make_function.html index c31144c9..0d7bb689 100644 --- a/doc/v2/make_function.html +++ b/doc/v2/make_function.html @@ -1,39 +1,50 @@ - + + + + Boost.Python - <boost/python/make_function.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      -

      Header <boost/python/make_function.hpp>

      +

      Header + <boost/python/make_function.hpp>

      +

      Contents

      -
      Introduction +
      Introduction
      -
      Functions +
      Functions
      -
      make_function +
      make_function
      -
      make_constructor +
      make_constructor
      +
      -
      Example +
      Example

      @@ -41,86 +52,99 @@

      make_function() and make_constructor() are - the functions used internally by class_<>::def, class_<>::def, and - class_<>::def_init to produce Python - callable objects which wrap C++ functions and member functions. + the functions used internally by def() and class_<>::def() to produce Python + callable objects which wrap C++ functions and member functions.

      Functions

       template <class F>
      -objects::function* make_function(F f)
      +object make_function(F f)
       
       template <class F, class Policies>
      -objects::function* make_function(F f, Policies const& policies)
      +object make_function(F f, Policies const& policies)
      +
      +template <class F, class Policies, class Keywords>
      +object make_function(F f, Policies const& policies, Keywords const& keywords)
       
      Requires: F is a function pointer or member - function pointer type + function pointer type. If policies are supplied, it must + be a model of CallPolicies. If + kewords are supplied, it must be the result of a keyword-expression + specifying no more arguments than the arity of f.
      Effects: Creates a Python callable object which, when called from Python, converts its arguments to C++ and calls f. If - F is a pointer-to-member-function type, the target object of - the function call (*this) will be taken from the first + F is a pointer-to-member-function type, the target object + of the function call (*this) will be taken from the first Python argument, and subsequent Python arguments will be used as the arguments to f. If policies are supplied, it - must be a model of CallPolicies, and will - be applied to the function as described here. + will be applied to the function as described here. If keywords are + supplied, the keywords will be applied in order to the final + arguments of the resulting function.
      -
      Returns: A pointer convertible to PyObject* which - refers to the new Python callable object. +
      Returns: An instance of object which holds the new Python + callable object.
       template <class T, class ArgList, class Generator>
      -objects::function* make_constructor();
      -
      +"make_constructor-spec">template <class T, class ArgList, class Generator>
      +object make_constructor();
      + 
       template <class ArgList, class Generator, class Policies>
      -objects::function* make_constructor(Policies const& policies)
      +object make_constructor(Policies const& policies)
       
      -
      Requires: T is a class - type. Policies is a model of CallPolicies. ArgList - is an MPL sequence - of C++ argument types (A1, A2,... AN) such that if - a1, a2... aN are objects of type - A1, A2,... AN respectively, the expression new - Generator::apply<T>::type(a1, a2... aN) is - valid. Generator is a model of HolderGenerator. +
      Requires: T is a class type. + Policies is a model of CallPolicies. ArgList is an MPL sequence of C++ argument + types (A1, A2,... AN) such that if + a1, a2... aN are objects of type + A1, A2,... AN respectively, the expression new + Generator::apply<T>::type(a1, a2... aN) + is valid. Generator is a model of HolderGenerator.
      Effects: Creates a Python callable object which, when called from Python, expects its first argument to be a Boost.Python extension class object. It converts its remaining its arguments to C++ and passes them to the constructor of a dynamically-allocated - Generator::apply<T>::type object, which is - then installed in the extension class object. In the second - form, the policies are applied to the arguments and - result (None) - of the Python callable object + Generator::apply<T>::type object, which is then + installed in the extension class object. In the second form, the + policies are applied to the arguments and result (None) + of the Python callable object
      -
      Returns: The new Python callable object +
      Returns: An instance of object which holds the new Python + callable object.

      Example

      -

      C++ function exposed below returns a callable object wrapping one of two - functions. +

      C++ function exposed below returns a callable object wrapping one of + two functions.

       #include <boost/python/make_function.hpp>
      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       
       char const* foo() { return "foo"; }
       char const* bar() { return "bar"; }
       
      -PyObject* choose_function(bool selector)
      +using namespace boost::python;
      +object choose_function(bool selector)
       {
           if (selector)
               return boost::python::make_function(foo);
      @@ -130,8 +154,7 @@ PyObject* choose_function(bool selector)
       
       BOOST_PYTHON_MODULE_INIT(make_function_test)
       {
      -    module("make_function_test")
      -        .def("choose_function", choose_function);
      +    def("choose_function", choose_function);
       }
       
      It can be used this way in Python: @@ -147,9 +170,13 @@ BOOST_PYTHON_MODULE_INIT(make_function_test)

      - 14 February 2002 + 29 September 2002 + +

      - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + diff --git a/doc/v2/manage_new_object.html b/doc/v2/manage_new_object.html index 8630dfa5..3efec0eb 100644 --- a/doc/v2/manage_new_object.html +++ b/doc/v2/manage_new_object.html @@ -1,46 +1,57 @@ - + + + + Boost.Python - <boost/python/manage_new_object.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      Header <boost/python/manage_new_object.hpp>

      +

      Contents

      -
      Classes +
      Classes
      Class - manage_new_object + manage_new_object
      Class - manage_new_object synopsis + manage_new_object synopsis
      Class - manage_new_object metafunctions + manage_new_object metafunctions
      +
      +
      -
      Example +
      Example

      @@ -50,10 +61,10 @@ manage_new_object

      manage_new_object is a model of ResultConverterGenerator which can be - used to wrap C++ functions which return a pointer to an object allocated - with a new-expression, and expect the caller to take responsibility - for deleting that object. + "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator + which can be used to wrap C++ functions which return a pointer to an + object allocated with a new-expression, and expect the caller to + take responsibility for deleting that object.

      Class manage_new_object synopsis

      @@ -75,18 +86,18 @@ template <class T> struct apply
      Requires: T is U* for some - U. + U.
      Returns: typedef to_python_indirect<T> - type; + type;

      Example

      -

      In C++: +

      In C++:

      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/manage_new_object.hpp>
       #include <boost/python/return_value_policy.hpp>
      @@ -104,15 +115,13 @@ Foo* make_foo(int x) { return new Foo(x); }
       using namespace boost::python;
       BOOST_PYTHON_MODULE_INIT(my_module)
       {
      -   module("my_module")
      -      .def("make_foo", make_foo, return_value_policy<manage_new_object>)
      -      .add(
      -         class_<Foo>()
      -            .def("get_x", &Foo::get_x)
      -         )
      +    def("make_foo", make_foo, return_value_policy<manage_new_object>())
      +    class_<Foo>()
      +        .def("get_x", &Foo::get_x)
      +        ;
       }
       
      -In Python: + In Python:
       >>> from my_module import *
       >>> f = make_foo(3)     # create a Foo object
      @@ -122,9 +131,13 @@ In Python:
       
           

      Revised - 14 February 2002 + 29 September 2002 + +

      - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From 170bbea1665ed9451fb7550cda0fc4a6b59670f8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 20:30:17 +0000 Subject: [PATCH 0781/1042] doc update [SVN r15561] --- doc/v2/operators.html | 1000 +++++++++++++++++-------- doc/v2/reference_existing_object.html | 83 +- doc/v2/return_internal_reference.html | 178 +++-- 3 files changed, 825 insertions(+), 436 deletions(-) diff --git a/doc/v2/operators.html b/doc/v2/operators.html index a43df858..6a551b92 100755 --- a/doc/v2/operators.html +++ b/doc/v2/operators.html @@ -1,407 +1,767 @@ - + + + + Boost.Python - <boost/python/operators.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      Header <boost/python/operators.hpp>

      +

      Contents

      -
      Introduction +
      Introduction
      + +
      Classes
      -
      Classes
      +
      Class + self_ns::self_t
      -
      Class self_ns::self_t
      -
      Class self_t synopsis +
      Class self_t + synopsis
      -
      Class self_t inplace operators +
      Class self_t + inplace operators
      -
      Class self_t comparison functions +
      Class + self_t comparison functions
      -
      Class self_t non-member operations +
      Class self_t + non-member operations
      -
      Class self_t unary operations +
      Class + self_t unary operations
      -
      Class self_t value operations +
      Class + self_t value operations
      +
      + +
      Class template + other
      -
      Class template other
      -
      Class other synopsis +
      Class other + synopsis
      +
      + +
      Class template + operator_
      -
      Class template operator_
      -
      Class operator_ synopsis +
      Class + operator_ synopsis
      - -
      - -
      Objects -
      -
      -
      self +
      + -
      Examples +
      Objects
      + +
      +
      +
      self
      +
      +
      + +
      Examples

      Introduction

      -

      <boost/python/operators.hpp> provides types - and functions for automatically generating Python special - methods from the corresponding C++ constructs. Most of these - constructs are operator expressions, hence the name. To use the - facility, substitute the self object for an object of the - class type being wrapped in the expression to be exposed, and pass - the result to class_<>::def(). Much - of what is exposed in this header should be considered part of the - implementation, so is not documented in detail here. +

      <boost/python/operators.hpp> provides types and + functions for automatically generating Python special methods + from the corresponding C++ constructs. Most of these constructs are + operator expressions, hence the name. To use the facility, substitute the + self object for an object of the + class type being wrapped in the expression to be exposed, and pass the + result to class_<>::def(). Much of + what is exposed in this header should be considered part of the + implementation, so is not documented in detail here.

      Classes

      Class self_ns::self_t

      -

      self_ns::self_t is the actual type of the self object. The library - isolates self_t in its own namespace, - self_ns, in order to prevent the generalized operator - templates which operate on it from being found by - argument-dependent lookup in other contexts. This should be - considered an implementation detail, since users should never have - to mention self_t directly. +

      self_ns::self_t is the actual type of the self object. The library isolates + self_t in its own namespace, self_ns, in order + to prevent the generalized operator templates which operate on it from + being found by argument-dependent lookup in other contexts. This should + be considered an implementation detail, since users should never have to + mention self_t directly.

      -

      Class self_ns::self_t synopsis

      +

      Class self_ns::self_t + synopsis

       namespace boost { namespace python { namespace self_ns {
       {
          class self_t {};
       
          // inplace operators
      -   template <class T> operator_<unspecified> operator+=(self_t, T);
      -   template <class T> operator_<unspecified> operator-=(self_t, T);
      -   template <class T> operator_<unspecified> operator*=(self_t, T);
      -   template <class T> operator_<unspecified> operator/=(self_t, T);
      -   template <class T> operator_<unspecified> operator%=(self_t, T);
      -   template <class T> operator_<unspecified> operator>>=(self_t, T);
      -   template <class T> operator_<unspecified> operator<<=(self_t, T);
      -   template <class T> operator_<unspecified> operator&=(self_t, T);
      -   template <class T> operator_<unspecified> operator^=(self_t, T);
      -   template <class T> operator_<unspecified> operator|=(self_t, T);
      +   template <class T> operator_<unspecified> operator+=(self_t, T);
      +   template <class T> operator_<unspecified> operator-=(self_t, T);
      +   template <class T> operator_<unspecified> operator*=(self_t, T);
      +   template <class T> operator_<unspecified> operator/=(self_t, T);
      +   template <class T> operator_<unspecified> operator%=(self_t, T);
      +   template <class T> operator_<unspecified> operator>>=(self_t, T);
      +   template <class T> operator_<unspecified> operator<<=(self_t, T);
      +   template <class T> operator_<unspecified> operator&=(self_t, T);
      +   template <class T> operator_<unspecified> operator^=(self_t, T);
      +   template <class T> operator_<unspecified> operator|=(self_t, T);
       
          // comparisons
      -   template <class L, class R> operator_<unspecified> operator==(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator!=(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator<(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator>(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator<=(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator>=(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator==(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator!=(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator<(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator>(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator<=(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator>=(L const&, R const&);
       
          // non-member operations
      -   template <class L, class R> operator_<unspecified> operator+(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator-(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator*(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator/(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator%(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator>>(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator<<(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator&(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator^(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> operator|(L const&, R const&);
      -   template <class L, class R> operator_<unspecified> pow(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator+(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator-(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator*(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator/(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator%(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator>>(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator<<(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator&(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator^(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> operator|(L const&, R const&);
      +   template <class L, class R> operator_<unspecified> pow(L const&, R const&);
       
          // unary operations
      -   operator_<unspecified> operator-(self_t);
      -   operator_<unspecified> operator+(self_t);
      -   operator_<unspecified> operator~(self_t);
      +   operator_<unspecified> operator-(self_t);
      +   operator_<unspecified> operator+(self_t);
      +   operator_<unspecified> operator~(self_t);
       
          // value operations
      -   operator_<unspecified> int_(self_t);
      -   operator_<unspecified> long_(self_t);
      -   operator_<unspecified> float_(self_t);
      -   operator_<unspecified> complex_(self_t);
      -   operator_<unspecified> str(self_t);
      +   operator_<unspecified> int_(self_t);
      +   operator_<unspecified> long_(self_t);
      +   operator_<unspecified> float_(self_t);
      +   operator_<unspecified> complex_(self_t);
      +   operator_<unspecified> str(self_t);
       
       }}};
       
      + The tables below describe the methods generated when the results of the + expressions described are passed as arguments to class_<>::def(). + x is an object of the class type being wrapped. -The tables below describe the methods generated when the results of -the expressions described are passed as arguments to class_<>::def(). -x is an object of the class type being wrapped. +

      Class self_t inplace + operators

      + In the table below, If r is an object of type + other<T>, + y is an object of type T; otherwise, + y is an object of the same type as + r. + + + -

      Class self_t inplace operators

      + + + + + -In the table below, If r is an object of type -other<T>, -y is an object of type T; otherwise, -y is an object of the same type as -r. + -
      C++ ExpressionPython Method NameC++ Implementation
      self += r__iadd__
      - - + - + - - + - + - - + - + - - + -
      C++ Expression - Python Method Name - C++ Implementation + x += y
      self += r -__iadd__ -x += y +
      self -= r
      self -= r -__isub__ -x -= y + __isub__
      self *= r -__imul__ -x *= y + x -= y
      self /= r -__idiv__ -x /= y +
      self *= r
      self %= r -__imod__ -x %= y + __imul__
      self >>= r -__irshift__ -x >>= y + x *= y
      self <<= r -__ilshift__ -x <<= y +
      self /= r
      self &= r -__iand__ -x &= y + __idiv__
      self ^= r -__ixor__ -x ^= y + x /= y
      self |= r -__ior__ -x |= y -
      + + self %= r -

      Class self_t comparison - functions

      + __imod__ -In the tables below, if r is of type self_t, y is an object -of the same type as x; -
      -if l or r is an object of type other<T>, -y is an object of type T; -
      -otherwise, y is an object of the same type as -l or r.
      -l -is never of type self_t. + x %= y + -

      -The column of Python Expressions illustrates the expressions -that will be supported in Python for objects convertible to the types -of x and y. The secondary operation arises -due to Python's reflection -rules for rich comparison operators, and are only used when the -corresponding operation is not defined as a method of the -y object. + + self >>= r - - - + - + - - + - + - - + - + - - + - + - - -
      C++ Expression Python Method Name C++ Implementation -Python Expressions
      (primary, secondary) - +
      __irshift__
      self == r __eq__ x == y -x == y, y == x + x >>= y
      l == self __eq__ y == x -y == x, x == y +
      self <<= r
      self != r __ne__ x != y -x != y, y != x + __ilshift__
      l != self __ne__ y != x -y != x, x != y + x <<= y
      self < r __lt__ x < y -x < y, y > x +
      self &= r
      l < self __gt__ y < x -y > x, x < y + __iand__
      self > r __gt__ x > y -x > y, y < x + x &= y
      l > self __lt__ y > x -y < x, x > y +
      self ^= r
      self <= r __le__ x <= y -x <= y, y >= x + __ixor__
      l <= self __ge__ y <= x -y >= x, x <= y + x ^= y
      self >= r __ge__ x >= y -x >= y, y <= x +
      self |= r
      l >= self __le__ y >= x -y <= x, x >= y + __ior__
      + x |= y + + +

      Class self_t + comparison functions

      + In the tables below, if r is of type self_t, y is an object of + the same type as x;
      + if l or r is an object of type + other<T>, + y is an object of type T;
      + otherwise, y is an object of the same type as + l or r.
      + l is never of type self_t. -

      Class - self_t non-member operations

      +

      The column of Python Expressions illustrates the expressions + that will be supported in Python for objects convertible to the types of + x and y. The secondary operation arises due to + Python's reflection + rules for rich comparison operators, and are only used when the + corresponding operation is not defined as a method of the y + object.

      -The operations whose names begin with "__r" -below will only be called if the left-hand operand does not already -support the given operation, as described here. + + + -
      C++ Expression
      - - - + - + - - - + - + - - - + - + - -
      C++ Expression Python Method Name C++ Implementation - + Python Method Name
      self + r __add__ x + y -
      l + self __radd__ y + x + C++ Implementation
      self - r __sub__ x - y -
      l - self __rsub__ y - x + Python Expressions
      + (primary, secondary)
      self * r __mul__ x * y -
      l * self __rmul__ y * x +
      self == r
      self / r __div__ x / y -
      l / self __rdiv__ y / x + __eq__
      self % r __mod__ x % y -
      l % self __rmod__ y % x + x == y
      self >> r __rshift__ x >> y -
      l >> self __rrshift__ y >> x + x == y, y == x
      self << r __lshift__ x << y -
      l << self __rlshift__ y << x +
      l == self
      self & r __and__ x & y -
      l & self __rand__ y & x + __eq__
      self ^ r __xor__ x ^ y -
      l ^ self __rxor__ y ^ x + y == x
      self | r __or__ x | y -
      l | self __ror__ y | x + y == x, x == y
      pow(self, r) __pow__ pow(x, y) -
      pow(l, self) __rpow__ pow(y, x) +
      self != r
      + __ne__ + x != y -

      Class - self_t unary operations

      + x != y, y != x + - - + - - -
      C++ Expression Python Method Name C++ Implementation - +
      l != self
      -self __neg__ -x -
      +self__pos__ +x -
      ~self__invert__ ~x + __ne__
      + y != x + y != x, x != y + -

      Class - self_t value operations

      + + self < r - - - - -
      C++ Expression Python Method Name C++ Implementation - + __lt__
      int_(self)__int__ long(x) -
      long___long__ PyLong_FromLong(x) -
      float___float__ double(x) -
      complex___complex__ std::complex<double>(x) -
      str__str__ lexical_cast<std::string>(x) + x < y
      + x < y, y > x + + + l < self + __gt__ + + y < x + + y > x, x < y + + + + self > r + + __gt__ + + x > y + + x > y, y < x + + + + l > self + + __lt__ + + y > x + + y < x, x > y + + + + self <= r + + __le__ + + x <= y + + x <= y, y >= x + + + + l <= self + + __ge__ + + y <= x + + y >= x, x <= y + + + + self >= r + + __ge__ + + x >= y + + x >= y, y <= x + + + + l >= self + + __le__ + + y >= x + + y <= x, x >= y + + + +

      Class self_t non-member + operations

      + The operations whose names begin with "__r" below will only + be called if the left-hand operand does not already support the given + operation, as described here. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      C++ ExpressionPython Method NameC++ Implementation
      self + r__add__x + y
      l + self__radd__y + x
      self - r__sub__x - y
      l - self__rsub__y - x
      self * r__mul__x * y
      l * self__rmul__y * x
      self / r__div__x / y
      l / self__rdiv__y / x
      self % r__mod__x % y
      l % self__rmod__y % x
      self >> r__rshift__x >> y
      l >> self__rrshift__y >> x
      self << r__lshift__x << y
      l << self__rlshift__y << x
      self & r__and__x & y
      l & self__rand__y & x
      self ^ r__xor__x ^ y
      l ^ self__rxor__y ^ x
      self | r__or__x | y
      l | self__ror__y | x
      pow(self, r)__pow__pow(x, y)
      pow(l, self)__rpow__pow(y, x)
      + +

      Class self_t unary + operations

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      C++ ExpressionPython Method NameC++ Implementation
      -self__neg__-x
      +self__pos__+x
      ~self__invert__~x
      + +

      Class self_t value + operations

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      C++ ExpressionPython Method NameC++ Implementation
      int_(self)__int__long(x)
      long___long__PyLong_FromLong(x)
      float___float__double(x)
      complex___complex__std::complex<double>(x)
      str__str__lexical_cast<std::string>(x)

      Class Template other

      -

      Instances of other<T> can be used in - operator expressions with self; the - result is equivalent to the same expression with a T - object in place of other<T>. Use - other<T> to prevent construction of a - T object in case it is heavyweight, when no - constructor is available, or simply for clarity. +

      Instances of other<T> can be used in operator + expressions with self; the result is equivalent + to the same expression with a T object in place of + other<T>. Use other<T> to prevent + construction of a T object in case it is heavyweight, when + no constructor is available, or simply for clarity.

      Class Template other synopsis

      @@ -413,19 +773,18 @@ namespace boost { namespace python
         };
       }}
       
      + - +

      Class Template + detail::operator_

      -

      Class Template detail::operator_

      +

      Instantiations of detail::operator_<> are used as + the return type of operator expressions involving self. This should be considered an implementation + detail and is only documented here as a way of showing how the result of + self-expressions match calls to class_<>::def().

      -

      Instantiations of detail::operator_<> are - used as the return type of operator expressions involving self. This should be considered an - implementation detail and is only documented here as a way of - showing how the result of self-expressions match - calls to class_<>::def(). -

      Class Template detail::operator_ synopsis

      @@ -440,8 +799,7 @@ namespace boost { namespace python { namespace detail
       
           

      Objects

      -

      self - +

      self

       namespace boost { namespace python
       {
      @@ -450,15 +808,15 @@ namespace boost { namespace python
       

      Example

      -
      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/operators.hpp>
       #include <boost/operators.hpp>
       
       struct number
      -   : boost::integer_arithmetic<number>
      +   : boost::integer_arithmetic<number>
       {
          number(long x_) : x(x_) {}
          operator long() const { return x; }
      @@ -480,52 +838,50 @@ struct number
       using namespace boost::python;
       BOOST_PYTHON_MODULE_INIT(demo)
       {
      -   module("demo")
      -      .add(
      -         class_<number>("number")
      -            // interoperate with self
      -            .def(self += self)
      -            .def(self + self)
      -            .def(self -= self)
      -            .def(self - self)
      -            .def(self *= self)
      -            .def(self * self)
      -            .def(self /= self)
      -            .def(self / self)
      -            .def(self %= self)
      -            .def(self % self)
      -            
      -            // Convert to Python int
      -            .def(int_(self))
      +   class_<number>("number")
      +      // interoperate with self
      +      .def(self += self)
      +      .def(self + self)
      +      .def(self -= self)
      +      .def(self - self)
      +      .def(self *= self)
      +      .def(self * self)
      +      .def(self /= self)
      +      .def(self / self)
      +      .def(self %= self)
      +      .def(self % self)
       
      -            // interoperate with long
      -            .def(self += long())
      -            .def(self + long())
      -            .def(long() + self)
      -            .def(self -= long())
      -            .def(self - long())
      -            .def(long() - self)
      -            .def(self *= long())
      -            .def(self * long())
      -            .def(long() * self)
      -            .def(self /= long())
      -            .def(self / long())
      -            .def(long() / self)
      -            .def(self %= long())
      -            .def(self % long())
      -            .def(long() % self)
      +      // Convert to Python int
      +      .def(int_(self))
       
      -         )
      +      // interoperate with long
      +      .def(self += long())
      +      .def(self + long())
      +      .def(long() + self)
      +      .def(self -= long())
      +      .def(self - long())
      +      .def(long() - self)
      +      .def(self *= long())
      +      .def(self * long())
      +      .def(long() * self)
      +      .def(self /= long())
      +      .def(self / long())
      +      .def(long() / self)
      +      .def(self %= long())
      +      .def(self % long())
      +      .def(long() % self)
             ;
       }
       

      Revised - 3 June, 2002 - + 29 Sept, 2002 +

      - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + diff --git a/doc/v2/reference_existing_object.html b/doc/v2/reference_existing_object.html index dbb7a983..59a47216 100644 --- a/doc/v2/reference_existing_object.html +++ b/doc/v2/reference_existing_object.html @@ -1,47 +1,59 @@ - + + + + Boost.Python - <boost/python/reference_existing_object.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      Header <boost/python/reference_existing_object.hpp>

      +

      Contents

      -
      Classes +
      Classes
      Class - reference_existing_object + reference_existing_object
      Class - reference_existing_object synopsis + reference_existing_object synopsis
      -
      Class - reference_existing_object metafunctions +
      Class + reference_existing_object metafunctions
      +
      +
      -
      Example +
      Example

      @@ -51,19 +63,20 @@ reference_existing_object

      reference_existing_object is a model of ResultConverterGenerator which can be - used to wrap C++ functions which return a reference or pointer to a C++ - object. When the wrapped function is called, the value referenced by its - return value is not copied. A new Python object is created which contains a - pointer to the referent, and no attempt is made to ensure that the lifetime - of the referent is at least as long as that of the corresponding Python - object. Thus, it can be highly - dangerous to use reference_existing_object without - additional lifetime management from such models of ResultConverterGenerator + which can be used to wrap C++ functions which return a reference or + pointer to a C++ object. When the wrapped function is called, the value + referenced by its return value is not copied. A new Python object is + created which contains a pointer to the referent, and no attempt is made + to ensure that the lifetime of the referent is at least as long as that + of the corresponding Python object. Thus, it can be highly dangerous to use + reference_existing_object without additional lifetime + management from such models of CallPolicies as with_custodian_and_ward. This class is used in the implementation of return_internal_reference. + "return_internal_reference.html#return_internal_reference-spec">return_internal_reference.

      Class reference_existing_object synopsis

      @@ -85,22 +98,22 @@ template <class T> struct apply
      Requires: T is U& or - U*for some U. + U*for some U.
      Returns: typedef to_python_indirect<T,V> type, where V is a HolderObjectGenerator which constructs an instance holder containing an unowned - U* pointing to the referent of the wrapped function's return - value. + U* pointing to the referent of the wrapped function's + return value.

      Example

      -

      In C++: +

      In C++:

      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/reference_existing_object.hpp>
       #include <boost/python/return_value_policy.hpp>
      @@ -130,12 +143,10 @@ Singleton& get_it()
       using namespace boost::python;
       BOOST_PYTHON_MODULE_INIT(singleton)
       {
      -   module("singleton")
      -      .def("get_it", get_it)
      -      .add(
      -         class_<Singleton>()
      -            .def("exchange", &Singleton::exchange)
      -         );
      +    def("get_it", get_it, reference_existing_object());
      +    class_<Singleton>()
      +       .def("exchange", &Singleton::exchange)
      +       ;
       }
       
      In Python: @@ -153,9 +164,13 @@ BOOST_PYTHON_MODULE_INIT(singleton)

      Revised - 14 February 2002 + 29 September 2002 + +

      - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + diff --git a/doc/v2/return_internal_reference.html b/doc/v2/return_internal_reference.html index 347db88c..596ed2c6 100644 --- a/doc/v2/return_internal_reference.html +++ b/doc/v2/return_internal_reference.html @@ -1,114 +1,129 @@ - + + + + - Boost.Python - <boost/python/return_internal_reference.hpp> + Boost.Python - + <boost/python/return_internal_reference.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      -

      Header <boost/python/return_internal_reference.hpp>

      +

      Header + <boost/python/return_internal_reference.hpp>

      +

      Contents

      -
      Introduction +
      Introduction
      - -
      Classes +
      Classes
      -
      Class Template return_internal_reference +
      Class Template + return_internal_reference
      - -
      Class Template - return_internal_reference synopsis +
      Class + Template return_internal_reference + synopsis
      Class - return_internal_reference static functions + return_internal_reference static + functions
      +
      +
      - -
      Example +
      Example

      Introduction

      - - return_internal_reference instantiations are models of CallPolicies which allow pointers and + return_internal_reference instantiations are models of CallPolicies which allow pointers and references to objects held internally by a free or member function - argument or from the target of a member function to be returned - safely without making a copy of the referent. The default for its - first template argument handles the common case where the - containing object is the target (*this) of a wrapped - member function. + argument or from the target of a member function to be returned safely + without making a copy of the referent. The default for its first template + argument handles the common case where the containing object is the + target (*this) of a wrapped member function.

      Classes

      -

      Class template return_internal_reference

      +

      Class template + return_internal_reference

      - - +
      - - - + + + + + + + + + + - - + - - - + +
      return_internal_reference template parameters
      Parameter - - Requirements - - Description - - Default
      owner_arg + ParameterRequirementsDescriptionDefault
      owner_arg A positive compile-time constant of type - std::size_t. + std::size_t.The index of the parameter which contains the object to - which the reference or pointer is being returned. If used to - wrap a member function, parameter 1 is the target object - (*this). Note that if the target Python object - type doesn't support weak references, a Python - TypeError exception will be raised when the - function being wrapped is called. + The index of the parameter which contains the object to which the + reference or pointer is being returned. If used to wrap a member + function, parameter 1 is the target object (*this). Note + that if the target Python object type doesn't support weak + references, a Python TypeError exception will be raised + when the function being wrapped is called.1 + 1
      Base + BaseA model of CallPolicies + A model of CallPoliciesUsed for policy composition. Any - result_converter it supplies will be overridden by - return_internal_reference, but its - precall and postcall policies are - composed as described here CallPolicies. - - default_call_policies + Used for policy composition. Any result_converter it + supplies will be overridden by + return_internal_reference, but its precall + and postcall policies are composed as described here CallPolicies.default_call_policies
      -

      Class template return_internal_reference synopsis

      +

      Class template + return_internal_reference synopsis

       namespace boost { namespace python
       {
      @@ -116,31 +131,34 @@ namespace boost { namespace python
          struct return_internal_reference : Base
          {
             static PyObject* postcall(PyObject*, PyObject* result);
      -      typedef reference_existing_object result_converter;
      +      typedef reference_existing_object result_converter;
          };
       }}
       

      Class default_call_policies static functions

      -
       PyObject* postcall(PyObject* args, PyObject* result);
       
      -
      Requires: PyTuple_Check(args) != 0 +
      Requires: PyTuple_Check(args) + != 0
      -
      Returns: with_custodian_and_ward_postcall::postcall(args, result) +
      Returns: + with_custodian_and_ward_postcall::postcall(args, + result)
      -

      Example

      -

      C++ module definition

      - +

      C++ module definition

      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/return_internal_reference.hpp>
       
      @@ -168,24 +186,20 @@ class Foo
       using namespace boost::python;
       BOOST_PYTHON_MODULE_INIT(internal_refs)
       {
      -   module m("internal_refs")
      -      .add(
      -         class_<Bar>()
      -            .def("get_x", &Bar::get_x)
      -            .def("set_x", &Bar::set_x)
      -         )
      -      .add(
      -         class_<Foo>()
      -            .def_init(args<int>())
      -            .def("get_bar", &Foo::get_bar
      -                , return_internal_reference<>())
      -         )
      +   class_<Bar>()
      +      .def("get_x", &Bar::get_x)
      +      .def("set_x", &Bar::set_x)
      +      ;
      +
      +   class_<Foo>()
      +      .def_init(args<int>())
      +      .def("get_bar", &Foo::get_bar
      +          , return_internal_reference<>())
             ;
       }
       
      -

      Python code

      - +

      Python code

       >>> from internal_refs import *
       >>> f = Foo(3)
      @@ -202,9 +216,13 @@ BOOST_PYTHON_MODULE_INIT(internal_refs)
       
           

      Revised - 15 February, 2002 + 15 February, 2002 +

      -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From 19982e555127456a87cfc19bef09b451829988fa Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Sep 2002 20:40:33 +0000 Subject: [PATCH 0782/1042] doc update [SVN r15562] --- doc/v2/has_back_reference.html | 6 +- doc/v2/manage_new_object.html | 2 +- doc/v2/reference_existing_object.html | 2 +- doc/v2/return_internal_reference.html | 5 +- doc/v2/return_value_policy.html | 119 ++++++++++++---------- doc/v2/to_python_converter.html | 141 ++++++++++++++------------ 6 files changed, 153 insertions(+), 122 deletions(-) diff --git a/doc/v2/has_back_reference.html b/doc/v2/has_back_reference.html index ed8b0342..7e3a8609 100644 --- a/doc/v2/has_back_reference.html +++ b/doc/v2/has_back_reference.html @@ -13,7 +13,7 @@ p.c3 {font-style: italic} h2.c2 {text-align: center} h1.c1 {text-align: center} - + @@ -97,8 +97,8 @@ namespace boost { namespace python
      Specializations may substitute a value convertible to true for value iff for each invocation of - class_<WrappedClass>::def_init(args<type-sequence... - >()), there exists a corresponding constructor + class_<WrappedClass>::def(init<type-sequence... + >()), there exists a corresponding constructor WrappedClass::WrappedClass(PyObject*, type-sequence... ). If such a specialization exists, the WrappedClass constructors will be called with a "back diff --git a/doc/v2/manage_new_object.html b/doc/v2/manage_new_object.html index 3efec0eb..f6b6168d 100644 --- a/doc/v2/manage_new_object.html +++ b/doc/v2/manage_new_object.html @@ -116,7 +116,7 @@ using namespace boost::python; BOOST_PYTHON_MODULE_INIT(my_module) { def("make_foo", make_foo, return_value_policy<manage_new_object>()) - class_<Foo>() + class_<Foo>("Foo") .def("get_x", &Foo::get_x) ; } diff --git a/doc/v2/reference_existing_object.html b/doc/v2/reference_existing_object.html index 59a47216..624bfc08 100644 --- a/doc/v2/reference_existing_object.html +++ b/doc/v2/reference_existing_object.html @@ -144,7 +144,7 @@ using namespace boost::python; BOOST_PYTHON_MODULE_INIT(singleton) { def("get_it", get_it, reference_existing_object()); - class_<Singleton>() + class_<Singleton>("Singleton") .def("exchange", &Singleton::exchange) ; } diff --git a/doc/v2/return_internal_reference.html b/doc/v2/return_internal_reference.html index 596ed2c6..f2b032a8 100644 --- a/doc/v2/return_internal_reference.html +++ b/doc/v2/return_internal_reference.html @@ -186,13 +186,12 @@ class Foo using namespace boost::python; BOOST_PYTHON_MODULE_INIT(internal_refs) { - class_<Bar>() + class_<Bar>("Bar") .def("get_x", &Bar::get_x) .def("set_x", &Bar::set_x) ; - class_<Foo>() - .def_init(args<int>()) + class_<Foo>("Foo", init<int>()) .def("get_bar", &Foo::get_bar , return_internal_reference<>()) ; diff --git a/doc/v2/return_value_policy.html b/doc/v2/return_value_policy.html index 88a72a0c..8f5d779d 100644 --- a/doc/v2/return_value_policy.html +++ b/doc/v2/return_value_policy.html @@ -1,89 +1,106 @@ - + + + + - Boost.Python - <boost/python/return_value_policy.hpp> + Boost.Python - + <boost/python/return_value_policy.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      -

      Header <boost/python/return_value_policy.hpp>

      +

      Header + <boost/python/return_value_policy.hpp>

      +

      Contents

      -
      Introduction +
      Introduction
      - -
      Classes +
      Classes
      -
      Class Template return_value_policy +
      Class Template + return_value_policy
      -
      Class Template - return_value_policy synopsis + return_value_policy synopsis
      +
      +
      - -
      Example +
      Example

      Introduction

      - - return_value_policy instantiations are simply models - of CallPolicies which are composed of a ResultConverterGenerator and optional Base CallPolicies. + return_value_policy instantiations are simply models of CallPolicies which are composed of a ResultConverterGenerator + and optional Base CallPolicies.

      Classes

      -

      Class template return_value_policy

      - +

      Class template + return_value_policy

      - - - + + + + + + + + + - - + +
      return_value_policy template parameters
      Parameter - - Requirements - - Default
      ResultConverterGenerator + ParameterRequirementsDefault
      ResultConverterGenerator A model of ResultConverterGenerator. + "ResultConverterGenerator.html">ResultConverterGenerator.
      Base + BaseA model of CallPolicies - - default_call_policies + A model of CallPoliciesdefault_call_policies
      -

      Class template return_value_policy synopsis

      +

      Class template + return_value_policy synopsis

       namespace boost { namespace python
       {
      @@ -97,9 +114,9 @@ namespace boost { namespace python
       
           

      Example

      -

      C++ Module Definition

      +

      C++ Module Definition

      -#include <boost/python/module.hpp>
      +#include <boost/python/module_init.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/copy_const_reference.hpp>
       #include <boost/python/return_value_policy.hpp>
      @@ -118,20 +135,16 @@ struct Foo {
       using namespace boost::python;
       BOOST_PYTHON_MODULE_INIT(my_module)
       {
      -   module("my_module")
      -      .add(
      -         class_<Bar>()
      -         )
      -      .add(
      -         class_<Foo>()
      -            .def_init(args<int>())
      -            .def("get_bar", &Foo::get_bar
      -                , return_value_policy<copy_const_reference>())
      -         )
      -       ;
      +   class_<Bar>("Bar");
      +
      +   class_<Foo>("Foo", init<int>())
      +      .def("get_bar", &Foo::get_bar
      +          , return_value_policy<copy_const_reference>())
      +      ;
       }
       
      -

      Python Code

      + +

      Python Code

       >>> from my_module import *
       >>> f = Foo(3)         # create a Foo object
      @@ -140,9 +153,13 @@ BOOST_PYTHON_MODULE_INIT(my_module)
       
           

      Revised - 15 February, 2002 + 15 February, 2002 +

      -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + diff --git a/doc/v2/to_python_converter.html b/doc/v2/to_python_converter.html index a2a985d8..f6682242 100644 --- a/doc/v2/to_python_converter.html +++ b/doc/v2/to_python_converter.html @@ -1,96 +1,114 @@ - + + + + - Boost.Python - <boost/python/to_python_converter.hpp> + Boost.Python - + <boost/python/to_python_converter.hpp> + + +
      -

      -

      +

      C++ Boost

      +

      Boost.Python

      -

      Header <boost/python/to_python_converter.hpp>

      +

      Header + <boost/python/to_python_converter.hpp>

      +

      Contents

      -
      Introduction +
      Introduction
      - -
      Classes +
      Classes
      -
      Class Template to_python_converter +
      Class Template + to_python_converter
      -
      Class Template - to_python_converter synopsis + to_python_converter synopsis
      Class Template - to_python_converter constructor + to_python_converter constructor
      +
      +
      -
      Example +
      Example

      Introduction

      - - to_python_converter registers a conversion from - objects of a given C++ type into a Python object. + to_python_converter registers a conversion from objects of a + given C++ type into a Python object.

      Classes

      -

      Class template to_python_converter

      - - to_python_converter adds a wrapper around a static - member function of its second template parameter, handling - low-level details such as insertion into the converter registry. +

      Class template + to_python_converter

      + to_python_converter adds a wrapper around a static member + function of its second template parameter, handling low-level details + such as insertion into the converter registry. - - - + + + + + + + + - + - - - + +
      to_python_converter template parameters
      -In the table below, x denotes an object of type T + In the table below, x denotes an object of type + T
      Parameter - - Requirements - - Description
      T + ParameterRequirementsDescription
      T + The C++ type of the source object in the conversion + The C++ type of the source object in the conversion
      Conversion + ConversionPyObject* p = Conversion::convert(x),
      - if p == 0, PyErr_Occurred() != 0. +
      + PyObject* p = Conversion::convert(x),
      + if p == 0, PyErr_Occurred() != 0.
      A class type whose static member function - convert does the real work of the conversion. - -
      A class type whose static member function convert + does the real work of the conversion.
      -

      Class template to_python_converter synopsis

      +

      Class template + to_python_converter synopsis

       namespace boost { namespace python
       {
      @@ -102,34 +120,31 @@ namespace boost { namespace python
       }}
       
      -

      Class template to_python_converter constructor

      +

      Class template + to_python_converter constructor

       to_python_converter();
       
      -
      Effects: Registers a to_python converter which uses - Conversion::convert() to do its work. - + Conversion::convert() to do its work.

      Example

      + This example presumes that someone has implemented the standard noddy example + module from the Python documentation, and placed the corresponding + declarations in "noddy.h". Because + noddy_NoddyObject is the ultimate trivial extension type, + the example is a bit contrived: it wraps a function for which all + information is contained in the type of its return value. -This example presumes that someone has implemented the standard noddy example -module from the Python documentation, and placed the corresponding -declarations in "noddy.h". Because -noddy_NoddyObject is the ultimate trivial extension type, -the example is a bit contrived: it wraps a function for which all -information is contained in the type of its return value. - -

      C++ module definition

      - +

      C++ module definition

       #include <boost/python/reference.hpp>
      -#include <boost/python/module.hpp>
      -#include "noddy.h"
      +#include <boost/python/module_init.hpp>
      +#include "noddy.h"
       
       struct tag {};
       tag make_tag() { return tag(); }
      @@ -146,15 +161,12 @@ struct tag_to_noddy
       
       BOOST_PYTHON_MODULE_INIT(to_python_converter)
       {
      -    module("to_python_converter")
      -        .def("make_tag", make_tag)
      -        ;
      +    def("make_tag", make_tag);
           to_python_converter<tag, tag_to_noddy>();
       }
       
      -

      Python code

      - +

      Python code

       >>> import to_python_converter
       >>> def always_none():
      @@ -180,10 +192,13 @@ BOOST_PYTHON_MODULE_INIT(to_python_converter)
       
           

      Revised - 05 November, 2001 + 29 September, 2002 +

      - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From 707ce53c1629e1ef5bbfe9268e41ee08e8f2a84b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 30 Sep 2002 03:35:53 +0000 Subject: [PATCH 0783/1042] Bugfix [SVN r15563] --- include/boost/python/numeric.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/python/numeric.hpp b/include/boost/python/numeric.hpp index d74aad06..c7563b09 100644 --- a/include/boost/python/numeric.hpp +++ b/include/boost/python/numeric.hpp @@ -10,6 +10,7 @@ # include # include # include +# include # include # include From 0e38aa7f372f9be4e89cc517839c85d63ab65fb6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 30 Sep 2002 16:52:57 +0000 Subject: [PATCH 0784/1042] doc updates [SVN r15571] --- doc/v2/ObjectWrapper.html | 155 ++++++++++++++++++++++++++++++++++++++ doc/v2/args.html | 103 +++++++++++++++++++++++++ doc/v2/class.html | 33 ++++---- doc/v2/faq.html | 108 +++++++++++++++++--------- 4 files changed, 348 insertions(+), 51 deletions(-) create mode 100644 doc/v2/ObjectWrapper.html create mode 100644 doc/v2/args.html diff --git a/doc/v2/ObjectWrapper.html b/doc/v2/ObjectWrapper.html new file mode 100644 index 00000000..c7d555cd --- /dev/null +++ b/doc/v2/ObjectWrapper.html @@ -0,0 +1,155 @@ + + + + + + + + + Boost.Python - ObjectWrapper Concept + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      ObjectWrapper and TypeWrapper Concepts

      +
      +
      + +
      +
      Introduction
      + +
      Concept Requirements
      + +
      +
      +
      ObjectWrapper Concept
      + +
      TypeWrapper Concept
      +
      +
      + +
      Caveat
      +
      + +

      Introduction

      + +

      This page defines two concepts used to describe classes which manage a + Python objects, and which are intended to support usage with a + Python-like syntax.

      + +

      Concept Requirements

      + +

      ObjectWrapper Concept

      + Models of the ObjectWrapper concept have object as a publicly-accessible base class, + and are used to supply special construction behavior and/or additional + convenient functionality through (often templated) member functions. + Except when the return type R is itself an TypeWrapper, a member function invocation of + the form +
      +x.some_function(a1, a2,...an)
      +
      + always has semantics equivalent to: +
      +extract<R>(x.attr("some_function")(object(a1), object(a2),...object(an)))()
      +
      + When the R is an TypeWrapper, the result type may be + constructed by taking direct posession of: +
      +x.attr("some_function")(object(a1), object(a2),...object(an)).ptr()
      +
      + [see caveat below] + +

      TypeWrapper Concept

      + TypeWrapper is a refinement of ObjectWrapper which is associated with a + particular Python type X. For a given TypeWrapper + T, a valid constructor expression +
      +T(a1, a2,...an)
      +
      + builds a new T object managing the result of invoking + X with arguments corresponding to +
      +object(a1), object(a2),...object(an)
      +
      + +When used as arguments to wrapped C++ functions, or as the template +parameter to extract<>, only +instances of the associated Python type will be considered a match. + +

      Caveat

      + The upshot of the special member function invocation rules when the + return type is a TypeWrapper is that it is possible for the returned + object to manage a Python object of an inappropriate type. This is not + usually a serious problem; the worst-case result is that errors will be + detected at runtime a little later than they might otherwise be. For an + example of how this can occur, note that the dict member function items + returns an object of type list. Now suppose the user defines this + dict subclass in Python: +
      +>>> class mydict(dict):
      +...     def items(self):
      +...         return tuple(dict.items(self)) # return a tuple
      +
      + Since an instance of mydict is also an instance of + dict, when used as an argument to a wrapped C++ function, + boost::python::dict can + accept objects of Python type mydict. Invoking + items() on this object can result in an instance of boost::python::list which actually + holds a Python tuple. Subsequent attempts to use list methods (e.g. + append, or any other mutating operation) on this object will + raise the same exception that would occur if you tried to do it from + Python. +
      + +

      Revised + + 30 Sept, 2002 +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + +

      Permission to copy, use, modify, sell and distribute this software is + granted provided this copyright notice appears in all copies. This + software is provided "as is" without express or implied warranty, and + with no claim as to its suitability for any purpose.

      + + + diff --git a/doc/v2/args.html b/doc/v2/args.html new file mode 100644 index 00000000..93443091 --- /dev/null +++ b/doc/v2/args.html @@ -0,0 +1,103 @@ + + + + + + + + + Boost.Python - <boost/python/args.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/args.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      keyword-expressions
      + +
      Functions
      + +
      +
      +
      args(...)
      +
      +
      + +
      Example(s)
      +
      +
      + +

      Introduction

      + +

      Supplies a family of overloaded functions for specifying argument + keywords for wrapped C++ functions.

      + +

      keyword-expressions

      + +

      A keyword-expression results in an object which holds a + sequence of ntbses, and whose type + encodes the number of keywords specified.

      + +

      Functions

      + +

      args(...)

      +
      +unspecified1 args(char const*);
      +unspecified2 args(char const*, char const*);
      +   .
      +   .
      +   .
      +unspecifiedN args(char const*, char const*, ... char const*);
      +
      + +
      +
      Requires: Every argument must be a ntbs.
      + +
      Returns: an object representing a keyword-expression encapsulating the + arguments passed.
      +
      + +

      Example

      +
      +#include <boost/python/def.hpp>
      +using namespace boost::python;
      +
      +int f(int x, int y, int z);
      +
      +BOOST_PYTHON_MODULE_INIT(xxx)
      +{
      +   def("f", f, args("x", "y", "z"));
      +}
      +
      + +

      Revised 05 November, 2001

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + diff --git a/doc/v2/class.html b/doc/v2/class.html index 240a1364..c66bf8dc 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -247,7 +247,7 @@ namespace boost { namespace python { template <class T - , class Bases = bases<> + , class Bases = bases<> , class HeldType = T , class NonCopyable = unspecified > @@ -742,23 +742,26 @@ template <class Policies> properties, used to describe a family of __init__ methods to be generated for an extension class: -
      -
      docstring: An ntbs whose - value will bound to the method's __doc__ attribute
      +
      +
      +
      docstring: An ntbs + whose value will bound to the method's __doc__ + attribute
      -
      keywords: A keyword-expression which will be - used to name (a trailing subset of) the arguments to the generated - __init__ function(s).
      +
      keywords: A keyword-expression which will be + used to name (a trailing subsequence of) the arguments to the generated + __init__ function(s).
      -
      call policies: An instance of a model of CallPolicies.
      +
      call policies: An instance of a model of CallPolicies.
      -
      argument types: An MPL sequence of C++ argument types which - will be used to construct the wrapped C++ object. An init expression - has one or more valid prefixes which are given by a sequence of - prefixes of its argument types.
      -
      +
      argument types: An MPL sequence of C++ argument types + which will be used to construct the wrapped C++ object. An init + expression has one or more valid prefixes which are given by a + sequence of prefixes of its argument types.
      +
      +

      Class template optional<T1 = unspecified, T2 = diff --git a/doc/v2/faq.html b/doc/v2/faq.html index 78a3940f..8e8be4e5 100644 --- a/doc/v2/faq.html +++ b/doc/v2/faq.html @@ -1,39 +1,75 @@ + + - - - -Boost.Python - FAQ - - - + + + + + Boost.Python - FAQ + + + +
      - - - - -
      -

      -

      -
      -

      Boost.Python

      -

      Frequently Asked Questions (FAQs)

      -
      -
      -
      -
      {{question}}
      -
      {{question}}
      -
      -

      {{question}}

      -

      {{answer}}

      -

      {{question}}

      -

      {{answer}}

      -
      -

      Revised - - 05 November, 2002 - -

      -

      © Copyright Dave Abrahams - 2002. All Rights Reserved.

      - + + +

      C++ Boost

      + + + +

      Boost.Python

      + +

      Frequently Asked Questions (FAQs)

      + + + +
      + +
      +
      {{question}}
      + +
      {{question}}
      +
      + +

      Is return_internal reference efficient?

      + +
      + Q: I have an object composed of 12 doubles. A const& to this object is + returned by a member function of another class. From the viewpoint of + using the returned object in Python I do not care if I get a copy or a + reference to the returned object. In Boost.Python Version 2 I have the + choice of using copy_const_reference or return_internal_reference. Are + there considerations that would lead me to prefer one over the other, + such as size of generated code or memory overhead? + +

      A: copy_const_reference will make an instance with storage for one of + your objects, size = base_size + 12 * sizeof(double). + return_internal_reference will make an instance with storage for a + pointer to one of your objects, size = base_size + sizeof(void*). + However, it will also create a weak reference object which goes in the + source object's weakreflist and a special callback object to manage the + lifetime of the internally-referenced object. My guess? + copy_const_reference is your friend here, resulting in less overall + memory use and less fragmentation, also probably fewer total cycles.

      +
      + +

      {{question}}

      + +

      {{answer}}

      +
      + +

      Revised + + 05 November, 2002 + +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From a06430c5faf6562c9a0431e5589f62f4ba0cacb8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 30 Sep 2002 17:40:47 +0000 Subject: [PATCH 0785/1042] doc updates [SVN r15573] --- doc/v2/dict.html | 150 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 doc/v2/dict.html diff --git a/doc/v2/dict.html b/doc/v2/dict.html new file mode 100644 index 00000000..ee38c2bc --- /dev/null +++ b/doc/v2/dict.html @@ -0,0 +1,150 @@ + + + + + + + + + Boost.Python - <boost/python/dict.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/dict.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Classes
      + +
      +
      +
      Class dict
      + +
      +
      +
      Class dict + synopsis
      +
      +
      +
      +
      + +
      Example(s)
      +
      +
      + +

      Introduction

      + +

      Exposes a TypeWrapper for the Python + dict + type.

      + +

      Classes

      + +

      Class dict

      + +

      Exposes the mapping + protocol of Python's built-in dict type. The semantics + of the constructors and member functions defined below can be fully + understood by reading the TypeWrapper concept + definition. Since dict is publicly derived from object, the public object + interfaceapplies to dict instances as well.

      + +

      Class dict + synopsis

      +
      +namespace boost
      +{
      +   class dict : public object
      +   {
      +      dict() ;
      +
      +      template< class T >
      +      dict(T const & data) ;
      +
      +      // modifiers
      +      void clear();
      +      dict copy();
      +
      +      template <class T1, class T2>
      +      tuple popitem();
      +
      +      template <class T>
      +      object setdefault(T const &k);
      +
      +      template <class T1, class T2>
      +      object setdefault(T1 const & k, T2 const & d);
      +
      +      void update(object_cref E);
      + 
      +      template< class T >
      +      void update(T const & E);
      +
      +      // observers
      +      list values() const;
      +    
      +      object get(object_cref k) const;
      +
      +      template<class T>
      +      object get(T const & k) const;
      +
      +      object get(object_cref k, object_cref d) const;
      +      object get(T1 const & k, T2 const & d) const;
      +
      +      bool has_key(object_cref k) const;
      +
      +      template< class T >
      +      bool has_key(T const & k) const;
      +
      +      list items() const;
      +      object iteritems() const;
      +      object iterkeys() const;
      +      object itervalues() const;
      +      list keys() const;
      +  };
      +};
      +
      + +

      Example

      +
      +using namespace boost::python;
      +dict swap_object_dict(object target, dict d)
      +{
      +    dict result = extract<dict>(target.attr("__dict__"));
      +    target.attr("__dict__") = d;
      +    return result;
      +}
      +
      + +

      Revised 30 September, 2002

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From 77b1b247c47db3e3060dae679eeee49b1a6f3e84 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 30 Sep 2002 22:05:20 +0000 Subject: [PATCH 0786/1042] doc updates [SVN r15577] --- doc/v2/exception_translator.html | 143 +++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 doc/v2/exception_translator.html diff --git a/doc/v2/exception_translator.html b/doc/v2/exception_translator.html new file mode 100644 index 00000000..9178d05c --- /dev/null +++ b/doc/v2/exception_translator.html @@ -0,0 +1,143 @@ + + + + + + + + + Boost.Python - + <boost/python/exception_translator.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header + <boost/python/exception_translator.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Functions
      + +
      +
      +
      register_exception_translator
      +
      +
      + +
      Example(s)
      +
      +
      + +

      Introduction

      + +

      As described here, it + is important to make sure that exceptions thrown by C++ code do not pass + into the Python interpreter core. By default, Boost.Python translates all + C++ exceptions thrown by wrapped functions and module init functions into + Python, but the default translators are extremely limited: most C++ + exceptions will appear in Python as a RuntimeError + exception whose representation is + 'Unidentifiable C++ Exception'. To produce better + error messages, users can register additional exception translators as + described below.

      + +

      Functions

      +
      +template<class ExceptionType, class Translate>
      +void register_exception_translator(Translate const& translate);
      +
      + +
      +
      Requires:
      + +
      + Translate is Copyconstructible, and + the following code is well-formed: +
      +void f(ExceptionType x) { translate(x); }
      +
      + The expression translate(x) must either throw a C++ + exception, or a subsequent call to PyErr_Occurred() + must return 1. +
      + +
      Effects: Adds a copy of translate to the sequence of + exception translators tried when Boost.Python catches an exception that + is about to pass into Python's core interpreter. The new translator + will get "first shot" at translating all exceptions matching the catch + clause shown above. Any subsequently-registered translators will be + allowed to translate the exception earlier. A translator which cannot + translate a given C++ exception can re-throw it, and it will be handled + by a translator which was registered earlier (or by the default + translator).
      +
      + +

      Example

      +
      +#include <boost/python/module_init.hpp>
      +#include <boost/python/def.hpp>
      +#include <boost/python/exception_translator.hpp>
      +#include <exception>
      +
      +struct my_exception : std::exception
      +{
      +  char const* what() throw() { return "One of my exceptions"; }
      +};
      +
      +void translate(my_exception const& e)
      +{
      +    // Use the Python 'C' API to set up an exception object
      +    PyErr_SetString(PyExc_RuntimeError, e.what());
      +}
      +
      +void something_which_throws()
      +{
      +    ...
      +    throw my_exception();
      +    ...
      +}
      +
      +BOOST_PYTHON_MODULE_INIT(exception_translator_ext)
      +{
      +  using namespace boost::python;
      +  register_exception_translator<my_exception>(&translate);
      +  
      +  def("something_which_throws", something_which_throws);
      +}
      +
      +
      +
      + +
      + +

      Revised 30 September, 2002

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From 61b528c85d545eb50647252c4914189517fc25df Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Oct 2002 01:16:25 +0000 Subject: [PATCH 0787/1042] doc update [SVN r15593] --- doc/v2/extract.html | 230 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 doc/v2/extract.html diff --git a/doc/v2/extract.html b/doc/v2/extract.html new file mode 100644 index 00000000..8c61be29 --- /dev/null +++ b/doc/v2/extract.html @@ -0,0 +1,230 @@ + + + + + + + + + Boost.Python - <boost/python/extract.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/extract.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Classes
      + +
      +
      +
      Class extract
      + +
      +
      +
      Class extract + synopsis
      + +
      Class extract + constructors and destructor
      + +
      Class + extract observer functions
      +
      +
      +
      +
      + + +
      Example
      +
      +
      + +

      Introduction

      + +

      Exposes a mechanism for extracting C++ object values from + generalized Python objects. Note that + extract<...> can also be used to + "downcast" an object to some specific ObjectWrapper. Because + invoking a mutable python type with an argument of the same type + (e.g. list([1,2]) typically makes a copy of + the argument object, this may be the only way to access the ObjectWrapper's + interface on the original object. + +

      Classes

      + +

      Class template extract

      + +

      extract<T> can be used to extract a value of + an arbitrary C++ type from an instance of object. Two usages are supported: +

        +
      1. extract<T>(o) is a temporary object +which is implicitly convertible to T (explicit conversion +is also available through the object's function-call +operator). However, if no conversion is available which can convert +o to an object of type T, a Python +TypeError exception will be raised. + +
      2. extract<T> x(o); constructs an extractor +whose check() member function can be used to ask whether +a conversion is available without causing an exception to be thrown. +
      + +

      Class template extract + synopsis

      +
      +namespace boost
      +{
      +template <class T>
      +struct extract
      +{
      +    typedef unspecified result_type;
      +    
      +    extract(PyObject*);
      +    extract(object const&);
      +
      +    result_type operator()() const;
      +    operator result_type() const;
      +    
      +    bool check() const;
      +};
      +};
      +
      + +

      Class extract + constructors and destructor

      +
      +extract(PyObject* p);
      +extract(object const&);
      +
      + +
      +
      Requires: The first form requires that p is non-null.
      + +
      Effects:Stores a pointer to the Python object managed + by its constructor argument. In particular, the reference + count of the object is not incremented. The onus is on the user + to be sure it is not destroyed before the extractor's conversion + function is called.
      +
      + +

      Class extract + observer functions

      +
      +result_type operator()() const;
      +operator result_type() const;
      +
      + +
      +
      Effects: Converts the stored pointer to + result_type, which is either T or + T const&. +
      + +
      Returns: An object of result_type + corresponding to the one referenced by the stored pointer.
      + +
      Throws: error_already_set + and sets a TypeError if no such conversion is + available. May also emit other unspecified exceptions thrown by + the converter which is actually used.
      +
      + +
      +bool check() const;
      +
      + +
      + +
      Postconditions: None. In particular, note that a + return value of true does not preclude an exception + being thrown from operator result_type() or + operator()().
      + +
      Returns: false only if no conversion from the + stored pointer to T is available.
      + +
      + + +

      Examples

      + +
      +#include <cstdio>
      +using namespace boost::python;
      +int Print(str s)
      +{ 
      +   // extract a C string from the Python string object
      +   char const* c_str = extract<char const*>(s);
      +
      +   // Print it using printf
      +   std::printf("%s\n", c_str);
      +
      +   // Get the Python string's length and convert it to an int
      +   return extract<int>(s.attr("__len__")())
      +}
      +
      + +The following example shows how extract can be used along with +class_<...> +to create and access an instance of a wrapped C++ class. + +
      +struct X
      +{
      +   X(int x) : v(x) {}
      +   int value() { return v; }
      + private:
      +   int v;
      +};
      +
      +BOOST_PYTHON_MODULE_INIT(extract_ext)
      +{
      +    object x_class(
      +       class_<X>("X", init<int>())
      +          .def("value", &X::value))
      +          ;
      +        
      +    // Instantiate an X object through the Python interface. 
      +    // Its lifetime is now managed by x_obj.
      +    object x_obj = x_class(3);
      +
      +    // Get a reference to the C++ object out of the Python object
      +    X const& x = extract<X&>(x_obj);
      +    assert(x.value() == 3);
      +}
      +
      +

      Revised 30 September, 2002

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From fa7b1404c1d08f47c297fb733fd0e3c5b6d78654 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Oct 2002 03:44:51 +0000 Subject: [PATCH 0788/1042] Bugfix [SVN r15595] --- include/boost/python/detail/defaults_gen.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 6106ce54..14fe7052 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -211,7 +211,7 @@ namespace detail { \ typedef typename ::boost::python::detail:: \ error::more_keywords_than_function_arguments< \ - Keywords::size,(n_args+n_dflts)>::too_many_keywords assertion; \ + Keywords::size,n_args>::too_many_keywords assertion; \ } \ template \ fstubs_name(Keywords const& keywords, char const* doc = 0) \ @@ -220,7 +220,7 @@ namespace detail { \ typedef typename ::boost::python::detail:: \ error::more_keywords_than_function_arguments< \ - Keywords::size,(n_args+n_dflts)>::too_many_keywords assertion; \ + Keywords::size,n_args>::too_many_keywords assertion; \ } # if defined(BOOST_NO_VOID_RETURNS) From 65ce6ddf1daf7d9dc19d25a1e47cf99b6359d956 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Oct 2002 03:45:33 +0000 Subject: [PATCH 0789/1042] doc update [SVN r15596] --- doc/v2/class.html | 29 +++++++++++++++-------------- doc/v2/definitions.html | 13 ++++++++++++- doc/v2/extract.html | 2 +- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/doc/v2/class.html b/doc/v2/class.html index c66bf8dc..d2e2d032 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -247,7 +247,7 @@ namespace boost { namespace python { template <class T - , class Bases = bases<> + , class Bases = bases<> , class HeldType = T , class NonCopyable = unspecified > @@ -319,7 +319,7 @@ class_(char const* name, char const* docstring, Init init_spec);
      -
      Requires: name is a Requires: name is an ntbs which conforms to Python's identifier naming rules. If docstring is supplied, it must be an @@ -404,7 +404,7 @@ class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3
      -
      Requires: name is a Requires: name is an ntbs which conforms to Python's identifier naming rules.
      @@ -414,8 +414,9 @@ class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3
    • If a1 is the result of an overload-dispatch-expression, - only the second is allowed and fn must be a pointer to [member] - function whose signature is compatible with A1. + only the second is allowed and fn must be a pointer to + function or pointer to member function whose signature is + compatible with A1.
      Effects: For each
      -
      Requires: name is a ntbs which conforms to - Python's Requires: name is an ntbs which conforms to Python's identifier naming rules.
      @@ -554,8 +555,8 @@ void add_property(char const* name, Get const& fget, Set const& fset);
    • -
      Requires: name is a ntbs which conforms to - Python's Requires: name is an ntbs which conforms to Python's identifier naming rules.
      @@ -580,8 +581,8 @@ class_& def_readonly(char const* name, D T::*pm);
      -
      Requires: name is a ntbs which conforms to - Python's Requires: name is an ntbs which conforms to Python's identifier naming rules.
      @@ -733,7 +734,7 @@ template <class Policies>
      Effects: Returns a new init-expression with all the same properties as the init object except that its - callpolicies are replaced by a reference to + call policies are replaced by a reference to policies.
      @@ -750,8 +751,8 @@ template <class Policies>
      keywords: A keyword-expression which will be - used to name (a trailing subsequence of) the arguments to the generated - __init__ function(s).
      + used to name (a trailing subsequence of) the arguments to the + generated __init__ function(s).
      call policies: An instance of a model of CallPolicies.
      diff --git a/doc/v2/definitions.html b/doc/v2/definitions.html index 4969f977..5c21e86e 100644 --- a/doc/v2/definitions.html +++ b/doc/v2/definitions.html @@ -37,12 +37,23 @@
      ntbs: Null-Terminated Byte String, or `C'-string. C++ string literals are ntbses. An ntbs must never be null.
      + +
      raise: Exceptions in Python are + "raised", not "thrown", as they are in + C++. When this documentation says that some Python exception is + "raised" in the context of C++ code, it means that the + corresponding Python exception is set via the Python/'C' + API, and throw_error_already_set() + is called.
      +

      Revised - 28 September, 2002 + 30 September, 2002

      diff --git a/doc/v2/extract.html b/doc/v2/extract.html index 8c61be29..98d52d69 100644 --- a/doc/v2/extract.html +++ b/doc/v2/extract.html @@ -192,7 +192,7 @@ int Print(str s) The following example shows how extract can be used along with class_<...> +href="class.html#class_-spec">class_<...> to create and access an instance of a wrapped C++ class.
      
      From c6cba55667281c888bd91574153c66dd64ab67e4 Mon Sep 17 00:00:00 2001
      From: Joel de Guzman 
      Date: Tue, 1 Oct 2002 03:55:54 +0000
      Subject: [PATCH 0790/1042] Placed the non-void and void stub structs inside
       the main stub struct.
      
      [SVN r15597]
      ---
       include/boost/python/detail/defaults_gen.hpp | 40 ++++++++++----------
       1 file changed, 19 insertions(+), 21 deletions(-)
      
      diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp
      index 14fe7052..d879da19 100644
      --- a/include/boost/python/detail/defaults_gen.hpp
      +++ b/include/boost/python/detail/defaults_gen.hpp
      @@ -50,7 +50,7 @@ namespace detail
             {
                 return m_keywords;
             }
      -      
      +
          private:
             char const* m_doc;
             detail::keyword_range m_keywords;
      @@ -226,53 +226,51 @@ namespace detail
       # if defined(BOOST_NO_VOID_RETURNS)
       
       #  define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts)   \
      -    BOOST_PYTHON_GEN_FUNCTION(                                                  \
      -        fname, BOOST_PP_CAT(fstubs_name, NonVoid), n_args, n_dflts, return)     \
      -    BOOST_PYTHON_GEN_FUNCTION(                                                  \
      -        fname, BOOST_PP_CAT(fstubs_name, Void), n_args, n_dflts, ;)             \
           struct fstubs_name                                                          \
               : public ::boost::python::detail::overloads_common         \
           {                                                                           \
      -        typedef BOOST_PP_CAT(fstubs_name, NonVoid)  non_void_return_type;       \
      -        typedef BOOST_PP_CAT(fstubs_name, Void)   void_return_type;             \
      +        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)       \
      -    BOOST_PYTHON_GEN_MEM_FUNCTION(                                                      \
      -        fname, BOOST_PP_CAT(fstubs_name, NonVoid), n_args, n_dflts, return)             \
      -    BOOST_PYTHON_GEN_MEM_FUNCTION(                                                      \
      -        fname, BOOST_PP_CAT(fstubs_name, Void), n_args, n_dflts, ;)                     \
           struct fstubs_name                                                                  \
               : public ::boost::python::detail::overloads_common                 \
           {                                                                                   \
      -        typedef BOOST_PP_CAT(fstubs_name, NonVoid)  non_void_return_type;               \
      -        typedef BOOST_PP_CAT(fstubs_name, Void)   void_return_type;                     \
      +        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, n_dflts)                \
           };
       
       # else // !defined(BOOST_NO_VOID_RETURNS)
       
       #  define BOOST_PYTHON_GEN_FUNCTION_STUB(fname, fstubs_name, n_args, n_dflts)   \
      -    BOOST_PYTHON_GEN_FUNCTION(                                                  \
      -        fname, BOOST_PP_CAT(fstubs_name, NonVoid), n_args, n_dflts, return)     \
           struct fstubs_name                                                          \
               : public ::boost::python::detail::overloads_common         \
           {                                                                           \
      -        typedef BOOST_PP_CAT(fstubs_name, NonVoid)  non_void_return_type;       \
      -        typedef BOOST_PP_CAT(fstubs_name, NonVoid)  void_return_type;           \
      +        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)       \
      -    BOOST_PYTHON_GEN_MEM_FUNCTION(                                                      \
      -        fname, BOOST_PP_CAT(fstubs_name, NonVoid), n_args, n_dflts, return)             \
           struct fstubs_name                                                                  \
               : public ::boost::python::detail::overloads_common                 \
           {                                                                                   \
      -        typedef BOOST_PP_CAT(fstubs_name, NonVoid)  non_void_return_type;               \
      -        typedef BOOST_PP_CAT(fstubs_name, NonVoid)  void_return_type;                   \
      +        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, n_dflts)                \
           };
       
      
      From 5cd513859dcf03babb2b2c914dba03fcd964c264 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Tue, 1 Oct 2002 14:40:41 +0000
      Subject: [PATCH 0791/1042] separate overloads.hpp BOOST_PYTHON_MODULE_INIT ->
       BOOST_PYTHON_MODULE
      
      [SVN r15609]
      ---
       doc/v2/args.html                             |  2 +-
       doc/v2/call_method.html                      |  4 +-
       doc/v2/copy_const_reference.html             |  4 +-
       doc/v2/copy_non_const_reference.html         |  4 +-
       doc/v2/data_members.html                     |  2 +-
       doc/v2/exception_translator.html             |  4 +-
       doc/v2/extract.html                          |  2 +-
       doc/v2/has_back_reference.html               |  4 +-
       doc/v2/implicit.html                         |  4 +-
       doc/v2/iterator.html                         |  4 +-
       doc/v2/lvalue_from_pytype.html               |  4 +-
       doc/v2/make_function.html                    |  4 +-
       doc/v2/manage_new_object.html                |  4 +-
       doc/v2/module.html                           | 10 +-
       doc/v2/operators.html                        |  4 +-
       doc/v2/reference_existing_object.html        |  4 +-
       doc/v2/return_internal_reference.html        |  4 +-
       doc/v2/return_value_policy.html              |  4 +-
       doc/v2/to_python_converter.html              |  4 +-
       include/boost/python/class.hpp               | 11 ++-
       include/boost/python/def.hpp                 |  2 +-
       include/boost/python/detail/defaults_def.hpp |  2 +-
       include/boost/python/init.hpp                |  2 +
       include/boost/python/module.hpp              | 99 +-------------------
       src/aix_init_module.cpp                      |  2 +-
       test/args.cpp                                |  5 +-
       test/back_reference.cpp                      |  4 +-
       test/bienstman1.cpp                          |  4 +-
       test/bienstman2.cpp                          |  4 +-
       test/bienstman3.cpp                          |  4 +-
       test/bienstman4.cpp                          |  4 +-
       test/bienstman5.cpp                          |  4 +-
       test/callbacks.cpp                           |  4 +-
       test/cltree.cpp                              |  4 +-
       test/comprehensive.cpp                       |  2 +-
       test/data_members.cpp                        |  4 +-
       test/defaults.cpp                            | 12 +--
       test/dict.cpp                                |  4 +-
       test/docstring.cpp                           |  4 +-
       test/enum.cpp                                |  4 +-
       test/exception_translator.cpp                |  4 +-
       test/extract.cpp                             |  4 +-
       test/implicit.cpp                            |  4 +-
       test/input_iterator.cpp                      |  4 +-
       test/iterator.cpp                            |  4 +-
       test/list.cpp                                |  4 +-
       test/long.cpp                                |  4 +-
       test/m1.cpp                                  |  4 +-
       test/m2.cpp                                  |  4 +-
       test/minimal.cpp                             |  4 +-
       test/multi_arg_constructor.cpp               |  4 +-
       test/nested.cpp                              |  4 +-
       test/numpy.cpp                               |  4 +-
       test/object.cpp                              |  4 +-
       test/operators.cpp                           |  4 +-
       test/pickle1.cpp                             |  4 +-
       test/pickle2.cpp                             |  4 +-
       test/pickle3.cpp                             |  4 +-
       test/str.cpp                                 |  4 +-
       test/submod_subclass_api.cpp                 |  6 +-
       test/test_builtin_converters.cpp             |  4 +-
       test/test_pointer_adoption.cpp               |  4 +-
       test/tuple.cpp                               |  4 +-
       test/virtual_functions.cpp                   |  4 +-
       64 files changed, 130 insertions(+), 229 deletions(-)
      
      diff --git a/doc/v2/args.html b/doc/v2/args.html
      index 93443091..1cff40a8 100644
      --- a/doc/v2/args.html
      +++ b/doc/v2/args.html
      @@ -87,7 +87,7 @@ using namespace boost::python;
       
       int f(int x, int y, int z);
       
      -BOOST_PYTHON_MODULE_INIT(xxx)
      +BOOST_PYTHON_MODULE(xxx)
       {
          def("f", f, args("x", "y", "z"));
       }
      diff --git a/doc/v2/call_method.html b/doc/v2/call_method.html
      index e5cf7e6b..86f6c9d5 100644
      --- a/doc/v2/call_method.html
      +++ b/doc/v2/call_method.html
      @@ -85,7 +85,7 @@ R call_method(PyObject* self, char const* method, A1 const&, A2 const&,
       
           

      C++ Module Definition

      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
       #include <boost/utility.hpp>
       #include <cstring>
      @@ -119,7 +119,7 @@ class Base_callback : public Base
       };
       
       using namespace boost::python;
      -BOOST_PYTHON_MODULE_INIT(my_module)
      +BOOST_PYTHON_MODULE(my_module)
       {
           def("is_base", is_base);
       
      diff --git a/doc/v2/copy_const_reference.html b/doc/v2/copy_const_reference.html
      index 41a9b9ab..a014ee28 100644
      --- a/doc/v2/copy_const_reference.html
      +++ b/doc/v2/copy_const_reference.html
      @@ -98,7 +98,7 @@ template <class T> struct apply
       
           

      C++ Module Definition

      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/copy_const_reference.hpp>
       #include <boost/python/return_value_policy.hpp>
      @@ -115,7 +115,7 @@ struct Foo {
       
       // Wrapper code
       using namespace boost::python;
      -BOOST_PYTHON_MODULE_INIT(my_module)
      +BOOST_PYTHON_MODULE(my_module)
       {
           class_<Bar>("Bar");
       
      diff --git a/doc/v2/copy_non_const_reference.html b/doc/v2/copy_non_const_reference.html
      index 0169fff1..ac796a21 100644
      --- a/doc/v2/copy_non_const_reference.html
      +++ b/doc/v2/copy_non_const_reference.html
      @@ -99,7 +99,7 @@ template <class T> struct apply
       
           

      C++ code:

      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/copy_non_const_reference.hpp>
       #include <boost/python/return_value_policy.hpp>
      @@ -116,7 +116,7 @@ struct Foo {
       
       // Wrapper code
       using namespace boost::python;
      -BOOST_PYTHON_MODULE_INIT(my_module)
      +BOOST_PYTHON_MODULE(my_module)
       {
           class_<Bar>("Bar");
       
      diff --git a/doc/v2/data_members.html b/doc/v2/data_members.html
      index eabf8183..5ec6ff01 100644
      --- a/doc/v2/data_members.html
      +++ b/doc/v2/data_members.html
      @@ -115,7 +115,7 @@ template <class C, class D, class Policies>
           member as functions:

       #include <boost/python/data_members.hpp>
      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
       
       struct X
      diff --git a/doc/v2/exception_translator.html b/doc/v2/exception_translator.html
      index 9178d05c..407ff95d 100644
      --- a/doc/v2/exception_translator.html
      +++ b/doc/v2/exception_translator.html
      @@ -97,7 +97,7 @@ void f(ExceptionType x) { translate(x); }
       
           

      Example

      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/def.hpp>
       #include <boost/python/exception_translator.hpp>
       #include <exception>
      @@ -120,7 +120,7 @@ void something_which_throws()
           ...
       }
       
      -BOOST_PYTHON_MODULE_INIT(exception_translator_ext)
      +BOOST_PYTHON_MODULE(exception_translator_ext)
       {
         using namespace boost::python;
         register_exception_translator<my_exception>(&translate);
      diff --git a/doc/v2/extract.html b/doc/v2/extract.html
      index 98d52d69..5ce2aec2 100644
      --- a/doc/v2/extract.html
      +++ b/doc/v2/extract.html
      @@ -204,7 +204,7 @@ struct X
          int v;
       };
       
      -BOOST_PYTHON_MODULE_INIT(extract_ext)
      +BOOST_PYTHON_MODULE(extract_ext)
       {
           object x_class(
              class_<X>("X", init<int>())
      diff --git a/doc/v2/has_back_reference.html b/doc/v2/has_back_reference.html
      index 7e3a8609..0a2f54ce 100644
      --- a/doc/v2/has_back_reference.html
      +++ b/doc/v2/has_back_reference.html
      @@ -111,7 +111,7 @@ namespace boost { namespace python
           

      C++ module definition

       #include <boost/python/class.hpp>
      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/has_back_reference.hpp>
       #include <boost/python/handle.hpp>
       #include <boost/shared_ptr.hpp>
      @@ -153,7 +153,7 @@ struct Y
       
       boost::shared_ptr<Y> Y_self(boost::shared_ptr<Y> self) const { return self; }
       
      -BOOST_PYTHON_MODULE_INIT(back_references)
      +BOOST_PYTHON_MODULE(back_references)
       {
           class_<X>("X")
              .def(init<int>())
      diff --git a/doc/v2/implicit.html b/doc/v2/implicit.html
      index aebe2b52..ea24c567 100644
      --- a/doc/v2/implicit.html
      +++ b/doc/v2/implicit.html
      @@ -103,7 +103,7 @@ void implicitly_convertible();
       
       #include <boost/python/class.hpp>
       #include <boost/python/implicit.hpp>
      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       
       using namespace boost::python;
       
      @@ -121,7 +121,7 @@ int x_value(X const& x)
       
       X make_x(int n) { return X(n); }
       
      -BOOST_PYTHON_MODULE_INIT(implicit_ext)
      +BOOST_PYTHON_MODULE(implicit_ext)
       {
           def("x_value", x_value);
           def("make_x", make_x);
      diff --git a/doc/v2/iterator.html b/doc/v2/iterator.html
      index 3388d913..03d0cb00 100644
      --- a/doc/v2/iterator.html
      +++ b/doc/v2/iterator.html
      @@ -355,13 +355,13 @@ template <class Accessor1, class Accessor2>
       
           

      Examples

      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
       
       #include <vector>
       
       using namespace boost::python;
      -BOOST_PYTHON_MODULE_INIT(demo)
      +BOOST_PYTHON_MODULE(demo)
       {
           class_<std::vector<double> >("dvec")
               .def("__iter__", iterator<std::vector<double> >())
      diff --git a/doc/v2/lvalue_from_pytype.html b/doc/v2/lvalue_from_pytype.html
      index 57997b3a..74b18f06 100755
      --- a/doc/v2/lvalue_from_pytype.html
      +++ b/doc/v2/lvalue_from_pytype.html
      @@ -239,7 +239,7 @@ static MemberType& execute(InstanceType& c);
           

      C++ module definition

       #include <boost/python/reference.hpp>
      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       
       // definition lifted from the Python docs
       typedef struct {
      @@ -259,7 +259,7 @@ void set_cache(noddy_NoddyObject* x)
          cache.reset((PyObject*)x, ref::increment_count);
       }
       
      -BOOST_PYTHON_MODULE_INIT(noddy_cache)
      +BOOST_PYTHON_MODULE(noddy_cache)
       {
          def("is_cached", is_cached);
          def("set_cache", set_cache);
      diff --git a/doc/v2/make_function.html b/doc/v2/make_function.html
      index 0d7bb689..080f95c7 100644
      --- a/doc/v2/make_function.html
      +++ b/doc/v2/make_function.html
      @@ -138,7 +138,7 @@ template <class ArgList, class Generator, class Policies>
           two functions.

       #include <boost/python/make_function.hpp>
      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       
       char const* foo() { return "foo"; }
       char const* bar() { return "bar"; }
      @@ -152,7 +152,7 @@ object choose_function(bool selector)
               return boost::python::make_function(bar);
       }
       
      -BOOST_PYTHON_MODULE_INIT(make_function_test)
      +BOOST_PYTHON_MODULE(make_function_test)
       {
           def("choose_function", choose_function);
       }
      diff --git a/doc/v2/manage_new_object.html b/doc/v2/manage_new_object.html
      index f6b6168d..c76a3a4d 100644
      --- a/doc/v2/manage_new_object.html
      +++ b/doc/v2/manage_new_object.html
      @@ -97,7 +97,7 @@ template <class T> struct apply
       
           

      In C++:

      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/manage_new_object.hpp>
       #include <boost/python/return_value_policy.hpp>
      @@ -113,7 +113,7 @@ Foo* make_foo(int x) { return new Foo(x); }
       
       // Wrapper code
       using namespace boost::python;
      -BOOST_PYTHON_MODULE_INIT(my_module)
      +BOOST_PYTHON_MODULE(my_module)
       {
           def("make_foo", make_foo, return_value_policy<manage_new_object>())
           class_<Foo>("Foo")
      diff --git a/doc/v2/module.html b/doc/v2/module.html
      index 3685934c..4b3017bc 100644
      --- a/doc/v2/module.html
      +++ b/doc/v2/module.html
      @@ -29,7 +29,7 @@
             
      BOOST_PYTHON_MODULE_INIT + "#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE
      Classes @@ -66,7 +66,7 @@

      Macros

      BOOST_PYTHON_MODULE_INIT(name) + "BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE(name) is used to declare Python module initialization functions. The name argument must @@ -81,7 +81,7 @@ void initname()

      Boost.Python modules should be initialized with
      -BOOST_PYTHON_MODULE_INIT(name)
      +BOOST_PYTHON_MODULE(name)
       {
          ...
       
      @@ -134,7 +134,7 @@ module(const char* name);
      Requires: name is a ntbs whose value matches the argument passed to BOOST_PYTHON_MODULE_INIT. + "#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE.
      Effects: Creates a module object representing a Python module named name. @@ -238,7 +238,7 @@ char const* greet() return "hello, Boost.Python!"; } -BOOST_PYTHON_MODULE_INIT(boost_greet) +BOOST_PYTHON_MODULE(boost_greet) { module("boost_greet") .def("greet", greet); diff --git a/doc/v2/operators.html b/doc/v2/operators.html index 6a551b92..307e949b 100755 --- a/doc/v2/operators.html +++ b/doc/v2/operators.html @@ -809,7 +809,7 @@ namespace boost { namespace python

      Example

      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/operators.hpp>
       #include <boost/operators.hpp>
      @@ -836,7 +836,7 @@ struct number
       };
       
       using namespace boost::python;
      -BOOST_PYTHON_MODULE_INIT(demo)
      +BOOST_PYTHON_MODULE(demo)
       {
          class_<number>("number")
             // interoperate with self
      diff --git a/doc/v2/reference_existing_object.html b/doc/v2/reference_existing_object.html
      index 624bfc08..88016dd8 100644
      --- a/doc/v2/reference_existing_object.html
      +++ b/doc/v2/reference_existing_object.html
      @@ -113,7 +113,7 @@ template <class T> struct apply
       
           

      In C++:

      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/reference_existing_object.hpp>
       #include <boost/python/return_value_policy.hpp>
      @@ -141,7 +141,7 @@ Singleton& get_it()
       
       // Wrapper code
       using namespace boost::python;
      -BOOST_PYTHON_MODULE_INIT(singleton)
      +BOOST_PYTHON_MODULE(singleton)
       {
           def("get_it", get_it, reference_existing_object());
           class_<Singleton>("Singleton")
      diff --git a/doc/v2/return_internal_reference.html b/doc/v2/return_internal_reference.html
      index f2b032a8..79c60abb 100644
      --- a/doc/v2/return_internal_reference.html
      +++ b/doc/v2/return_internal_reference.html
      @@ -158,7 +158,7 @@ PyObject* postcall(PyObject* args, PyObject* result);
       
           

      C++ module definition

      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/return_internal_reference.hpp>
       
      @@ -184,7 +184,7 @@ class Foo
       };
       
       using namespace boost::python;
      -BOOST_PYTHON_MODULE_INIT(internal_refs)
      +BOOST_PYTHON_MODULE(internal_refs)
       {
          class_<Bar>("Bar")
             .def("get_x", &Bar::get_x)
      diff --git a/doc/v2/return_value_policy.html b/doc/v2/return_value_policy.html
      index 8f5d779d..1482d6e8 100644
      --- a/doc/v2/return_value_policy.html
      +++ b/doc/v2/return_value_policy.html
      @@ -116,7 +116,7 @@ namespace boost { namespace python
       
           

      C++ Module Definition

      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include <boost/python/class.hpp>
       #include <boost/python/copy_const_reference.hpp>
       #include <boost/python/return_value_policy.hpp>
      @@ -133,7 +133,7 @@ struct Foo {
       
       // Wrapper code
       using namespace boost::python;
      -BOOST_PYTHON_MODULE_INIT(my_module)
      +BOOST_PYTHON_MODULE(my_module)
       {
          class_<Bar>("Bar");
       
      diff --git a/doc/v2/to_python_converter.html b/doc/v2/to_python_converter.html
      index f6682242..757d9f0e 100644
      --- a/doc/v2/to_python_converter.html
      +++ b/doc/v2/to_python_converter.html
      @@ -143,7 +143,7 @@ to_python_converter();
           

      C++ module definition

       #include <boost/python/reference.hpp>
      -#include <boost/python/module_init.hpp>
      +#include <boost/python/module.hpp>
       #include "noddy.h"
       
       struct tag {};
      @@ -159,7 +159,7 @@ struct tag_to_noddy
           }
       };
       
      -BOOST_PYTHON_MODULE_INIT(to_python_converter)
      +BOOST_PYTHON_MODULE(to_python_converter)
       {
           def("make_tag", make_tag);
           to_python_converter<tag, tag_to_noddy>();
      diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp
      index 2e0840b3..3ec153b4 100644
      --- a/include/boost/python/class.hpp
      +++ b/include/boost/python/class.hpp
      @@ -13,7 +13,6 @@
       # include 
       
       # include 
      -# include 
       # include 
       # include 
       # include 
      @@ -25,17 +24,19 @@
       # include 
       # include 
       # include 
      -# include 
       # include 
       # include 
       # include 
      -# include 
      -# include 
      -# include 
       # include 
       # include 
       # include 
       
      +# include 
      +# include 
      +# include 
      +# include 
      +# include 
      +
       namespace boost { namespace python {
       
       enum no_init_t { no_init };
      diff --git a/include/boost/python/def.hpp b/include/boost/python/def.hpp
      index f6218886..5631fb56 100644
      --- a/include/boost/python/def.hpp
      +++ b/include/boost/python/def.hpp
      @@ -9,7 +9,7 @@
       # include 
       # include 
       # include 
      -# include 
      +# include 
       # include 
       # include 
       # include 
      diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp
      index d7262316..7062283e 100644
      --- a/include/boost/python/detail/defaults_def.hpp
      +++ b/include/boost/python/detail/defaults_def.hpp
      @@ -219,7 +219,7 @@ namespace detail
               char const* name,
               OverloadsT const& overloads,
               NameSpaceT& name_space,
      -        SigT sig)
      +        SigT const& sig)
           {
               typedef typename mpl::front::type return_type;
               typedef typename OverloadsT::void_return_type void_return_type;
      diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp
      index 35f2dc90..6727135b 100644
      --- a/include/boost/python/init.hpp
      +++ b/include/boost/python/init.hpp
      @@ -12,6 +12,8 @@
       
       #include 
       #include 
      +#include 
      +
       #include 
       #include 
       #include 
      diff --git a/include/boost/python/module.hpp b/include/boost/python/module.hpp
      index 69e9001d..d259d2da 100644
      --- a/include/boost/python/module.hpp
      +++ b/include/boost/python/module.hpp
      @@ -6,104 +6,7 @@
       #ifndef MODULE_DWA2001128_HPP
       # define MODULE_DWA2001128_HPP
       
      -# include 
      -# include 
      -# include 
      -# include 
      -# include 
       # include 
      -# include 
      -# include 
      -# include 
      -# include 
      -
      -namespace boost { namespace python {
      -
      -class module : public detail::module_base
      -{
      - public:
      -    typedef detail::module_base base;
      -
      -    module(char const* name, char const* doc = 0)
      -        : base(name, doc) {}
      -
      -    // Add elements to the module
      -    template 
      -    module& setattr(const char* name, T const& x)
      -    {
      -        this->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 
      -    void
      -    dispatch_def(
      -        char const* name,
      -        Fn fn,
      -        CallPolicyOrDoc const& policy_or_doc,
      -        char const* doc,
      -        void const*)
      -    {
      -        detail::def_helper helper(policy_or_doc, doc);
      -
      -        this->setattr_doc(
      -            name
      -            , boost::python::make_function(fn, helper.policies())
      -            , helper.doc());
      -    }
      -
      -    template 
      -    void
      -    dispatch_def(
      -        char const* name,
      -        SigT sig,
      -        StubsT const& stubs,
      -        char const* doc,
      -        detail::overloads_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));
      -    }
      -};
      -
      -//
      -// inline implementations
      -//
      -inline module& module::add(type_handle x)
      -{
      -    this->base::add(x);
      -    return *this;
      -}
      -
      -}} // namespace boost::python
      +# define BOOST_PYTHON_MODULE BOOST_PYTHON_MODULE_INIT
       
       #endif // MODULE_DWA20011221_HPP
      diff --git a/src/aix_init_module.cpp b/src/aix_init_module.cpp
      index 3d74596e..2345aa4f 100644
      --- a/src/aix_init_module.cpp
      +++ b/src/aix_init_module.cpp
      @@ -17,7 +17,7 @@ extern "C"
       # include 
       # include 
       # include 
      -# include 
      +# include 
       
       namespace boost { namespace python { namespace detail {
       
      diff --git a/test/args.cpp b/test/args.cpp
      index ee79fcfa..281ca236 100644
      --- a/test/args.cpp
      +++ b/test/args.cpp
      @@ -3,11 +3,12 @@
       // copyright notice appears in all copies. This software is provided
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
      -#include 
      +#include 
       #include 
       #include 
       #include 
       #include 
      +#include 
       #include 
       #include "test_class.hpp"
       
      @@ -38,7 +39,7 @@ struct X
       
       BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3)
       
      -BOOST_PYTHON_MODULE_INIT(args_ext)
      +BOOST_PYTHON_MODULE(args_ext)
       {
           def("f", f, args("x", "y", "z")
               , "This is f's docstring"
      diff --git a/test/back_reference.cpp b/test/back_reference.cpp
      index d5ae5ece..75233c6b 100644
      --- a/test/back_reference.cpp
      +++ b/test/back_reference.cpp
      @@ -4,7 +4,7 @@
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
       #include 
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -87,7 +87,7 @@ bool y_equality(back_reference y1, Y const& y2)
           return &y1.get() == &y2;
       }
       
      -BOOST_PYTHON_MODULE_INIT(back_reference_ext)
      +BOOST_PYTHON_MODULE(back_reference_ext)
       {
           def("copy_Y", copy_Y, return_value_policy());
           def("copy_Z", copy_Z, return_value_policy());
      diff --git a/test/bienstman1.cpp b/test/bienstman1.cpp
      index b4acf059..7f1736e0 100644
      --- a/test/bienstman1.cpp
      +++ b/test/bienstman1.cpp
      @@ -1,4 +1,4 @@
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -18,7 +18,7 @@ struct V
       
       const A* outside(const V& v) {return &v.a;}
       
      -BOOST_PYTHON_MODULE_INIT(bienstman1_ext)
      +BOOST_PYTHON_MODULE(bienstman1_ext)
       {
         using namespace boost::python;
         using boost::shared_ptr;
      diff --git a/test/bienstman2.cpp b/test/bienstman2.cpp
      index 7e4f951c..94f2a8c3 100644
      --- a/test/bienstman2.cpp
      +++ b/test/bienstman2.cpp
      @@ -1,4 +1,4 @@
      -#include 
      +#include 
       #include 
       #include 
       
      @@ -15,7 +15,7 @@ struct E
          const D fe2(const C&, const C&) {return D();}
       };
       
      -BOOST_PYTHON_MODULE_INIT(bienstman2_ext)
      +BOOST_PYTHON_MODULE(bienstman2_ext)
       {
         using namespace boost::python;
       
      diff --git a/test/bienstman3.cpp b/test/bienstman3.cpp
      index 22c7638e..9248ef8f 100644
      --- a/test/bienstman3.cpp
      +++ b/test/bienstman3.cpp
      @@ -1,4 +1,4 @@
      -#include 
      +#include 
       #include 
       #include 
       
      @@ -12,7 +12,7 @@ struct B
           B(const V&) {}    
       };
       
      -BOOST_PYTHON_MODULE_INIT(bienstman3_ext)
      +BOOST_PYTHON_MODULE(bienstman3_ext)
       {
         using namespace boost::python;
       
      diff --git a/test/bienstman4.cpp b/test/bienstman4.cpp
      index ee510f2d..124d76a5 100644
      --- a/test/bienstman4.cpp
      +++ b/test/bienstman4.cpp
      @@ -4,7 +4,7 @@
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
       
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -16,7 +16,7 @@ struct Term {Term(Type1 const&) {} };
       
       struct Expression {void add(Term const&) {} };
       
      -BOOST_PYTHON_MODULE_INIT(bienstman4_ext)
      +BOOST_PYTHON_MODULE(bienstman4_ext)
       {
         using namespace boost::python;
         using boost::mpl::list;
      diff --git a/test/bienstman5.cpp b/test/bienstman5.cpp
      index 75fbd8da..72875663 100644
      --- a/test/bienstman5.cpp
      +++ b/test/bienstman5.cpp
      @@ -4,7 +4,7 @@
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
       
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -13,7 +13,7 @@
       
       struct M {M(const std::complex&) {} };
       
      -BOOST_PYTHON_MODULE_INIT(bienstman5_ext)
      +BOOST_PYTHON_MODULE(bienstman5_ext)
       {
         using namespace boost::python;
       
      diff --git a/test/callbacks.cpp b/test/callbacks.cpp
      index 763dcda8..036c532a 100644
      --- a/test/callbacks.cpp
      +++ b/test/callbacks.cpp
      @@ -3,7 +3,7 @@
       // copyright notice appears in all copies. This software is provided
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
      -#include 
      +#include 
       #include 
       //#include 
       #include 
      @@ -113,7 +113,7 @@ object apply_object_object(PyObject* f, object x)
       
       int X::counter;
       
      -BOOST_PYTHON_MODULE_INIT(callbacks_ext)
      +BOOST_PYTHON_MODULE(callbacks_ext)
       {
           def("apply_object_object", apply_object_object);
           def("apply_to_own_type", apply_to_own_type);
      diff --git a/test/cltree.cpp b/test/cltree.cpp
      index f7ea9eeb..099d5cb7 100755
      --- a/test/cltree.cpp
      +++ b/test/cltree.cpp
      @@ -1,4 +1,4 @@
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -49,7 +49,7 @@ public:
       
       };
       
      -BOOST_PYTHON_MODULE_INIT(cltree)
      +BOOST_PYTHON_MODULE(cltree)
       {
           boost::python::class_("basic")
               .def("__repr__",&basic::repr)
      diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp
      index be638066..e3a756b9 100644
      --- a/test/comprehensive.cpp
      +++ b/test/comprehensive.cpp
      @@ -1196,7 +1196,7 @@ PyObject* raw(const boost::python::tuple& args, const boost::python::dictionary&
           return BOOST_PYTHON_CONVERSION::to_python(first->i_ + second + third + fourth);
       }
       
      -BOOST_PYTHON_MODULE_INIT(boost_python_test)
      +BOOST_PYTHON_MODULE(boost_python_test)
       {
           boost::python::module_builder boost_python_test("boost_python_test");
           init_module(boost_python_test);
      diff --git a/test/data_members.cpp b/test/data_members.cpp
      index 7a05d359..2345634a 100644
      --- a/test/data_members.cpp
      +++ b/test/data_members.cpp
      @@ -4,7 +4,7 @@
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
       #include 
      -#include 
      +#include 
       #include "test_class.hpp"
       
       #if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
      @@ -20,7 +20,7 @@ typedef test_class<1> Y;
       
       double get_fair_value(X const& x) { return x.value(); }
       
      -BOOST_PYTHON_MODULE_INIT(data_members_ext)
      +BOOST_PYTHON_MODULE(data_members_ext)
       {
           class_("X", init())
               .def("value", &X::value)
      diff --git a/test/defaults.cpp b/test/defaults.cpp
      index 41341e72..1c173a79 100644
      --- a/test/defaults.cpp
      +++ b/test/defaults.cpp
      @@ -5,11 +5,11 @@
       // to its suitability for any purpose.
       
       #include 
      -#include 
      +#include 
       #include 
       #include 
       #include 
      -#include 
      +#include 
       #include 
       
       #if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
      @@ -147,17 +147,11 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_3_stubs, foo, 2, 3)
       
       ///////////////////////////////////////////////////////////////////////////////
       
      -BOOST_PYTHON_MODULE_INIT(defaults_ext)
      +BOOST_PYTHON_MODULE(defaults_ext)
       {
           def("foo", foo, foo_stubs());
           def("bar", (object(*)(int, char, std::string, double))0, bar_stubs());
       
      -    // Show that this works with the old obsolete module version of def().
      -    module("defaults_ext")
      -        .def("foobar", foo, foo_stubs())
      -        .def("barfoo", (object(*)(int, char, std::string, double))0, bar_stubs())
      -        ;
      -
           class_("Y", init<>("doc of Y init")) // this should work
       	    .def("get_state", &Y::get_state)
               ;
      diff --git a/test/dict.cpp b/test/dict.cpp
      index 0850c6be..538c7930 100644
      --- a/test/dict.cpp
      +++ b/test/dict.cpp
      @@ -1,4 +1,4 @@
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -68,7 +68,7 @@ void test_templates(object print)
           //print(tmp[3]);
       }
           
      -BOOST_PYTHON_MODULE_INIT(dict_ext)
      +BOOST_PYTHON_MODULE(dict_ext)
       {
           def("new_dict", new_dict);
           def("data_dict", data_dict);
      diff --git a/test/docstring.cpp b/test/docstring.cpp
      index 417a6635..65893d02 100644
      --- a/test/docstring.cpp
      +++ b/test/docstring.cpp
      @@ -6,7 +6,7 @@
       #include 
       #include 
       #include 
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -30,7 +30,7 @@ unsigned long fact(unsigned long n)
           return n <= 1 ? n : n * fact(n - 1);
       }
       
      -BOOST_PYTHON_MODULE_INIT(docstring_ext)
      +BOOST_PYTHON_MODULE(docstring_ext)
       {
           scope().attr("__doc__") =
               "A simple test module for documentation strings\n"
      diff --git a/test/enum.cpp b/test/enum.cpp
      index d6147bc0..b0dd02ae 100644
      --- a/test/enum.cpp
      +++ b/test/enum.cpp
      @@ -5,7 +5,7 @@
       // to its suitability for any purpose.
       #include 
       #include 
      -#include 
      +#include 
       
       using namespace boost::python;
       
      @@ -13,7 +13,7 @@ enum color { red = 1, green = 2, blue = 4 };
       
       color identity_(color x) { return x; }
       
      -BOOST_PYTHON_MODULE_INIT(enum_ext)
      +BOOST_PYTHON_MODULE(enum_ext)
       {
           enum_("color")
               .value("red", red)
      diff --git a/test/exception_translator.cpp b/test/exception_translator.cpp
      index 8a6428fd..f9c38ab9 100644
      --- a/test/exception_translator.cpp
      +++ b/test/exception_translator.cpp
      @@ -1,4 +1,4 @@
      -#include 
      +#include 
       #include 
       #include 
       
      @@ -15,7 +15,7 @@ void throw_error()
           
       }
       
      -BOOST_PYTHON_MODULE_INIT(exception_translator_ext)
      +BOOST_PYTHON_MODULE(exception_translator_ext)
       {
         using namespace boost::python;
         register_exception_translator(&translate);
      diff --git a/test/extract.cpp b/test/extract.cpp
      index 2faa27e9..a7749043 100644
      --- a/test/extract.cpp
      +++ b/test/extract.cpp
      @@ -7,7 +7,7 @@
       #include "test_class.hpp"
       #include 
       #include 
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -96,7 +96,7 @@ std::string x_rep(X const& x)
           return "X("  + boost::lexical_cast(x.value()) + ")";
       }
       
      -BOOST_PYTHON_MODULE_INIT(extract_ext)
      +BOOST_PYTHON_MODULE(extract_ext)
       {
           implicitly_convertible();
       
      diff --git a/test/implicit.cpp b/test/implicit.cpp
      index 2637f5ca..b56e6b10 100644
      --- a/test/implicit.cpp
      +++ b/test/implicit.cpp
      @@ -5,7 +5,7 @@
       // to its suitability for any purpose.
       #include 
       #include 
      -#include 
      +#include 
       #include 
       #include "test_class.hpp"
       
      @@ -20,7 +20,7 @@ int x_value(X const& x)
       
       X make_x(int n) { return X(n); }
       
      -BOOST_PYTHON_MODULE_INIT(implicit_ext)
      +BOOST_PYTHON_MODULE(implicit_ext)
       {
           implicitly_convertible();
           
      diff --git a/test/input_iterator.cpp b/test/input_iterator.cpp
      index 19b50f77..eacae455 100644
      --- a/test/input_iterator.cpp
      +++ b/test/input_iterator.cpp
      @@ -3,7 +3,7 @@
       // copyright notice appears in all copies. This software is provided
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -35,7 +35,7 @@ list_range2 range2(list_int& x)
       // to work around an MSVC6 linker bug, which causes it to complain
       // about a "duplicate comdat" if the input iterator is instantiated in
       // the same module with the others.
      -BOOST_PYTHON_MODULE_INIT(input_iterator)
      +BOOST_PYTHON_MODULE(input_iterator)
       {
           def("range2", &::range2);
           
      diff --git a/test/iterator.cpp b/test/iterator.cpp
      index 02e67546..93d4c009 100644
      --- a/test/iterator.cpp
      +++ b/test/iterator.cpp
      @@ -3,7 +3,7 @@
       // copyright notice appears in all copies. This software is provided
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -77,7 +77,7 @@ private:
           list_int two;
       };
       
      -BOOST_PYTHON_MODULE_INIT(iterator_ext)
      +BOOST_PYTHON_MODULE(iterator_ext)
       {
           def("range", &::range);
       
      diff --git a/test/list.cpp b/test/list.cpp
      index 83ea063b..15871e6a 100644
      --- a/test/list.cpp
      +++ b/test/list.cpp
      @@ -4,7 +4,7 @@
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
       
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -125,7 +125,7 @@ void exercise(list x, object y, object print)
           assert(w[3] == 'i');
       }
       
      -BOOST_PYTHON_MODULE_INIT(list_ext)
      +BOOST_PYTHON_MODULE(list_ext)
       {
           def("new_list", new_list);
           def("listify", listify);
      diff --git a/test/long.cpp b/test/long.cpp
      index 32d3164a..cc619987 100644
      --- a/test/long.cpp
      +++ b/test/long.cpp
      @@ -4,7 +4,7 @@
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
       
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -39,7 +39,7 @@ int is_long2(char const*)
           return 0;
       }
       
      -BOOST_PYTHON_MODULE_INIT(long_ext)
      +BOOST_PYTHON_MODULE(long_ext)
       {
           def("new_long", new_long);
           def("longify", longify);
      diff --git a/test/m1.cpp b/test/m1.cpp
      index 122ad04d..60498d2a 100644
      --- a/test/m1.cpp
      +++ b/test/m1.cpp
      @@ -8,7 +8,7 @@
       #include "simple_type.hpp"
       #include "complicated.hpp"
       #include 
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -199,7 +199,7 @@ D take_d_shared_ptr(boost::shared_ptr d) { return *d; }
       
       boost::shared_ptr d_factory() { return boost::shared_ptr(new D); }
       
      -BOOST_PYTHON_MODULE_INIT(m1)
      +BOOST_PYTHON_MODULE(m1)
       {
           using namespace boost::python;
           using boost::shared_ptr;
      diff --git a/test/m2.cpp b/test/m2.cpp
      index 5eee1a89..3108b2de 100644
      --- a/test/m2.cpp
      +++ b/test/m2.cpp
      @@ -7,7 +7,7 @@
       // This module exercises the converters exposed in m1 at a low level
       // by exposing raw Python extension functions that use wrap<> and
       // unwrap<> objects.
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -61,7 +61,7 @@ struct rewrap
           static T f(T x) { return x; }
       };
       
      -BOOST_PYTHON_MODULE_INIT(m2)
      +BOOST_PYTHON_MODULE(m2)
       {
           using boost::python::return_value_policy;
           using boost::python::copy_const_reference;
      diff --git a/test/minimal.cpp b/test/minimal.cpp
      index be0fe6ec..ac6fb4ae 100644
      --- a/test/minimal.cpp
      +++ b/test/minimal.cpp
      @@ -3,14 +3,14 @@
       // copyright notice appears in all copies. This software is provided
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
      -#include 
      +#include 
       #include 
       
       #if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245
       # include  // works around a KCC intermediate code generation bug
       #endif
       
      -BOOST_PYTHON_MODULE_INIT(minimal_ext)
      +BOOST_PYTHON_MODULE(minimal_ext)
       {
       }
       
      diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp
      index 24bc4d9a..d80f57ab 100644
      --- a/test/multi_arg_constructor.cpp
      +++ b/test/multi_arg_constructor.cpp
      @@ -1,4 +1,4 @@
      -#include 
      +#include 
       #include 
       #include 
       
      @@ -10,7 +10,7 @@ struct A
               ) {}
       };
       
      -BOOST_PYTHON_MODULE_INIT(multi_arg_constructor_ext)
      +BOOST_PYTHON_MODULE(multi_arg_constructor_ext)
       {
         using namespace boost::python;
         using boost::shared_ptr;
      diff --git a/test/nested.cpp b/test/nested.cpp
      index 8cbe3d79..12fd7bb1 100644
      --- a/test/nested.cpp
      +++ b/test/nested.cpp
      @@ -3,7 +3,7 @@
       // copyright notice appears in all copies. This software is provided
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -28,7 +28,7 @@ std::ostream& operator<<(std::ostream& s, Y const& x)
       }
       
       
      -BOOST_PYTHON_MODULE_INIT(nested_ext)
      +BOOST_PYTHON_MODULE(nested_ext)
       {
           using namespace boost::python;
       
      diff --git a/test/numpy.cpp b/test/numpy.cpp
      index 36b9e070..8a02f6ee 100644
      --- a/test/numpy.cpp
      +++ b/test/numpy.cpp
      @@ -6,7 +6,7 @@
       
       #include 
       #include 
      -#include 
      +#include 
       #include 
       
       using namespace boost::python;
      @@ -92,7 +92,7 @@ void exercise_numarray(numeric::array& y, object check)
           check(y.factory(make_tuple(1.2, 3.4), "Double", make_tuple(2), true, true));
       }
       
      -BOOST_PYTHON_MODULE_INIT(numpy_ext)
      +BOOST_PYTHON_MODULE(numpy_ext)
       {
           def("new_array", new_array);
           def("take_array", take_array);
      diff --git a/test/object.cpp b/test/object.cpp
      index 6a76aeb3..bf702099 100755
      --- a/test/object.cpp
      +++ b/test/object.cpp
      @@ -3,7 +3,7 @@
       // copyright notice appears in all copies. This software is provided
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
      -#include 
      +#include 
       #include 
       #include 
       
      @@ -279,7 +279,7 @@ bool check_inplace(object l, object o)
           return true;
       }
       
      -BOOST_PYTHON_MODULE_INIT(object_ext)
      +BOOST_PYTHON_MODULE(object_ext)
       {
           def("call_object_3", call_object_3);
           def("message", message);
      diff --git a/test/operators.cpp b/test/operators.cpp
      index dc2313df..e4ac1e07 100755
      --- a/test/operators.cpp
      +++ b/test/operators.cpp
      @@ -6,7 +6,7 @@
       #include 
       #include 
       #include 
      -#include 
      +#include 
       #include 
       #include "test_class.hpp"
       #if __GNUC__ != 2
      @@ -57,7 +57,7 @@ std::ostream& operator<<(std::ostream& s, X const& x)
           return s << x.value();
       }
       
      -BOOST_PYTHON_MODULE_INIT(operators_ext)
      +BOOST_PYTHON_MODULE(operators_ext)
       {
           class_("X", init())
               .def("value", &X::value)
      diff --git a/test/pickle1.cpp b/test/pickle1.cpp
      index 1f9e5139..794799f8 100644
      --- a/test/pickle1.cpp
      +++ b/test/pickle1.cpp
      @@ -10,7 +10,7 @@
           For more information refer to boost/libs/python/doc/pickle.html.
        */
       
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -45,7 +45,7 @@ namespace {
       
       }
       
      -BOOST_PYTHON_MODULE_INIT(pickle1_ext)
      +BOOST_PYTHON_MODULE(pickle1_ext)
       {
         using namespace boost::python;
         class_("world", init())
      diff --git a/test/pickle2.cpp b/test/pickle2.cpp
      index b8aacbd7..99401973 100644
      --- a/test/pickle2.cpp
      +++ b/test/pickle2.cpp
      @@ -22,7 +22,7 @@
       
       #include 
       
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -87,7 +87,7 @@ namespace { // Avoid cluttering the global namespace.
       
       }
       
      -BOOST_PYTHON_MODULE_INIT(pickle2_ext)
      +BOOST_PYTHON_MODULE(pickle2_ext)
       {
           boost::python::class_(
               "world", boost::python::init())
      diff --git a/test/pickle3.cpp b/test/pickle3.cpp
      index 5fae9e6c..8f243d39 100644
      --- a/test/pickle3.cpp
      +++ b/test/pickle3.cpp
      @@ -17,7 +17,7 @@
       
       #include 
       
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -95,7 +95,7 @@ namespace { // Avoid cluttering the global namespace.
       
       }
       
      -BOOST_PYTHON_MODULE_INIT(pickle3_ext)
      +BOOST_PYTHON_MODULE(pickle3_ext)
       {
           boost::python::class_(
               "world", boost::python::init())
      diff --git a/test/str.cpp b/test/str.cpp
      index 646f8676..e0252a17 100644
      --- a/test/str.cpp
      +++ b/test/str.cpp
      @@ -1,4 +1,4 @@
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -59,7 +59,7 @@ void work_with_string(object print)
       }
          
       
      -BOOST_PYTHON_MODULE_INIT(str_ext)
      +BOOST_PYTHON_MODULE(str_ext)
       {
           def("convert_to_string",convert_to_string);
           def("work_with_string",work_with_string);
      diff --git a/test/submod_subclass_api.cpp b/test/submod_subclass_api.cpp
      index b2c5293e..e716aaf0 100644
      --- a/test/submod_subclass_api.cpp
      +++ b/test/submod_subclass_api.cpp
      @@ -110,7 +110,7 @@ struct main_args {
       int python_main(main_args const &ma);
       
       // python module init
      -BOOST_PYTHON_MODULE_INIT(python_main)
      +BOOST_PYTHON_MODULE(python_main)
       {
           DEF(python_main);
           CLASS(main_args);
      @@ -121,7 +121,7 @@ namespace sm {
       
       int test_func() { return 7; }
       
      -BOOST_PYTHON_MODULE_INIT(sm_test)
      +BOOST_PYTHON_MODULE(sm_test)
       {
           // define a submodule
           boost::python::module(".sm");
      @@ -160,7 +160,7 @@ c1::c2 test_func() {
           return c1().t;
       }
       
      -BOOST_PYTHON_MODULE_INIT(sc_test)
      +BOOST_PYTHON_MODULE(sc_test)
       {
           class_("c1.c2")
               .def_init()
      diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp
      index 912f2dc5..917a468a 100644
      --- a/test/test_builtin_converters.cpp
      +++ b/test/test_builtin_converters.cpp
      @@ -4,7 +4,7 @@
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
       #include 
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -57,7 +57,7 @@ handle<> return_null_handle()
       
       char const* rewrap_value_mutable_cstring(char* x) { return x; }
       
      -BOOST_PYTHON_MODULE_INIT(builtin_converters)
      +BOOST_PYTHON_MODULE(builtin_converters)
       {
           def("get_type", get_type);
           def("return_null_handle", return_null_handle);
      diff --git a/test/test_pointer_adoption.cpp b/test/test_pointer_adoption.cpp
      index 90b39ea7..6631d8ea 100644
      --- a/test/test_pointer_adoption.cpp
      +++ b/test/test_pointer_adoption.cpp
      @@ -3,7 +3,7 @@
       // copyright notice appears in all copies. This software is provided
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -87,7 +87,7 @@ A* as_A(Base* b)
           return dynamic_cast(b);
       }
       
      -BOOST_PYTHON_MODULE_INIT(test_pointer_adoption_ext)
      +BOOST_PYTHON_MODULE(test_pointer_adoption_ext)
       {
           def("num_a_instances", num_a_instances);
       
      diff --git a/test/tuple.cpp b/test/tuple.cpp
      index d5569185..fce3da85 100644
      --- a/test/tuple.cpp
      +++ b/test/tuple.cpp
      @@ -1,4 +1,4 @@
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -19,7 +19,7 @@ tuple mktuple0() { return make_tuple(); }
       tuple mktuple1(int x) { return make_tuple(x); }
       tuple mktuple2(char const* a1, int x) { return make_tuple(a1, x); }
       
      -BOOST_PYTHON_MODULE_INIT(tuple_ext)
      +BOOST_PYTHON_MODULE(tuple_ext)
       {
           def("convert_to_tuple",convert_to_tuple);
           def("test_operators",test_operators);
      diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp
      index f0bfd787..92a6e78c 100644
      --- a/test/virtual_functions.cpp
      +++ b/test/virtual_functions.cpp
      @@ -4,7 +4,7 @@
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
       #include 
      -#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -87,7 +87,7 @@ struct concrete_callback : concrete
       
       int X::counter;
       
      -BOOST_PYTHON_MODULE_INIT(virtual_functions_ext)
      +BOOST_PYTHON_MODULE(virtual_functions_ext)
       {
           class_("concrete", init())
               .def("value", &concrete::value)
      
      From 2aa23a317dd2ba5869042f16ae0e00008e9878f5 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Tue, 1 Oct 2002 15:08:08 +0000
      Subject: [PATCH 0792/1042] separate overloads.hpp BOOST_PYTHON_MODULE_INIT ->
       BOOST_PYTHON_MODULE
      
      [SVN r15615]
      ---
       include/boost/python/overloads.hpp | 12 ++++++++++++
       1 file changed, 12 insertions(+)
       create mode 100644 include/boost/python/overloads.hpp
      
      diff --git a/include/boost/python/overloads.hpp b/include/boost/python/overloads.hpp
      new file mode 100644
      index 00000000..50fc2497
      --- /dev/null
      +++ b/include/boost/python/overloads.hpp
      @@ -0,0 +1,12 @@
      +// Copyright David Abrahams 2002. Permission to copy, use,
      +// modify, sell and distribute this software is granted provided this
      +// copyright notice appears in all copies. This software is provided
      +// "as is" without express or implied warranty, and with no claim as
      +// to its suitability for any purpose.
      +#ifndef OVERLOADS_DWA2002101_HPP
      +# define OVERLOADS_DWA2002101_HPP
      +
      +# include 
      +# include 
      +
      +#endif // OVERLOADS_DWA2002101_HPP
      
      From 09eba4c38f7dde2452f2e0ce420f7217994d8b47 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Tue, 1 Oct 2002 15:12:46 +0000
      Subject: [PATCH 0793/1042] Separate init.hpp docs from class.hpp
      
      [SVN r15616]
      ---
       doc/v2/class.html | 196 ++++------------------------------------------
       1 file changed, 15 insertions(+), 181 deletions(-)
      
      diff --git a/doc/v2/class.html b/doc/v2/class.html
      index d2e2d032..768a1444 100644
      --- a/doc/v2/class.html
      +++ b/doc/v2/class.html
      @@ -64,41 +64,6 @@
                     bases synopsis
      - -
      Class template init
      - -
      -
      -
      Class template - init synopsis
      - -
      Class init - constructors
      - -
      init-expressions
      -
      -
      - -
      Class template - optional
      - -
      -
      -
      Class template - optional synopsis
      -
      -
      - -
      Class template - init_with_call_policies
      - -
      -
      -
      Class - template init_with_call_policies synopsis
      -
      -
      @@ -208,14 +173,14 @@ HeldType instance, as shown in this example. This argument is not included in the init-expression passed to def(init_expr), below, nor is - it passed explicitly by users when Python instances of T - are created. This idiom allows C++ virtual functions which will be - overridden in Python to access the Python object so the Python method - can be invoked. Boost.Python automatically registers additional - converters which allow wrapped instances of T to be passed - to wrapped C++ functions expecting HeldType + "init.html#init-expressions">init-expression passed to def(init_expr), below, + nor is it passed explicitly by users when Python instances of + T are created. This idiom allows C++ virtual functions + which will be overridden in Python to access the Python object so the + Python method can be invoked. Boost.Python automatically registers + additional converters which allow wrapped instances of T + to be passed to wrapped C++ functions expecting HeldType arguments.
    • Because Boost.Python will always allow wrapped instances of @@ -247,7 +212,7 @@ namespace boost { namespace python { template <class T - , class Bases = bases<> + , class Bases = bases<> , class HeldType = T , class NonCopyable = unspecified > @@ -326,7 +291,7 @@ class_(char const* name, char const* docstring, Init init_spec); ntbs. If init_spec is supplied, it must be either the special enumeration constant no_init or an init-expression compatible with + "init.html#init-expression">init-expression compatible with T.
      Effects: Constructs a class_ object holding a @@ -370,10 +335,10 @@ class_& def(Init init_expr);
      Requires: init_expr is the result of an init-expression compatible with + href="init.html#init-expression">init-expression compatible with T.
      -
      Effects: For each valid +
      Effects: For each valid prefix P of Init, adds an __init__(...) function overload to the extension class accepting P as arguments. Each overload @@ -414,9 +379,9 @@ class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3
    • If a1 is the result of an overload-dispatch-expression, - only the second is allowed and fn must be a pointer to - function or pointer to member function whose signature is - compatible with A1. + only the second is allowed and fn must be a pointer to function + or pointer to member function whose signature is compatible with + A1.
      Effects: For each -

      Class template init<T1 = - unspecified, T2 = - unspecified,...Tn = - unspecified>

      - -

      A MPL sequence which - can be used to specify a family of one or more __init__ - functions. Only the last Ti supplied - may be an instantiation of optional<...>.

      - -

      Class template init - synopsis

      -
      -namespace boost { namespace python
      -{
      -  template <T1 = unspecified,...Tn = unspecified>
      -  struct init
      -  {
      -      init(char const* doc = 0);
      -      template <class Keywords> init(Keywords const& kw, char const* doc = 0);
      -      template <class Keywords> init(char const* doc, Keywords const& kw);
      -
      -      template <class CallPolicies>
      -      unspecified operator[](CallPolicies const& policies) const
      -  };
      -}}
      -
      - -

      Class template init - constructors

      -
      -init(char const* doc = 0);
      -template <class Keywords> init(Keywords const& kw, char const* doc = 0);
      -template <class Keywords> init(char const* doc, Keywords const& kw);
      -
      - -
      -
      Requires: If supplied, doc is an ntbs. If supplied, kw is the - result of a
      - -
      Effects: The result is an init-expression whose - docstring is doc and whose keywords are - a reference to kw. If the first form is used, the - resulting expression's keywords are empty. The expression's - call policies are an instance of default_call_policies. - If Tn is optional<U1, U2,... - Um>, the - expression's valid prefixes are given by:
      - -
      -
      - (T1, T2,...Tn-1), - (T1, T2,...Tn-1 - , U1), - (T1, T2,...Tn-1 - , U1, U2), - ...(T1, T2,...Tn-1 - , U1, U2,...Um). -
      - Otherwise, the expression has one valid prefix given by the - the template arguments the user specified. -
      -
      - -

      Class template init - observer functions

      -
      -template <class Policies>
      -unspecified operator[](Policies const& policies) const
      -
      - -
      -
      Requires: Policies is a model of CallPolicies.
      - -
      Effects: Returns a new init-expression with all the same - properties as the init object except that its - call policies are replaced by a reference to - policies.
      -
      - -

      init-expressions

      - An init-expression is a transport vehicle for the following - properties, used to describe a family of __init__ methods to - be generated for an extension class: - -
      -
      -
      docstring: An ntbs - whose value will bound to the method's __doc__ - attribute
      - -
      keywords: A keyword-expression which will be - used to name (a trailing subsequence of) the arguments to the - generated __init__ function(s).
      - -
      call policies: An instance of a model of CallPolicies.
      - -
      argument types: An MPL sequence of C++ argument types - which will be used to construct the wrapped C++ object. An init - expression has one or more valid prefixes which are given by a - sequence of prefixes of its argument types.
      -
      -
      - -

      Class template optional<T1 - = unspecified, T2 = - unspecified,...Tn = - unspecified>

      - -

      A MPL sequence which - can be used to specify the optional arguments to an __init__ - function.

      - -

      Class template - optional synopsis

      -
      -namespace boost { namespace python
      -{
      -  template <T1 = unspecified,...Tn = unspecified>
      -  struct optional {};
      -}}
      -
      -

      Class template bases<T1, T2,...TN>

      From e13d09242cb0cd8806c0f3f60d75923b2a0119e8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Oct 2002 17:22:26 +0000 Subject: [PATCH 0794/1042] doc update [SVN r15621] --- doc/v2/class.html | 24 ++-- doc/v2/init.html | 250 ++++++++++++++++++++++++++++++++++++++++++ doc/v2/overloads.html | 225 +++++++++++++++++++++++++++++++++++++ 3 files changed, 489 insertions(+), 10 deletions(-) create mode 100644 doc/v2/init.html create mode 100644 doc/v2/overloads.html diff --git a/doc/v2/class.html b/doc/v2/class.html index 768a1444..c3e95f74 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -345,7 +345,7 @@ class_& def(Init init_expr); generated constructs an object of HeldType according to the semantics described above, using a copy of init_expr's call policies. - If the longest valid prefix of Init contains N + If the longest valid prefix of Init contains N types and init_expr holds M keywords, an initial sequence of the keywords are used for all but the first N - M arguments of each overload.
      @@ -378,17 +378,21 @@ class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3
      • If a1 is the result of an overload-dispatch-expression, - only the second is allowed and fn must be a pointer to function - or pointer to member function whose signature is compatible with - A1. + "overloads.html#overload-dispatch-expression">overload-dispatch-expression, + only the second form is allowed and fn must be a pointer + to function or pointer to member function whose arity is the same as A1's maximum arity.
        -
        Effects: For each valid prefix - P of A1, adds a - name(...) function overload - to the extension class. Each overload generated invokes +
        Effects: For each prefix P of + Fn's sequence of argument types, beginning + with the one whose length is A1's minimum + arity, adds a + name(...) method + overload to the extension class. Each overload generated + invokes a1's call-expression with P, using a copy of a1's call policies. If the longest valid prefix of A1 diff --git a/doc/v2/init.html b/doc/v2/init.html new file mode 100644 index 00000000..710287ef --- /dev/null +++ b/doc/v2/init.html @@ -0,0 +1,250 @@ + + + + + + + + + Boost.Python - <boost/python/init.hpp> + + + + + + + + + +
        +

        C++ Boost

        +
        +

        Boost.Python

        + +

        Headers <boost/python/init.hpp>, + <boost/python/class_fwd.hpp>

        +
        +
        + +

        Contents

        + +
        +
        Introduction
        + +
        init-expressions
        + +
        Classes
        + +
        +
        +
        Class template init
        + +
        +
        +
        Class template + init synopsis
        + +
        Class init + constructors
        + +
        +
        + +
        Class template + optional
        + +
        +
        +
        Class template + optional synopsis
        +
        +
        +
        +
        + +
        Example(s)
        +
        +
        + +

        Introduction

        + +

        <boost/python/init.hpp> defines the interface for + exposing C++ constructors to Python as extension class + __init__ functions.

        + +

        init-expressions

        + An init-expression is used to describe a family of + __init__ methods to be generated for an extension class, and + the result has the following properties: + +
        +
        +
        docstring: An ntbs + whose value will bound to the method's __doc__ + attribute
        + +
        keywords: A keyword-expression which will be + used to name (a trailing subsequence of) the arguments to the + generated __init__ function(s).
        + +
        call policies: An instance of a model of CallPolicies.
        + +
        argument types: An MPL sequence of C++ argument types + which will be used to construct the wrapped C++ object. An init + expression has one or more + valid prefixes which are given by a sequence of + prefixes of its argument types.
        +
        +
        + +

        Classes

        + +

        Class template init<T1 = + unspecified, T2 = + unspecified,...Tn = + unspecified>

        + +

        A MPL sequence which + can be used to specify a family of one or more __init__ + functions. Only the last Ti supplied + may be an instantiation of optional<...>.

        + +

        Class template init + synopsis

        +
        +namespace boost { namespace python
        +{
        +  template <T1 = unspecified,...Tn = unspecified>
        +  struct init
        +  {
        +      init(char const* doc = 0);
        +      template <class Keywords> init(Keywords const& kw, char const* doc = 0);
        +      template <class Keywords> init(char const* doc, Keywords const& kw);
        +
        +      template <class CallPolicies>
        +      unspecified operator[](CallPolicies const& policies) const
        +  };
        +}}
        +
        + +

        Class template init + constructors

        +
        +init(char const* doc = 0);
        +template <class Keywords> init(Keywords const& kw, char const* doc = 0);
        +template <class Keywords> init(char const* doc, Keywords const& kw);
        +
        + +
        +
        Requires: If supplied, doc is an ntbs. If supplied, kw is the + result of a
        + +
        Effects: The result is an init-expression whose + docstring is doc and whose keywords are + a reference to kw. If the first form is used, the + resulting expression's keywords are empty. The expression's + call policies are an instance of default_call_policies. + If Tn is optional<U1, U2,... + Um>, the + expression's valid prefixes are given by:
        + +
        +
        + (T1, T2,...Tn-1), + (T1, T2,...Tn-1 + , U1), + (T1, T2,...Tn-1 + , U1, U2), + ...(T1, T2,...Tn-1 + , U1, U2,...Um). +
        + Otherwise, the expression has one valid prefix given by the + the template arguments the user specified. +
        +
        + +

        Class template init + observer functions

        +
        +template <class Policies>
        +unspecified operator[](Policies const& policies) const
        +
        + +
        +
        Requires: Policies is a model of CallPolicies.
        + +
        Effects: Returns a new init-expression with all the same + properties as the init object except that its call + policies are replaced by a reference to + policies.
        +
        + +

        Class template optional<T1 + = unspecified, T2 = + unspecified,...Tn = + unspecified>

        + +

        A MPL sequence which + can be used to specify the optional arguments to an __init__ + function.

        + +

        Class template + optional synopsis

        +
        +namespace boost { namespace python
        +{
        +  template <T1 = unspecified,...Tn = unspecified>
        +  struct optional {};
        +}}
        +
        + +

        Example(s)

        + +

        Given the C++ declarations:

        +
        +class Y;
        +class X
        +{
        + public:
        +   X(int x, Y* y) : m_y(y) {}
        +   X(double);
        + private:
        +   Y* m_y;
        +};
        +
        + A corresponding Boost.Python extension class can be created with: +
        +using namespace boost::python;
        +
        +class_<X>("X", "This is X's docstring.",
        +          init<int,char const*>(args("x","y"), "X.__init__'s docstring")[
        +                with_custodian_and_ward<1,3>()]
        +          )
        +   .def(init<double>())
        +   ;
        +
        +
        + Revised + + 1 October, 2002 + + + +

        © Copyright Dave Abrahams 2002. All Rights + Reserved.

        + + + diff --git a/doc/v2/overloads.html b/doc/v2/overloads.html new file mode 100644 index 00000000..3e931980 --- /dev/null +++ b/doc/v2/overloads.html @@ -0,0 +1,225 @@ + + + + + + + + + Boost.Python - <boost/python/overloads.hpp> + + + + + + + + + +
        +

        C++ Boost

        +
        +

        Boost.Python

        + +

        Header <boost/python/overloads.hpp>

        +
        +
        + +

        Contents

        + +
        +
        Introduction
        + +
        overload-dispatch-expressions
        + +
        OverloadDispatcher concept
        + +
        Macros
        + +
        +
        +
        BOOST_PYTHON_FUNCTION_OVERLOADS
        + +
        BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
        +
        +
        + +
        Example(s)
        +
        +
        + +

        Introduction

        + +

        Defines facilities for generating families of overloaded Python + functions and extension class methods from C++ functions and + member functions with default arguments, or from similar families + of C++ overloads

        + +

        overload-dispatch-expressions

        + +

        + An overload-dispatch-expression is used to describe a + family of overloaded methods to be generated for an extension + class. It has the following properties: + +

        +
        +
        docstring: An ntbs + whose value will bound to the methods' __doc__ + attribute
        + +
        keywords: A keyword-expression which + will be used to name (a trailing subsequence of) the arguments + to the generated methods.
        + +
        call policies: An instance of some type which models CallPolicies.
        + +
        minimum arity + The minimum number of arguments to be accepted by a generated + method overload.
        + +
        maximum arity + The maximum number of arguments to be accepted by a generated + method overload.
        +
        +
        + +

        OverloadDispatcher Concept

        + + An OverloadDispatcher X is a class which has a + minimum arity and a maximum arity, and for which + the following following are valid overload-dispatch-expressions, + with the same minimum and maximum arity as the OverloadDispatcher. + +
        +X()
        +X(docstring)
        +X(docstring, keywords)
        +X(keywords, docstring)
        +X()[policies]
        +X(docstring)[policies]
        +X(docstring, keywords)[policies]
        +X(keywords, docstring)[policies]
        +
        + +
          +
        • If policies are supplied, it must be an instance of a +type which models CallPolicies, and +will be used as the result's call policies. Otherwise the result's +call policies will be an instance of default_call_policies. + +
        • If docstring is supplied it must be an ntbs, and will be used as the result's docstring. Otherwise the result has an empty docstring. + +
        • If keywords is supplied it must be the result of a keyword-expression + whose length is no greater than X's maximum + arity, and will be used as the result's keywords. Otherwise + the result's keywords will be empty. +
        + + + + +

        Macros

        + +

        BOOST_PYTHON_FUNCTION_OVERLOADS(name, func_id, min_args, max_args)

        + Expands to the definition of an OverloadDispatcher called + name in the current scope which can be used to + generate the following function invocation: +
        +func_id(a1, a2,...ai);
        +
        + + for all min_args <= i <= max_args. + +

        BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(name, member_name, min_args, max_args)

        + + Expands to the definition of an OverloadDispatcher called + name in the current scope which can be used to + generate the following function invocation: +
        +x.member_name(a1, a2,...ai);
        +
        + + for all min_args <= i <= + max_args, where x is a reference to an + object of class type. + +

        Example(s)

        + +
        +#include <boost/python/module.hpp>
        +#include <boost/python/def.hpp>
        +#include <boost/python/args.hpp>
        +#include <boost/python/tuple.hpp>
        +#include <boost/python/class.hpp>
        +#include <boost/python/overloads.hpp>
        +#include <boost/python/return_internal_reference.hpp>
        +
        +using namespace boost::python;
        +
        +tuple f(int x = 1, double y = 4.25, char const* z = "wow")
        +{
        +    return make_tuple(x, y, z);
        +}
        +
        +BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3)
        +
        +stryct Y {};
        +struct X
        +{
        +    Y& f(int x, double y = 4.25, char const* z = "wow")
        +    {
        +        return inner;
        +    }
        +    Y inner;
        +};
        +
        +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 1, 3)
        +
        +BOOST_PYTHON_MODULE(args_ext)
        +{
        +    def("f", f, args("x", "y", "z")
        +        , "This is f's docstring"
        +        );
        +
        +    
        +    class_<Y>("Y")
        +        ;
        +            
        +    class_<X>("X", "This is X's docstring")
        +        .def("f1", &X::f, 
        +                X_f_overloads(args("x", "y", "z"),
        +                              "f's docstring"
        +                                  )[return_internal_reference<>()])
        +        ;
        +}
        +
        + +

        Revised + + 01 October, 2002 + +

        + +

        © Copyright Dave Abrahams 2002. All Rights + Reserved.

        + + + From 23730202256b980ed69def105ad7bda65fed2d69 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Oct 2002 22:48:24 +0000 Subject: [PATCH 0795/1042] doc update [SVN r15639] --- doc/v2/dict.html | 4 +- doc/v2/list.html | 140 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 doc/v2/list.html diff --git a/doc/v2/dict.html b/doc/v2/dict.html index ee38c2bc..0fe58f1b 100644 --- a/doc/v2/dict.html +++ b/doc/v2/dict.html @@ -72,7 +72,7 @@ "ObjectWrapper.html#TypeWrapper-concept">TypeWrapper concept definition. Since dict is publicly derived from object, the public object - interfaceapplies to dict instances as well.

        + interface applies to dict instances as well.

        Class dict synopsis

        @@ -126,7 +126,7 @@ namespace boost object itervalues() const; list keys() const; }; -}; +}
    • Example

      diff --git a/doc/v2/list.html b/doc/v2/list.html new file mode 100644 index 00000000..843e4519 --- /dev/null +++ b/doc/v2/list.html @@ -0,0 +1,140 @@ + + + + + + + + + Boost.Python - <boost/python/list.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/list.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Classes
      + +
      +
      +
      Class list
      + +
      +
      +
      Class list + synopsis
      +
      +
      +
      +
      + +
      Example(s)
      +
      +
      + +

      Introduction

      + +

      Exposes a TypeWrapper for the Python + list + type.

      + +

      Classes

      + +

      Class list

      + +

      Exposes the mapping + protocol of Python's built-in list type. The semantics + of the constructors and member functions defined below can be fully + understood by reading the TypeWrapper concept + definition. Since list is publicly derived from object, the public object + interface applies to list instances as well.

      + +

      Class list + synopsis

      +
      +namespace boost
      +{
      +  class list : public object
      +  {
      +   public:
      +      list(); // new list
      +
      +      template <class T>
      +      explicit list(T const& sequence);
      +
      +      template <class T>
      +      void append(T const& x);
      +
      +      template <class T>
      +      long count(T const& value) const;
      +
      +      template <class T>
      +      void extend(T const& x);
      +
      +      template <class T>
      +      long index(T const& x) const;
      +
      +      template <class T>
      +      void insert(object const& index, T const& x); // insert object before index
      +
      +      object pop(); // remove and return item at index (default last)
      +      object pop(long index);
      +      object pop(object const& index);
      +
      +      template <class T>
      +      void remove(T const& value);
      +
      +      void reverse(); // reverse *IN PLACE*
      +
      +      void sort(); //  sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1
      +
      +      template <class T>
      +      void sort(T const& value);
      +  };
      +}
      +
      + +

      Example

      +
      +using namespace boost::python;
      +
      +// Return the number of zeroes in the list
      +long zeroes(list l)
      +{
      +   return l.count(0);
      +}
      +
      + +

      Revised 1 October, 2002

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From 2a199af8f760844ee7a7792edf0dd0eb078a9f0b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 1 Oct 2002 23:03:09 +0000 Subject: [PATCH 0796/1042] doc update [SVN r15641] --- doc/v2/long.html | 117 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 doc/v2/long.html diff --git a/doc/v2/long.html b/doc/v2/long.html new file mode 100644 index 00000000..799fa533 --- /dev/null +++ b/doc/v2/long.html @@ -0,0 +1,117 @@ + + + + + + + + + Boost.Python - <boost/python/long.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/long.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Classes
      + +
      +
      +
      Class long_
      + +
      +
      +
      Class long_ + synopsis
      +
      +
      +
      +
      + +
      Example(s)
      +
      +
      + +

      Introduction

      + +

      Exposes a TypeWrapper for the Python + long + integer type.

      + +

      Classes

      + +

      Class long_

      + +

      Exposes the numeric type + protocol of Python's built-in long type. The semantics + of the constructors and member functions defined below can be fully + understood by reading the TypeWrapper concept + definition. Since long_ is publicly derived from object, the public object + interface applies to long_ instances as well.

      + +

      Class long_ + synopsis

      +
      +namespace boost
      +{
      +  class long_ : public object
      +  {
      +   public:
      +      long_(); // new long_
      +
      +      template <class T>
      +      explicit long_(T const& rhs);
      +
      +      template <class T, class U>
      +      long_(T const& rhs, U const& base);
      +  };
      +}
      +
      + +

      Example

      +
      +namespace python = boost::python;
      +
      +// compute a factorial without overflowing
      +python::long_ fact(long n)
      +{
      +   if (n == 0)
      +      return python::long_(1);
      +   else
      +      return n * fact(n - 1);
      +}
      +
      + +

      Revised 1 October, 2002

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From f8a9b922beb9b2eb088d3c49cdd09dcfa3981fc7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 2 Oct 2002 11:20:56 +0000 Subject: [PATCH 0797/1042] *** empty log message *** [SVN r15645] --- include/boost/python/detail/overloads_fwd.hpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 include/boost/python/detail/overloads_fwd.hpp diff --git a/include/boost/python/detail/overloads_fwd.hpp b/include/boost/python/detail/overloads_fwd.hpp new file mode 100644 index 00000000..94ec503f --- /dev/null +++ b/include/boost/python/detail/overloads_fwd.hpp @@ -0,0 +1,19 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OVERLOADS_FWD_DWA2002101_HPP +# define OVERLOADS_FWD_DWA2002101_HPP + +namespace boost { namespace python { namespace detail { + +// forward declarations +struct overloads_base; + +template +inline void define_with_defaults(char const* name, OverloadsT const&, NameSpaceT&, SigT const&); + +}}} // namespace boost::python::detail + +#endif // OVERLOADS_FWD_DWA2002101_HPP From 28e5bedf4995914b05815962aa0cf62349b9095b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 2 Oct 2002 12:00:22 +0000 Subject: [PATCH 0798/1042] doc update [SVN r15647] --- doc/v2/module.html | 195 +++++---------------------------------------- 1 file changed, 19 insertions(+), 176 deletions(-) diff --git a/doc/v2/module.html b/doc/v2/module.html index 4b3017bc..42658832 100644 --- a/doc/v2/module.html +++ b/doc/v2/module.html @@ -32,36 +32,14 @@ "#BOOST_PYTHON_MODULE-spec">BOOST_PYTHON_MODULE -
      Classes - -
      -
      -
      Class module - -
      -
      -
      Class module - synopsis - -
      Class module - constructor - -
      Class module - modifier functions - -
      Class module - observer functions -
      -
      -
      Example(s)

      Introduction

      -

      This header provides the basic facilities needed to create an - extension module. +

      This header provides the basic facilities needed to create a + Boost.Python extension module.

      Macros

      @@ -75,157 +53,27 @@ "http://www.python.org/doc/2.2/ref/identifiers.html">identifier naming rules. Where you would normally write
      -void initname()
      +extern "C" void initname()
       {
          ...
      +}
       
      Boost.Python modules should be initialized with
       BOOST_PYTHON_MODULE(name)
       {
          ...
      +}
       
      -

      Classes

      +This macro generates two functions in the scope where it is used: +extern "C" void initname(), +and void init_module_name(), whose body must +follow the macro invocation. init_name passes +init_module_name to () so that any C++ +exceptions generated are safely processeed. -

      Class module

      - -

      This class represents the Python extension module under construction. It - provides functions for adding attributes and for retrieving the underlying - Python module object. - -

      Class module - synopsis

      -
      -namespace boost { namespace python
      -{
      -  class module : public module_base
      -  {
      -   public:
      -      module(const char* name);
      -
      -      // modifier functions
      -      module& setattr(const char* name, PyObject*);
      -      module& setattr(const char* name, PyTypeObject*);
      -      module& setattr(const char* name, ref const&);
      -
      -      module& add(PyTypeObject* x);
      -      template <class T, class Bases, class HolderGenerator>
      -      module& add(class_<T,Bases,HolderGenerator> const& c);
      -
      -      template <class Fn>
      -      module& def(char const* name, Fn fn);
      -      template <class Fn, class ResultHandler>
      -      module& def(char const* name, Fn fn, ResultHandler handler);
      -
      -      // observer function
      -      ref object() const;
      -  };
      -
      -}}
      -
      - -

      Class module - constructor

      -
      -module(const char* name);
      -
      - -
      -
      Requires: name is a ntbs whose value matches the - argument passed to BOOST_PYTHON_MODULE. - -
      Effects: Creates a module object representing a - Python module named name. -
      - -

      Class module modifier - functions

      -
      -module& setattr(const char* name, PyObject* obj);
      -module& setattr(const char* name, PyTypeObject* obj);
      -module& setattr(const char* name, ref const& r);
      -
      - -
      -
      Requires: name is a ntbs which conforms to - Python's identifier - naming rules. In the first two forms, obj is non-null. - In the third form, r.get() is non-null. - -
      Effects: Adds the given Python object to the module. If the - object is a product of make_function(), the - usual overloading procedure applies. - In the first two forms, ownership of a reference to obj is transferred - from caller to callee, even if an exception is thrown. - -
      Returns: *this -
      -
      -module& add(PyTypeObject* x);
      -
      -template <class T, class Bases, class HolderGenerator>
      -module& add(class_<T,Bases,HolderGenerator> const& c);
      -
      - -
      -
      Requires: In the first form, x is non-null - -
      Effects: The first form adds the Python type object named by - x to the Python module under construction, with the name - given by the type's tp_name - field. The second form adds the extension class object being constructed - by c to the module, with the same name that was passed to - c's constructor. - -
      Returns: *this - -
      Rationale: Provides a way to set type attributes in the module - without having to explicitly specify the name. -
      -
      -template <class Fn>
      -module& def(char const* name, Fn f);
      -
      -template <class Fn, class ResultHandler>
      -module& def(char const* name, Fn f, ResultHandler handler);
      -
      - -
      - -
      Requires: f is a non-null pointer-to-function or - pointer-to-member-function. name is a ntbs which conforms to - Python's identifier - naming rules. In the first form, the return type of - f is not a reference and is not a pointer other - than char const* or PyObject*. In the - second form policy is a model of CallPolicy. - -
      Effects: Adds the result of make_function(f) to - the extension module being defined, with the given name. If - the module already has an attribute named name, the - usual overloading procedure applies. - -
      Returns: *this -
      - -

      Class module observer - functions

      -
      -ref object() const;
      -
      - -
      -
      Returns: A ref object which holds a reference to - the Python module object created by the module constructor. -

      Example(s)

      @@ -233,28 +81,23 @@ ref object() const;
       #include <boost/python/module.hpp>
       
      -char const* greet()
      +BOOST_PYTHON_MODULE(xxx)
       {
      -    return "hello, Boost.Python!";
      -}
      -
      -BOOST_PYTHON_MODULE(boost_greet)
      -{
      -    module("boost_greet")
      -        .def("greet", greet);
      +    throw "something bad happened"
       }
       
      Interactive Python:
      ->>> import boost_greet
      ->>> boost_greet.greet()
      -'hello, Boost.Python!'
      +>>> import xxx
      +Traceback (most recent call last):
      +  File "", line 1, in ?
      +RuntimeError: Unidentifiable C++ Exception
       

      Revised - 14 February, 2002 + 2 October, 2002 From f2055b0d80c18bcb8fe29c6114a9208df9d3da52 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 2 Oct 2002 20:33:14 +0000 Subject: [PATCH 0799/1042] doc update [SVN r15654] --- doc/v2/object.html | 925 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 925 insertions(+) create mode 100644 doc/v2/object.html diff --git a/doc/v2/object.html b/doc/v2/object.html new file mode 100644 index 00000000..8fcd05c5 --- /dev/null +++ b/doc/v2/object.html @@ -0,0 +1,925 @@ + + + + + + + + + Boost.Python - <boost/python/object.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/object.hpp>

      +
      +


      + +

      Contents

      + +
      +
      Introduction
      + +
      Types
      + +
      +
      +
      slice_nil
      +
      +
      + +
      Classes
      + +
      +
      +
      Class + const_attribute_policies
      + +
      +
      +
      Class + const_attribute_policies synopsis
      + +
      Class + const_attribute_policies static functions
      +
      +
      + +
      Class + attribute_policies
      + +
      +
      +
      Class + attribute_policies synopsis
      + +
      Class + attribute_policies static functions
      +
      +
      + +
      Class + const_item_policies
      + +
      +
      +
      Class + const_item_policies synopsis
      + +
      Class + const_item_policies static functions
      +
      +
      + +
      Class + item_policies
      + +
      +
      +
      Class + item_policies synopsis
      + +
      Class + item_policies static functions
      +
      +
      + +
      Class + const_slice_policies
      + +
      +
      +
      Class + const_slice_policies synopsis
      + +
      Class + const_slice_policies static functions
      +
      +
      + +
      Class + slice_policies
      + +
      +
      +
      Class + slice_policies synopsis
      + +
      Class + slice_policies static functions
      +
      +
      + +
      Class + object_operators
      + +
      +
      +
      Class + object_operators synopsis
      + +
      Class + object_operators observer functions
      +
      +
      + +
      Class object
      + +
      +
      +
      Class object + synopsis
      + +
      Class object + constructors and destructor
      + +
      Class template + object modifier functions
      + +
      Class template + object observer functions
      +
      +
      + +
      Class template + proxy
      + +
      +
      +
      Class template + proxy synopsis
      + +
      Class template + proxy modifier functions
      + +
      Class template + proxy observer functions
      +
      +
      +
      +
      + +
      Functions
      + +
      +
      +
      del
      + +
      comparisons
      + +
      binary operations
      + +
      assignment operations
      +
      + +
      +
      operators
      +
      +
      + +
      Example
      +
      +
      + +

      Introduction

      + +

      Exposes the generic Python object wrapper class object, + and related classes. In order to avoid some potenential problems with + argument-dependent lookup and the generalized operators defined on + object, all these facilities are defined in + namespace boost::python::api, and object + is imported into namespace boost::python with a + using-declaration.

      + +

      Types

      + +

      +
      +enum slice_nil { _ };
      +
      + A type that can be used to get the effect of leaving out an index in a + Python slice expression: +
      +>>> x[:-1]
      +
      + C++ equivalent: +
      +x.slice(_,-1)
      +
      + +

      Classes

      + + +

      Class + const_attribute_policies

      + +

      The policies which are used for proxies representing an attribute + access to a const object.

      + +

      Class + const_attribute_policies synopsis

      +
      +namespace boost { namespace python { namespace api
      +{
      +  struct const_attribute_policies
      +  {
      +      typedef char const* key_type;
      +      static object get(object const& target, char const* key);
      +  };
      +}}}
      +
      + +

      Class + const_attribute_policies static functions

      +
      +static object get(object const& target, char const* key);
      +
      + +
      +
      Requires: key is an ntbs.
      + +
      Effects: accesses the attribute of target named + by key.
      + +
      Returns: An object managing the result of the + attribute access.
      + +
      Throws: error_already_set if a + Python exception is raised.
      +
      + +

      Class + attribute_policies

      + +

      The policies which are used for proxies representing an attribute + access to a mutable object.

      + +

      Class + attribute_policies synopsis

      +
      +namespace boost { namespace python { namespace api
      +{
      +  struct attribute_policies : const_attribute_policies
      +  {
      +      static object const& set(object const& target, char const* key, object const& value);
      +      static void del(object const&target, char const* key);
      +  };
      +}}}
      +
      + +

      Class + attribute_policies static functions

      +
      +static object const& set(object const& target, char const* key, object const& value);
      +
      + +
      +
      Requires: key is an ntbs.
      + +
      Effects: sets the attribute of target named by + key to value.
      + +
      Throws: error_already_set if a + Python exception is raised.
      +
      +
      +static void del(object const&target, char const* key);
      +
      + +
      +
      Requires: key is an ntbs.
      + +
      Effects: deletes the attribute of target named + by key.
      + +
      Throws: error_already_set if a + Python exception is raised.
      +
      + + + +

      Class + const_item_policies

      + +

      The policies which are used for proxies representing an item access + (via the Python bracket operators []) to a + const object.

      + +

      Class + const_item_policies synopsis

      +
      +namespace boost { namespace python { namespace api
      +{
      +  struct const_item_policies
      +  {
      +      typedef object key_type;
      +      static object get(object const& target, object const& key);
      +  };
      +}}}
      +
      + +

      Class + const_item_policies static functions

      +
      +static object get(object const& target, object const& key);
      +
      + +
      +
      Effects: accesses the item of target specified + by key.
      + +
      Returns: An object managing the result of the + item access.
      + +
      Throws: error_already_set if a + Python exception is raised.
      +
      + +

      Class + item_policies

      + +

      The policies which are used for proxies representing an item access + (via the Python bracket operators []) to a mutable + object.

      + +

      Class + item_policies synopsis

      +
      +namespace boost { namespace python { namespace api
      +{
      +  struct item_policies : const_item_policies
      +  {
      +      static object const& set(object const& target, object const& key, object const& value);
      +      static void del(object const& target, object const& key);
      +  };
      +}}}
      +
      + +

      Class + item_policies static functions

      +
      +static object const& set(object const& target, object const& key, object const& value);
      +
      + +
      +
      Effects: sets the item of target specified by + key to value.
      + +
      Throws: error_already_set if a + Python exception is raised.
      +
      +
      +static void del(object const& target, object const& key);
      +
      + +
      +
      Effects: deletes the item of target specified + by key.
      + +
      Throws: error_already_set if a + Python exception is raised.
      +
      + + + +

      Class + const_slice_policies

      + +

      The policies which are used for proxies representing an slice access + (via the Python slice notation + [x:y]) to a + const object.

      + +

      Class + const_slice_policies synopsis

      +
      +namespace boost { namespace python { namespace api
      +{
      +  struct const_slice_policies
      +  {
      +      typedef std::pair<handle<>, handle<> > key_type;
      +      static object get(object const& target, key_type const& key);
      +  };
      +}}}
      +
      + +

      Class + const_slice_policies static functions

      +
      +static object get(object const& target, key_type const& key);
      +
      + +
      +
      Effects: accesses the slice of target specified + by key.
      + +
      Returns: An object managing the result of the + slice access.
      + +
      Throws: error_already_set if a + Python exception is raised.
      +
      + +

      Class + slice_policies

      + +

      The policies which are used for proxies representing an slice access + to a mutable object.

      + +

      Class + slice_policies synopsis

      +
      +namespace boost { namespace python { namespace api
      +{
      +  struct slice_policies : const_slice_policies
      +  {
      +      static object const& set(object const& target, key_type const& key, object const& value);
      +      static void del(object const& target, key_type const& key);
      +  };
      +}}}
      +
      + +

      Class + slice_policies static functions

      +
      +static object const& set(object const& target, key_type const& key, object const& value);
      +
      + +
      +
      Effects: sets the slice of target specified by + key to value.
      + +
      Throws: error_already_set if a + Python exception is raised.
      +
      +
      +static void del(object const& target, key_type const& key);
      +
      + +
      +
      Effects: deletes the slice of target specified + by key.
      + +
      Throws: error_already_set if a + Python exception is raised.
      +
      + + +

      Class template + object_operators<U>

      + +

      This is the base class of object and its + proxy template used to supply common interface: member + functions, and operators which must be defined within the class body. Its + template parameter U is expected to be a class derived from + object_operators<U>. In practice users should never + use this class directly, but it is documented here because it supplies + important interface to object and its proxies.

      + +

      Class template + object_operators synopsis

      +
      +namespace boost { namespace python { namespace api
      +{
      +  template <class U>
      +  class object_operators
      +  {
      +   public:
      +      // function call
      +      //
      +      object operator()() const;
      +
      +      template <class A0>
      +      object operator()(A0 const&) const;
      +      template <class A0, class A1>
      +      object operator()(A0 const&, A1 const&) const;
      +      ...
      +      template <class A0, class A1,...class An>
      +      object operator()(A0 const&, A1 const&,...An const&) const;
      +
      +      // truth value testing
      +      //
      +      typedef unspecified bool_type;
      +      operator bool_type() const;
      +
      +      // Attribute access
      +      //
      +      proxy<const_object_attribute> attr(char const*) const;
      +      proxy<object_attribute> attr(char const*);
      +
      +      // item access
      +      //
      +      template <class T>
      +      proxy<const_object_item> operator[](T const& key) const;
      +    
      +      template <class T>
      +      proxy<object_item> operator[](T const& key);
      +
      +      // slicing
      +      //
      +      template <class T, class V>
      +      proxy<const_object_slice> slice(T const& start, V const& end) const
      +    
      +      template <class T, class V>
      +      proxy<object_slice> slice(T const& start, V const& end);
      +  };
      +}}}
      +
      + +

      Class template + object_operators observer functions

      +
      +object operator()() const;
      +template <class A0>
      +object operator()(A0 const&) const;
      +template <class A0, class A1>
      +object operator()(A0 const&, A1 const&) const;
      +...
      +template <class A0, class A1,...class An>
      +object operator()(A0 const& a1, A1 const& a2,...An const& aN) const;
      +
      + +
      +
      Effects: + call<object>(object(*static_cast<U*>(this)).ptr(), a1, + a2,...aN)
      +
      +
      +operator bool_type() const;
      +
      + +
      +
      Effects: Tests truth value of *this.
      + +
      Returns: + call<object>(object(*static_cast<U*>(this)).ptr(), a1, + a2,...aN)
      +
      +
      +proxy<const_object_attribute> attr(char const* name) const;
      +proxy<object_attribute> attr(char const* name);
      +
      + +
      +
      Requires: name is an ntbs.
      + +
      Effects: accesses the named attribute of + *this.
      + +
      Returns: a proxy object which binds + object(*static_cast<U*>(this)) as its target, and + name as its key.
      +
      +
      +template <class T>
      +proxy<const_object_item> operator[](T const& key) const;
      +template <class T>
      +proxy<object_item> operator[](T const& key);
      +
      + +
      +
      Effects: accesses the item of *this indicated + by key.
      + +
      Returns: a proxy object which binds + object(*static_cast<U*>(this)) as its target, and + object(key) as its key.
      +
      +
      +template <class T, class V>
      +proxy<const_object_slice> slice(T const& start; start, V const& finish) const
      +template <class T, class V>
      +proxy<object_slice> slice(T const& start; start, V const& finish);
      +
      + +
      +
      Effects: accesses the slice of *this indicated + by std::make_pair(object(start), object(finish)).
      + +
      Returns: a proxy object which binds + object(*static_cast<U*>(this)) as its target, and + std::make_pair(object(start), object(finish)) as its + key.
      +
      + + +

      Class object

      + +

      The intention is that object acts as much like a Python + variable as possible. Thus expressions you'd expect to work in Python + should generally work in the same way from C++.

      + +

      Class object + synopsis

      +
      +namespace boost { namespace python { namespace api
      +{
      +  class object : public object_operators<object>
      +  {
      +   public:
      +      object();
      +
      +      object(object const&);
      +      
      +      template <class T>
      +      explicit object(T const& x);
      +
      +      ~object();
      +
      +      object& operator=(object const&); 
      +
      +      PyObject* ptr() const;
      +  };
      +}}}
      +
      + +

      Class object + constructors and destructor

      +
      +object();
      +
      + +
      +
      Effects: Constructs an object managing a reference to the + Python None object.
      + +
      Throws: nothing.
      +
      +
      +template <class T>
      +explicit object(T const& x);
      +
      + +
      +
      Effects: converts x to python and manages a + reference to it.
      + +
      Throws: error_already_set and sets a Python + TypeError exception if no such conversion is + possible.
      +
      +
      +~object();
      +
      + +
      +
      Effects: decrements the reference count of the + internally-held object.
      +
      + +

      Class object + modifiers

      +
      +object& operator=(object const& rhs); 
      +
      + +
      +
      Effects: increments the reference count of the object held + by rhs and decrements the reference count of the object + held by *this.
      +
      + +

      Class object + observers

      +
      +PyObject* ptr() const;
      +
      + +
      +
      Returns: a pointer to the internally-held Python + object.
      +
      + + +

      Class template proxy

      + +

      This template is instantiated with various Policies described in this + document in order to implement attribute, item, and slice access for + object. It stores an object of type + Policies::key_type.

      + +

      Class template proxy + synopsis

      +
      +namespace boost { namespace python { namespace api
      +{
      +  template <class Policies>
      +  class proxy : public object_operators<proxy<Policies> >
      +  {
      +   public:
      +      operator object() const;
      +
      +      proxy const& operator=(proxy const&) const;
      +      template <class T>
      +      inline proxy const& operator=(T const& rhs) const;
      +      
      +      void del() const;
      +
      +      template <class R>
      +      proxy operator+=(R const& rhs);
      +      template <class R>
      +      proxy operator-=(R const& rhs);
      +      template <class R>
      +      proxy operator*=(R const& rhs);
      +      template <class R>
      +      proxy operator/=(R const& rhs);
      +      template <class R>
      +      proxy operator%=(R const& rhs);
      +      template <class R>
      +      proxy operator<<=(R const& rhs);
      +      template <class R>
      +      proxy operator>>=(R const& rhs);
      +      template <class R>
      +      proxy operator&=(R const& rhs);
      +      template <class R>
      +      proxy operator|=(R const& rhs);
      +  };
      +}}}
      +
      + +

      Class template proxy + observer functions

      +
      +operator object() const;
      +
      + +
      +
      Effects: applies + Policies::get(target, key + ) with the proxy's target and key objects.
      +
      + +

      Class template proxy + modifier functions

      +
      +proxy const& operator=(proxy const& rhs) const;
      +template <class T>
      +inline proxy const& operator=(T const& rhs) const;
      +
      + +
      +
      Effects: + Policies::set(target, key + , object(rhs)) with the proxy's target and key + objects.
      +
      +
      +template <class R>
      +proxy operator+=(R const& rhs);
      +template <class R>
      +proxy operator-=(R const& rhs);
      +template <class R>
      +proxy operator*=(R const& rhs);
      +template <class R>
      +proxy operator/=(R const& rhs);
      +template <class R>
      +proxy operator%=(R const& rhs);
      +template <class R>
      +proxy operator<<=(R const& rhs);
      +template <class R>
      +proxy operator>>=(R const& rhs);
      +template <class R>
      +proxy operator&=(R const& rhs);
      +template <class R>
      +proxy operator|=(R const& rhs);
      +
      + +
      +
      Effects: for a given operator@=, + object(*this) @= rhs;
      +
      Returns: *this
      +
      +
      +void del() const;
      +
      + +
      +
      Effects: + Policies::del(target, key + ) with the proxy's target and key objects.
      +
      + + +

      Functions

      +
      +template <class T>
      +void del(proxy<T> const& x);
      +
      + +
      +
      Effects: x.del()
      +
      +
      +
      +template<class L,class R> bool operator>(L const&l,R const&r);
      +template<class L,class R> bool operator>=(L const&l,R const&r);
      +template<class L,class R> bool operator<(L const&l,R const&r);
      +template<class L,class R> bool operator<=(L const&l,R const&r);
      +template<class L,class R> bool operator==(L const&l,R const&r);
      +template<class L,class R> bool operator!=(L const&l,R const&r);
      +
      + +
      +
      Effects: returns the result of applying the operator to + object(l) and object(r), respectively, in + Python.
      +
      +
      +
      +template<class L,class R> object operator+(L const&l,R const&r);
      +template<class L,class R> object operator-(L const&l,R const&r);
      +template<class L,class R> object operator*(L const&l,R const&r);
      +template<class L,class R> object operator/(L const&l,R const&r);
      +template<class L,class R> object operator%(L const&l,R const&r);
      +template<class L,class R> object operator<<(L const&l,R const&r);
      +template<class L,class R> object operator>>(L const&l,R const&r);
      +template<class L,class R> object operator&(L const&l,R const&r);
      +template<class L,class R> object operator^(L const&l,R const&r);
      +template<class L,class R> object operator|(L const&l,R const&r);
      +
      + +
      +
      Effects: returns the result of applying the operator to + object(l) and object(r), respectively, in + Python.
      +
      +
      +
      +template<class R> object& operator+=(object&l,R const&r);
      +template<class R> object& operator-=(object&l,R const&r);
      +template<class R> object& operator*=(object&l,R const&r);
      +template<class R> object& operator/=(object&l,R const&r);
      +template<class R> object& operator%=(object&l,R const&r);
      +template<class R> object& operator<<=(object&l,R const&r)
      +template<class R> object& operator>>=(object&l,R const&r);
      +template<class R> object& operator&=(object&l,R const&r);
      +template<class R> object& operator^=(object&l,R const&r);
      +template<class R> object& operator|=(object&l,R const&r);
      +
      + +
      +
      Effects: assigns to l the result of applying the + corresponding Python inplace operator to l and + object(r), respectively.
      + +
      Returns: l.
      +
      + +

      Example

      + Python code: +
      +def sum_items(seq):
      +   result = 0
      +   for x in seq:
      +      result += x
      +   return result
      +
      + C++ version: +
      +object sum_items(object seq)
      +{
      +   object result = object(0);
      +   for (int i = 0; i < seq.attr("__len__")(); ++i)
      +      result += seq[i];
      +   return result;
      +}
      +
      + +

      Revised + + 02 October, 2002 + +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From 8cecbe31a7a1197107b23d282b85b1041dfb5d8e Mon Sep 17 00:00:00 2001 From: Aleksey Gurtovoy Date: Thu, 3 Oct 2002 09:23:27 +0000 Subject: [PATCH 0800/1042] fix for empty type_list problem [SVN r15663] --- include/boost/python/detail/type_list_impl_no_pts.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/detail/type_list_impl_no_pts.hpp b/include/boost/python/detail/type_list_impl_no_pts.hpp index be537793..d4d282aa 100644 --- a/include/boost/python/detail/type_list_impl_no_pts.hpp +++ b/include/boost/python/detail/type_list_impl_no_pts.hpp @@ -95,9 +95,9 @@ struct type_list_impl_chooser > struct result_ { - typedef BOOST_PP_CAT(mpl::list,N)< + typedef typename BOOST_PP_CAT(mpl::list,N)< BOOST_PP_ENUM_PARAMS(N, T) - > type; + >::type type; }; }; From f7b087ed8f6649716e4d3b5a225e1b7e6eaa7676 Mon Sep 17 00:00:00 2001 From: Aleksey Gurtovoy Date: Thu, 3 Oct 2002 09:28:47 +0000 Subject: [PATCH 0801/1042] get rid of leftover MPL includes [SVN r15664] --- include/boost/python/detail/defaults_gen.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index d879da19..be41c716 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -24,8 +24,7 @@ #include #include #include -#include -#include +#include namespace boost { namespace python { From f43b913302fff757a0816cdd8931a3112378d8f7 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 3 Oct 2002 12:41:12 +0000 Subject: [PATCH 0802/1042] reference doc for .def_pickle() [SVN r15665] --- doc/v2/class.html | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/doc/v2/class.html b/doc/v2/class.html index c3e95f74..f2fd15c5 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -265,7 +265,6 @@ namespace boost { namespace python void add_property(char const* name, Get const& fget, Set const& fset); // pickle support - void enable_pickling(bool getstate_manages_dict); template <typename PickleSuite> self& def_pickle(PickleSuite const&); }; @@ -593,30 +592,32 @@ this->add_property(name,
      -void enable_pickling(bool getstate_manages_dict);
      -
      - -
      -
      Requires: {{Ralf}}
      - -
      Effects: {{Ralf}}
      - -
      Rationale: Allows users to easily expose functions that can - be invoked from Python with attribute access syntax.
      -
      -
       template <typename PickleSuite>
       class_& def_pickle(PickleSuite const&);
       
      -
      Requires: {{Ralf}}
      +
      Requires: PickleSuite must be publically derived from + pickle_suite.
      -
      Effects: {{Ralf}}
      +
      Effects: Defines a legal combination of the special + attributes and methods: + __getinitargs__, + __getstate__, + __setstate__, + __getstate_manages_dict__, + __safe_for_unpickling__, + __reduce__ +
      Returns: *this
      -
      Rationale: {{Ralf}}
      +
      Rationale: Provides an + easy to use high-level interface + for establishing complete pickle support for the wrapped class. + The user is protected by compile-time consistency checks.

      From 17033037eb2173408d961c9ae7519f7a3b4d5545 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 3 Oct 2002 12:41:22 +0000 Subject: [PATCH 0803/1042] explains that enable_pickling() is an implementation detail [SVN r15666] --- include/boost/python/object/class.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index e97f8edd..f551c29c 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -35,7 +35,6 @@ struct BOOST_PYTHON_DECL class_base : python::api::object void add_property(char const* name, object const& fget); void add_property(char const* name, object const& fget, object const& fset); void setattr(char const* name, object const&); - void enable_pickling(bool getstate_manages_dict); // Set a special attribute in the class which tells Boost.Python // to allocate extra bytes for embedded C++ objects in Python @@ -45,6 +44,10 @@ struct BOOST_PYTHON_DECL class_base : python::api::object // Set an __init__ function which throws an appropriate exception // for abstract classes. void def_no_init(); + + // Implementation detail. Hiding this in the private section would + // require use of template friend declarations. + void enable_pickling(bool getstate_manages_dict); }; }}} // namespace boost::python::objects From 48fffd7a7bb5fe96179f435ef26bd147f83e541b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 3 Oct 2002 13:09:24 +0000 Subject: [PATCH 0804/1042] doc update [SVN r15667] --- doc/v2/pointee.html | 116 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 doc/v2/pointee.html diff --git a/doc/v2/pointee.html b/doc/v2/pointee.html new file mode 100644 index 00000000..a5387da4 --- /dev/null +++ b/doc/v2/pointee.html @@ -0,0 +1,116 @@ + + + + + + Boost.Python - <boost/python/pointee.hpp> + + + +
      +

      +

      + +
      +

      Boost.Python

      + +

      Header <boost/python/pointee.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction + +
      Classes + +
      +
      +
      Class Templatepointee + +
      +
      +
      Class Template + pointee synopsis +
      +
      + +
      Example +
      +
      + +

      Introduction

      + +

      <boost/python/pointee.hpp> introduces a + traits metafunction + template pointee<T> which can be used to extract the "pointed-to" type from the type of a pointer or smart pointer. + +

      Classes

      + +

      Class Template pointee<class T>

      + +

      pointee<T> is used by the class_<...> + template to deduce the type being held when a pointer or smart + pointer type is used as its HeldType argument. + +

      Class Template + pointee synopsis

      +
      +namespace boost { namespace python
      +{
      +   template <class T> struct pointee
      +   {
      +      typedef T::element_type type;
      +   };
      +
      +   // specialization for pointers
      +   template <T> struct pointee<T*>
      +   {
      +      typedef T type;
      +   };
      +}
      +
      + + +

      Example

      + +Given a 3rd-party smart pointer type +smart_pointer<T>, one might partially specialize +pointee<smart_pointer<T> > so that it can be +used as the HeldType for a class wrapper: + +
      +#include <boost/python/pointee.hpp>
      +#include <boost/python/class.hpp>
      +#include <third_party_lib.hpp>
      +
      +namespace boost { namespace python
      +{
      +  template <class T> struct pointee<smart_pointer<T> >
      +  {
      +     typedef T type;
      +  };
      +}}
      +
      +BOOST_PYTHON_MODULE(pointee_demo)
      +{
      +   class_<third_party_class, smart_pointer<third_party_class> >("third_party_class")
      +      .def(...)
      +      ...
      +      ;
      +}
      +
      + +

      Revised + + 03 October, 2002 + + + +

      © Copyright Dave + Abrahams 2002. All Rights Reserved. + From 021aa51707ed1e359d75575b897fbe74cce20641 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 3 Oct 2002 14:07:13 +0000 Subject: [PATCH 0805/1042] doc update [SVN r15674] --- doc/v2/object.html | 12 ++- doc/v2/str.html | 230 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 239 insertions(+), 3 deletions(-) create mode 100644 doc/v2/str.html diff --git a/doc/v2/object.html b/doc/v2/object.html index 8fcd05c5..9d6c6b53 100644 --- a/doc/v2/object.html +++ b/doc/v2/object.html @@ -631,9 +631,15 @@ proxy<object_slice> slice(T const& start; start, V const& finish);

      Class object

      -

      The intention is that object acts as much like a Python - variable as possible. Thus expressions you'd expect to work in Python - should generally work in the same way from C++.

      +

      The intention is that object acts as much like a + Python variable as possible. Thus expressions you'd expect to work + in Python should generally work in the same way from C++. Most of + object's interface is provided by its base class + object_operators<object>, + and the free functions defined in this + header. +

      Class object synopsis

      diff --git a/doc/v2/str.html b/doc/v2/str.html new file mode 100644 index 00000000..9985fb53 --- /dev/null +++ b/doc/v2/str.html @@ -0,0 +1,230 @@ + + + + + + + + + Boost.Python - <boost/python/str.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/str.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Classes
      + +
      +
      +
      Class str
      + +
      +
      +
      Class str + synopsis
      +
      +
      +
      +
      + +
      Example(s)
      +
      +
      + +

      Introduction

      + +

      Exposes a TypeWrapper for the Python + str + type.

      + +

      Classes

      + +

      Class str

      + +

      Exposes the string + methods of Python's built-in str type. The + semantics of the constructors and member functions defined below + can be fully understood by reading the TypeWrapper concept + definition. Since str is publicly derived from + object, the + public object interface applies to str instances as + well.

      + +

      Class str + synopsis

      +
      +namespace boost
      +{
      +  class str : public object
      +  {
      +   public:
      +      str(); // new str
      +
      +      str(const char* s); // new str
      +
      +      template <class T>
      +      explicit str(T const& other);
      +
      +      str capitalize() const;
      +
      +      template <class T>
      +      str center(T const& width) const;
      +
      +      template<class T>
      +      long count(T const& sub) const;
      +      template<class T1, class T2>
      +      long count(T1 const& sub,T2 const& start) const;
      +      template<class T1, class T2, class T3>
      +      long count(T1 const& sub,T2 const& start, T3 const& end) const;
      +
      +      object decode() const;
      +      template<class T>
      +      object decode(T const& encoding) const;
      +      template<class T1, class T2>
      +      object decode(T1 const& encoding, T2 const& errors) const;
      +
      +      object encode() const;
      +      template <class T>
      +      object encode(T const& encoding) const;
      +      template <class T1, class T2>
      +      object encode(T1 const& encoding, T2 const& errors) const;
      +
      +      template <class T>
      +      bool endswith(T const& suffix) const;
      +      template <class T1, class T2>
      +      bool endswith(T1 const& suffix, T2 const& start) const;
      +      template <class T1, class T2, class T3>
      +      bool endswith(T1 const& suffix, T2 const& start, T3 const& end) const;
      +
      +      str expandtabs() const;
      +      template <class T>
      +      str expandtabs(T const& tabsize) const;
      +
      +      template <class T>
      +      long find(T const& sub) const;
      +      template <class T1, class T2>
      +      long find(T1 const& sub, T2 const& start) const;
      +      template <class T1, class T2, class T3>
      +      long find(T1 const& sub, T2 const& start, T3 const& end) const;
      +
      +      template <class T>
      +      long index(T const& sub) const;
      +      template <class T1, class T2>
      +      long index(T1 const& sub, T2 const& start) const;
      +      template <class T1, class T2, class T3>
      +      long index(T1 const& sub, T2 const& start, T3 const& end) const;
      +
      +      bool isalnum() const;
      +      bool isalpha() const;
      +      bool isdigit() const;
      +      bool islower() const;
      +      bool isspace() const;
      +      bool istitle() const;
      +      bool isupper() const;
      +
      +      template <class T>
      +      str join(T const& sequence) const;
      +
      +      template <class T>
      +      str ljust(T const& width) const;
      +
      +      str lower() const;
      +      str lstrip() const;
      +
      +      template <class T1, class T2>
      +      str replace(T1 const& old, T2 const& new_) const;
      +      template <class T1, class T2, class T3>
      +      str replace(T1 const& old, T2 const& new_, T3 const& maxsplit) const;
      +
      +      template <class T>
      +      long rfind(T const& sub) const;
      +      template <class T1, class T2>
      +      long rfind(T1 const& sub, T2 const& start) const;
      +      template <class T1, class T2, class T3>
      +      long rfind(T1 const& sub, T2 const& start, T3 const& end) const;
      +
      +      template <class T>
      +      long rindex(T const& sub) const;
      +      template <class T1, class T2>
      +      long rindex(T1 const& sub, T2 const& start) const;
      +      template <class T1, class T2, class T3>
      +      long rindex(T1 const& sub, T2 const& start, T3 const& end) const;
      +
      +      template <class T>
      +      str rjust(T const& width) const;
      +
      +      str rstrip() const;
      +
      +      list split() const; 
      +      template <class T>
      +      list split(T const& sep) const;
      +      template <class T1, class T2>
      +      list split(T1 const& sep, T2 const& maxsplit) const;
      +
      +      list splitlines() const;
      +      template <class T>
      +      list splitlines(T const& keepends) const;
      +
      +      template <class T>
      +      bool startswith(T const& prefix) const;
      +      template <class T1, class T2>
      +      bool startswidth(T1 const& prefix, T2 const& start) const;
      +      template <class T1, class T2, class T3>
      +      bool startswidth(T1 const& prefix, T2 const& start, T3 const& end) const;
      +
      +      str strip() const;
      +      str swapcase() const;
      +      str title() const;
      +
      +      template <class T>
      +      str translate(T const& table) const;
      +      template <class T1, class T2>
      +      str translate(T1 const& table, T2 const& deletechars) const;
      +
      +      str upper() const;
      +  };
      +}
      +
      + +

      Example

      +
      +using namespace boost::python;
      +str remove_angle_brackets(str x)
      +{
      +  return x.strip('<').strip('>');
      +}
      +
      + +

      Revised 3 October, 2002

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From 90a6d484b75f6d871fe521ef1b6cba5599a6f3d4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 3 Oct 2002 14:53:32 +0000 Subject: [PATCH 0806/1042] doc update [SVN r15675] --- doc/v2/dict.html | 8 ++++---- doc/v2/extract.html | 28 ++++++++++++++-------------- doc/v2/list.html | 4 ++-- doc/v2/long.html | 4 ++-- doc/v2/str.html | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/doc/v2/dict.html b/doc/v2/dict.html index 0fe58f1b..4ab47aa3 100644 --- a/doc/v2/dict.html +++ b/doc/v2/dict.html @@ -77,14 +77,14 @@

      Class dict synopsis

      -namespace boost
      +namespace boost { namespace python
       {
          class dict : public object
          {
      -      dict() ;
      +      dict();
       
             template< class T >
      -      dict(T const & data) ;
      +      dict(T const & data);
       
             // modifiers
             void clear();
      @@ -126,7 +126,7 @@ namespace boost
             object itervalues() const;
             list keys() const;
         };
      -}
      +}}
       

      Example

      diff --git a/doc/v2/extract.html b/doc/v2/extract.html index 5ce2aec2..b49d587b 100644 --- a/doc/v2/extract.html +++ b/doc/v2/extract.html @@ -97,22 +97,22 @@ a conversion is available without causing an exception to be thrown.

      Class template extract synopsis

      -namespace boost
      +namespace boost { namespace python
       {
      -template <class T>
      -struct extract
      -{
      -    typedef unspecified result_type;
      -    
      -    extract(PyObject*);
      -    extract(object const&);
      +  template <class T>
      +  struct extract
      +  {
      +      typedef unspecified result_type;
       
      -    result_type operator()() const;
      -    operator result_type() const;
      -    
      -    bool check() const;
      -};
      -};
      +      extract(PyObject*);
      +      extract(object const&);
      +
      +      result_type operator()() const;
      +      operator result_type() const;
      +
      +      bool check() const;
      +  };
      +}}
       

      Class extract diff --git a/doc/v2/list.html b/doc/v2/list.html index 843e4519..858102e0 100644 --- a/doc/v2/list.html +++ b/doc/v2/list.html @@ -77,7 +77,7 @@

      Class list synopsis

      -namespace boost
      +namespace boost { namespace python
       {
         class list : public object
         {
      @@ -116,7 +116,7 @@ namespace boost
             template <class T>
             void sort(T const& value);
         };
      -}
      +}}
       

      Example

      diff --git a/doc/v2/long.html b/doc/v2/long.html index 799fa533..13079684 100644 --- a/doc/v2/long.html +++ b/doc/v2/long.html @@ -77,7 +77,7 @@

      Class long_ synopsis

      -namespace boost
      +namespace boost { namespace python
       {
         class long_ : public object
         {
      @@ -90,7 +90,7 @@ namespace boost
             template <class T, class U>
             long_(T const& rhs, U const& base);
         };
      -}
      +}}
       

      Example

      diff --git a/doc/v2/str.html b/doc/v2/str.html index 9985fb53..842dc660 100644 --- a/doc/v2/str.html +++ b/doc/v2/str.html @@ -78,7 +78,7 @@

      Class str synopsis

      -namespace boost
      +namespace boost { namespace python
       {
         class str : public object
         {
      @@ -208,7 +208,7 @@ namespace boost
       
             str upper() const;
         };
      -}
      +}}
       

      Example

      From 2bdc4cdffa78ce623bb1e260d0c50e94d997d0ce Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 3 Oct 2002 16:49:55 +0000 Subject: [PATCH 0807/1042] doc update [SVN r15679] --- doc/v2/tuple.html | 137 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 doc/v2/tuple.html diff --git a/doc/v2/tuple.html b/doc/v2/tuple.html new file mode 100644 index 00000000..8fb672fa --- /dev/null +++ b/doc/v2/tuple.html @@ -0,0 +1,137 @@ + + + + + + + + + Boost.Python - <boost/python/tuple.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/tuple.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Classes
      + +
      +
      +
      Class tuple
      + +
      +
      +
      Class tuple + synopsis
      +
      +
      +
      +
      + +
      Functions
      + +
      +
      +
      make_tuple
      +
      +
      + +
      Example
      +
      +
      + +

      Introduction

      + +

      Exposes a TypeWrapper for the Python + + tuple type.

      + +

      Classes

      + +

      Class tuple

      + +

      Exposes the interface of Python's built-in tuple type. + The semantics of the constructors and member functions defined below can + be fully understood by reading the TypeWrapper concept + definition. Since tuple is publicly derived from object, the public object + interface applies to tuple instances as well.

      + +

      Class tuple + synopsis

      +
      +namespace boost { namespace python
      +{
      +   class tuple : public object
      +   {
      +      // tuple() -> an empty tuple
      +      tuple();
      +
      +      // tuple(sequence) -> tuple initialized from sequence's items
      +      template <class T>
      +      explicit tuple(T const& sequence)
      +  };
      +}}
      +
      + +

      Functions

      + +

      make_tuple

      +
      +namespace boost { namespace python
      +{
      +  tuple make_tuple();
      +
      +  template <class A0>
      +  tuple make_tuple(A0 const& a0);
      +
      +  template <class A0, class A1>
      +  tuple make_tuple(A0 const& a0, A1 const& a1);
      +  ...
      +  template <class A0, class A1,...class An> 
      +  tuple make_tuple(A0 const& a0, A1 const& a1,...An const& an);
      +}}
      +
      + Constructs a new tuple object composed of object(a0), + object(a0),...object(an). + +

      Example

      +
      +using namespace boost::python;
      +tuple head_and_tail(object sequence)
      +{
      +    return make_tuple(sequence[0],sequence[-1]);
      +}
      +
      + +

      Revised 03 October, 2002

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From 2bdd01d084b66b375e4900e0172c8fd44a416341 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 3 Oct 2002 18:20:06 +0000 Subject: [PATCH 0808/1042] doc update [SVN r15680] --- doc/v2/scope.html | 153 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 doc/v2/scope.html diff --git a/doc/v2/scope.html b/doc/v2/scope.html new file mode 100644 index 00000000..17450645 --- /dev/null +++ b/doc/v2/scope.html @@ -0,0 +1,153 @@ + + + + + + + + + Boost.Python - <boost/python/scope.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/scope.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Classes
      + +
      +
      +
      Class scope
      + +
      +
      +
      Class scope + synopsis
      + +
      Class scope + constructors and destructor
      +
      +
      +
      +
      + +
      Example
      +
      +
      + +

      Introduction

      + +

      Defines facilities for querying and controlling the Python scope + (namespace) which will contain new wrapped classes and functions.

      + +

      Classes

      + +

      Class scope

      + +

      The scope class has an associated global Python object + which controls the Python namespace in which new extension classes and + wrapped functions will be defined as attributes. Default-constructing a + new scope object binds that object to the associated Python + object. Constructing a is associated with , and

      + +

      Class scope + synopsis

      +
      +namespace boost { namespace python
      +{
      +  class scope : public object, private noncopyable
      +  {
      +   public:
      +      scope(object const&);
      +      scope();
      +      ~scope()
      +  };
      +}}
      +
      + +

      Class scope constructors + and destructor

      +
      +scope(object const& x);
      +
      + Stores a reference to the current associated scope object, and sets the + associated scope object to the one referred to by x.ptr(). + The object base class is initialized with x. +
      +scope();
      +
      + Stores a reference to the current associated scope object. The + object base class is initialized with the current associated + scope object. Outside any module initialization function, the current + associated Python object is None. +
      +~scope()
      +
      + Sets the current associated Python object to the stored object. + +

      Example

      + The following example shows how scope setting can be used to define + nested classes. + +

      C++ Module definition:

      +
      +#include <boost/python/class.hpp>
      +#include <boost/python/scope.hpp>
      +using namespace boost::python;
      +
      +struct X
      +{
      +  void f();
      +
      +  struct Y { int g() { return 0; } };
      +};
      +
      +BOOST_PYTHON_MODULE(nested)
      +{
      +   scope outer
      +       = class_<X>("X")
      +            .def("f", &X::f)
      +            ;
      +   class_<Y>("Y")
      +      .def("g", &Y::g)
      +      ;
      +}
      +
      + Interactive Python: +
      +>>> import nested
      +>>> y = nested.X.Y()
      +>>> y.g()
      +0
      +
      + +

      Revised 03 October, 2002

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From 66ff762fbb22fd3830f8731365c454ca156f6774 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 3 Oct 2002 18:40:58 +0000 Subject: [PATCH 0809/1042] doc update [SVN r15681] --- doc/v2/def.html | 195 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 doc/v2/def.html diff --git a/doc/v2/def.html b/doc/v2/def.html new file mode 100644 index 00000000..25a78bf8 --- /dev/null +++ b/doc/v2/def.html @@ -0,0 +1,195 @@ + + + + + + + + + Boost.Python - <boost/python/def.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/def.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Functions
      + +
      +
      +
      def
      +
      +
      + +
      Example
      +
      +
      + +

      Introduction

      + +

      def() is the function which can + be used to expose C++ functions and callable objects as Python functions + in the current scope.

      + +

      Functions

      +
      +template <class F>
      +void def(char const* name, F f);
      +
      +template <class Fn, class A1>
      +void def(char const* name, Fn fn, A1 const&);
      +
      +template <class Fn, class A1, class A2>
      +void def(char const* name, Fn fn, A1 const&, A2 const&);
      +
      +template <class Fn, class A1, class A2, class A3>
      +void def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
      +
      + +
      +
      Requires: name is an ntbs which conforms to Python's identifier + naming rules.
      + +
      +
        +
      • + If a1 is the result of an overload-dispatch-expression, + only the second form is allowed and fn must be a pointer to + function or pointer to member function whose arity is the same as A1's maximum + arity. + +
        +
        Effects: For each prefix P of + Fn's sequence of argument types, beginning with + the one whose length is A1's minimum + arity, adds a + name(...) function overload + to the current scope. Each overload + generated invokes a1's call-expression with + P, using a copy of a1's call policies. If the longest valid + prefix of A1 contains N types and + a1 holds M keywords, an initial sequence + of the keywords are used for all but the first + N - M arguments of each + overload.
        +
        +
        +
      • + +
      • + Otherwise, a single function overload built around fn (which must + not be null) is added to the current + scope: + +
          +
        • If fn is a function or member function pointer, + a1-a3 (if supplied) may be selected + in any order from the table below.
        • + +
        • Otherwise, Fn must be [derived from] object, and + a1-a2 (if supplied) may be selcted in any order + from the first two rows of the table below. To be useful, + fn should be + callable.
        • +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Memnonic NameRequirements/Type propertiesEffects
        docstringAny ntbs.Value will be bound to the __doc__ attribute + of the resulting method overload.
        policiesA model of CallPoliciesA copy will be used as the call policies of the resulting + method overload.
        keywordsThe result of a keyword-expression + specifying no more arguments than the arity of fn.A copy will be used as the call policies of the resulting + method overload.
        +
      • +
      +
      +
      + +

      Example

      +
      +#include <boost/python/def.hpp>
      +#include <boost/python/module.hpp>
      +#include <boost/python/args.hpp>
      +
      +char const* foo(int x, int y) { return "foo"; }
      +
      +BOOST_PYTHON_MODULE(def_test)
      +{
      +    def("foo", foo, args("x", "y"), "foo's docstring");
      +}
      +
      + +

      + + 03 October, 2002 + +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From f5eab480178ccfd04b5c49adb091f1f5684b5bfe Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 3 Oct 2002 18:54:19 +0000 Subject: [PATCH 0810/1042] doc update [SVN r15682] --- doc/v2/faq.html | 131 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 20 deletions(-) diff --git a/doc/v2/faq.html b/doc/v2/faq.html index 8e8be4e5..7a2811af 100644 --- a/doc/v2/faq.html +++ b/doc/v2/faq.html @@ -29,36 +29,127 @@
      -
      {{question}}
      +
      Is return_internal reference + efficient?
      -
      {{question}}
      +
      How can I which take C++ containers as + arguments?

      Is return_internal reference efficient?

      - Q: I have an object composed of 12 doubles. A const& to this object is - returned by a member function of another class. From the viewpoint of - using the returned object in Python I do not care if I get a copy or a - reference to the returned object. In Boost.Python Version 2 I have the - choice of using copy_const_reference or return_internal_reference. Are - there considerations that would lead me to prefer one over the other, - such as size of generated code or memory overhead? + Q: I have an object composed of 12 doubles. A const& to + this object is returned by a member function of another class. From the + viewpoint of using the returned object in Python I do not care if I get + a copy or a reference to the returned object. In Boost.Python Version 2 + I have the choice of using copy_const_reference or + return_internal_reference. Are there considerations that would lead me + to prefer one over the other, such as size of generated code or memory + overhead? -

      A: copy_const_reference will make an instance with storage for one of - your objects, size = base_size + 12 * sizeof(double). - return_internal_reference will make an instance with storage for a - pointer to one of your objects, size = base_size + sizeof(void*). - However, it will also create a weak reference object which goes in the - source object's weakreflist and a special callback object to manage the - lifetime of the internally-referenced object. My guess? - copy_const_reference is your friend here, resulting in less overall - memory use and less fragmentation, also probably fewer total cycles.

      +

      A: copy_const_reference will make an instance with storage + for one of your objects, size = base_size + 12 * sizeof(double). + return_internal_reference will make an instance with storage for a + pointer to one of your objects, size = base_size + sizeof(void*). + However, it will also create a weak reference object which goes in the + source object's weakreflist and a special callback object to manage the + lifetime of the internally-referenced object. My guess? + copy_const_reference is your friend here, resulting in less overall + memory use and less fragmentation, also probably fewer total + cycles.

      -

      {{question}}

      +

      How can I wrap functions which take C++ + containers as arguments?

      -

      {{answer}}

      +

      Ralf W. Grosse-Kunstleve provides these notes:

      + +
        +
      1. + Using the regular class_<> wrapper: +
        +class_<std::vector<double> >("std_vector_double")
        +  .def(...)
        +  ...
        +  ;
        +
        + This can be moved to a template so that several types (double, int, + long, etc.) can be wrapped with the same code. This technique is used + in the file + +
        + scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h +
        + in the "scitbx" package. The file could easily be modified for + wrapping std::vector<> instantiations. + +

        This type of C++/Python binding is most suitable for containers + that may contain a large number of elements (>10000).

        +
      2. + +
      3. + Using custom rvalue converters. Boost.Python "rvalue converters" + match function signatures such as: +
        +void foo(std::vector<double> const& array); // pass by const-reference
        +void foo(std::vector<double> array); // pass by value
        +
        + Some custom rvalue converters are implemented in the file + +
        + scitbx/include/scitbx/boost_python/container_conversions.h +
        + This code can be used to convert from C++ container types such as + std::vector<> or std::list<> to Python tuples and vice + versa. A few simple examples can be found in the file + +
        + scitbx/array_family/boost_python/regression_test_module.cpp +
        + Automatic C++ container <-> Python tuple conversions are most + suitable for containers of moderate size. These converters generate + significantly less object code compared to alternative 1 above. +
      4. +
      + A disadvantage of using alternative 2 is that operators such as + arithmetic +,-,*,/,% are not available. It would be useful to have custom + rvalue converters that convert to a "math_array" type instead of tuples. + This is currently not implemented but is possible within the framework of + Boost.Python V2 as it will be released in the next couple of weeks. [ed.: + this was posted on 2002/03/10] + +

      It would also be useful to also have "custom lvalue converters" such + as std::vector<> <-> Python list. These converters would + support the modification of the Python list from C++. For example:

      + +

      C++:

      +
      +void foo(std::vector<double>& array)
      +{
      +  for(std::size_t i=0;i<array.size();i++) {
      +    array[i] *= 2;
      +  }
      +}
      +
      + Python: +
      +>>> l = [1, 2, 3]
      +>>> foo(l)
      +>>> print l
      +[2, 4, 6]
      +
      + Custom lvalue converters require changes to the Boost.Python core library + and are currently not available. + +

      P.S.:

      + +

      The "scitbx" files referenced above are available via anonymous + CVS:

      +
      +cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login
      +cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
      +

      Revised From 7b9dad44d1d7a76c604392a638cab3bc2c6651f5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 3 Oct 2002 20:18:53 +0000 Subject: [PATCH 0811/1042] doc update [SVN r15683] --- doc/v2/numeric.html | 268 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 doc/v2/numeric.html diff --git a/doc/v2/numeric.html b/doc/v2/numeric.html new file mode 100644 index 00000000..554d7611 --- /dev/null +++ b/doc/v2/numeric.html @@ -0,0 +1,268 @@ + + + + + + + + + Boost.Python - <boost/python/numeric.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/numeric.hpp>

      +
      +


      + +

      Contents

      + +
      +
      Introduction
      + +
      Classes
      + +
      +
      +
      Class array
      + +
      +
      +
      Class array + synopsis
      + +
      Class array + observer functions
      + +
      Class array + static functions
      +
      +
      +
      +
      + +
      Example(s)
      +
      +
      + +

      Introduction

      + +

      Exposes a TypeWrapper for the Python + array + type.

      + +

      Classes

      + +

      Class array

      + +

      Provides access to the array types of Numerical Python's Numeric and NumArray modules. With + the exception of the functions documented below, the semantics of the constructors and + member functions defined below can be fully understood by reading the TypeWrapper concept + definition. Since array is publicly derived from object, the public object + interface applies to array instances as well.

      + +

      The default behavior is to use + Numeric.ArrayType as the associated Python type if the + Numeric module is installed in the default location. + Otherwise it falls back to use numarray.NDArray. If neither + extension module is installed, conversions to arguments of type + numeric::array will cause overload resolution to reject the + overload, and other attempted uses of numeric::array will raise an appropriate Python exception. + The associated Python type can be set manually using the set_module_and_type(...) static + function.

      + +

      Class array + synopsis

      +
      +namespace boost { namespace python { namespace numeric
      +{
      +   class array : public object
      +   {
      +    public:
      +      object astype();
      +      template <class Type>
      +      object astype(Type const& type_);
      +
      +      template <class Type>
      +      object new_(Type const& type_) const;
      +
      +      template <class Sequence> 
      +      void resize(Sequence const& x);
      +      void resize(long x1);
      +      void resize(long x1, long x2);
      +      ...
      +      void resize(long x1, long x2,...long xn);
      +
      +      template <class Sequence> 
      +      void setshape(Sequence const& x);
      +      void setshape(long x1);
      +      void setshape(long x1, long x2);
      +      ...
      +      void setshape(long x1, long x2,...long xn);
      +
      +      template <class Indices, class Values>
      +      void put(Indices const& indices, Values const& values);
      +
      +      template <class Sequence>
      +      object take(Sequence const& sequence, long axis = 0);
      +
      +      template <class File>
      +      void tofile(File const& f) const;
      +
      +      object factory();
      +      template <class Buffer>
      +      object factory(Buffer const&);
      +      template <class Buffer, class Type>
      +      object factory(Buffer const&, Type const&);
      +      template <class Buffer, class Type, class Shape>
      +      object factory(Buffer const&, Type const&, Shape const&, bool copy = true, bool savespace = false);
      +      template <class Buffer, class Type, class Shape>
      +      object factory(Buffer const&, Type const&, Shape const&, bool copy, bool savespace, char typecode);
      +
      +      template <class T1>
      +      explicit array(T1 const& x1);
      +      template <class T1, class T2>
      +      explicit array(T1 const& x1, T2 const& x2);
      +      ...
      +      template <class T1, class T2,...class Tn>
      +      explicit array(T1 const& x1, T2 const& x2,...Tn const& xn);
      +
      +      static void set_module_and_type();
      +      static void set_module_and_type(char const* package_path = 0, char const* type_name = 0);
      +
      +      object argmax(long axis=-1);
      +
      +      object argmin(long axis=-1);
      +
      +      object argsort(long axis=-1);
      +
      +      void byteswap();
      +
      +      object copy() const;
      +
      +      object diagonal(long offset = 0, long axis1 = 0, long axis2 = 1) const;
      +
      +      void info() const;
      +
      +      bool is_c_array() const;
      +      bool isbyteswapped() const;
      +      void sort();
      +      object trace(long offset = 0, long axis1 = 0, long axis2 = 1) const;
      +      object type() const;
      +      char typecode() const;
      +      
      +      object getflat() const;
      +      long getrank() const;
      +      object getshape() const;
      +      bool isaligned() const;
      +      bool iscontiguous() const;
      +      long itemsize() const;
      +      long nelements() const;
      +      object nonzero() const;
      +   
      +      void ravel();
      +   
      +      object repeat(object const& repeats, long axis=0);
      +   
      +      void setflat(object const& flat);
      +   
      +      void swapaxes(long axis1, long axis2);
      +   
      +      str tostring() const;
      +   
      +      void transpose(object const& axes = object());
      +   
      +      object view() const;
      +  };
      +}}}
      +
      + +

      Class array observer + functions

      +
      +object factory();
      +template <class Buffer>
      +object factory(Buffer const&);
      +template <class Buffer, class Type>
      +object factory(Buffer const&, Type const&);
      +template <class Buffer, class Type, class Shape>
      +object factory(Buffer const&, Type const&, Shape const&, bool copy = true, bool savespace = false);
      +template <class Buffer, class Type, class Shape>
      +object factory(Buffer const&, Type const&, Shape const&, bool copy, bool savespace, char typecode);
      +
      + These functions map to the underlying array type's array() + function family. They are not called "array" because of the + C++ limitation that you can't define a member function with the same name + as its enclosing class. +
      +template <class Type>
      +object new_(Type const&) const;
      +
      + This function maps to the underlying array type's new() + function. It is not called "new" because that is a keyword + in C++. + +

      Class array static + functions

      +
      +static void set_module_and_type(char const* package_path, char const* type_name);
      +static void set_module_and_type();
      +
      + +
      +
      Requires: package_path and + type_name, if supplied, is an ntbs.
      + +
      Effects: The first form sets the package path of the module + which supplies the type named by type_name to + package_path. The second form restores the default search behavior. The associated Python + type will be searched for only the first time it is needed, and + thereafter the first time it is needed after an invocation of + set_module_and_type.
      +
      + +

      Example

      +
      +#include <boost/python/numeric.hpp>
      +#include <boost/python/tuple.hpp>
      +
      +// sets the first element in a 2d numeric array
      +void set_first_element(numeric::array& y, double value)
      +{
      +    y[make_tuple(0,0)] = value;
      +}
      +
      + +

      Revised 03 October, 2002

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From 8f989f318bf63cd67081d5c33153f82906625a36 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 3 Oct 2002 20:59:43 +0000 Subject: [PATCH 0812/1042] doc update [SVN r15684] --- doc/v2/enum.html | 203 +++++++++++++++++++++++++++++++++++++++++++++ doc/v2/init.html | 3 +- doc/v2/module.html | 8 +- 3 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 doc/v2/enum.html diff --git a/doc/v2/enum.html b/doc/v2/enum.html new file mode 100644 index 00000000..38d878b1 --- /dev/null +++ b/doc/v2/enum.html @@ -0,0 +1,203 @@ + + + + + + + + + Boost.Python - <boost/python/enum.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/enum.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Classes
      + +
      +
      +
      Class template + enum_
      + +
      +
      +
      Class template enum_ + synopsis
      + +
      Class template enum_ + constructors
      + +
      Class template enum_ + modifier functions
      +
      +
      + +
      +
      + +
      Example(s)
      +
      +
      + +

      Introduction

      + +

      <boost/python/enum.hpp> defines the + interface through which users expose their C++ enumeration types + to Python. It declares the + enum_ class template, which is parameterized on the + enumeration type being exposed.

      + + +

      Classes

      + +

      Class template + enum_<T>

      + +

      Creates a Python class derived from Python's int + type which is associated with the C++ type passed as its first + parameter. + +

      Class template enum_ + synopsis

      +
      +namespace boost { namespace python
      +{
      +  template <class T>
      +  class enum_ : public object
      +  {
      +    enum_(char const* name);
      +    inline enum_<T>& value(char const* name, T);
      +  };
      +}}
      +
      + +

      Class template enum_ + constructors

      +
      +enum_(char const* name);
      +
      + +
      +
      Requires: name is an ntbs which conforms to Python's identifier + naming rules. + +
      Effects: Constructs an enum_ object + holding a Python extension type derived from int + which is named name. The + named attribute of the current scope is bound to the new + extension type.
      +
      + +

      Class template + enum_ modifier functions

      +
      +inline enum_<T>& value(char const* name, T x);
      +
      + +
      +
      Requires: name is an ntbs which conforms to Python's identifier + naming rules. + +
      Effects: adds an instance of the wrapped enumeration + type with value x to the type's dictionary as the + named attribute
      . + +
      Returns: *this
      + +
      + +

      Example(s)

      + +

      C++ module definition +

      +#include <boost/python/enum.hpp>
      +#include <boost/python/def.hpp>
      +#include <boost/python/module.hpp>
      +
      +using namespace boost::python;
      +
      +enum color { red = 1, green = 2, blue = 4 };
      +
      +color identity_(color x) { return x; }
      +
      +BOOST_PYTHON_MODULE(enums)
      +{
      +    enum_<color>("color")
      +        .value("red", red)
      +        .value("green", green)
      +        .value("blue", blue)
      +        ;
      +    
      +    def("identity", identity_);
      +}
      +
      +

      Interactive Python: +

      +>>> from enums import *
      +
      +>>> identity(color.red)
      +enums.color.red
      +
      +>>> identity(color.green)
      +enums.color.green
      +
      +>>> identity(color.blue)
      +enums.color.blue
      +
      +>>> identity(color(1))
      +enums.color.red
      +
      +>>> identity(color(2))
      +enums.color.green
      +
      +>>> identity(color(3))
      +enums.color(3)
      +
      +>>> identity(color(4))
      +enums.color.blue
      +
      +>>> identity(1)
      +Traceback (most recent call last):
      +  File "<stdin>", line 1, in ?
      +TypeError: bad argument type for built-in operation
      +
      +
      + + Revised + + 03 October, 2002 + + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + diff --git a/doc/v2/init.html b/doc/v2/init.html index 710287ef..2f6b938e 100644 --- a/doc/v2/init.html +++ b/doc/v2/init.html @@ -22,8 +22,7 @@

      Boost.Python

      -

      Headers <boost/python/init.hpp>, - <boost/python/class_fwd.hpp>

      +

      Headers <boost/python/init.hpp>

      diff --git a/doc/v2/module.html b/doc/v2/module.html index 42658832..e6b170b3 100644 --- a/doc/v2/module.html +++ b/doc/v2/module.html @@ -71,9 +71,11 @@ This macro generates two functions in the scope where it is used: and void init_module_name(), whose body must follow the macro invocation. init_name passes init_module_name to () so that any C++ -exceptions generated are safely processeed. - +href="errors.html#handle_exception">handle_exception() so +that any C++ exceptions generated are safely processeed. During the +body of init_name, the current scope refers to the module +being initialized.

      Example(s)

      From ecd7905e8f8abd0d094f3da6b3e4d5ac81a83d2a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 3 Oct 2002 23:21:48 +0000 Subject: [PATCH 0813/1042] doc update [SVN r15697] --- doc/v2/exception_translator.html | 15 +- doc/v2/operators.html | 4 +- doc/v2/ptr.html | 2 + doc/v2/reference.html | 700 ++++++++++++++++++++----------- 4 files changed, 474 insertions(+), 247 deletions(-) diff --git a/doc/v2/exception_translator.html b/doc/v2/exception_translator.html index 407ff95d..f460c1ce 100644 --- a/doc/v2/exception_translator.html +++ b/doc/v2/exception_translator.html @@ -40,7 +40,7 @@
      register_exception_translator
      + "#register_exception_translator-spec">register_exception_translator
      @@ -63,8 +63,11 @@ described below.

      Functions

      + +

      register_exception_translator

      +
      -template<class ExceptionType, class Translate>
      +template<class ExceptionType, class Translate>
       void register_exception_translator(Translate const& translate);
       
      @@ -74,7 +77,7 @@ void register_exception_translator(Translate const& translate);
      Translate is Copyconstructible, and - the following code is well-formed: + the following code must be well-formed:
       void f(ExceptionType x) { translate(x); }
       
      @@ -84,7 +87,9 @@ void f(ExceptionType x) { translate(x); } must return 1.
      -
      Effects: Adds a copy of translate to the sequence of +

      + +

      Effects: Adds a copy of translate to the sequence of exception translators tried when Boost.Python catches an exception that is about to pass into Python's core interpreter. The new translator will get "first shot" at translating all exceptions matching the catch @@ -133,7 +138,7 @@ BOOST_PYTHON_MODULE(exception_translator_ext)
      -

      Revised 30 September, 2002

      +

      Revised 03 October, 2002

      © Copyright Dave Abrahams 2002. All Rights diff --git a/doc/v2/operators.html b/doc/v2/operators.html index 307e949b..ea642321 100755 --- a/doc/v2/operators.html +++ b/doc/v2/operators.html @@ -127,7 +127,7 @@

       namespace boost { namespace python { namespace self_ns {
       {
      -   class self_t {};
      +   unspecified-type-declaration self_t;
       
          // inplace operators
          template <class T> 
       namespace boost { namespace python
       {
      -  extern self_ns self;
      +  using self_ns::self;
       }}
       
      diff --git a/doc/v2/ptr.html b/doc/v2/ptr.html index 71cc6975..98bfd195 100644 --- a/doc/v2/ptr.html +++ b/doc/v2/ptr.html @@ -175,6 +175,8 @@ Ptr get() const; better to have an explicit way to retrieve the pointer. +

      Metafunctions

      +

      Class template is_pointer_wrapper

      A unary metafunction whose value is true iff its diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 9db8240b..0ec9b86c 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -1,56 +1,66 @@ - - + + + + Boost.Python - Reference - + + - + +
      +
      -

      C++ Boost

      +

      C++ Boost

      +

      Boost.Python

      Reference

      +


      Contents

      -
      Concepts +
      Concepts
      -
      High Level Components +
      High Level Components
      -
      Function Invocation and Creation +
      Object Wrappers
      + +
      Function Invocation and Creation
      Models of - CallPolicies + CallPolicies
      Models of - ResultConverter + ResultConverter
      Models of - ResultConverterGenerator + ResultConverterGenerator
      +
      -
      To/From Python Type Conversion +
      To/From Python Type Conversion
      -
      Utility and Infrastructure +
      Utility and Infrastructure

      @@ -59,220 +69,397 @@
      CallPolicies + "CallPolicies.html#CallPolicies-concept">CallPolicies
      Dereferenceable + "Dereferenceable.html#Dereferenceable-concept">Dereferenceable
      + +
      Extractor
      Extractor + "HolderGenerator.html#HolderGenerator-concept">HolderGenerator
      HolderGenerator + "ResultConverter.html#ResultConverter-concept">ResultConverter
      ResultConverter + "ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator
      ResultConverterGenerator + "ObjectWrapper.html#ObjectWrapper-concept">ObjectWrapper
      + +
      TypeWrapper

      High Level Components

      -
      class.hpp/class_fwd.hpp +
      class.hpp/class_fwd.hpp
      -
      Classes +
      Classes
      -
      class_ +
      class_
      -
      bases - -
      args +
      bases
      +
      +
      -
      errors.hpp +
      errors.hpp
      -
      Classes +
      Classes
      error_already_set + "errors.html#error_already_set-spec">error_already_set
      +
      -
      Functions +
      Functions
      handle_exception + "errors.html#handle_exception-spec">handle_exception
      expect_non_null -
      -
      + "errors.html#expect_non_null-spec">expect_non_null
      -
      iterator.hpp +
      throw_error_already_set
      + + + + + + +
      exception_translator.hpp
      - -
      Classes -
      -
      -
      iterator - -
      iterators -
      - -
      Functions +
      Functions
      -
      range +
      register_exception_translator
      +
      +
      + +
      init.hpp
      -
      module.hpp
      -
      Classes +
      Classes
      -
      module -
      -
      +
      init
      + +
      optional
      + + + + + +
      iterator.hpp
      -
      objects.hpp
      -
      Classes +
      Classes
      -
      not yet - documented -
      -
      +
      iterator
      + +
      iterators
      + + + +
      Functions
      + +
      +
      +
      range
      +
      +
      + + + +
      module.hpp
      -
      operators.hpp
      -
      Classes +
      Macros
      +
      -
      self_t -
      other -
      operator_ +
      BOOST_PYTHON_MODULE
      - -
      Objects -
      -
      -
      self -
      - +
      +
      +
      operators.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      self_t
      + +
      other
      + +
      operator_
      +
      +
      + +
      Objects
      + +
      +
      +
      self
      +
      +
      +
      +
      + + +

      Object Wrappers

      + +
      +
      dict.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      dict
      +
      +
      +
      +
      + +
      list.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      list
      +
      +
      +
      +
      + +
      long.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      long_
      +
      +
      +
      +
      + +
      numeric.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      numeric::array
      +
      +
      +
      +
      + +
      object.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      object
      +
      +
      +
      +
      + +
      str.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      str
      +
      +
      +
      +

      Function Invocation and Creation

      -
      call.hpp +
      args.hpp
      -
      Functions +
      Functions
      +
      -
      call +
      args
      +
      +
      -
      call_method.hpp +
      call.hpp
      -
      Functions +
      Functions
      -
      call_method +
      call
      +
      +
      -
      data_members.hpp +
      call_method.hpp
      -
      Functions +
      Functions
      make_getter - -
      make_setter + "call_method.html#call_method-spec">call_method
      +
      +
      -
      make_function.hpp +
      data_members.hpp
      -
      Functions +
      Functions
      make_function + "data_members.html#make_getter-spec">make_getter
      make_constructor + "data_members.html#make_setter-spec">make_setter
      +
      +
      -
      ptr.hpp +
      make_function.hpp
      -
      Functions - -
      -
      -
      ptr -
      - -
      Classes +
      Functions
      pointer_wrapper -
      + "make_function.html#make_function-spec">make_function -
      MetaFunctions +
      make_constructor
      +
      +
      +
      + + +
      overloads.hpp
      + +
      +
      +
      macros
      is_pointer_wrapper + "overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec">BOOST_PYTHON_FUNCTION_OVERLOADS
      unwrap_pointer + "overloads.html#BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS-spec">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS
      +
      +
      +
      + +
      ptr.hpp
      + +
      +
      +
      Functions
      + +
      +
      +
      ptr
      +
      +
      + +
      Classes
      + +
      +
      +
      pointer_wrapper
      +
      +
      + +
      MetaFunctions
      + +
      +
      +
      is_pointer_wrapper
      + +
      unwrap_pointer
      +
      +
      @@ -280,75 +467,80 @@
      default_call_policies.hpp + "default_call_policies.html">default_call_policies.hpp
      Classes + "default_call_policies.html#classes">Classes
      -
      - default_call_policies +
      default_call_policies
      -
      - default_result_converter +
      default_result_converter
      +
      +
      return_internal_reference.hpp + "return_internal_reference.html">return_internal_reference.hpp
      Classes + "return_internal_reference.html#classes">Classes
      -
      - return_internal_reference + return_internal_reference
      +
      +
      return_value_policy.hpp + "return_value_policy.html">return_value_policy.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      return_value_policy
      +
      +
      +
      +
      + +
      with_custodian_and_ward.hpp
      Classes + "with_custodian_and_ward.html#classes">Classes
      -
      return_value_policy -
      -
      - -
      with_custodian_and_ward.hpp - -
      -
      -
      Classes - -
      -
      -
      - with_custodian_and_ward + with_custodian_and_ward
      -
      - with_custodian_and_ward_postcall + with_custodian_and_ward_postcall
      +
      +
      @@ -356,31 +548,35 @@
      to_python_indirect.hpp + "to_python_indirect.html">to_python_indirect.hpp
      -
      Classes - -
      -
      -
      to_python_indirect -
      -
      - -
      to_python_value.hpp - -
      -
      -
      Classes +
      Classes
      to_python_value + "to_python_indirect.html#to_python_indirect-spec">to_python_indirect
      +
      +
      + +
      to_python_value.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      to_python_value
      +
      +
      +
      +
      @@ -388,224 +584,248 @@
      copy_const_reference.hpp + "copy_const_reference.html">copy_const_reference.hpp
      Classes + "copy_const_reference.html#classes">Classes
      -
      - copy_const_reference +
      copy_const_reference
      +
      +
      copy_non_const_reference.hpp + "copy_non_const_reference.html">copy_non_const_reference.hpp
      Classes + "copy_non_const_reference.html#classes">Classes
      -
      - copy_non_const_reference + copy_non_const_reference
      +
      +
      -
      manage_new_object.hpp +
      manage_new_object.hpp
      -
      Classes +
      Classes
      -
      manage_new_object +
      manage_new_object
      +
      +
      reference_existing_object.hpp + "reference_existing_object.html">reference_existing_object.hpp
      Classes + "reference_existing_object.html#classes">Classes
      -
      - reference_existing_object + reference_existing_object
      +
      +
      +
      -

      To/From Python Type - Conversion

      +

      To/From Python Type Conversion

      -
      from_python.hpp +
      extract.hpp
      -
      Classes +
      Classes
      + +
      +
      +
      extract
      +
      +
      +
      +
      + +
      implicit.hpp
      + +
      +
      +
      Functions
      from_python + "implicit.html#implicitly_convertible-spec">implicitly_convertible
      +
      +
      -
      implicit.hpp +
      lvalue_from_pytype.hpp
      -
      Functions +
      Classes
      implicitly_convertible -
      -
      + "lvalue_from_pytype.html#lvalue_from_pytype-spec">lvalue_from_pytype -
      lvalue_from_pytype.hpp +
      extract_identity
      + +
      extract_member
      +
      + + + + +
      to_python_converter.hpp
      -
      Classes +
      Classes
      -
      lvalue_from_pytype -
      extract_identity - -
      extract_member + "to_python_converter.html#to_python_converter-spec">to_python_converter
      +
      - -
      to_python_converter.hpp - -
      -
      -
      Classes - -
      -
      -
      to_python_converter -
      -
      - +

      Utility and Infrastructure

      -
      has_back_reference.hpp +
      has_back_reference.hpp
      -
      Classes - -
      -
      -
      has_back_reference -
      -
      - -
      instance_holder.hpp - -
      -
      -
      Classes +
      Classes
      instance_holder + "has_back_reference.html#has_back_reference-spec">has_back_reference
      +
      +
      -
      pointee.hpp +
      instance_holder.hpp
      -
      Classes +
      Classes
      + +
      +
      +
      instance_holder
      +
      +
      +
      +
      + +
      pointee.hpp
      + +
      +
      +
      Classes
      class template pointee + "pointee.html#pointee">pointee
      +
      +
      -
      reference.hpp +
      reference.hpp
      -
      Classes +
      Classes
      reference + "reference_hpp.html#reference-spec">reference
      +
      -
      Types +
      Types
      -
      ref +
      ref
      +
      +
      -
      type_id.hpp +
      type_id.hpp
      -
      Functions +
      Functions
      -
      type_id +
      type_id
      +
      -
      Classes +
      Classes
      -
      type_info +
      type_info
      +
      +

      Revised - 3 June, 2002 - + 3 June, 2002 +

      - -

      © Copyright Dave Abrahams 2002. All - Rights Reserved. +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + From 2b5f4215019b54b7f9c1b805056126fe6042fbe8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 3 Oct 2002 23:59:08 +0000 Subject: [PATCH 0814/1042] Remove needless specialization [SVN r15701] --- include/boost/python/init.hpp | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 6727135b..9991268e 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -283,34 +283,6 @@ class init : public init_base > BOOST_STATIC_CONSTANT(int, n_arguments = mpl::size::value); }; -# if 1 -template <> // specialization for zero args -class init<> : public init_base > -{ - typedef init_base > base; - public: - typedef init<> self_t; - - init(char const* doc_ = 0) - : base(doc_) - { - } - - template - init_with_call_policies - operator[](CallPoliciesT const& policies) const - { - return init_with_call_policies( - policies, this->doc_string(), this->keywords()); - } - - BOOST_STATIC_CONSTANT(int, n_defaults = 0); - BOOST_STATIC_CONSTANT(int, n_arguments = 0); - - typedef detail::type_list<> reversed_args; -}; -# endif - /////////////////////////////////////////////////////////////////////////////// // // optional From a91112e5d9eaec5be48e87a6e96fd0913731bbce Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 4 Oct 2002 00:45:29 +0000 Subject: [PATCH 0815/1042] doc update [SVN r15702] --- doc/v2/definitions.html | 39 ++++- doc/v2/handle.html | 322 ++++++++++++++++++++++++++++++++++++++++ doc/v2/reference.html | 14 +- 3 files changed, 361 insertions(+), 14 deletions(-) create mode 100644 doc/v2/handle.html diff --git a/doc/v2/definitions.html b/doc/v2/definitions.html index 5c21e86e..f36dc284 100644 --- a/doc/v2/definitions.html +++ b/doc/v2/definitions.html @@ -34,26 +34,49 @@ hidden "this" argument to member functions is not counted when specifying arity +

      +
      +
      ntbs: Null-Terminated Byte String, or `C'-string. C++ string literals are ntbses. An ntbs must never be null.
      +

      +
      +
      raise: Exceptions in Python are - "raised", not "thrown", as they are in - C++. When this documentation says that some Python exception is - "raised" in the context of C++ code, it means that the - corresponding Python exception is set via the Python/'C' - API, and throw_error_already_set() + "raised", not "thrown", as they are in C++. When this documentation + says that some Python exception is "raised" in the context of C++ code, + it means that the corresponding Python exception is set via the Python/'C' + API, and throw_error_already_set() is called.
      +

      +
      + +
      POD: A technical term from the C++ + standard. Short for "Plain Ol'Data": A POD-struct is an aggregate class + that has no non-static data members of type pointer to member, + non-POD-struct, non-POD-union (or array of such types) or reference, + and has no user-defined copy assign- ment operator and no user-defined + destructor. Similarly, a POD-union is an aggregate union that has no + non-static data members of type pointer to member, non-POD-struct, + non-POD-union (or array of such types) or reference, and has no + user-defined copy assignment operator and no user-defined destructor. A + POD class is a class that is either a POD-struct or a POD-union. An + aggregate is an array or a class (clause 9) with no user-declared + constructors (12.1), no private or protected non-static data members + (clause 11), no base classes (clause 10), and no virtual functions + (10.3).

      Revised - 30 September, 2002 + 03 October, 2002

      diff --git a/doc/v2/handle.html b/doc/v2/handle.html new file mode 100644 index 00000000..2c0ffcc2 --- /dev/null +++ b/doc/v2/handle.html @@ -0,0 +1,322 @@ + + + + + + + + + Boost.Python - <boost/python/handle.hpp> + + + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/handle.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Classes
      + +
      +
      +
      Class template + handle
      + +
      +
      +
      Class handle + synopsis
      + +
      Class handle + constructors and destructor
      + +
      Class handle + modifier functions
      + +
      Class handle + observer functions
      +
      +
      +
      +
      + +
      Functions
      + +
      +
      +
      borrowed
      + +
      allow_null
      +
      +
      + +
      +
      + +

      Introduction

      + +

      <boost/python/handle.hpp> provides + class template handle, a smart pointer for + managing reference-counted Python objects.

      + +

      Classes

      + +

      Class template handle

      + +

      handle is a smart pointer to a Python object type; it + holds a pointer of type T*, where T is its template + parameter. T must be either a type derived from + PyObject or a POD + type whose initial sizeof(PyObject) bytes are + layout-compatible with PyObject. Use + handle<> at the boundary between tehe + Python/'C' API and high-level code; prefer object for a generalized + interface to Python objects. + +

      In this document, the term "upcast" refers to an + operation which converts a pointer Y* to a base class + pointer T* via static_cast<T*> if + Y is derived from T, or via C-style cast + (T*) if it is not. However, in the latter case the "upcast" + is ill-formed if the initial sizeof(PyObject) bytes of + Y are not layout-compatible with PyObject.

      + +

      Class template handle + synopsis

      +
      +namespace boost { namespace python
      +{
      +  template <class T>
      +  class handle
      +  {
      +      typedef unspecified-member-function-pointer bool_type;
      +
      +   public: // types
      +      typedef T element_type;
      +
      +   public: // member functions
      +      ~handle();
      +
      +      template <class Y>
      +      explicit handle(detail::borrowed<null_ok<Y> >* p);
      +
      +      template <class Y>
      +      explicit handle(null_ok<detail::borrowed<Y> >* p);
      +
      +      template <class Y>
      +      explicit handle(detail::borrowed<Y>* p);
      +
      +      template <class Y>
      +      explicit handle(null_ok<Y>* p);
      +
      +      template <class Y>
      +      explicit handle(Y* p);
      +
      +      handle();
      +
      +      handle& operator=(handle const& r);
      +
      +      template<typename Y>
      +      handle& operator=(handle<Y> const & r); // never throws
      +
      +
      +      template <typename Y>
      +      handle(handle<Y> const& r);
      +
      +      handle(handle const& r);
      +
      +      T* operator-> () const;
      +      T& operator* () const;
      +      T* get() const;
      +      T* release();
      +
      +      operator bool_type() const; // never throws
      +   private:
      +      T* m_p;
      +  };
      +  
      +  template <class T> struct null_ok;
      +  namespace detail { template <class T> struct borrowed; }
      +}}
      +
      + +

      Class handle constructors + and destructor

      +
      +virtual ~handle();
      +
      + +
      +
      Effects: Py_XDECREF(m_p)
      +
      +
      +template <class Y>
      +explicit handle(detail::borrowed<null_ok<Y> >* p);
      +
      + +
      +
      Effects: Py_XDECREF(m_p)
      +
      +
      +template <class Y>
      +explicit handle(null_ok<detail::borrowed<Y> >* p);
      +
      + +
      +
      Effects: + m_p = upcast<T*>(p);
      +
      +
      +template <class Y>
      +explicit handle(detail::borrowed<Y>* p);
      +
      + +
      +
      Effects: + m_p = upcast<T*>(expect_non_null(p));
      +
      +
      +template <class Y>
      +explicit handle(null_ok<Y>* p);
      +
      + +
      +
      Effects: + Py_XINCREF(p); m_p = upcast<T*>(p);
      +
      +
      +template <class Y>
      +explicit handle(Y* p);
      +
      + +
      +
      Effects: + Py_XINCREF(p); m_p = upcast<T*>(expect_non_null(p));
      +
      +
      +handle();
      +
      + +
      +
      Effects: m_p = 0;
      +
      +
      +template <typename Y>
      +handle(handle<Y> const& r);
      +handle(handle const& r);
      +
      + +
      +
      Effects: + m_p = r.m_p; Py_XINCREF(m_p);
      +
      + +

      Class handle + modifiers

      +
      +handle& operator=(handle const& r);
      +template<typename Y>
      +handle& operator=(handle<Y> const & r); // never throws
      +
      + +
      +
      Effects: + Py_XINCREF(r.m_p); Py_XDECREF(m_p); m_p = r.m_p;
      +
      +
      +T* release();
      +
      + +
      +
      Effects: T* x = m_p; m_p = 0;return + x;
      +
      + +

      Class handle + observers

      +
      +T* operator-> () const;
      +T* get() const;
      +
      + +
      +
      Returns: m_p;
      +
      +
      +T& operator* () const;
      +
      + +
      +
      Returns: *m_p;
      +
      +
      +operator bool_type() const; // never throws
      +
      + +
      +
      Returns: 0 if m_p == 0, a pointer + convertible to true otherwise.
      +
      + +

      Functions

      + +

      borrowed

      +
      +template 
      +detail::borrowed* borrowed(T* p)
      +{
      +    return (detail::borrowed*)p;
      +}
      +
      + +

      allow_null

      + +
      +template 
      +null_ok* allow_null(T* p)
      +{
      +    return (null_ok*)p;
      +}
      +
      + + +

      Revised + + 03 October, 2002 +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 0ec9b86c..0923a434 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -771,24 +771,26 @@ -
      reference.hpp
      +
      handle.hpp
      -
      Classes
      +
      Classes
      reference
      + "handle.html#handle-spec">handle
      - -
      Types
      +
      Functions
      -
      ref
      +
      borrowed
      +
      allow_null
      From e5fbe651d86bf51c5d07d96e73c4c3f70afc6920 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 4 Oct 2002 03:46:43 +0000 Subject: [PATCH 0816/1042] Tru64 CXX updates [SVN r15704] --- include/boost/python/args.hpp | 7 ------- include/boost/python/args_fwd.hpp | 8 +++++++- .../boost/python/converter/rvalue_from_python_data.hpp | 2 +- include/boost/python/detail/config.hpp | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index 4e2e922b..9a5902ae 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -7,7 +7,6 @@ # define KEYWORDS_DWA2002323_HPP # include -# include # include # include # include @@ -32,12 +31,6 @@ namespace boost { namespace python { namespace detail { - struct keyword - { - char const* name; - handle<> default_value; - }; - template struct keywords { diff --git a/include/boost/python/args_fwd.hpp b/include/boost/python/args_fwd.hpp index b8ca0c7d..e310f761 100644 --- a/include/boost/python/args_fwd.hpp +++ b/include/boost/python/args_fwd.hpp @@ -6,6 +6,7 @@ #ifndef ARGS_FWD_DWA2002927_HPP # define ARGS_FWD_DWA2002927_HPP +# include # include # include # include @@ -14,7 +15,12 @@ namespace boost { namespace python { namespace detail { - struct keyword; + struct keyword + { + char const* name; + handle<> default_value; + }; + template struct keywords; typedef std::pair keyword_range; diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp index 16c9d44b..7f512830 100644 --- a/include/boost/python/converter/rvalue_from_python_data.hpp +++ b/include/boost/python/converter/rvalue_from_python_data.hpp @@ -96,7 +96,7 @@ struct rvalue_from_python_data : rvalue_from_python_storage && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \ && (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) // This must always be a POD struct with m_data its first member. - BOOST_STATIC_ASSERT(offsetof(rvalue_from_python_storage,stage1) == 0); + BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage,stage1) == 0); # endif // The usual constructor diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index 16948010..fb263dbe 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -97,7 +97,7 @@ # define BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(instantiation) struct ThIsTyPeNeVeRuSeD #endif -#if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590014) +#if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031) // Replace broken Tru64/cxx offsetof macro # define BOOST_PYTHON_OFFSETOF(s_name, s_member) \ ((size_t)__INTADDR__(&(((s_name *)0)->s_member))) From 81ffe96c7622a8a6f81a4203e9f9ab1d4b5af6d6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 4 Oct 2002 05:14:45 +0000 Subject: [PATCH 0817/1042] Update Tru64 workarounds [SVN r15705] --- include/boost/python/detail/string_literal.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/string_literal.hpp b/include/boost/python/detail/string_literal.hpp index dc8b0791..3b3c4bd9 100644 --- a/include/boost/python/detail/string_literal.hpp +++ b/include/boost/python/detail/string_literal.hpp @@ -27,7 +27,7 @@ struct is_string_literal BOOST_STATIC_CONSTANT(bool, value = true); }; -# if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590014) \ +# if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031) \ || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) // This compiler mistakenly gets the type of string literals as char* // instead of char[NN]. From bd0175c167e89c41423f390249f2951176d6aa8b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 4 Oct 2002 13:05:57 +0000 Subject: [PATCH 0818/1042] Backport to Python 2.2 [SVN r15706] --- src/object/class.cpp | 14 ++++++++------ test/defaults.py | 2 ++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index 3cd62a37..201499e2 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -330,7 +330,7 @@ namespace objects // rest corresponding to its declared bases. // inline object - new_class(char const* name, std::size_t num_types, class_id const* const types) + new_class(char const* name, std::size_t num_types, class_id const* const types, char const* doc) { assert(num_types >= 1); @@ -348,7 +348,12 @@ namespace objects } // Call the class metatype to create a new class - object result = object(class_metatype())(module_prefix() + name, bases, dict()); + dict d; + + if (doc != 0) + d["__doc__"] = doc; + + object result = object(class_metatype())(module_prefix() + name, bases, d); assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type)); if (scope().ptr() != Py_None) @@ -360,7 +365,7 @@ namespace objects class_base::class_base( char const* name, std::size_t num_types, class_id const* const types, char const* doc) - : object(new_class(name, num_types, types)) + : object(new_class(name, num_types, types, doc)) { // Insert the new class object in the registry converter::registration& converters = const_cast( @@ -368,9 +373,6 @@ namespace objects // Class object is leaked, for now converters.class_object = (PyTypeObject*)incref(this->ptr()); - - if (doc) - this->attr("__doc__") = doc; } void class_base::set_instance_size(std::size_t instance_size) diff --git a/test/defaults.py b/test/defaults.py index ee7a6588..168c5de3 100644 --- a/test/defaults.py +++ b/test/defaults.py @@ -1,4 +1,6 @@ """ +>>> False = 0 # Python 2.2 needs these +>>> True = 1 >>> from defaults_ext import * >>> bar(1) From f4d457998f24674b38d1e4df2ea9c31074c72baf Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 4 Oct 2002 14:24:25 +0000 Subject: [PATCH 0819/1042] doc update [SVN r15709] --- doc/v2/configuration.html | 226 +++++++++++++++++++++++--------------- doc/v2/definitions.html | 12 ++ 2 files changed, 150 insertions(+), 88 deletions(-) diff --git a/doc/v2/configuration.html b/doc/v2/configuration.html index bb6b7344..d6a1fdef 100644 --- a/doc/v2/configuration.html +++ b/doc/v2/configuration.html @@ -1,91 +1,141 @@ + + - - - -Boost.Python - Configuration - - - + + + + + Boost.Python - Configuration + + + +
      - - - - -
      -

      -

      -
      -

      Boost.Python

      -

      Configuration

      -
      -
      -
      -
      Introduction
      -
      Application Defined Macros
      -
      Public Library Defined Macros
      -
      Library Defined Implementation Macros
      -
      -

      Introduction

      -

      Boost.Python uses several configuration macros in <boost/config.hpp>, - as well as configuration macros meant to be supplied by the application. These - macros are documented here.

      -

      Application Defined Macros

      -

      These are the macros that may be defined by an application using Boost.Python.

      - - - - - - - - - - - - - -
      MacroMeaning
      {{macro}}{{meaning}}
      {{macro}}{{meaning}}
      -

      Public Library Defined Macros

      -

      These macros are defined by Boost.Python but are expected to be used by application - code.

      - - - - - - - - - - - - - -
      MacroMeaning
      {{macro}}{{meaning}}
      {{macro}}{{meaning}}
      -

      Library Defined Implementation Macros

      -

      These macros are defined by Boost.Python and are implementation details of interest - only to implementers.

      - - - - - - - - - - - - - -
      MacroMeaning
      {{macro}}{{meaning}}
      {{macro}}{{meaning}}
      -
      -

      Revised - - 05 November, 2002 - -

      -

      © Copyright Dave Abrahams - 2002. All Rights Reserved.

      - + + +

      C++ Boost

      + + + +

      Boost.Python

      + +

      Configuration

      + + + +
      + +
      +
      Introduction
      + +
      Application Defined Macros
      + +
      Library Defined Implementation + Macros
      +
      + +

      Introduction

      + +

      Boost.Python uses several configuration macros in <boost/config.hpp>, + as well as configuration macros meant to be supplied by the application. + These macros are documented here.

      + +

      Application Defined Macros

      + +

      These are the macros that may be defined by an application using + Boost.Python. Note that if you extend a strict interpretation of the C++ + standard to cover dynamic libraries, using different values of these + macros when compiling different libraries (including extension modules + and the Boost.Python library itself) is a violation of the ODR. However, we know of no C++ + implementations on which this particular violation is detectable or + causes any problems.

      + + + + + + + + + + + + + + + + + + + + +
      Macro + + Default + + Meaning +
      BOOST_PYTHON_MAX_ARITY15The maximum arity of any + function, member function, or constructor to be wrapped, invocation + of a Boost.Python function wich is specified as taking arguments + x1, x2,...Xn. This includes, in + particular, callback mechanisms such as object::operator()(...) + or call_method<R>(... + ).
      BOOST_PYTHON_MAX_BASES10The maximum number of template arguments to the bases<...> + class template, which is used to specify the bases of a wrapped C++ + class..
      + +

      Library Defined Implementation + Macros

      + +

      These macros are defined by Boost.Python and are + implementation details of interest only to implementors and those porting + to new platforms.

      + + + + + + + + + + + + +
      Macro + + Default + + Meaning +
      BOOST_PYTHON_TYPE_ID_NAMEnot definedIf defined, this indicates that the type_info comparison across + shared library boundaries does not work on this platform. In other + words, if shared-lib-1 passes typeid(T) to a function in + shared-lib-2 which compares it to typeid(T), that + comparison may return false. If this macro is #defined, + Boost.Python uses and compares typeid(T).name() instead + of using and comparing the std::type_info objects + directly.
      +
      + +

      Revised + + 04 October, 2002 + +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + diff --git a/doc/v2/definitions.html b/doc/v2/definitions.html index f36dc284..5268b9c5 100644 --- a/doc/v2/definitions.html +++ b/doc/v2/definitions.html @@ -71,6 +71,18 @@ constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3). + +

      +
      + +
      ODR: The "One Definition + Rule", which says that any entity in a C++ program must have the same definition in all translation units (object files) which make up a program. +
      + +

      +
      + +
      From 5e8d775b87dba5dd9350aa8dd1d4dc9850c95c5a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 4 Oct 2002 21:34:32 +0000 Subject: [PATCH 0820/1042] Support for MinGW-2.0 [SVN r15719] --- include/boost/python/dict.hpp | 142 +-- include/boost/python/list.hpp | 97 +- include/boost/python/long.hpp | 36 +- include/boost/python/object/instance.hpp | 2 +- include/boost/python/str.hpp | 310 +++--- include/boost/python/tuple.hpp | 31 +- src/dict.cpp | 45 +- src/list.cpp | 38 +- src/long.cpp | 18 +- src/str.cpp | 214 ++-- src/tuple.cpp | 12 +- test/doctest.py | 1173 ---------------------- 12 files changed, 482 insertions(+), 1636 deletions(-) delete mode 100644 test/doctest.py diff --git a/include/boost/python/dict.hpp b/include/boost/python/dict.hpp index d78ccaf8..6bda6e2c 100644 --- a/include/boost/python/dict.hpp +++ b/include/boost/python/dict.hpp @@ -8,110 +8,126 @@ namespace boost { namespace python { -class dict : public object +class dict; + +namespace detail { - public: + struct BOOST_PYTHON_DECL dict_base : object + { + // D.clear() -> None. Remove all items from D. + void clear(); + + // D.copy() -> a shallow copy of D + dict copy(); + + // D.get(k[,d]) -> D[k] if D.has_key(k), else d. d defaults to None. + object get(object_cref k) const; + + object get(object_cref k, object_cref d) const; + + // D.has_key(k) -> 1 if D has a key k, else 0 + bool has_key(object_cref k) const; + + // D.items() -> list of D's (key, value) pairs, as 2-tuples + list items() const; + + // D.iteritems() -> an iterator over the (key, value) items of D + object iteritems() const; + + // D.iterkeys() -> an iterator over the keys of D + object iterkeys() const; + + // D.itervalues() -> an iterator over the values of D + object itervalues() const; + + // D.keys() -> list of D's keys + list keys() const; + + // D.popitem() -> (k, v), remove and return some (key, value) pair as a + // 2-tuple; but raise KeyError if D is empty + tuple popitem(); + + // D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if not D.has_key(k) + object setdefault(object_cref k); + + object setdefault(object_cref k, object_cref d); + + // D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k] + void update(object_cref E); + + // D.values() -> list of D's values + list values() const; + + protected: + // dict() -> new empty dictionary. + // dict(mapping) -> new dictionary initialized from a mapping object's + // (key, value) pairs. + // dict(seq) -> new dictionary initialized as if via: + dict_base(); // new dict + explicit dict_base(object_cref data); + + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict_base, object) + private: + static detail::new_reference call(object const&); + }; +} + +class dict : public detail::dict_base +{ + typedef detail::dict_base base; + public: // dict() -> new empty dictionary. // dict(mapping) -> new dictionary initialized from a mapping object's // (key, value) pairs. // dict(seq) -> new dictionary initialized as if via: - BOOST_PYTHON_DECL dict(); // new dict - explicit BOOST_PYTHON_DECL dict(object_cref data); + dict() {} // new dict template explicit dict(T const& data) - : object(dict::call(object(data))) + : base(object(data)) { } - // D.clear() -> None. Remove all items from D. - BOOST_PYTHON_DECL void clear(); - - // D.copy() -> a shallow copy of D - BOOST_PYTHON_DECL dict copy(); - - // D.get(k[,d]) -> D[k] if D.has_key(k), else d. d defaults to None. - BOOST_PYTHON_DECL object get(object_cref k) const; - template object get(T const& k) const { - return this->get(object(k)); + return base::get(object(k)); } - BOOST_PYTHON_DECL object get(object_cref k, object_cref d) const; - template object get(T1 const& k, T2 const& d) const { - return this->get(object(k),object(d)); + return base::get(object(k),object(d)); } - - // D.has_key(k) -> 1 if D has a key k, else 0 - BOOST_PYTHON_DECL bool has_key(object_cref k) const; - + template bool has_key(T const& k) const { - return this->has_key(object(k)); + return base::has_key(object(k)); } - - // D.items() -> list of D's (key, value) pairs, as 2-tuples - BOOST_PYTHON_DECL list items() const; - - // D.iteritems() -> an iterator over the (key, value) items of D - BOOST_PYTHON_DECL object iteritems() const; - - // D.iterkeys() -> an iterator over the keys of D - BOOST_PYTHON_DECL object iterkeys() const; - - // D.itervalues() -> an iterator over the values of D - BOOST_PYTHON_DECL object itervalues() const; - - // D.keys() -> list of D's keys - BOOST_PYTHON_DECL list keys() const; - - // D.popitem() -> (k, v), remove and return some (key, value) pair as a - // 2-tuple; but raise KeyError if D is empty - BOOST_PYTHON_DECL tuple popitem(); - - // D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if not D.has_key(k) - BOOST_PYTHON_DECL object setdefault(object_cref k); - + template object setdefault(T const& k) { - return this->setdefault(object(k)); + return base::setdefault(object(k)); } - - BOOST_PYTHON_DECL object setdefault(object_cref k, object_cref d); - + template object setdefault(T1 const& k, T2 const& d) { - return this->setdefault(object(k),object(d)); + return base::setdefault(object(k),object(d)); } - // D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k] - BOOST_PYTHON_DECL void update(object_cref E); - template void update(T const& E) { - this->update(object(E)); + base::update(object(E)); } - // D.values() -> list of D's values - BOOST_PYTHON_DECL list values() const; - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict, object) - - private: - static BOOST_PYTHON_DECL detail::new_reference call(object const&); + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dict, base) }; - // // Converter Specializations // diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp index e6696878..ce6cfab4 100644 --- a/include/boost/python/list.hpp +++ b/include/boost/python/list.hpp @@ -11,93 +11,116 @@ namespace boost { namespace python { -class list : public object +namespace detail { + struct BOOST_PYTHON_DECL list_base : object + { + void append(object_cref); // append object to end + + long count(object_cref value) const; // return number of occurrences of value + + void extend(object_cref sequence); // extend list by appending sequence elements + + long index(object_cref value) const; // return index of first occurrence of value + + void insert(int index, object_cref); // insert object before index + void insert(object const& index, object_cref); + + object pop(); // remove and return item at index (default last) + object pop(long index); + object pop(object const& index); + + void remove(object_cref value); // remove first occurrence of value + + void reverse(); // reverse *IN PLACE* + + void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1 + void sort(object_cref cmpfunc); + + + protected: + list_base(); // new list + explicit list_base(object_cref sequence); // new list initialized from sequence's items + + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list_base, object) + private: + static detail::new_non_null_reference call(object const&); + }; +} + +class list : public detail::list_base +{ + typedef detail::list_base base; public: - BOOST_PYTHON_DECL list(); // new list - explicit BOOST_PYTHON_DECL list(object_cref sequence); // new list initialized from sequence's items + list() {} // new list template explicit list(T const& sequence) - : object(list::call(object(sequence))) + : base(object(sequence)) { } - BOOST_PYTHON_DECL void append(object_cref); // append object to end - template void append(T const& x) { - this->append(object(x)); + base::append(object(x)); } - BOOST_PYTHON_DECL long count(object_cref value) const; // return number of occurrences of value - template long count(T const& value) const { - return this->count(object(value)); + return base::count(object(value)); } - BOOST_PYTHON_DECL void extend(object_cref sequence); // extend list by appending sequence elements - template void extend(T const& x) { - this->extend(object(x)); + base::extend(object(x)); } - BOOST_PYTHON_DECL long index(object_cref value) const; // return index of first occurrence of value - template long index(T const& x) const { - return this->index(object(x)); + return base::index(object(x)); } - BOOST_PYTHON_DECL void insert(int index, object_cref); // insert object before index - BOOST_PYTHON_DECL void insert(object const& index, object_cref); - template void insert(int index, T const& x) // insert object before index { - this->insert(index, object(x)); + base::insert(index, object(x)); } template void insert(object const& index, T const& x) // insert object before index { - this->insert(index, object(x)); + base::insert(index, object(x)); } - - BOOST_PYTHON_DECL object pop(); // remove and return item at index (default last) - BOOST_PYTHON_DECL object pop(long index); - BOOST_PYTHON_DECL object pop(object const& index); - BOOST_PYTHON_DECL void remove(object_cref value); // remove first occurrence of value + object pop() { return base::pop(); } + object pop(long index) { return base::pop(index); } + template + object pop(T const& index) + { + return base::pop(object(index)); + } + template void remove(T const& value) { - this->remove(object(value)); + base::remove(object(value)); } + + void sort() { base::sort(); } - BOOST_PYTHON_DECL void reverse(); // reverse *IN PLACE* - - BOOST_PYTHON_DECL void sort(); // sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1 - BOOST_PYTHON_DECL void sort(object_cref cmpfunc); - template void sort(T const& value) { - this->sort(object(value)); + base::sort(object(value)); } public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list, object) - - private: - static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&); + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(list, base) }; // diff --git a/include/boost/python/long.hpp b/include/boost/python/long.hpp index b0cc6417..284296be 100644 --- a/include/boost/python/long.hpp +++ b/include/boost/python/long.hpp @@ -11,31 +11,43 @@ namespace boost { namespace python { -class long_ : public object +namespace detail { + struct BOOST_PYTHON_DECL long_base : object + { + protected: + long_base(); // new long_ + explicit long_base(object_cref rhs); + explicit long_base(object_cref rhs, object_cref base); + + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_base, object) + + private: + static detail::new_non_null_reference call(object const&); + static detail::new_non_null_reference call(object const&, object const&); + }; +} + +class long_ : public detail::long_base +{ + typedef detail::long_base base; public: - BOOST_PYTHON_DECL long_(); // new long_ - explicit BOOST_PYTHON_DECL long_(object_cref rhs); + long_() {} // new long_ template explicit long_(T const& rhs) - : object(long_::call(object(rhs))) + : base(object(rhs)) { } - explicit BOOST_PYTHON_DECL long_(object_cref rhs, object_cref base); - template explicit long_(T const& rhs, U const& base) - : object(long_::call(object(rhs), object(base))) + : base(object(rhs), object(base)) { } - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_, object) - private: - static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&); - static BOOST_PYTHON_DECL detail::new_non_null_reference call(object const&, object const&); + public: // implementation detail -- for internal use only + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(long_, base) }; // diff --git a/include/boost/python/object/instance.hpp b/include/boost/python/object/instance.hpp index 4cddcc99..b258a2a0 100644 --- a/include/boost/python/object/instance.hpp +++ b/include/boost/python/object/instance.hpp @@ -12,7 +12,7 @@ namespace boost { namespace python { - struct instance_holder; + struct BOOST_PYTHON_DECL instance_holder; }} // namespace boost::python namespace boost { namespace python { namespace objects { diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index ffb3c362..285d7153 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -15,347 +15,367 @@ namespace boost { namespace python { -class str : public object -{ - public: - BOOST_PYTHON_DECL str(); // new str - - BOOST_PYTHON_DECL str(const char* s); // new str - explicit BOOST_PYTHON_DECL str(object_cref other); +class str; +namespace detail +{ + struct BOOST_PYTHON_DECL str_base : object + { + str capitalize() const; + + str center(object_cref width) const; + + long count(object_cref sub) const; + + long count(object_cref sub, object_cref start) const; + + long count(object_cref sub, object_cref start, object_cref end) const; + + object decode() const; + object decode(object_cref encoding) const; + + object decode(object_cref encoding, object_cref errors) const; + + object encode() const; + object encode(object_cref encoding) const; + object encode(object_cref encoding, object_cref errors) const; + + bool endswith(object_cref suffix) const; + + bool endswith(object_cref suffix, object_cref start) const; + bool endswith(object_cref suffix, object_cref start, object_cref end) const; + + str expandtabs() const; + str expandtabs(object_cref tabsize) const; + + long find(object_cref sub) const; + long find(object_cref sub, object_cref start) const; + + long find(object_cref sub, object_cref start, object_cref end) const; + + long index(object_cref sub) const; + + long index(object_cref sub, object_cref start) const; + long index(object_cref sub, object_cref start, object_cref end) const; + + bool isalnum() const; + bool isalpha() const; + bool isdigit() const; + bool islower() const; + bool isspace() const; + bool istitle() const; + bool isupper() const; + + str join(object_cref sequence) const; + + str ljust(object_cref width) const; + str lower() const; + str lstrip() const; + + str replace(object_cref old, object_cref new_) const; + str replace(object_cref old, object_cref new_, object_cref maxsplit) const; + long rfind(object_cref sub) const; + + long rfind(object_cref sub, object_cref start) const; + + long rfind(object_cref sub, object_cref start, object_cref end) const; + long rindex(object_cref sub) const; + long rindex(object_cref sub, object_cref start) const; + + + long rindex(object_cref sub, object_cref start, object_cref end) const; + + str rjust(object_cref width) const; + + str rstrip() const; + + list split() const; + list split(object_cref sep) const; + + list split(object_cref sep, object_cref maxsplit) const; + + + list splitlines() const; + list splitlines(object_cref keepends) const; + + bool startswith(object_cref prefix) const; + + + bool startswith(object_cref prefix, object_cref start) const; + bool startswith(object_cref prefix, object_cref start, object_cref end) const; + + str strip() const; + str swapcase() const; + str title() const; + + str translate(object_cref table) const; + + str translate(object_cref table, object_cref deletechars) const; + + + str upper() const; + + protected: + str_base(); // new str + + str_base(const char* s); // new str + explicit str_base(object_cref other); + + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str_base, object) + private: + static new_reference call(object const&); + }; +} + + +class str : public detail::str_base +{ + typedef detail::str_base base; + public: + str() {} // new str + + str(const char* s) : str_base(s) {} // new str + template explicit str(T const& other) - : object(str::call(object(other))) + : str_base(object(other)) { } - BOOST_PYTHON_DECL str capitalize() const ; - - BOOST_PYTHON_DECL str center(object_cref width) const ; - template str center(T const& width) const { - return this->center(object(width)); + return base::center(object(width)); } - BOOST_PYTHON_DECL long count(object_cref sub) const; - template long count(T const& sub) const { - return this->count(object(sub)); + return base::count(object(sub)); } - BOOST_PYTHON_DECL long count(object_cref sub, object_cref start) const; - template long count(T1 const& sub,T2 const& start) const { - return this->count(object(sub), object(start)); + return base::count(object(sub), object(start)); } - BOOST_PYTHON_DECL long count(object_cref sub, object_cref start, object_cref end) const; - template long count(T1 const& sub,T2 const& start, T3 const& end) const { - return this->count(object(sub), object(start)); + return base::count(object(sub), object(start)); } - BOOST_PYTHON_DECL object decode() const; - BOOST_PYTHON_DECL object decode(object_cref encoding) const; - + object decode() const { return base::decode(); } + template object decode(T const& encoding) const { - return this->decode(object(encoding)); + return base::decode(object(encoding)); } - BOOST_PYTHON_DECL object decode(object_cref encoding, object_cref errors) const; - template object decode(T1 const& encoding, T2 const& errors) const { - return this->decode(object(encoding),object(errors)); + return base::decode(object(encoding),object(errors)); } - BOOST_PYTHON_DECL object encode() const; - BOOST_PYTHON_DECL object encode(object_cref encoding) const; + object encode() const { return base::encode(); } template object encode(T const& encoding) const { - return this->encode(object(encoding)); + return base::encode(object(encoding)); } - BOOST_PYTHON_DECL object encode(object_cref encoding, object_cref errors) const; - template object encode(T1 const& encoding, T2 const& errors) const { - return this->encode(object(encoding),object(errors)); + return base::encode(object(encoding),object(errors)); } - BOOST_PYTHON_DECL bool endswith(object_cref suffix) const; - template bool endswith(T const& suffix) const { - return this->endswith(object(suffix)); + return base::endswith(object(suffix)); } - BOOST_PYTHON_DECL bool endswith(object_cref suffix, object_cref start) const; - template bool endswith(T1 const& suffix, T2 const& start) const { - return this->endswith(object(suffix), object(start)); + return base::endswith(object(suffix), object(start)); } - BOOST_PYTHON_DECL bool endswith(object_cref suffix, object_cref start, object_cref end) const; - template bool endswith(T1 const& suffix, T2 const& start, T3 const& end) const { - return this->endswith(object(suffix), object(start), object(end)); + return base::endswith(object(suffix), object(start), object(end)); } - BOOST_PYTHON_DECL str expandtabs() const; - BOOST_PYTHON_DECL str expandtabs(object_cref tabsize) const; + str expandtabs() const { return base::expandtabs(); } template str expandtabs(T const& tabsize) const { - return this->expandtabs(object(tabsize)); + return base::expandtabs(object(tabsize)); } - BOOST_PYTHON_DECL long find(object_cref sub) const; - template long find(T const& sub) const { - return this->find(object(sub)); + return base::find(object(sub)); } - BOOST_PYTHON_DECL long find(object_cref sub, object_cref start) const; - template long find(T1 const& sub, T2 const& start) const { - return this->find(object(sub), object(start)); + return base::find(object(sub), object(start)); } - BOOST_PYTHON_DECL long find(object_cref sub, object_cref start, object_cref end) const; - template long find(T1 const& sub, T2 const& start, T3 const& end) const { - return this->find(object(sub), object(start), object(end)); + return base::find(object(sub), object(start), object(end)); } - BOOST_PYTHON_DECL long index(object_cref sub) const; - template long index(T const& sub) const { - return this->index(object(sub)); + return base::index(object(sub)); } - BOOST_PYTHON_DECL long index(object_cref sub, object_cref start) const; - template long index(T1 const& sub, T2 const& start) const { - return this->index(object(sub), object(start)); + return base::index(object(sub), object(start)); } - BOOST_PYTHON_DECL long index(object_cref sub, object_cref start, object_cref end) const; - template long index(T1 const& sub, T2 const& start, T3 const& end) const { - return this->index(object(sub), object(start), object(end)); + return base::index(object(sub), object(start), object(end)); } - BOOST_PYTHON_DECL bool isalnum() const; - BOOST_PYTHON_DECL bool isalpha() const; - BOOST_PYTHON_DECL bool isdigit() const; - BOOST_PYTHON_DECL bool islower() const; - BOOST_PYTHON_DECL bool isspace() const; - BOOST_PYTHON_DECL bool istitle() const; - BOOST_PYTHON_DECL bool isupper() const; - - BOOST_PYTHON_DECL str join(object_cref sequence) const; - template str join(T const& sequence) const { - return this->join(object(sequence)); + return base::join(object(sequence)); } - BOOST_PYTHON_DECL str ljust(object_cref width) const; - template str ljust(T const& width) const { - return this->ljust(object(width)); + return base::ljust(object(width)); } - BOOST_PYTHON_DECL str lower() const; - BOOST_PYTHON_DECL str lstrip() const; - - BOOST_PYTHON_DECL str replace(object_cref old, object_cref new_) const ; - template str replace(T1 const& old, T2 const& new_) const { - return this->replace(object(old),object(new_)); + return base::replace(object(old),object(new_)); } - BOOST_PYTHON_DECL str replace(object_cref old, object_cref new_, object_cref maxsplit) const ; - template str replace(T1 const& old, T2 const& new_, T3 const& maxsplit) const { - return this->replace(object(old),object(new_),object(maxsplit)); + return base::replace(object(old),object(new_), object(maxsplit)); } - BOOST_PYTHON_DECL long rfind(object_cref sub) const; - template long rfind(T const& sub) const { - return this->rfind(object(sub)); + return base::rfind(object(sub)); } - BOOST_PYTHON_DECL long rfind(object_cref sub, object_cref start) const; - template long rfind(T1 const& sub, T2 const& start) const { - return this->rfind(object(sub), object(start)); + return base::rfind(object(sub), object(start)); } - BOOST_PYTHON_DECL long rfind(object_cref sub, object_cref start, object_cref end) const; - template long rfind(T1 const& sub, T2 const& start, T3 const& end) const { - return this->rfind(object(sub), object(start), object(end)); + return base::rfind(object(sub), object(start), object(end)); } - BOOST_PYTHON_DECL long rindex(object_cref sub) const; - template long rindex(T const& sub) const { - return this->rindex(object(sub)); + return base::rindex(object(sub)); } - BOOST_PYTHON_DECL long rindex(object_cref sub, object_cref start) const; - template long rindex(T1 const& sub, T2 const& start) const { - return this->rindex(object(sub), object(start)); + return base::rindex(object(sub), object(start)); } - BOOST_PYTHON_DECL long rindex(object_cref sub, object_cref start, object_cref end) const; - template long rindex(T1 const& sub, T2 const& start, T3 const& end) const { - return this->rindex(object(sub), object(start), object(end)); + return base::rindex(object(sub), object(start), object(end)); } - BOOST_PYTHON_DECL str rjust(object_cref width) const; - template str rjust(T const& width) const { - return this->rjust(object(width)); + return base::rjust(object(width)); } - BOOST_PYTHON_DECL str rstrip() const; - - BOOST_PYTHON_DECL list split() const; - BOOST_PYTHON_DECL list split(object_cref sep) const; + list split() const { return base::split(); } template list split(T const& sep) const { - return this->split(object(sep)); + return base::split(object(sep)); } - BOOST_PYTHON_DECL list split(object_cref sep, object_cref maxsplit) const; - template list split(T1 const& sep, T2 const& maxsplit) const { - return this->split(object(sep), object(maxsplit)); + return base::split(object(sep), object(maxsplit)); } - BOOST_PYTHON_DECL list splitlines() const; - BOOST_PYTHON_DECL list splitlines(object_cref keepends) const; + list splitlines() const { return base::splitlines(); } template list splitlines(T const& keepends) const { - return this->splitlines(object(keepends)); + return base::splitlines(object(keepends)); } - BOOST_PYTHON_DECL bool startswith(object_cref prefix) const ; - template bool startswith(T const& prefix) const { - return this->startswith(object(prefix)); + return base::startswith(object(prefix)); } - BOOST_PYTHON_DECL bool startswith(object_cref prefix, object_cref start) const ; - template bool startswidth(T1 const& prefix, T2 const& start) const { - return this->startswidth(object(prefix), object(start)); + return base::startswidth(object(prefix), object(start)); } - BOOST_PYTHON_DECL bool startswith(object_cref prefix, object_cref start, object_cref end) const ; - template bool startswidth(T1 const& prefix, T2 const& start, T3 const& end) const { - return this->startswidth(object(prefix), object(start), object(end)); + return base::startswidth(object(prefix), object(start), object(end)); } - BOOST_PYTHON_DECL str strip() const ; - BOOST_PYTHON_DECL str swapcase() const ; - BOOST_PYTHON_DECL str title() const ; - - BOOST_PYTHON_DECL str translate(object_cref table) const; - template str translate(T const& table) const { - return this->translate(object(table)); + return base::translate(object(table)); } - BOOST_PYTHON_DECL str translate(object_cref table, object_cref deletechars) const; - template str translate(T1 const& table, T2 const& deletechars) const { - return this->translate(object(table), object(deletechars)); + return base::translate(object(table), object(deletechars)); } - BOOST_PYTHON_DECL str upper() const; - public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str, object) - - private: - static BOOST_PYTHON_DECL detail::new_reference call(object const&); + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(str, base) }; // diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp index 77c5e67c..5fe4cb3b 100644 --- a/include/boost/python/tuple.hpp +++ b/include/boost/python/tuple.hpp @@ -8,26 +8,35 @@ namespace boost { namespace python { -class tuple : public object +namespace detail { - public: - // tuple() -> an empty tuple - BOOST_PYTHON_DECL tuple(); + struct BOOST_PYTHON_DECL tuple_base : object + { + protected: + tuple_base(); + tuple_base(object_cref sequence); + + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple_base, object) - // tuple(sequence) -> tuple initialized from sequence's items - BOOST_PYTHON_DECL tuple(object_cref sequence); + private: + static detail::new_reference call(object const&); + }; +} + +class tuple : public detail::tuple_base +{ + typedef detail::tuple_base base; + public: + tuple() {} template explicit tuple(T const& sequence) - : object(tuple::call(object(sequence))) + : tuple_base(object(sequence)) { } public: // implementation detail -- for internal use only - BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple, object) - - private: - static BOOST_PYTHON_DECL detail::new_reference call(object const&); + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(tuple, base) }; // diff --git a/src/dict.cpp b/src/dict.cpp index e24145d0..847d2182 100644 --- a/src/dict.cpp +++ b/src/dict.cpp @@ -1,8 +1,7 @@ #include #include -namespace boost { namespace python { - +namespace boost { namespace python { namespace detail { namespace { // When returning list objects from methods, it may turn out that the @@ -18,28 +17,28 @@ namespace } // No PyDict_CheckExact; roll our own. - inline bool check_exact(dict const* p) + inline bool check_exact(dict_base const* p) { return p->ptr()->ob_type == &PyDict_Type; } } -detail::new_reference dict::call(object const& arg_) +detail::new_reference dict_base::call(object const& arg_) { return (detail::new_reference)PyObject_CallFunction( (PyObject*)&PyDict_Type, "(O)", arg_.ptr()); } -dict::dict() +dict_base::dict_base() : object(detail::new_reference(PyDict_New())) {} -dict::dict(object_cref data) - : object(dict::call(data)) +dict_base::dict_base(object_cref data) + : object(call(data)) {} -void dict::clear() +void dict_base::clear() { if (check_exact(this)) PyDict_Clear(this->ptr()); @@ -47,7 +46,7 @@ void dict::clear() this->attr("clear")(); } -dict dict::copy() +dict dict_base::copy() { if (check_exact(this)) { @@ -62,7 +61,7 @@ dict dict::copy() } } -object dict::get(object_cref k) const +object dict_base::get(object_cref k) const { if (check_exact(this)) { @@ -75,17 +74,17 @@ object dict::get(object_cref k) const } } -object dict::get(object_cref k, object_cref d) const +object dict_base::get(object_cref k, object_cref d) const { return this->attr("get")(k,d); } -bool dict::has_key(object_cref k) const +bool dict_base::has_key(object_cref k) const { return extract(this->attr("has_key")(k)); } -list dict::items() const +list dict_base::items() const { if (check_exact(this)) { @@ -98,22 +97,22 @@ list dict::items() const } } -object dict::iteritems() const +object dict_base::iteritems() const { return this->attr("iteritems")(); } -object dict::iterkeys() const +object dict_base::iterkeys() const { return this->attr("iterkeys")(); } -object dict::itervalues() const +object dict_base::itervalues() const { return this->attr("itervalues")(); } -list dict::keys() const +list dict_base::keys() const { if (check_exact(this)) { @@ -126,24 +125,24 @@ list dict::keys() const } } -tuple dict::popitem() +tuple dict_base::popitem() { return tuple(detail::borrowed_reference( this->attr("popitem")().ptr() )); } -object dict::setdefault(object_cref k) +object dict_base::setdefault(object_cref k) { return this->attr("setdefault")(k); } -object dict::setdefault(object_cref k, object_cref d) +object dict_base::setdefault(object_cref k, object_cref d) { return this->attr("setdefault")(k,d); } -void dict::update(object_cref other) +void dict_base::update(object_cref other) { if (check_exact(this)) { @@ -156,7 +155,7 @@ void dict::update(object_cref other) } } -list dict::values() const +list dict_base::values() const { if (check_exact(this)) { @@ -169,4 +168,4 @@ list dict::values() const } } -}} // namespace boost::python +}}} // namespace boost::python diff --git a/src/list.cpp b/src/list.cpp index 1f434320..aab01bc3 100644 --- a/src/list.cpp +++ b/src/list.cpp @@ -5,9 +5,9 @@ // to its suitability for any purpose. #include -namespace boost { namespace python { +namespace boost { namespace python { namespace detail { -detail::new_non_null_reference list::call(object const& arg_) +detail::new_non_null_reference list_base::call(object const& arg_) { return (detail::new_non_null_reference) (expect_non_null)( @@ -16,15 +16,15 @@ detail::new_non_null_reference list::call(object const& arg_) arg_.ptr())); } -list::list() +list_base::list_base() : object(detail::new_reference(PyList_New(0))) {} -list::list(object_cref sequence) - : object(list::call(sequence)) +list_base::list_base(object_cref sequence) + : object(list_base::call(sequence)) {} -void list::append(object_cref x) +void list_base::append(object_cref x) { if (PyList_CheckExact(this->ptr())) { @@ -37,7 +37,7 @@ void list::append(object_cref x) } } -long list::count(object_cref value) const +long list_base::count(object_cref value) const { object result_obj(this->attr("count")(value)); long result = PyInt_AsLong(result_obj.ptr()); @@ -46,12 +46,12 @@ long list::count(object_cref value) const return result; } -void list::extend(object_cref sequence) +void list_base::extend(object_cref sequence) { this->attr("extend")(sequence); } -long list::index(object_cref value) const +long list_base::index(object_cref value) const { object result_obj(this->attr("index")(value)); long result = PyInt_AsLong(result_obj.ptr()); @@ -60,7 +60,7 @@ long list::index(object_cref value) const return result; } -void list::insert(int index, object_cref item) +void list_base::insert(int index, object_cref item) { if (PyList_CheckExact(this->ptr())) { @@ -73,7 +73,7 @@ void list::insert(int index, object_cref item) } } -void list::insert(object const& index, object_cref x) +void list_base::insert(object const& index, object_cref x) { long index_ = PyInt_AsLong(index.ptr()); if (index_ == -1 && PyErr_Occurred()) @@ -81,27 +81,27 @@ void list::insert(object const& index, object_cref x) this->insert(index_, x); } -object list::pop() +object list_base::pop() { return this->attr("pop")(); } -object list::pop(long index) +object list_base::pop(long index) { return this->pop(object(index)); } -object list::pop(object const& index) +object list_base::pop(object const& index) { return this->attr("pop")(index); } -void list::remove(object_cref value) +void list_base::remove(object_cref value) { this->attr("remove")(value); } -void list::reverse() +void list_base::reverse() { if (PyList_CheckExact(this->ptr())) { @@ -114,7 +114,7 @@ void list::reverse() } } -void list::sort() +void list_base::sort() { if (PyList_CheckExact(this->ptr())) { @@ -127,9 +127,9 @@ void list::sort() } } -void list::sort(object_cref cmpfunc) +void list_base::sort(object_cref cmpfunc) { this->attr("sort")(cmpfunc); } -}} // namespace boost::python +}}} // namespace boost::python diff --git a/src/long.cpp b/src/long.cpp index e66d4bdd..bfc09257 100644 --- a/src/long.cpp +++ b/src/long.cpp @@ -5,36 +5,36 @@ // to its suitability for any purpose. #include -namespace boost { namespace python { +namespace boost { namespace python { namespace detail { -detail::new_non_null_reference long_::call(object const& arg_) +new_non_null_reference long_base::call(object const& arg_) { return (detail::new_non_null_reference)PyObject_CallFunction( (PyObject*)&PyLong_Type, "(O)", arg_.ptr()); } -detail::new_non_null_reference long_::call(object const& arg_, object const& base) +new_non_null_reference long_base::call(object const& arg_, object const& base) { return (detail::new_non_null_reference)PyObject_CallFunction( (PyObject*)&PyLong_Type, "(OO)", arg_.ptr(), base.ptr()); } -long_::long_() +long_base::long_base() : object( detail::new_reference( PyObject_CallFunction((PyObject*)&PyLong_Type, "()")) ) {} -long_::long_(object_cref arg) - : object(long_::call(arg)) +long_base::long_base(object_cref arg) + : object(long_base::call(arg)) {} -long_::long_(object_cref arg, object_cref base) - : object(long_::call(arg, base)) +long_base::long_base(object_cref arg, object_cref base) + : object(long_base::call(arg, base)) {} -}} // namespace boost::python +}}} // namespace boost::python diff --git a/src/str.cpp b/src/str.cpp index fff18221..a8a2383f 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -1,99 +1,98 @@ #include #include -namespace boost { namespace python { +namespace boost { namespace python { namespace detail { -detail::new_reference str::call(object const& arg_) +detail::new_reference str_base::call(object const& arg_) { return (detail::new_reference)PyObject_CallFunction( (PyObject*)&PyString_Type, "(O)", arg_.ptr()); } -str::str() +str_base::str_base() : object(detail::new_reference(PyString_FromString(""))) {} -str::str(const char* s) +str_base::str_base(const char* s) : object(detail::new_reference(PyString_FromString(s))) {} -str::str(object_cref other) - : object(str::call(other)) +str_base::str_base(object_cref other) + : object(str_base::call(other)) {} namespace { - // When returning str objects from methods, it may turn out that the - // derived class is returning something else, perhaps something not - // even derived from str. Since it is generally harmless for a - // Boost.Python wrapper object to hold an object of a different - // type, and because calling str() with an object may in fact - // perform a conversion, the least-bad alternative is to assume that - // we have a Python str object and stuff it into the str result. - str assume_str(object const& o) + new_reference new_attr_reference(object const* obj, char const* name) { - return str(detail::borrowed_reference(o.ptr())); + return new_reference(incref(object(obj->attr(name)).ptr())); } } -str str::capitalize() const -{ - return assume_str(this->attr("capitalize")()); + +#define BOOST_PYTHON_FORMAT_OBJECT(z, n, data) "O" +#define BOOST_PYTHON_OBJECT_PTR(z, n, data) , x##n .ptr() + +#define BOOST_PYTHON_DEFINE_STR_METHOD(name, arity) \ +str str_base:: name ( BOOST_PP_ENUM_PARAMS(arity, object_cref x) ) const \ +{ \ + return str(new_reference( \ + expect_non_null( \ + PyObject_CallMethod( \ + this->ptr(), #name, \ + "(" BOOST_PP_REPEAT(arity, BOOST_PYTHON_FORMAT_OBJECT, _) ")" \ + BOOST_PP_REPEAT_1(arity, BOOST_PYTHON_OBJECT_PTR, _))))); \ } -str str::center(object_cref width) const -{ - return assume_str( - this->attr("center")(width) - ); -} +BOOST_PYTHON_DEFINE_STR_METHOD(capitalize, 0) +BOOST_PYTHON_DEFINE_STR_METHOD(center, 1) -long str::count(object_cref sub) const +long str_base::count(object_cref sub) const { return extract(this->attr("count")(sub)); } -long str::count(object_cref sub, object_cref start) const +long str_base::count(object_cref sub, object_cref start) const { return extract(this->attr("count")(sub,start)); } -long str::count(object_cref sub, object_cref start, object_cref end) const +long str_base::count(object_cref sub, object_cref start, object_cref end) const { return extract(this->attr("count")(sub,start,end)); } -object str::decode() const +object str_base::decode() const { return this->attr("decode")(); } -object str::decode(object_cref encoding) const +object str_base::decode(object_cref encoding) const { return this->attr("decode")(encoding); } -object str::decode(object_cref encoding, object_cref errors) const +object str_base::decode(object_cref encoding, object_cref errors) const { return this->attr("decode")(encoding,errors); } -object str::encode() const +object str_base::encode() const { return this->attr("encode")(); } -object str::encode(object_cref encoding) const +object str_base::encode(object_cref encoding) const { return this->attr("encode")(encoding); } -object str::encode(object_cref encoding, object_cref errors) const +object str_base::encode(object_cref encoding, object_cref errors) const { return this->attr("encode")(encoding,errors); } -bool str::endswith(object_cref suffix) const +bool str_base::endswith(object_cref suffix) const { bool result = PyInt_AsLong(this->attr("endswith")(suffix).ptr()); if (PyErr_Occurred()) @@ -101,17 +100,10 @@ bool str::endswith(object_cref suffix) const return result; } -str str::expandtabs() const -{ - return assume_str(this->attr("expandtabs")()); -} +BOOST_PYTHON_DEFINE_STR_METHOD(expandtabs, 0) +BOOST_PYTHON_DEFINE_STR_METHOD(expandtabs, 1) -str str::expandtabs(object_cref tabsize) const -{ - return assume_str(this->attr("expandtabs")(tabsize)); -} - -long str::find(object_cref sub) const +long str_base::find(object_cref sub) const { long result = PyInt_AsLong(this->attr("find")(sub).ptr()); if (PyErr_Occurred()) @@ -119,7 +111,7 @@ long str::find(object_cref sub) const return result; } -long str::find(object_cref sub, object_cref start) const +long str_base::find(object_cref sub, object_cref start) const { long result = PyInt_AsLong(this->attr("find")(sub,start).ptr()); if (PyErr_Occurred()) @@ -127,7 +119,7 @@ long str::find(object_cref sub, object_cref start) const return result; } -long str::find(object_cref sub, object_cref start, object_cref end) const +long str_base::find(object_cref sub, object_cref start, object_cref end) const { long result = PyInt_AsLong(this->attr("find")(sub,start,end).ptr()); if (PyErr_Occurred()) @@ -135,7 +127,7 @@ long str::find(object_cref sub, object_cref start, object_cref end) const return result; } -long str::index(object_cref sub) const +long str_base::index(object_cref sub) const { long result = PyInt_AsLong(this->attr("index")(sub).ptr()); if (PyErr_Occurred()) @@ -143,7 +135,7 @@ long str::index(object_cref sub) const return result; } -long str::index(object_cref sub, object_cref start) const +long str_base::index(object_cref sub, object_cref start) const { long result = PyInt_AsLong(this->attr("index")(sub,start).ptr()); if (PyErr_Occurred()) @@ -151,7 +143,7 @@ long str::index(object_cref sub, object_cref start) const return result; } -long str::index(object_cref sub, object_cref start, object_cref end) const +long str_base::index(object_cref sub, object_cref start, object_cref end) const { long result = PyInt_AsLong(this->attr("index")(sub,start,end).ptr()); if (PyErr_Occurred()) @@ -159,7 +151,7 @@ long str::index(object_cref sub, object_cref start, object_cref end) const return result; } -bool str::isalnum() const +bool str_base::isalnum() const { bool result = PyInt_AsLong(this->attr("isalnum")().ptr()); if (PyErr_Occurred()) @@ -167,7 +159,7 @@ bool str::isalnum() const return result; } -bool str::isalpha() const +bool str_base::isalpha() const { bool result = PyInt_AsLong(this->attr("isalpha")().ptr()); if (PyErr_Occurred()) @@ -175,7 +167,7 @@ bool str::isalpha() const return result; } -bool str::isdigit() const +bool str_base::isdigit() const { bool result = PyInt_AsLong(this->attr("isdigit")().ptr()); if (PyErr_Occurred()) @@ -183,7 +175,7 @@ bool str::isdigit() const return result; } -bool str::islower() const +bool str_base::islower() const { bool result = PyInt_AsLong(this->attr("islower")().ptr()); if (PyErr_Occurred()) @@ -191,7 +183,7 @@ bool str::islower() const return result; } -bool str::isspace() const +bool str_base::isspace() const { bool result = PyInt_AsLong(this->attr("isspace")().ptr()); if (PyErr_Occurred()) @@ -199,7 +191,7 @@ bool str::isspace() const return result; } -bool str::istitle() const +bool str_base::istitle() const { bool result = PyInt_AsLong(this->attr("istitle")().ptr()); if (PyErr_Occurred()) @@ -207,7 +199,7 @@ bool str::istitle() const return result; } -bool str::isupper() const +bool str_base::isupper() const { bool result = PyInt_AsLong(this->attr("isupper")().ptr()); if (PyErr_Occurred()) @@ -215,36 +207,14 @@ bool str::isupper() const return result; } -str str::join(object_cref sequence) const -{ - return assume_str(this->attr("join")(sequence)); -} +BOOST_PYTHON_DEFINE_STR_METHOD(join, 1) +BOOST_PYTHON_DEFINE_STR_METHOD(ljust, 1) +BOOST_PYTHON_DEFINE_STR_METHOD(lower, 0) +BOOST_PYTHON_DEFINE_STR_METHOD(lstrip, 0) +BOOST_PYTHON_DEFINE_STR_METHOD(replace, 2) +BOOST_PYTHON_DEFINE_STR_METHOD(replace, 3) -str str::ljust(object_cref width) const -{ - return assume_str(this->attr("ljust")(width)); -} - -str str::lower() const -{ - return assume_str(this->attr("lower")()); -} - -str str::lstrip() const -{ - return assume_str(this->attr("lstrip")()); -} - -str str::replace(object_cref old, object_cref new_) const -{ - return assume_str(this->attr("replace")(old,new_)); -} - -str str::replace(object_cref old, object_cref new_, object_cref maxsplit) const { - return assume_str(this->attr("replace")(old,new_,maxsplit)); -} - -long str::rfind(object_cref sub) const +long str_base::rfind(object_cref sub) const { long result = PyInt_AsLong(this->attr("rfind")(sub).ptr()); if (PyErr_Occurred()) @@ -252,7 +222,7 @@ long str::rfind(object_cref sub) const return result; } -long str::rfind(object_cref sub, object_cref start) const +long str_base::rfind(object_cref sub, object_cref start) const { long result = PyInt_AsLong(this->attr("rfind")(sub,start).ptr()); if (PyErr_Occurred()) @@ -260,7 +230,7 @@ long str::rfind(object_cref sub, object_cref start) const return result; } -long str::rfind(object_cref sub, object_cref start, object_cref end) const +long str_base::rfind(object_cref sub, object_cref start, object_cref end) const { long result = PyInt_AsLong(this->attr("rfind")(sub,start,end).ptr()); if (PyErr_Occurred()) @@ -268,7 +238,7 @@ long str::rfind(object_cref sub, object_cref start, object_cref end) const return result; } -long str::rindex(object_cref sub) const +long str_base::rindex(object_cref sub) const { long result = PyInt_AsLong(this->attr("rindex")(sub).ptr()); if (PyErr_Occurred()) @@ -276,7 +246,7 @@ long str::rindex(object_cref sub) const return result; } -long str::rindex(object_cref sub, object_cref start) const +long str_base::rindex(object_cref sub, object_cref start) const { long result = PyInt_AsLong(this->attr("rindex")(sub,start).ptr()); if (PyErr_Occurred()) @@ -284,7 +254,7 @@ long str::rindex(object_cref sub, object_cref start) const return result; } -long str::rindex(object_cref sub, object_cref start, object_cref end) const +long str_base::rindex(object_cref sub, object_cref start, object_cref end) const { long result = PyInt_AsLong(this->attr("rindex")(sub,start,end).ptr()); if (PyErr_Occurred()) @@ -292,42 +262,35 @@ long str::rindex(object_cref sub, object_cref start, object_cref end) const return result; } -str str::rjust(object_cref width) const -{ - return assume_str(this->attr("rjust")(width)); -} +BOOST_PYTHON_DEFINE_STR_METHOD(rjust, 1) +BOOST_PYTHON_DEFINE_STR_METHOD(rstrip, 0) -str str::rstrip() const -{ - return assume_str(this->attr("rstrip")()); -} - -list str::split() const +list str_base::split() const { return list(this->attr("split")()); } -list str::split(object_cref sep) const +list str_base::split(object_cref sep) const { return list(this->attr("split")(sep)); } -list str::split(object_cref sep, object_cref maxsplit) const +list str_base::split(object_cref sep, object_cref maxsplit) const { return list(this->attr("split")(sep,maxsplit)); } -list str::splitlines() const +list str_base::splitlines() const { return list(this->attr("splitlines")()); } -list str::splitlines(object_cref keepends) const +list str_base::splitlines(object_cref keepends) const { return list(this->attr("splitlines")(keepends)); } -bool str::startswith(object_cref prefix) const +bool str_base::startswith(object_cref prefix) const { bool result = PyInt_AsLong(this->attr("startswith")(prefix).ptr()); if (PyErr_Occurred()) @@ -335,7 +298,7 @@ bool str::startswith(object_cref prefix) const return result; } -bool str::startswith(object_cref prefix, object_cref start) const +bool str_base::startswith(object_cref prefix, object_cref start) const { bool result = PyInt_AsLong(this->attr("startswith")(prefix,start).ptr()); if (PyErr_Occurred()) @@ -343,7 +306,7 @@ bool str::startswith(object_cref prefix, object_cref start) const return result; } -bool str::startswith(object_cref prefix, object_cref start, object_cref end) const +bool str_base::startswith(object_cref prefix, object_cref start, object_cref end) const { bool result = PyInt_AsLong(this->attr("startswith")(prefix,start,end).ptr()); if (PyErr_Occurred()) @@ -351,34 +314,11 @@ bool str::startswith(object_cref prefix, object_cref start, object_cref end) con return result; } -str str::strip() const -{ - return assume_str(this->attr("strip")()); -} +BOOST_PYTHON_DEFINE_STR_METHOD(strip, 0) +BOOST_PYTHON_DEFINE_STR_METHOD(swapcase, 0) +BOOST_PYTHON_DEFINE_STR_METHOD(title, 0) +BOOST_PYTHON_DEFINE_STR_METHOD(translate, 1) +BOOST_PYTHON_DEFINE_STR_METHOD(translate, 2) +BOOST_PYTHON_DEFINE_STR_METHOD(upper, 0) -str str::swapcase() const -{ - return assume_str(this->attr("swapcase")()); -} - -str str::title() const -{ - return assume_str(this->attr("title")()); -} - -str str::translate(object_cref table) const -{ - return assume_str(this->attr("translate")(table)); -} - -str str::translate(object_cref table, object_cref deletechars) const -{ - return assume_str(this->attr("translate")(table,deletechars)); -} - -str str::upper() const -{ - return assume_str(this->attr("upper")()); -} - -}} // namespace boost::python +}}} // namespace boost::python diff --git a/src/tuple.cpp b/src/tuple.cpp index 16b8e773..2762ab27 100644 --- a/src/tuple.cpp +++ b/src/tuple.cpp @@ -1,20 +1,20 @@ #include -namespace boost { namespace python { +namespace boost { namespace python { namespace detail { -detail::new_reference tuple::call(object const& arg_) +detail::new_reference tuple_base::call(object const& arg_) { return (detail::new_reference)PyObject_CallFunction( (PyObject*)&PyTuple_Type, "(O)", arg_.ptr()); } -tuple::tuple() +tuple_base::tuple_base() : object(detail::new_reference(PyTuple_New(0))) {} -tuple::tuple(object_cref sequence) - : object(tuple::call(sequence)) +tuple_base::tuple_base(object_cref sequence) + : object(call(sequence)) {} -}} // namespace boost::python +}}} // namespace boost::python diff --git a/test/doctest.py b/test/doctest.py deleted file mode 100644 index 2829f1e6..00000000 --- a/test/doctest.py +++ /dev/null @@ -1,1173 +0,0 @@ -# Module doctest. -# Released to the public domain 16-Jan-2001, -# by Tim Peters (tim.one@home.com). - -# Provided as-is; use at your own risk; no warranty; no promises; enjoy! - -"""Module doctest -- a framework for running examples in docstrings. - -NORMAL USAGE - -In normal use, end each module M with: - -def _test(): - import doctest, M # replace M with your module's name - return doctest.testmod(M) # ditto - -if __name__ == "__main__": - _test() - -Then running the module as a script will cause the examples in the -docstrings to get executed and verified: - -python M.py - -This won't display anything unless an example fails, in which case the -failing example(s) and the cause(s) of the failure(s) are printed to stdout -(why not stderr? because stderr is a lame hack <0.2 wink>), and the final -line of output is "Test failed.". - -Run it with the -v switch instead: - -python M.py -v - -and a detailed report of all examples tried is printed to stdout, along -with assorted summaries at the end. - -You can force verbose mode by passing "verbose=1" to testmod, or prohibit -it by passing "verbose=0". In either of those cases, sys.argv is not -examined by testmod. - -In any case, testmod returns a 2-tuple of ints (f, t), where f is the -number of docstring examples that failed and t is the total number of -docstring examples attempted. - - -WHICH DOCSTRINGS ARE EXAMINED? - -+ M.__doc__. - -+ f.__doc__ for all functions f in M.__dict__.values(), except those - with private names and those defined in other modules. - -+ C.__doc__ for all classes C in M.__dict__.values(), except those with - private names and those defined in other modules. - -+ If M.__test__ exists and "is true", it must be a dict, and - each entry maps a (string) name to a function object, class object, or - string. Function and class object docstrings found from M.__test__ - are searched even if the name is private, and strings are searched - directly as if they were docstrings. In output, a key K in M.__test__ - appears with name - .__test__.K - -Any classes found are recursively searched similarly, to test docstrings in -their contained methods and nested classes. Private names reached from M's -globals are skipped, but all names reached from M.__test__ are searched. - -By default, a name is considered to be private if it begins with an -underscore (like "_my_func") but doesn't both begin and end with (at least) -two underscores (like "__init__"). You can change the default by passing -your own "isprivate" function to testmod. - -If you want to test docstrings in objects with private names too, stuff -them into an M.__test__ dict, or see ADVANCED USAGE below (e.g., pass your -own isprivate function to Tester's constructor, or call the rundoc method -of a Tester instance). - -WHAT'S THE EXECUTION CONTEXT? - -By default, each time testmod finds a docstring to test, it uses a *copy* -of M's globals (so that running tests on a module doesn't change the -module's real globals, and so that one test in M can't leave behind crumbs -that accidentally allow another test to work). This means examples can -freely use any names defined at top-level in M. It also means that sloppy -imports (see above) can cause examples in external docstrings to use -globals inappropriate for them. - -You can force use of your own dict as the execution context by passing -"globs=your_dict" to testmod instead. Presumably this would be a copy of -M.__dict__ merged with the globals from other imported modules. - - -WHAT IF I WANT TO TEST A WHOLE PACKAGE? - -Piece o' cake, provided the modules do their testing from docstrings. -Here's the test.py I use for the world's most elaborate Rational/ -floating-base-conversion pkg (which I'll distribute some day): - -from Rational import Cvt -from Rational import Format -from Rational import machprec -from Rational import Rat -from Rational import Round -from Rational import utils - -modules = (Cvt, - Format, - machprec, - Rat, - Round, - utils) - -def _test(): - import doctest - import sys - verbose = "-v" in sys.argv - for mod in modules: - doctest.testmod(mod, verbose=verbose, report=0) - doctest.master.summarize() - -if __name__ == "__main__": - _test() - -IOW, it just runs testmod on all the pkg modules. testmod remembers the -names and outcomes (# of failures, # of tries) for each item it's seen, and -passing "report=0" prevents it from printing a summary in verbose mode. -Instead, the summary is delayed until all modules have been tested, and -then "doctest.master.summarize()" forces the summary at the end. - -So this is very nice in practice: each module can be tested individually -with almost no work beyond writing up docstring examples, and collections -of modules can be tested too as a unit with no more work than the above. - - -WHAT ABOUT EXCEPTIONS? - -No problem, as long as the only output generated by the example is the -traceback itself. For example: - - >>> [1, 2, 3].remove(42) - Traceback (most recent call last): - File "", line 1, in ? - ValueError: list.remove(x): x not in list - >>> - -Note that only the exception type and value are compared (specifically, -only the last line in the traceback). - - -ADVANCED USAGE - -doctest.testmod() captures the testing policy I find most useful most -often. You may want other policies. - -testmod() actually creates a local instance of class doctest.Tester, runs -appropriate methods of that class, and merges the results into global -Tester instance doctest.master. - -You can create your own instances of doctest.Tester, and so build your own -policies, or even run methods of doctest.master directly. See -doctest.Tester.__doc__ for details. - - -SO WHAT DOES A DOCSTRING EXAMPLE LOOK LIKE ALREADY!? - -Oh ya. It's easy! In most cases a copy-and-paste of an interactive -console session works fine -- just make sure the leading whitespace is -rigidly consistent (you can mix tabs and spaces if you're too lazy to do it -right, but doctest is not in the business of guessing what you think a tab -means). - - >>> # comments are ignored - >>> x = 12 - >>> x - 12 - >>> if x == 13: - ... print "yes" - ... else: - ... print "no" - ... print "NO" - ... print "NO!!!" - ... - no - NO - NO!!! - >>> - -Any expected output must immediately follow the final ">>>" or "..." line -containing the code, and the expected output (if any) extends to the next -">>>" or all-whitespace line. That's it. - -Bummers: - -+ Expected output cannot contain an all-whitespace line, since such a line - is taken to signal the end of expected output. - -+ Output to stdout is captured, but not output to stderr (exception - tracebacks are captured via a different means). - -+ If you continue a line via backslashing in an interactive session, or for - any other reason use a backslash, you need to double the backslash in the - docstring version. This is simply because you're in a string, and so the - backslash must be escaped for it to survive intact. Like: - ->>> if "yes" == \\ -... "y" + \\ -... "es": # in the source code you'll see the doubled backslashes -... print 'yes' -yes - -The starting column doesn't matter: - ->>> assert "Easy!" - >>> import math - >>> math.floor(1.9) - 1.0 - -and as many leading whitespace characters are stripped from the expected -output as appeared in the initial ">>>" line that triggered it. - -If you execute this very file, the examples above will be found and -executed, leading to this output in verbose mode: - -Running doctest.__doc__ -Trying: [1, 2, 3].remove(42) -Expecting: -Traceback (most recent call last): - File "", line 1, in ? -ValueError: list.remove(x): x not in list -ok -Trying: x = 12 -Expecting: nothing -ok -Trying: x -Expecting: 12 -ok -Trying: -if x == 13: - print "yes" -else: - print "no" - print "NO" - print "NO!!!" -Expecting: -no -NO -NO!!! -ok -... and a bunch more like that, with this summary at the end: - -5 items had no tests: - doctest.Tester.__init__ - doctest.Tester.run__test__ - doctest.Tester.summarize - doctest.run_docstring_examples - doctest.testmod -12 items passed all tests: - 8 tests in doctest - 6 tests in doctest.Tester - 10 tests in doctest.Tester.merge - 14 tests in doctest.Tester.rundict - 3 tests in doctest.Tester.rundoc - 3 tests in doctest.Tester.runstring - 2 tests in doctest.__test__._TestClass - 2 tests in doctest.__test__._TestClass.__init__ - 2 tests in doctest.__test__._TestClass.get - 1 tests in doctest.__test__._TestClass.square - 2 tests in doctest.__test__.string - 7 tests in doctest.is_private -60 tests in 17 items. -60 passed and 0 failed. -Test passed. -""" - -__all__ = [ - 'testmod', - 'run_docstring_examples', - 'is_private', - 'Tester', -] - -import __future__ - -import re -PS1 = ">>>" -PS2 = "..." -_isPS1 = re.compile(r"(\s*)" + re.escape(PS1)).match -_isPS2 = re.compile(r"(\s*)" + re.escape(PS2)).match -_isEmpty = re.compile(r"\s*$").match -_isComment = re.compile(r"\s*#").match -del re - -from types import StringTypes as _StringTypes - -from inspect import isclass as _isclass -from inspect import isfunction as _isfunction -from inspect import ismodule as _ismodule -from inspect import classify_class_attrs as _classify_class_attrs - -# Extract interactive examples from a string. Return a list of triples, -# (source, outcome, lineno). "source" is the source code, and ends -# with a newline iff the source spans more than one line. "outcome" is -# the expected output if any, else an empty string. When not empty, -# outcome always ends with a newline. "lineno" is the line number, -# 0-based wrt the start of the string, of the first source line. - -def _extract_examples(s): - isPS1, isPS2 = _isPS1, _isPS2 - isEmpty, isComment = _isEmpty, _isComment - examples = [] - lines = s.split("\n") - i, n = 0, len(lines) - while i < n: - line = lines[i] - i = i + 1 - m = isPS1(line) - if m is None: - continue - j = m.end(0) # beyond the prompt - if isEmpty(line, j) or isComment(line, j): - # a bare prompt or comment -- not interesting - continue - lineno = i - 1 - if line[j] != " ": - raise ValueError("line " + `lineno` + " of docstring lacks " - "blank after " + PS1 + ": " + line) - j = j + 1 - blanks = m.group(1) - nblanks = len(blanks) - # suck up this and following PS2 lines - source = [] - while 1: - source.append(line[j:]) - line = lines[i] - m = isPS2(line) - if m: - if m.group(1) != blanks: - raise ValueError("inconsistent leading whitespace " - "in line " + `i` + " of docstring: " + line) - i = i + 1 - else: - break - if len(source) == 1: - source = source[0] - else: - # get rid of useless null line from trailing empty "..." - if source[-1] == "": - del source[-1] - source = "\n".join(source) + "\n" - # suck up response - if isPS1(line) or isEmpty(line): - expect = "" - else: - expect = [] - while 1: - if line[:nblanks] != blanks: - raise ValueError("inconsistent leading whitespace " - "in line " + `i` + " of docstring: " + line) - expect.append(line[nblanks:]) - i = i + 1 - line = lines[i] - if isPS1(line) or isEmpty(line): - break - expect = "\n".join(expect) + "\n" - examples.append( (source, expect, lineno) ) - return examples - -# Capture stdout when running examples. - -class _SpoofOut: - def __init__(self): - self.clear() - def write(self, s): - self.buf.append(s) - def get(self): - guts = "".join(self.buf) - # If anything at all was written, make sure there's a trailing - # newline. There's no way for the expected output to indicate - # that a trailing newline is missing. - if guts and not guts.endswith("\n"): - guts = guts + "\n" - # Prevent softspace from screwing up the next test case, in - # case they used print with a trailing comma in an example. - if hasattr(self, "softspace"): - del self.softspace - return guts - def clear(self): - self.buf = [] - if hasattr(self, "softspace"): - del self.softspace - def flush(self): - # JPython calls flush - pass - -# Display some tag-and-msg pairs nicely, keeping the tag and its msg -# on the same line when that makes sense. - -def _tag_out(printer, *tag_msg_pairs): - for tag, msg in tag_msg_pairs: - printer(tag + ":") - msg_has_nl = msg[-1:] == "\n" - msg_has_two_nl = msg_has_nl and \ - msg.find("\n") < len(msg) - 1 - if len(tag) + len(msg) < 76 and not msg_has_two_nl: - printer(" ") - else: - printer("\n") - printer(msg) - if not msg_has_nl: - printer("\n") - -# Run list of examples, in context globs. "out" can be used to display -# stuff to "the real" stdout, and fakeout is an instance of _SpoofOut -# that captures the examples' std output. Return (#failures, #tries). - -def _run_examples_inner(out, fakeout, examples, globs, verbose, name, - compileflags): - import sys, traceback - OK, BOOM, FAIL = range(3) - NADA = "nothing" - stderr = _SpoofOut() - failures = 0 - for source, want, lineno in examples: - if verbose: - _tag_out(out, ("Trying", source), - ("Expecting", want or NADA)) - fakeout.clear() - try: - exec compile(source, "", "single", - compileflags, 1) in globs - got = fakeout.get() - state = OK - except: - # See whether the exception was expected. - if want.find("Traceback (innermost last):\n") == 0 or \ - want.find("Traceback (most recent call last):\n") == 0: - # Only compare exception type and value - the rest of - # the traceback isn't necessary. - want = want.split('\n')[-2] + '\n' - exc_type, exc_val = sys.exc_info()[:2] - got = traceback.format_exception_only(exc_type, exc_val)[-1] - state = OK - else: - # unexpected exception - stderr.clear() - traceback.print_exc(file=stderr) - state = BOOM - - if state == OK: - if got == want: - if verbose: - out("ok\n") - continue - state = FAIL - - assert state in (FAIL, BOOM) - failures = failures + 1 - out("*" * 65 + "\n") - _tag_out(out, ("Failure in example", source)) - out("from line #" + `lineno` + " of " + name + "\n") - if state == FAIL: - _tag_out(out, ("Expected", want or NADA), ("Got", got)) - else: - assert state == BOOM - _tag_out(out, ("Exception raised", stderr.get())) - - return failures, len(examples) - -# Get the future-flags associated with the future features that have been -# imported into globs. - -def _extract_future_flags(globs): - flags = 0 - for fname in __future__.all_feature_names: - feature = globs.get(fname, None) - if feature is getattr(__future__, fname): - flags |= feature.compiler_flag - return flags - -# Run list of examples, in a shallow copy of context (dict) globs. -# Return (#failures, #tries). - -def _run_examples(examples, globs, verbose, name, compileflags): - import sys - saveout = sys.stdout - globs = globs.copy() - try: - sys.stdout = fakeout = _SpoofOut() - x = _run_examples_inner(saveout.write, fakeout, examples, - globs, verbose, name, compileflags) - finally: - sys.stdout = saveout - # While Python gc can clean up most cycles on its own, it doesn't - # chase frame objects. This is especially irksome when running - # generator tests that raise exceptions, because a named generator- - # iterator gets an entry in globs, and the generator-iterator - # object's frame's traceback info points back to globs. This is - # easy to break just by clearing the namespace. This can also - # help to break other kinds of cycles, and even for cycles that - # gc can break itself it's better to break them ASAP. - globs.clear() - return x - -def run_docstring_examples(f, globs, verbose=0, name="NoName", - compileflags=None): - """f, globs, verbose=0, name="NoName" -> run examples from f.__doc__. - - Use (a shallow copy of) dict globs as the globals for execution. - Return (#failures, #tries). - - If optional arg verbose is true, print stuff even if there are no - failures. - Use string name in failure msgs. - """ - - try: - doc = f.__doc__ - if not doc: - # docstring empty or None - return 0, 0 - # just in case CT invents a doc object that has to be forced - # to look like a string <0.9 wink> - doc = str(doc) - except: - return 0, 0 - - e = _extract_examples(doc) - if not e: - return 0, 0 - if compileflags is None: - compileflags = _extract_future_flags(globs) - return _run_examples(e, globs, verbose, name, compileflags) - -def is_private(prefix, base): - """prefix, base -> true iff name prefix + "." + base is "private". - - Prefix may be an empty string, and base does not contain a period. - Prefix is ignored (although functions you write conforming to this - protocol may make use of it). - Return true iff base begins with an (at least one) underscore, but - does not both begin and end with (at least) two underscores. - - >>> is_private("a.b", "my_func") - 0 - >>> is_private("____", "_my_func") - 1 - >>> is_private("someclass", "__init__") - 0 - >>> is_private("sometypo", "__init_") - 1 - >>> is_private("x.y.z", "_") - 1 - >>> is_private("_x.y.z", "__") - 0 - >>> is_private("", "") # senseless but consistent - 0 - """ - - return base[:1] == "_" and not base[:2] == "__" == base[-2:] - -# Determine if a class of function was defined in the given module. - -def _from_module(module, object): - if _isfunction(object): - return module.__dict__ is object.func_globals - if _isclass(object): - return module.__name__ == object.__module__ - raise ValueError("object must be a class or function") - -class Tester: - """Class Tester -- runs docstring examples and accumulates stats. - -In normal use, function doctest.testmod() hides all this from you, -so use that if you can. Create your own instances of Tester to do -fancier things. - -Methods: - runstring(s, name) - Search string s for examples to run; use name for logging. - Return (#failures, #tries). - - rundoc(object, name=None) - Search object.__doc__ for examples to run; use name (or - object.__name__) for logging. Return (#failures, #tries). - - rundict(d, name, module=None) - Search for examples in docstrings in all of d.values(); use name - for logging. Exclude functions and classes not defined in module - if specified. Return (#failures, #tries). - - run__test__(d, name) - Treat dict d like module.__test__. Return (#failures, #tries). - - summarize(verbose=None) - Display summary of testing results, to stdout. Return - (#failures, #tries). - - merge(other) - Merge in the test results from Tester instance "other". - ->>> from doctest import Tester ->>> t = Tester(globs={'x': 42}, verbose=0) ->>> t.runstring(r''' -... >>> x = x * 2 -... >>> print x -... 42 -... ''', 'XYZ') -***************************************************************** -Failure in example: print x -from line #2 of XYZ -Expected: 42 -Got: 84 -(1, 2) ->>> t.runstring(">>> x = x * 2\\n>>> print x\\n84\\n", 'example2') -(0, 2) ->>> t.summarize() -***************************************************************** -1 items had failures: - 1 of 2 in XYZ -***Test Failed*** 1 failures. -(1, 4) ->>> t.summarize(verbose=1) -1 items passed all tests: - 2 tests in example2 -***************************************************************** -1 items had failures: - 1 of 2 in XYZ -4 tests in 2 items. -3 passed and 1 failed. -***Test Failed*** 1 failures. -(1, 4) ->>> -""" - - def __init__(self, mod=None, globs=None, verbose=None, - isprivate=None): - """mod=None, globs=None, verbose=None, isprivate=None - -See doctest.__doc__ for an overview. - -Optional keyword arg "mod" is a module, whose globals are used for -executing examples. If not specified, globs must be specified. - -Optional keyword arg "globs" gives a dict to be used as the globals -when executing examples; if not specified, use the globals from -module mod. - -In either case, a copy of the dict is used for each docstring -examined. - -Optional keyword arg "verbose" prints lots of stuff if true, only -failures if false; by default, it's true iff "-v" is in sys.argv. - -Optional keyword arg "isprivate" specifies a function used to determine -whether a name is private. The default function is doctest.is_private; -see its docs for details. -""" - - if mod is None and globs is None: - raise TypeError("Tester.__init__: must specify mod or globs") - if mod is not None and not _ismodule(mod): - raise TypeError("Tester.__init__: mod must be a module; " + - `mod`) - if globs is None: - globs = mod.__dict__ - self.globs = globs - - if verbose is None: - import sys - verbose = "-v" in sys.argv - self.verbose = verbose - - if isprivate is None: - isprivate = is_private - self.isprivate = isprivate - - self.name2ft = {} # map name to (#failures, #trials) pair - - self.compileflags = _extract_future_flags(globs) - - def runstring(self, s, name): - """ - s, name -> search string s for examples to run, logging as name. - - Use string name as the key for logging the outcome. - Return (#failures, #examples). - - >>> t = Tester(globs={}, verbose=1) - >>> test = r''' - ... # just an example - ... >>> x = 1 + 2 - ... >>> x - ... 3 - ... ''' - >>> t.runstring(test, "Example") - Running string Example - Trying: x = 1 + 2 - Expecting: nothing - ok - Trying: x - Expecting: 3 - ok - 0 of 2 examples failed in string Example - (0, 2) - """ - - if self.verbose: - print "Running string", name - f = t = 0 - e = _extract_examples(s) - if e: - f, t = _run_examples(e, self.globs, self.verbose, name, - self.compileflags) - if self.verbose: - print f, "of", t, "examples failed in string", name - self.__record_outcome(name, f, t) - return f, t - - def rundoc(self, object, name=None): - """ - object, name=None -> search object.__doc__ for examples to run. - - Use optional string name as the key for logging the outcome; - by default use object.__name__. - Return (#failures, #examples). - If object is a class object, search recursively for method - docstrings too. - object.__doc__ is examined regardless of name, but if object is - a class, whether private names reached from object are searched - depends on the constructor's "isprivate" argument. - - >>> t = Tester(globs={}, verbose=0) - >>> def _f(): - ... '''Trivial docstring example. - ... >>> assert 2 == 2 - ... ''' - ... return 32 - ... - >>> t.rundoc(_f) # expect 0 failures in 1 example - (0, 1) - """ - - if name is None: - try: - name = object.__name__ - except AttributeError: - raise ValueError("Tester.rundoc: name must be given " - "when object.__name__ doesn't exist; " + `object`) - if self.verbose: - print "Running", name + ".__doc__" - f, t = run_docstring_examples(object, self.globs, self.verbose, name, - self.compileflags) - if self.verbose: - print f, "of", t, "examples failed in", name + ".__doc__" - self.__record_outcome(name, f, t) - if _isclass(object): - # In 2.2, class and static methods complicate life. Build - # a dict "that works", by hook or by crook. - d = {} - for tag, kind, homecls, value in _classify_class_attrs(object): - - if homecls is not object: - # Only look at names defined immediately by the class. - continue - - elif self.isprivate(name, tag): - continue - - elif kind == "method": - # value is already a function - d[tag] = value - - elif kind == "static method": - # value isn't a function, but getattr reveals one - d[tag] = getattr(object, tag) - - elif kind == "class method": - # Hmm. A classmethod object doesn't seem to reveal - # enough. But getattr turns it into a bound method, - # and from there .im_func retrieves the underlying - # function. - d[tag] = getattr(object, tag).im_func - - elif kind == "property": - # The methods implementing the property have their - # own docstrings -- but the property may have one too. - if value.__doc__ is not None: - d[tag] = str(value.__doc__) - - elif kind == "data": - # Grab nested classes. - if _isclass(value): - d[tag] = value - - else: - raise ValueError("teach doctest about %r" % kind) - - f2, t2 = self.run__test__(d, name) - f += f2 - t += t2 - - return f, t - - def rundict(self, d, name, module=None): - """ - d, name, module=None -> search for docstring examples in d.values(). - - For k, v in d.items() such that v is a function or class, - do self.rundoc(v, name + "." + k). Whether this includes - objects with private names depends on the constructor's - "isprivate" argument. If module is specified, functions and - classes that are not defined in module are excluded. - Return aggregate (#failures, #examples). - - Build and populate two modules with sample functions to test that - exclusion of external functions and classes works. - - >>> import new - >>> m1 = new.module('_m1') - >>> m2 = new.module('_m2') - >>> test_data = \""" - ... def _f(): - ... '''>>> assert 1 == 1 - ... ''' - ... def g(): - ... '''>>> assert 2 != 1 - ... ''' - ... class H: - ... '''>>> assert 2 > 1 - ... ''' - ... def bar(self): - ... '''>>> assert 1 < 2 - ... ''' - ... \""" - >>> exec test_data in m1.__dict__ - >>> exec test_data in m2.__dict__ - >>> m1.__dict__.update({"f2": m2._f, "g2": m2.g, "h2": m2.H}) - - Tests that objects outside m1 are excluded: - - >>> t = Tester(globs={}, verbose=0) - >>> t.rundict(m1.__dict__, "rundict_test", m1) # _f, f2 and g2 and h2 skipped - (0, 3) - - Again, but with a custom isprivate function allowing _f: - - >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) - >>> t.rundict(m1.__dict__, "rundict_test_pvt", m1) # Only f2, g2 and h2 skipped - (0, 4) - - And once more, not excluding stuff outside m1: - - >>> t = Tester(globs={}, verbose=0, isprivate=lambda x,y: 0) - >>> t.rundict(m1.__dict__, "rundict_test_pvt") # None are skipped. - (0, 8) - - The exclusion of objects from outside the designated module is - meant to be invoked automagically by testmod. - - >>> testmod(m1) - (0, 3) - - """ - - if not hasattr(d, "items"): - raise TypeError("Tester.rundict: d must support .items(); " + - `d`) - f = t = 0 - # Run the tests by alpha order of names, for consistency in - # verbose-mode output. - names = d.keys() - names.sort() - for thisname in names: - value = d[thisname] - if _isfunction(value) or _isclass(value): - if module and not _from_module(module, value): - continue - f2, t2 = self.__runone(value, name + "." + thisname) - f = f + f2 - t = t + t2 - return f, t - - def run__test__(self, d, name): - """d, name -> Treat dict d like module.__test__. - - Return (#failures, #tries). - See testmod.__doc__ for details. - """ - - failures = tries = 0 - prefix = name + "." - savepvt = self.isprivate - try: - self.isprivate = lambda *args: 0 - # Run the tests by alpha order of names, for consistency in - # verbose-mode output. - keys = d.keys() - keys.sort() - for k in keys: - v = d[k] - thisname = prefix + k - if type(v) in _StringTypes: - f, t = self.runstring(v, thisname) - elif _isfunction(v) or _isclass(v): - f, t = self.rundoc(v, thisname) - else: - raise TypeError("Tester.run__test__: values in " - "dict must be strings, functions " - "or classes; " + `v`) - failures = failures + f - tries = tries + t - finally: - self.isprivate = savepvt - return failures, tries - - def summarize(self, verbose=None): - """ - verbose=None -> summarize results, return (#failures, #tests). - - Print summary of test results to stdout. - Optional arg 'verbose' controls how wordy this is. By - default, use the verbose setting established by the - constructor. - """ - - if verbose is None: - verbose = self.verbose - notests = [] - passed = [] - failed = [] - totalt = totalf = 0 - for x in self.name2ft.items(): - name, (f, t) = x - assert f <= t - totalt = totalt + t - totalf = totalf + f - if t == 0: - notests.append(name) - elif f == 0: - passed.append( (name, t) ) - else: - failed.append(x) - if verbose: - if notests: - print len(notests), "items had no tests:" - notests.sort() - for thing in notests: - print " ", thing - if passed: - print len(passed), "items passed all tests:" - passed.sort() - for thing, count in passed: - print " %3d tests in %s" % (count, thing) - if failed: - print "*" * 65 - print len(failed), "items had failures:" - failed.sort() - for thing, (f, t) in failed: - print " %3d of %3d in %s" % (f, t, thing) - if verbose: - print totalt, "tests in", len(self.name2ft), "items." - print totalt - totalf, "passed and", totalf, "failed." - if totalf: - print "***Test Failed***", totalf, "failures." - elif verbose: - print "Test passed." - return totalf, totalt - - def merge(self, other): - """ - other -> merge in test results from the other Tester instance. - - If self and other both have a test result for something - with the same name, the (#failures, #tests) results are - summed, and a warning is printed to stdout. - - >>> from doctest import Tester - >>> t1 = Tester(globs={}, verbose=0) - >>> t1.runstring(''' - ... >>> x = 12 - ... >>> print x - ... 12 - ... ''', "t1example") - (0, 2) - >>> - >>> t2 = Tester(globs={}, verbose=0) - >>> t2.runstring(''' - ... >>> x = 13 - ... >>> print x - ... 13 - ... ''', "t2example") - (0, 2) - >>> common = ">>> assert 1 + 2 == 3\\n" - >>> t1.runstring(common, "common") - (0, 1) - >>> t2.runstring(common, "common") - (0, 1) - >>> t1.merge(t2) - *** Tester.merge: 'common' in both testers; summing outcomes. - >>> t1.summarize(1) - 3 items passed all tests: - 2 tests in common - 2 tests in t1example - 2 tests in t2example - 6 tests in 3 items. - 6 passed and 0 failed. - Test passed. - (0, 6) - >>> - """ - - d = self.name2ft - for name, (f, t) in other.name2ft.items(): - if d.has_key(name): - print "*** Tester.merge: '" + name + "' in both" \ - " testers; summing outcomes." - f2, t2 = d[name] - f = f + f2 - t = t + t2 - d[name] = f, t - - def __record_outcome(self, name, f, t): - if self.name2ft.has_key(name): - print "*** Warning: '" + name + "' was tested before;", \ - "summing outcomes." - f2, t2 = self.name2ft[name] - f = f + f2 - t = t + t2 - self.name2ft[name] = f, t - - def __runone(self, target, name): - if "." in name: - i = name.rindex(".") - prefix, base = name[:i], name[i+1:] - else: - prefix, base = "", base - if self.isprivate(prefix, base): - return 0, 0 - return self.rundoc(target, name) - -master = None - -def testmod(m, name=None, globs=None, verbose=None, isprivate=None, - report=1): - """m, name=None, globs=None, verbose=None, isprivate=None, report=1 - - Test examples in docstrings in functions and classes reachable from - module m, starting with m.__doc__. Private names are skipped. - - Also test examples reachable from dict m.__test__ if it exists and is - not None. m.__dict__ maps names to functions, classes and strings; - function and class docstrings are tested even if the name is private; - strings are tested directly, as if they were docstrings. - - Return (#failures, #tests). - - See doctest.__doc__ for an overview. - - Optional keyword arg "name" gives the name of the module; by default - use m.__name__. - - Optional keyword arg "globs" gives a dict to be used as the globals - when executing examples; by default, use m.__dict__. A copy of this - dict is actually used for each docstring, so that each docstring's - examples start with a clean slate. - - Optional keyword arg "verbose" prints lots of stuff if true, prints - only failures if false; by default, it's true iff "-v" is in sys.argv. - - Optional keyword arg "isprivate" specifies a function used to - determine whether a name is private. The default function is - doctest.is_private; see its docs for details. - - Optional keyword arg "report" prints a summary at the end when true, - else prints nothing at the end. In verbose mode, the summary is - detailed, else very brief (in fact, empty if all tests passed). - - Advanced tomfoolery: testmod runs methods of a local instance of - class doctest.Tester, then merges the results into (or creates) - global Tester instance doctest.master. Methods of doctest.master - can be called directly too, if you want to do something unusual. - Passing report=0 to testmod is especially useful then, to delay - displaying a summary. Invoke doctest.master.summarize(verbose) - when you're done fiddling. - """ - - global master - - if not _ismodule(m): - raise TypeError("testmod: module required; " + `m`) - if name is None: - name = m.__name__ - tester = Tester(m, globs=globs, verbose=verbose, isprivate=isprivate) - failures, tries = tester.rundoc(m, name) - f, t = tester.rundict(m.__dict__, name, m) - failures = failures + f - tries = tries + t - if hasattr(m, "__test__"): - testdict = m.__test__ - if testdict: - if not hasattr(testdict, "items"): - raise TypeError("testmod: module.__test__ must support " - ".items(); " + `testdict`) - f, t = tester.run__test__(testdict, name + ".__test__") - failures = failures + f - tries = tries + t - if report: - tester.summarize() - if master is None: - master = tester - else: - master.merge(tester) - return failures, tries - -class _TestClass: - """ - A pointless class, for sanity-checking of docstring testing. - - Methods: - square() - get() - - >>> _TestClass(13).get() + _TestClass(-12).get() - 1 - >>> hex(_TestClass(13).square().get()) - '0xa9' - """ - - def __init__(self, val): - """val -> _TestClass object with associated value val. - - >>> t = _TestClass(123) - >>> print t.get() - 123 - """ - - self.val = val - - def square(self): - """square() -> square TestClass's associated value - - >>> _TestClass(13).square().get() - 169 - """ - - self.val = self.val ** 2 - return self - - def get(self): - """get() -> return TestClass's associated value. - - >>> x = _TestClass(-42) - >>> print x.get() - -42 - """ - - return self.val - -__test__ = {"_TestClass": _TestClass, - "string": r""" - Example of a string object, searched as-is. - >>> x = 1; y = 2 - >>> x + y, x * y - (3, 2) - """ - } - -def _test(): - import doctest - return doctest.testmod(doctest) - -if __name__ == "__main__": - _test() From ee17b41e62ba1bb14d6e0c37b8b3314d793c671e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 4 Oct 2002 21:58:21 +0000 Subject: [PATCH 0821/1042] Clean up module flotsam [SVN r15720] --- src/module.cpp | 40 ++-------------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/src/module.cpp b/src/module.cpp index d81e626a..42bb7a8c 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -6,39 +6,12 @@ // The author gratefully acknowleges the support of Dragon Systems, Inc., in // producing this work. -#include -#include -#include -#include -#include -#include -#include #include +#include namespace boost { namespace python { namespace detail { -module_base::module_base(char const* name, char const* doc) - : m_module( - allow_null(python::borrowed( - scope().ptr() - ))) -{ - if (doc != 0) - scope().attr("__doc__") = doc; -} - -module_base::~module_base() -{ -} - -void module_base::setattr_doc(const char* name, python::object const& x, char const* doc) -{ - // Use function::add_to_namespace to achieve overloading if - // appropriate. - objects::add_to_namespace(python::object(m_module), name, x, doc); -} - -void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& x, char const* doc) +BOOST_PYTHON_DECL void scope_setattr_doc(char const* name, object const& x, char const* doc) { // Use function::add_to_namespace to achieve overloading if // appropriate. @@ -46,13 +19,6 @@ void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& x, char objects::add_to_namespace(current, name, x, doc); } -void module_base::add(type_handle const& x) -{ - this->setattr_doc(x->tp_name, python::object(x), 0); -} - -PyMethodDef module_base::initial_methods[] = { { 0, 0, 0, 0 } }; - namespace { PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; @@ -66,8 +32,6 @@ BOOST_PYTHON_DECL void init_module(char const* name, void(*init_function)()) if (m != 0) { - ; - // Create the current module scope scope current_module( (object( From 1887594d8a397a521f47f5afc4594a8799115696 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 4 Oct 2002 23:27:35 +0000 Subject: [PATCH 0822/1042] Bug fix [SVN r15721] --- include/boost/python/str.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index 285d7153..d32367dd 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -351,15 +351,15 @@ class str : public detail::str_base } template - bool startswidth(T1 const& prefix, T2 const& start) const + bool startswith(T1 const& prefix, T2 const& start) const { - return base::startswidth(object(prefix), object(start)); + return base::startswith(object(prefix), object(start)); } template - bool startswidth(T1 const& prefix, T2 const& start, T3 const& end) const + bool startswith(T1 const& prefix, T2 const& start, T3 const& end) const { - return base::startswidth(object(prefix), object(start), object(end)); + return base::startswith(object(prefix), object(start), object(end)); } template From 8207dc756a840d6b5c6710fdea59dc2912532a11 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 5 Oct 2002 00:23:10 +0000 Subject: [PATCH 0823/1042] Workaround for IRIX CC [SVN r15722] --- include/boost/python/str.hpp | 4 ++-- include/boost/python/tuple.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index d32367dd..d283fe8a 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -134,11 +134,11 @@ class str : public detail::str_base public: str() {} // new str - str(const char* s) : str_base(s) {} // new str + str(const char* s) : base(s) {} // new str template explicit str(T const& other) - : str_base(object(other)) + : base(object(other)) { } diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp index 5fe4cb3b..af5bbf8a 100644 --- a/include/boost/python/tuple.hpp +++ b/include/boost/python/tuple.hpp @@ -31,7 +31,7 @@ class tuple : public detail::tuple_base template explicit tuple(T const& sequence) - : tuple_base(object(sequence)) + : base(object(sequence)) { } From 30d93310795941f76b2201682aaf4a89e0759bc7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 5 Oct 2002 04:37:49 +0000 Subject: [PATCH 0824/1042] Remove Boost.Python v1 from main trunk [SVN r15723] --- Jamfile | 45 - build/Jamfile | 177 +-- build/como.mak | 59 - build/filemgr.py | 146 -- build/gcc.mak | 88 -- build/irix_CC.mak | 184 --- build/linux_gcc.mak | 184 --- build/mingw32.mak | 222 --- build/tru64_cxx.mak | 199 --- build/vc60.mak | 154 -- build/win32_mwcc.mak | 149 -- build/win32_mwcc_setup.bat | 2 - example/Attic/project.zip | Bin 1469 -> 0 bytes example/Jamfile | 26 +- example/README | 19 +- example/abstract.cpp | 32 - example/do_it_yourself_convts.cpp | 121 -- example/dvect.cpp | 48 - example/dvect.h | 32 - example/dvect_conversions.cpp | 51 - example/dvect_defs.cpp | 13 - example/getting_started1.cpp | 17 +- example/getting_started2.cpp | 33 +- example/ivect.cpp | 49 - example/ivect.h | 32 - example/ivect_conversions.cpp | 51 - example/ivect_defs.cpp | 13 - example/nested.cpp | 37 - example/noncopyable.h | 14 - example/noncopyable_export.cpp | 28 - example/noncopyable_import.cpp | 45 - example/pickle1.cpp | 57 - example/pickle2.cpp | 93 -- example/pickle3.cpp | 143 -- example/project.zip | Bin 1469 -> 0 bytes example/richcmp1.cpp | 84 -- example/richcmp2.cpp | 62 - example/richcmp3.cpp | 175 --- example/simple_vector.cpp | 104 -- example/test_abstract.py | 24 - example/test_cross_module.py | 140 -- example/test_do_it_yourself_convts.py | 23 - example/test_example1.py | 51 - example/test_getting_started1.py | 18 - example/test_getting_started2.py | 31 - example/test_nested.py | 23 - example/test_pickle1.py | 33 - example/test_pickle2.py | 47 - example/test_pickle3.py | 39 - example/test_richcmp1.py | 40 - example/test_richcmp2.py | 41 - example/test_richcmp3.py | 77 - example/test_rwgk1.py | 19 - example/test_simple_vector.py | 42 - example/tst_dvect1.py | 20 - example/tst_dvect2.py | 104 -- example/tst_ivect1.py | 20 - example/tst_ivect2.py | 104 -- example/tst_noncopyable.py | 16 - example/vector_wrapper.h | 117 -- include/boost/python/callback.hpp | 829 ----------- include/boost/python/caller.hpp | 1279 ----------------- include/boost/python/class_builder.hpp | 182 --- include/boost/python/classes.hpp | 677 --------- include/boost/python/conversions.hpp | 415 ------ include/boost/python/cross_module.hpp | 329 ----- include/boost/python/detail/base_object.hpp | 60 - include/boost/python/detail/cast.hpp | 81 -- .../boost/python/detail/extension_class.hpp | 1002 ------------- include/boost/python/detail/functions.hpp | 311 ---- include/boost/python/detail/init_function.hpp | 562 -------- include/boost/python/detail/module_base.hpp | 1 + include/boost/python/detail/module_info.hpp | 51 - include/boost/python/detail/signatures.hpp | 251 ---- include/boost/python/detail/singleton.hpp | 68 - include/boost/python/detail/types.hpp | 413 ------ include/boost/python/detail/void_adaptor.hpp | 39 - include/boost/python/module_builder.hpp | 76 - include/boost/python/objects.hpp | 396 ----- include/boost/python/py_interface.hpp | 700 --------- include/boost/python/reference.hpp | 236 --- src/classes.cpp | 1047 -------------- src/conversions.cpp | 223 --- src/cross_module.cpp | 104 -- src/extension_class.cpp | 685 --------- src/functions.cpp | 181 --- src/gen_all.py | 26 - src/gen_arg_tuple_size.py | 139 -- src/gen_call.py | 82 -- src/gen_callback.py | 124 -- src/gen_caller.py | 138 -- src/gen_extclass.py | 948 ------------ src/gen_function.py | 243 ---- src/gen_init_function.py | 215 --- src/gen_py_api.py | 776 ---------- src/gen_returning.py | 201 --- src/gen_signature.py | 90 -- src/gen_signatures.py | 158 -- src/gen_singleton.py | 58 - src/gen_value_holder.py | 35 - src/init_function.cpp | 38 - src/module_builder.cpp | 64 - src/objects.cpp | 488 ------- src/py_interface.cpp | 1103 -------------- src/types.cpp | 1272 ---------------- test/Jamfile | 9 +- 106 files changed, 88 insertions(+), 20334 deletions(-) delete mode 100644 Jamfile delete mode 100644 build/como.mak delete mode 100644 build/filemgr.py delete mode 100644 build/gcc.mak delete mode 100644 build/irix_CC.mak delete mode 100644 build/linux_gcc.mak delete mode 100644 build/mingw32.mak delete mode 100644 build/tru64_cxx.mak delete mode 100644 build/vc60.mak delete mode 100755 build/win32_mwcc.mak delete mode 100755 build/win32_mwcc_setup.bat delete mode 100644 example/Attic/project.zip delete mode 100644 example/abstract.cpp delete mode 100644 example/do_it_yourself_convts.cpp delete mode 100644 example/dvect.cpp delete mode 100644 example/dvect.h delete mode 100644 example/dvect_conversions.cpp delete mode 100644 example/dvect_defs.cpp delete mode 100644 example/ivect.cpp delete mode 100644 example/ivect.h delete mode 100644 example/ivect_conversions.cpp delete mode 100644 example/ivect_defs.cpp delete mode 100644 example/nested.cpp delete mode 100644 example/noncopyable.h delete mode 100644 example/noncopyable_export.cpp delete mode 100644 example/noncopyable_import.cpp delete mode 100644 example/pickle1.cpp delete mode 100644 example/pickle2.cpp delete mode 100644 example/pickle3.cpp delete mode 100644 example/project.zip delete mode 100644 example/richcmp1.cpp delete mode 100644 example/richcmp2.cpp delete mode 100644 example/richcmp3.cpp delete mode 100644 example/simple_vector.cpp delete mode 100644 example/test_abstract.py delete mode 100644 example/test_cross_module.py delete mode 100644 example/test_do_it_yourself_convts.py delete mode 100644 example/test_example1.py delete mode 100644 example/test_getting_started1.py delete mode 100644 example/test_getting_started2.py delete mode 100644 example/test_nested.py delete mode 100644 example/test_pickle1.py delete mode 100644 example/test_pickle2.py delete mode 100644 example/test_pickle3.py delete mode 100644 example/test_richcmp1.py delete mode 100644 example/test_richcmp2.py delete mode 100644 example/test_richcmp3.py delete mode 100644 example/test_rwgk1.py delete mode 100644 example/test_simple_vector.py delete mode 100644 example/tst_dvect1.py delete mode 100644 example/tst_dvect2.py delete mode 100644 example/tst_ivect1.py delete mode 100644 example/tst_ivect2.py delete mode 100644 example/tst_noncopyable.py delete mode 100644 example/vector_wrapper.h delete mode 100644 include/boost/python/callback.hpp delete mode 100644 include/boost/python/caller.hpp delete mode 100644 include/boost/python/class_builder.hpp delete mode 100644 include/boost/python/classes.hpp delete mode 100644 include/boost/python/conversions.hpp delete mode 100644 include/boost/python/cross_module.hpp delete mode 100644 include/boost/python/detail/base_object.hpp delete mode 100644 include/boost/python/detail/cast.hpp delete mode 100644 include/boost/python/detail/extension_class.hpp delete mode 100644 include/boost/python/detail/functions.hpp delete mode 100644 include/boost/python/detail/init_function.hpp delete mode 100644 include/boost/python/detail/module_info.hpp delete mode 100644 include/boost/python/detail/signatures.hpp delete mode 100644 include/boost/python/detail/singleton.hpp delete mode 100644 include/boost/python/detail/types.hpp delete mode 100644 include/boost/python/detail/void_adaptor.hpp delete mode 100644 include/boost/python/module_builder.hpp delete mode 100644 include/boost/python/objects.hpp delete mode 100644 include/boost/python/py_interface.hpp delete mode 100644 include/boost/python/reference.hpp delete mode 100644 src/classes.cpp delete mode 100644 src/conversions.cpp delete mode 100644 src/cross_module.cpp delete mode 100644 src/extension_class.cpp delete mode 100644 src/functions.cpp delete mode 100644 src/gen_all.py delete mode 100644 src/gen_arg_tuple_size.py delete mode 100644 src/gen_call.py delete mode 100644 src/gen_callback.py delete mode 100644 src/gen_caller.py delete mode 100644 src/gen_extclass.py delete mode 100644 src/gen_function.py delete mode 100644 src/gen_init_function.py delete mode 100644 src/gen_py_api.py delete mode 100644 src/gen_returning.py delete mode 100644 src/gen_signature.py delete mode 100644 src/gen_signatures.py delete mode 100644 src/gen_singleton.py delete mode 100644 src/gen_value_holder.py delete mode 100644 src/init_function.cpp delete mode 100644 src/module_builder.cpp delete mode 100644 src/objects.cpp delete mode 100644 src/py_interface.cpp delete mode 100644 src/types.cpp diff --git a/Jamfile b/Jamfile deleted file mode 100644 index 243e4829..00000000 --- a/Jamfile +++ /dev/null @@ -1,45 +0,0 @@ -subproject libs/python ; - -# bring in the rules for python -SEARCH on python.jam = $(BOOST_BUILD_PATH) ; -include python.jam ; - -local bpl-linkflags ; - -if $(UNIX) && ( $(OS) = AIX ) -{ - bpl-linkflags = "-e initlibbpl" ; -} - -dll bpl - : - src/numeric.cpp - - src/list.cpp - src/long.cpp - src/dict.cpp - src/tuple.cpp - src/str.cpp - - src/aix_init_module.cpp - src/converter/from_python.cpp - src/converter/registry.cpp - src/converter/type_id.cpp - src/object/enum.cpp - src/object/class.cpp - src/object/function.cpp - src/object/inheritance.cpp - src/object/life_support.cpp - src/object/pickle_support.cpp - src/errors.cpp - src/module.cpp - src/converter/builtin_converters.cpp - src/converter/arg_to_python_base.cpp - src/object/iterator.cpp - src/object_protocol.cpp - src/object_operators.cpp - : - $(BOOST_PYTHON_V2_PROPERTIES) - BOOST_PYTHON_SOURCE - $(bpl-linkflags) - ; diff --git a/build/Jamfile b/build/Jamfile index 2b583d17..97d8222e 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -3,56 +3,8 @@ # in all copies. This software is provided "as is" without express or implied # warranty, and with no claim as to its suitability for any purpose. # -# Boost.Python build and test Jamfile -# -# To run all tests quietly: jam test -# To run all tests with verbose output: jam -sPYTHON_TEST_ARGS=-v test -# -# Declares the following targets: -# 1. libboost_python.dll/.so, a dynamic library to be linked with all -# Boost.Python modules -# -# 2. pairs of test targets of the form .test and .run -# .test runs the test when it is out-of-date, and the "test" -# pseudotarget depends on it. .run runs -# a test unconditionally, and can be used to force a test to run.. Each -# test target builds one or more Boost.Python modules and runs a Python -# script to test them. The test names are: -# -# from ../test -# -# comprehensive - a comprehensive test of Boost.Python features -# -# from ../example: -# abstract - -# getting_started1 - -# getting_started2 - -# simple_vector - -# do_it_yourself_convts - -# pickle1 - -# pickle2 - -# pickle3 - -# -# dvect1 - -# dvect2 - -# ivect1 - -# ivect2 - -# noncopyable - -# -# subproject-specific environment/command-line variables: -# -# PYTHON - How to invoke the Python interpreter. Defaults to "python" -# -# PYTHON_ROOT - Windows only: where Python is installed. Defaults to "c:/tools/python" -# -# PYTHON_VERSION - Version of Python. Defaults to "2.1" on Windows, "1.5" on Unix -# -# PYTHON_TEST_ARGS - specifies arguments to be passed to test scripts on -# the command line. "-v" can be useful if you want to -# see the output of successful tests. -# -# PYTHON_VECT_ITERATIONS - specifies the number of test iterations to use for -# the dvect and ivect tests above. +# Boost.Python library Jamfile + # declare the location of this subproject relative to the root subproject libs/python/build ; @@ -64,106 +16,51 @@ include python.jam ; if [ check-python-config ] { -local PYTHON_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_DYNAMIC_LIB ; + local bpl-linkflags ; -####################### -rule bpl-test ( test-name : sources + ) -{ - boost-python-test $(test-name) : $(sources) boost_python ; -} + if $(UNIX) && ( $(OS) = AIX ) + { + bpl-linkflags = "-e initlibbpl" ; + } -####################### + dll boost_python + : + ../src/numeric.cpp -# -# Declare the boost python static link library -# + ../src/list.cpp + ../src/long.cpp + ../src/dict.cpp + ../src/tuple.cpp + ../src/str.cpp -# Base names of the source files for libboost_python -local CPP_SOURCES = - types classes conversions extension_class functions - init_function module_builder objects cross_module errors - ; - -lib boost_python_static : ../src/$(CPP_SOURCES).cpp - # requirements - : $(BOOST_PYTHON_INCLUDES) - true - BOOST_PYTHON_STATIC_LIB=1 - [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] - : true # don't build this unless the user asks for it by name + ../src/aix_init_module.cpp + ../src/converter/from_python.cpp + ../src/converter/registry.cpp + ../src/converter/type_id.cpp + ../src/object/enum.cpp + ../src/object/class.cpp + ../src/object/function.cpp + ../src/object/inheritance.cpp + ../src/object/life_support.cpp + ../src/object/pickle_support.cpp + ../src/errors.cpp + ../src/module.cpp + ../src/converter/builtin_converters.cpp + ../src/converter/arg_to_python_base.cpp + ../src/object/iterator.cpp + ../src/object_protocol.cpp + ../src/object_operators.cpp + : + $(BOOST_PYTHON_V2_PROPERTIES) + BOOST_PYTHON_SOURCE + $(bpl-linkflags) ; -dll boost_python - # $(SUFDLL[1]) - : ../src/$(CPP_SOURCES).cpp - # requirements - : $(BOOST_PYTHON_INCLUDES) - true - dynamic - $(PYTHON_PROPERTIES) - ; - -stage bin-stage : boost_python + stage bin-stage : boost_python : "_debug" "_pydebug" : debug release ; - -############# comprehensive module and test ########### -bpl-test boost_python_test - : ../test/comprehensive.cpp ; - -boost-python-runtest comprehensive - : ../test/comprehensive.py boost_python_test boost_python ; - -############# simple tests from ../example ############ - -rule boost-python-example-runtest ( name ) -{ - bpl-test $(name) - : ../example/$(name).cpp ; - - boost-python-runtest $(name) - : ../example/test_$(name).py $(name) boost_python ; -} - - -boost-python-example-runtest abstract ; -boost-python-example-runtest getting_started1 ; -boost-python-example-runtest getting_started2 ; -boost-python-example-runtest simple_vector ; -boost-python-example-runtest do_it_yourself_convts ; -boost-python-example-runtest pickle1 ; -boost-python-example-runtest pickle2 ; -boost-python-example-runtest pickle3 ; - - -bpl-test ivect : ../example/ivect.cpp ; -bpl-test dvect : ../example/dvect.cpp ; -bpl-test noncopyable_export : ../example/noncopyable_export.cpp ; -bpl-test noncopyable_import : ../example/noncopyable_import.cpp ; - -############## cross-module tests from ../example ########## - -# A simple rule to build a test which depends on multiple modules in the PYTHONPATH -rule boost-python-multi-example-runtest ( test-name : modules + ) -{ - boost-python-runtest $(test-name) - : ../example/tst_$(test-name).py $(modules) boost_python - : : : $(PYTHON_VECT_ITERATIONS) ; -} - -PYTHON_VECT_ITERATIONS ?= 10 ; - -boost-python-multi-example-runtest dvect1 : ivect dvect ; -boost-python-multi-example-runtest dvect2 : ivect dvect ; - -boost-python-multi-example-runtest ivect1 : ivect dvect ; -boost-python-multi-example-runtest ivect2 : ivect dvect ; - -boost-python-multi-example-runtest - noncopyable : noncopyable_import noncopyable_export ; - } \ No newline at end of file diff --git a/build/como.mak b/build/como.mak deleted file mode 100644 index edf05f83..00000000 --- a/build/como.mak +++ /dev/null @@ -1,59 +0,0 @@ -# Revision History: -# 17 Apr 01 include cross-module support, compile getting_started1 (R.W. Grosse-Kunstleve) UNTESTED! -# 06 Mar 01 Fixed typo in use of "PYTHON_LIB" (Dave Abrahams) -# 04 Mar 01 Changed library name to libboost_python.a (David Abrahams) - -LIBSRC = \ - classes.cpp \ - conversions.cpp \ - cross_module.cpp \ - errors.cpp \ - extension_class.cpp \ - functions.cpp \ - init_function.cpp \ - module_builder.cpp \ - objects.cpp \ - types.cpp - -LIBOBJ = $(LIBSRC:.cpp=.o) -OBJ = $(LIBOBJ) - - -ifeq "$(OS)" "Windows_NT" -PYTHON_LIB=c:/tools/python/libs/python15.lib -INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -Ic:/tools/python/include -MODULE_EXTENSION=dll -else -INC = -I/usr/local/include/python1.5 -MODULE_EXTENSION=so -endif - -%.o: ../src/%.cpp - como --pic $(INC) -o $*.o -c $< - -%.d: ../src/%.cpp - @echo creating $@ - @set -e; como -M $(INC) -c $< \ - | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ - [ -s $@ ] || rm -f $@ - -getting_started1: getting_started1.o libboost_python.a - como-dyn-link -o ../example/getting_started1.$(MODULE_EXTENSION) $(PYTHON_LIB) getting_started1.o -L. -lboost_python - ln -s ../test/doctest.py ../example - python ../example/test_getting_started1.py - -getting_started1.o: ../example/getting_started1.cpp - como --pic $(INC) -o $*.o -c $< - -clean: - rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out - -libboost_python.a: $(LIBOBJ) - rm -f libboost_python.a - ar cq libboost_python.a $(LIBOBJ) - -DEP = $(OBJ:.o=.d) - -ifneq "$(MAKECMDGOALS)" "clean" -include $(DEP) -endif diff --git a/build/filemgr.py b/build/filemgr.py deleted file mode 100644 index 93cef1cb..00000000 --- a/build/filemgr.py +++ /dev/null @@ -1,146 +0,0 @@ -# Revision history: -# 12 Apr 01 use os.path, shutil -# Initial version: R.W. Grosse-Kunstleve - -bpl_src = "/libs/python/src" -bpl_tst = "/libs/python/test" -bpl_exa = "/libs/python/example" -files = ( -bpl_src + "/classes.cpp", -bpl_src + "/conversions.cpp", -bpl_src + "/errors.cpp", -bpl_src + "/extension_class.cpp", -bpl_src + "/functions.cpp", -bpl_src + "/init_function.cpp", -bpl_src + "/module_builder.cpp", -bpl_src + "/objects.cpp", -bpl_src + "/types.cpp", -bpl_src + "/cross_module.cpp", -bpl_tst + "/comprehensive.cpp", -bpl_tst + "/comprehensive.hpp", -bpl_tst + "/comprehensive.py", -bpl_tst + "/doctest.py", -bpl_exa + "/abstract.cpp", -bpl_exa + "/getting_started1.cpp", -bpl_exa + "/getting_started2.cpp", -bpl_exa + "/simple_vector.cpp", -bpl_exa + "/do_it_yourself_convts.cpp", -bpl_exa + "/nested.cpp", -bpl_exa + "/pickle1.cpp", -bpl_exa + "/pickle2.cpp", -bpl_exa + "/pickle3.cpp", -bpl_exa + "/test_abstract.py", -bpl_exa + "/test_getting_started1.py", -bpl_exa + "/test_getting_started2.py", -bpl_exa + "/test_simple_vector.py", -bpl_exa + "/test_do_it_yourself_convts.py", -bpl_exa + "/test_nested.py", -bpl_exa + "/test_pickle1.py", -bpl_exa + "/test_pickle2.py", -bpl_exa + "/test_pickle3.py", -bpl_exa + "/noncopyable.h", -bpl_exa + "/noncopyable_export.cpp", -bpl_exa + "/noncopyable_import.cpp", -bpl_exa + "/dvect.h", -bpl_exa + "/dvect.cpp", -bpl_exa + "/dvect_conversions.cpp", -bpl_exa + "/dvect_defs.cpp", -bpl_exa + "/ivect.h", -bpl_exa + "/ivect.cpp", -bpl_exa + "/ivect_conversions.cpp", -bpl_exa + "/ivect_defs.cpp", -bpl_exa + "/tst_noncopyable.py", -bpl_exa + "/tst_dvect1.py", -bpl_exa + "/tst_dvect2.py", -bpl_exa + "/tst_ivect1.py", -bpl_exa + "/tst_ivect2.py", -bpl_exa + "/test_cross_module.py", -bpl_exa + "/vector_wrapper.h", -bpl_exa + "/richcmp1.cpp", -bpl_exa + "/richcmp2.cpp", -bpl_exa + "/richcmp3.cpp", -bpl_exa + "/test_richcmp1.py", -bpl_exa + "/test_richcmp2.py", -bpl_exa + "/test_richcmp3.py", -) - -defs = ( -"boost_python_test", -"abstract", -"getting_started1", -"getting_started2", -"simple_vector", -"do_it_yourself_convts", -"nested", -"pickle1", -"pickle2", -"pickle3", -"noncopyable_export", -"noncopyable_import", -"ivect", -"dvect", -"richcmp1", -"richcmp2", -"richcmp3", -) - -if (__name__ == "__main__"): - - import sys, os, shutil - - path = sys.argv[1] - mode = sys.argv[2] - if (not mode in ("softlinks", "unlink", "cp", "rm", "copy", "del")): - raise RuntimeError, \ - "usage: python filemgr.py path " - - if (mode in ("cp", "copy")): - for fn in files: - f = os.path.basename(fn) - print "Copying: " + f - shutil.copy(path + fn, ".") - - elif (mode == "softlinks"): - for fn in files: - f = os.path.basename(fn) - if (os.path.exists(f)): - print "File exists: " + f - else: - print "Linking: " + f - os.symlink(path + fn, f) - - elif (mode in ("rm", "del")): - for fn in files: - f = os.path.basename(fn) - if (os.path.exists(f)): - print "Removing: " + f - try: os.unlink(f) - except: pass - - elif (mode == "unlink"): - for fn in files: - f = os.path.basename(fn) - if (os.path.exists(f)): - if (os.path.islink(f)): - print "Unlinking: " + f - try: os.unlink(f) - except: pass - else: - print "Not a softlink: " + f - - if (mode in ("softlinks", "cp", "copy")): - for d in defs: - fn = d + ".def" - print "Creating: " + fn - f = open(fn, "w") - f.write("EXPORTS\n") - f.write("\tinit" + d + "\n") - f.close() - - if (mode in ("unlink", "rm", "del")): - for d in defs: - fn = d + ".def" - if (os.path.exists(fn)): - print "Removing: " + fn - try: os.unlink(fn) - except: pass diff --git a/build/gcc.mak b/build/gcc.mak deleted file mode 100644 index b818030e..00000000 --- a/build/gcc.mak +++ /dev/null @@ -1,88 +0,0 @@ -# Revision History - -# 17 Apr 01 include cross-module support, compile getting_started1 (R.W. Grosse-Kunstleve) -# 17 Apr 01 build shared library (patch provided by Dan Nuffer) -# 04 Mar 01 Changed library name to libboost_python.a, various cleanups, -# attempted Cygwin compatibility. Still needs testing on Linux -# (David Abrahams) - - -LIBSRC = \ - classes.cpp \ - conversions.cpp \ - cross_module.cpp \ - errors.cpp \ - extension_class.cpp \ - functions.cpp \ - init_function.cpp \ - module_builder.cpp \ - objects.cpp \ - types.cpp - -LIBOBJ = $(LIBSRC:.cpp=.o) -OBJ = $(LIBOBJ) - -LIBNAME = libboost_python -# libpython2.0.dll - -ifeq "$(OS)" "Windows_NT" -ROOT=c:/cygnus -INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -I$(PYTHON_INC) -MODULE_EXTENSION=dll -PYTHON_LIB=c:/cygnus/usr/local/lib/python2.0/config/libpython2.0.dll.a -SHARED_LIB = $(LIBNAME).dll -else -PYTHON_INC=$(ROOT)/usr/local/Python-2.0/include/python2.0 -BOOST_INC=../../.. -INC = -I$(BOOST_INC) -I$(PYTHON_INC) -MODULE_EXTENSION=so -VERSION=1 -SHARED_LIB = $(LIBNAME).so.$(VERSION) -endif - -%.o: ../src/%.cpp - g++ -fPIC -Wall -W $(INC) $(CXXFLAGS) -o $*.o -c $< - -%.d: ../src/%.cpp - @echo creating $@ - @set -e; g++ -M $(INC) -c $< \ - | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ - [ -s $@ ] || rm -f $@ - - -PYTHON = python - -all: test $(SHARED_LIB) getting_started1 - -test: comprehensive.o $(LIBNAME).a $(SHARED_LIB) - g++ $(CXXFLAGS) -shared -o ../test/boost_python_test.$(MODULE_EXTENSION) comprehensive.o -L. -lboost_python $(PYTHON_LIB) - $(PYTHON) ../test/comprehensive.py - -comprehensive.o: ../test/comprehensive.cpp - g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $< - - -getting_started1: getting_started1.o $(LIBNAME).a - g++ $(CXXFLAGS) -shared -o ../example/getting_started1.$(MODULE_EXTENSION) getting_started1.o -L. -lboost_python $(PYTHON_LIB) - ln -s ../test/doctest.py ../example - $(PYTHON) ../example/test_getting_started1.py - -getting_started1.o: ../example/getting_started1.cpp - g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $< - - -clean: - rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out - -$(LIBNAME).a: $(LIBOBJ) - rm -f $@ - ar cqs $@ $(LIBOBJ) - -$(SHARED_LIB): $(LIBOBJ) - g++ $(CXXFLAGS) -shared -o $@ -Wl,--soname=$(LIBNAME).$(MODULE_EXTENSION) - -DEP = $(OBJ:.o=.d) - -ifneq "$(MAKECMDGOALS)" "clean" -include $(DEP) -endif diff --git a/build/irix_CC.mak b/build/irix_CC.mak deleted file mode 100644 index f7d6004e..00000000 --- a/build/irix_CC.mak +++ /dev/null @@ -1,184 +0,0 @@ -# Usage: -# -# Create a new empty directory anywhere (preferably not in the boost tree). -# Copy this Makefile to that new directory and rename it to "Makefile" -# Adjust the pathnames below. -# -# make softlinks Create softlinks to source code and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make unlink Remove softlinks -# -# Revision history: -# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) -# Initial version: R.W. Grosse-Kunstleve - -ROOT=$(HOME) -BOOST=$(ROOT)/boost - -#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python -#PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python -PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1 -STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers - -STDOPTS= -WARNOPTS=-woff 1001,1234,1682 -OPTOPTS=-g - -CPP=CC -LANG:std -n32 -mips4 -CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) $(OPTOPTS) -MAKEDEP=-M - -LD=CC -LANG:std -n32 -mips4 -LDOPTS=-shared - -OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o cross_module.o -DEPOBJ=$(OBJ) \ - comprehensive.o \ - abstract.o \ - getting_started1.o getting_started2.o \ - simple_vector.o \ - do_it_yourself_convts.o \ - nested.o \ - pickle1.o pickle2.o pickle3.o \ - noncopyable_export.o noncopyable_import.o \ - ivect.o dvect.o \ - richcmp1.o richcmp2.o richcmp3.o - -.SUFFIXES: .o .cpp - -all: libboost_python.a \ - boost_python_test.so \ - abstract.so \ - getting_started1.so getting_started2.so \ - simple_vector.so \ - do_it_yourself_convts.so \ - nested.so \ - pickle1.so pickle2.so pickle3.so \ - noncopyable_export.so noncopyable_import.so \ - ivect.so dvect.so \ - richcmp1.so richcmp2.so richcmp3.so - -libboost_python.a: $(OBJ) - rm -f libboost_python.a - $(CPP) -ar -o libboost_python.a $(OBJ) - -boost_python_test.so: $(OBJ) comprehensive.o - $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm - -abstract.so: $(OBJ) abstract.o - $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so - -getting_started1.so: $(OBJ) getting_started1.o - $(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so - -getting_started2.so: $(OBJ) getting_started2.o - $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so - -simple_vector.so: $(OBJ) simple_vector.o - $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so - -do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so - -nested.so: $(OBJ) nested.o - $(LD) $(LDOPTS) $(OBJ) nested.o -o nested.so - -pickle1.so: $(OBJ) pickle1.o - $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so - -pickle2.so: $(OBJ) pickle2.o - $(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so - -pickle3.so: $(OBJ) pickle3.o - $(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so - -noncopyable_export.so: $(OBJ) noncopyable_export.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_export.o -o noncopyable_export.so - -noncopyable_import.so: $(OBJ) noncopyable_import.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_import.o -o noncopyable_import.so - -ivect.so: $(OBJ) ivect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so - -dvect.so: $(OBJ) dvect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so - -richcmp1.so: $(OBJ) richcmp1.o - $(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so - -richcmp2.so: $(OBJ) richcmp2.o - $(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so - -richcmp3.so: $(OBJ) richcmp3.o - $(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so - -.cpp.o: - $(CPP) $(CPPOPTS) -c $*.cpp - -test: - $(PYEXE) comprehensive.py - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - rm -f $(OBJ) libboost_python.a libboost_python.a.input - rm -f comprehensive.o boost_python_test.so - rm -f abstract.o abstract.so - rm -f getting_started1.o getting_started1.so - rm -f getting_started2.o getting_started2.so - rm -f simple_vector.o simple_vector.so - rm -f do_it_yourself_convts.o do_it_yourself_convts.so - rm -f nested.o nested.so - rm -f pickle1.o pickle1.so - rm -f pickle2.o pickle2.so - rm -f pickle3.o pickle3.so - rm -f noncopyable_export.o noncopyable_export.so - rm -f noncopyable_import.o noncopyable_import.so - rm -f ivect.o ivect.so - rm -f dvect.o dvect.so - rm -f richcmp1.o richcmp1.so - rm -f richcmp2.o richcmp2.so - rm -f richcmp3.o richcmp3.so - rm -f so_locations *.pyc - rm -rf ii_files - -softlinks: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks - -unlink: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink - -cp: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp - -rm: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm - -depend: - @ cat Makefile.nodepend; \ - for obj in $(DEPOBJ); \ - do \ - bn=`echo "$$obj" | cut -d. -f1`; \ - $(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \ - done - diff --git a/build/linux_gcc.mak b/build/linux_gcc.mak deleted file mode 100644 index 3b466e7d..00000000 --- a/build/linux_gcc.mak +++ /dev/null @@ -1,184 +0,0 @@ -# Usage: -# -# Create a new empty directory anywhere (preferably not in the boost tree). -# Copy this Makefile to that new directory and rename it to "Makefile" -# Adjust the pathnames below. -# -# make softlinks Create softlinks to source code and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make unlink Remove softlinks -# -# Revision history: -# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) -# Initial version: R.W. Grosse-Kunstleve - -ROOT=$(HOME) -BOOST=$(ROOT)/boost - -#PYEXE=PYTHONPATH=. /usr/bin/python -#PYINC=-I/usr/include/python1.5 -#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python -#PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python -PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1 - -STDOPTS=-fPIC -ftemplate-depth-21 -WARNOPTS= -OPTOPTS=-g - -CPP=g++ -CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) $(OPTOPTS) -MAKEDEP=-M - -LD=$(CPP) -LDOPTS=-shared - -OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o cross_module.o -DEPOBJ=$(OBJ) \ - comprehensive.o \ - abstract.o \ - getting_started1.o getting_started2.o \ - simple_vector.o \ - do_it_yourself_convts.o \ - nested.o \ - pickle1.o pickle2.o pickle3.o \ - noncopyable_export.o noncopyable_import.o \ - ivect.o dvect.o \ - richcmp1.o richcmp2.o richcmp3.o - -.SUFFIXES: .o .cpp - -all: libboost_python.a \ - boost_python_test.so \ - abstract.so \ - getting_started1.so getting_started2.so \ - simple_vector.so \ - do_it_yourself_convts.so \ - nested.so \ - pickle1.so pickle2.so pickle3.so \ - noncopyable_export.so noncopyable_import.so \ - ivect.so dvect.so \ - richcmp1.so richcmp2.so richcmp3.so - -libboost_python.a: $(OBJ) - rm -f libboost_python.a - ar r libboost_python.a $(OBJ) - -boost_python_test.so: $(OBJ) comprehensive.o - $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm - -abstract.so: $(OBJ) abstract.o - $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so - -getting_started1.so: $(OBJ) getting_started1.o - $(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so - -getting_started2.so: $(OBJ) getting_started2.o - $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so - -simple_vector.so: $(OBJ) simple_vector.o - $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so - -do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so - -nested.so: $(OBJ) nested.o - $(LD) $(LDOPTS) $(OBJ) nested.o -o nested.so - -pickle1.so: $(OBJ) pickle1.o - $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so - -pickle2.so: $(OBJ) pickle2.o - $(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so - -pickle3.so: $(OBJ) pickle3.o - $(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so - -noncopyable_export.so: $(OBJ) noncopyable_export.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_export.o -o noncopyable_export.so - -noncopyable_import.so: $(OBJ) noncopyable_import.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_import.o -o noncopyable_import.so - -ivect.so: $(OBJ) ivect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so - -dvect.so: $(OBJ) dvect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so - -richcmp1.so: $(OBJ) richcmp1.o - $(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so - -richcmp2.so: $(OBJ) richcmp2.o - $(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so - -richcmp3.so: $(OBJ) richcmp3.o - $(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so - -.cpp.o: - $(CPP) $(CPPOPTS) -c $*.cpp - -test: - $(PYEXE) comprehensive.py - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - rm -f $(OBJ) libboost_python.a libboost_python.a.input - rm -f comprehensive.o boost_python_test.so - rm -f abstract.o abstract.so - rm -f getting_started1.o getting_started1.so - rm -f getting_started2.o getting_started2.so - rm -f simple_vector.o simple_vector.so - rm -f do_it_yourself_convts.o do_it_yourself_convts.so - rm -f nested.o nested.so - rm -f pickle1.o pickle1.so - rm -f pickle2.o pickle2.so - rm -f pickle3.o pickle3.so - rm -f noncopyable_export.o noncopyable_export.so - rm -f noncopyable_import.o noncopyable_import.so - rm -f ivect.o ivect.so - rm -f dvect.o dvect.so - rm -f richcmp1.o richcmp1.so - rm -f richcmp2.o richcmp2.so - rm -f richcmp3.o richcmp3.so - rm -f so_locations *.pyc - -softlinks: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks - -unlink: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink - -cp: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp - -rm: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm - -depend: - @ cat Makefile.nodepend; \ - for obj in $(DEPOBJ); \ - do \ - bn=`echo "$$obj" | cut -d. -f1`; \ - $(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \ - done - diff --git a/build/mingw32.mak b/build/mingw32.mak deleted file mode 100644 index d8c31b68..00000000 --- a/build/mingw32.mak +++ /dev/null @@ -1,222 +0,0 @@ -# Usage: -# -# make copy Copy the sources and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make del Remove the sources and tests -# -# Revision history: -# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) -# Initial version: R.W. Grosse-Kunstleve - -# To install mingw32, follow instructions at: -# http://starship.python.net/crew/kernr/mingw32/Notes.html -# In particular, install: -# ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/gcc-2.95.2/gcc-2.95.2-msvcrt.exe -# ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/gcc-2.95.2/fixes/quote-fix-msvcrt.exe -# http://starship.python.net/crew/kernr/mingw32/Python-1.5.2-mingw32.zip -# Unpack the first two archives in the default locations and update your PATH. -# Unpack the third archive in \usr. - -# Note: comprehensive.cpp generates compiler errors and later crashes. -# L:\boost\boost\python\detail\extension_class.hpp:643: warning: -# alignment of `vtable for class -# boost::python::detail::held_instance' -# is greater than maximum object file alignment. Using 16. -# Could this be fixed with compiler options? -# -fhuge-objects looks interesting, but requires recompiling the C++ library. -# (what exactly does that mean?) -# -fvtable-thunks eliminates the compiler warning, but -# "import boost_python_test" still causes a crash. - -ROOT=R: -BOOST_WIN="$(ROOT)\boost" -BOOST_UNIX=$(HOME)/boost - -PYEXE="C:\Program files\Python\python.exe" -PYINC=-I"C:\usr\include\python1.5" -PYLIB="C:\usr\lib\libpython15.a" -#PYEXE="C:\Python21\python.exe" -#PYINC=-I"C:\usr\include\python2.1" -#PYLIB="C:\usr\lib\libpython21.a" - -STDOPTS=-ftemplate-depth-21 -WARNOPTS= -OPTOPTS=-g - -CPP=g++ -CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) $(OPTOPTS) - -LD=g++ -LDOPTS=-shared - -OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o cross_module.o - -.SUFFIXES: .o .cpp - -all: libboost_python.a \ - abstract.pyd \ - getting_started1.pyd getting_started2.pyd \ - simple_vector.pyd \ - do_it_yourself_convts.pyd \ - nested.pyd \ - pickle1.pyd pickle2.pyd pickle3.pyd \ - noncopyable_export.pyd noncopyable_import.pyd \ - ivect.pyd dvect.pyd \ - richcmp1.pyd richcmp2.pyd richcmp3.pyd - -libboost_python.a: $(OBJ) - -del libboost_python.a - ar r libboost_python.a $(OBJ) - -DLLWRAPOPTS=-s --driver-name g++ -s \ - --entry _DllMainCRTStartup@12 --target=i386-mingw32 - -boost_python_test.pyd: $(OBJ) comprehensive.o - dllwrap $(DLLWRAPOPTS) \ - --dllname boost_python_test.pyd \ - --def boost_python_test.def \ - $(OBJ) comprehensive.o $(PYLIB) - -abstract.pyd: $(OBJ) abstract.o - dllwrap $(DLLWRAPOPTS) \ - --dllname abstract.pyd \ - --def abstract.def \ - $(OBJ) abstract.o $(PYLIB) - -getting_started1.pyd: $(OBJ) getting_started1.o - dllwrap $(DLLWRAPOPTS) \ - --dllname getting_started1.pyd \ - --def getting_started1.def \ - $(OBJ) getting_started1.o $(PYLIB) - -getting_started2.pyd: $(OBJ) getting_started2.o - dllwrap $(DLLWRAPOPTS) \ - --dllname getting_started2.pyd \ - --def getting_started2.def \ - $(OBJ) getting_started2.o $(PYLIB) - -simple_vector.pyd: $(OBJ) simple_vector.o - dllwrap $(DLLWRAPOPTS) \ - --dllname simple_vector.pyd \ - --def simple_vector.def \ - $(OBJ) simple_vector.o $(PYLIB) - -do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.o - dllwrap $(DLLWRAPOPTS) \ - --dllname do_it_yourself_convts.pyd \ - --def do_it_yourself_convts.def \ - $(OBJ) do_it_yourself_convts.o $(PYLIB) - -nested.pyd: $(OBJ) nested.o - dllwrap $(DLLWRAPOPTS) \ - --dllname nested.pyd \ - --def nested.def \ - $(OBJ) nested.o $(PYLIB) - -pickle1.pyd: $(OBJ) pickle1.o - dllwrap $(DLLWRAPOPTS) \ - --dllname pickle1.pyd \ - --def pickle1.def \ - $(OBJ) pickle1.o $(PYLIB) - -pickle2.pyd: $(OBJ) pickle2.o - dllwrap $(DLLWRAPOPTS) \ - --dllname pickle2.pyd \ - --def pickle2.def \ - $(OBJ) pickle2.o $(PYLIB) - -pickle3.pyd: $(OBJ) pickle3.o - dllwrap $(DLLWRAPOPTS) \ - --dllname pickle3.pyd \ - --def pickle3.def \ - $(OBJ) pickle3.o $(PYLIB) - -noncopyable_export.pyd: $(OBJ) noncopyable_export.o - dllwrap $(DLLWRAPOPTS) \ - --dllname noncopyable_export.pyd \ - --def noncopyable_export.def \ - $(OBJ) noncopyable_export.o $(PYLIB) - -noncopyable_import.pyd: $(OBJ) noncopyable_import.o - dllwrap $(DLLWRAPOPTS) \ - --dllname noncopyable_import.pyd \ - --def noncopyable_import.def \ - $(OBJ) noncopyable_import.o $(PYLIB) - -ivect.pyd: $(OBJ) ivect.o - dllwrap $(DLLWRAPOPTS) \ - --dllname ivect.pyd \ - --def ivect.def \ - $(OBJ) ivect.o $(PYLIB) - -dvect.pyd: $(OBJ) dvect.o - dllwrap $(DLLWRAPOPTS) \ - --dllname dvect.pyd \ - --def dvect.def \ - $(OBJ) dvect.o $(PYLIB) - -richcmp1.pyd: $(OBJ) richcmp1.o - dllwrap $(DLLWRAPOPTS) \ - --dllname richcmp1.pyd \ - --def richcmp1.def \ - $(OBJ) richcmp1.o $(PYLIB) - -richcmp2.pyd: $(OBJ) richcmp2.o - dllwrap $(DLLWRAPOPTS) \ - --dllname richcmp2.pyd \ - --def richcmp2.def \ - $(OBJ) richcmp2.o $(PYLIB) - -richcmp3.pyd: $(OBJ) richcmp3.o - dllwrap $(DLLWRAPOPTS) \ - --dllname richcmp3.pyd \ - --def richcmp3.def \ - $(OBJ) richcmp3.o $(PYLIB) - -.cpp.o: - $(CPP) $(CPPOPTS) -c $*.cpp - -test: -# $(PYEXE) comprehensive.py - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - -del *.o - -del *.a - -del *.pyd - -del *.pyc - -softlinks: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks - -unlink: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink - -cp: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp - -rm: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm - -copy: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy - -del: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del diff --git a/build/tru64_cxx.mak b/build/tru64_cxx.mak deleted file mode 100644 index a64927b1..00000000 --- a/build/tru64_cxx.mak +++ /dev/null @@ -1,199 +0,0 @@ -# Usage: -# -# Create a new empty directory anywhere (preferably not in the boost tree). -# Copy this Makefile to that new directory and rename it to "Makefile" -# Adjust the pathnames below. -# -# make softlinks Create softlinks to source code and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make unlink Remove softlinks -# -# Revision history: -# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) -# Initial version: R.W. Grosse-Kunstleve - -ROOT=$(HOME) -BOOST=$(ROOT)/boost - -#PYEXE=PYTHONPATH=. /usr/local/Python-1.5.2/bin/python -#PYINC=-I/usr/local/Python-1.5.2/include/python1.5 -PYEXE=PYTHONPATH=. /usr/local_cci/Python-2.1.1/bin/python -PYINC=-I/usr/local_cci/Python-2.1.1/include/python2.1 -#STLPORTINC=-I/usr/local/STLport-4.1b3/stlport -#STLPORTINC=-I/usr/local/STLport-4.1b4/stlport -#STLPORTOPTS= \ -# -D__USE_STD_IOSTREAM \ -# -D__STL_NO_SGI_IOSTREAMS \ -# -D__STL_USE_NATIVE_STRING \ -# -D__STL_NO_NEW_C_HEADERS \ -# -D_RWSTD_COMPILE_INSTANTIATE=1 -STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers - -STDOPTS=-std strict_ansi -# use -msg_display_number to obtain integer tags for -msg_disable -WARNOPTS=-msg_disable 186,450,1115 -OPTOPTS=-g - -CPP=cxx -CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) $(OPTOPTS) -MAKEDEP=-Em - -LD=cxx -LDOPTS=-shared -expect_unresolved 'Py*' -expect_unresolved '_Py*' - -#HIDDEN=-hidden - -OBJ=classes.o conversions.o errors.o extension_class.o functions.o \ - init_function.o module_builder.o \ - objects.o types.o cross_module.o -DEPOBJ=$(OBJ) \ - comprehensive.o \ - abstract.o \ - getting_started1.o getting_started2.o \ - simple_vector.o \ - do_it_yourself_convts.o \ - nested.o \ - pickle1.o pickle2.o pickle3.o \ - noncopyable_export.o noncopyable_import.o \ - ivect.o dvect.o \ - richcmp1.o richcmp2.o richcmp3.o - -.SUFFIXES: .o .cpp - -all: libboost_python.a \ - boost_python_test.so \ - abstract.so \ - getting_started1.so getting_started2.so \ - simple_vector.so \ - do_it_yourself_convts.so \ - nested.so \ - pickle1.so pickle2.so pickle3.so \ - noncopyable_export.so noncopyable_import.so \ - ivect.so dvect.so \ - richcmp1.so richcmp2.so richcmp3.so - -libboost_python.a: $(OBJ) - rm -f libboost_python.a - cd cxx_repository; \ - ls -1 > ../libboost_python.a.input; \ - ar r ../libboost_python.a -input ../libboost_python.a.input - rm -f libboost_python.a.input - ar r libboost_python.a $(OBJ) - -boost_python_test.so: $(OBJ) comprehensive.o - $(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm - -abstract.so: $(OBJ) abstract.o - $(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so - -getting_started1.so: $(OBJ) getting_started1.o - $(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so - -getting_started2.so: $(OBJ) getting_started2.o - $(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so - -simple_vector.so: $(OBJ) simple_vector.o - $(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so - -do_it_yourself_convts.so: $(OBJ) do_it_yourself_convts.o - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.o -o do_it_yourself_convts.so - -nested.so: $(OBJ) nested.o - $(LD) $(LDOPTS) $(OBJ) nested.o -o nested.so - -pickle1.so: $(OBJ) pickle1.o - $(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so - -pickle2.so: $(OBJ) pickle2.o - $(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so - -pickle3.so: $(OBJ) pickle3.o - $(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so - -noncopyable_export.so: $(OBJ) noncopyable_export.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_export.o -o noncopyable_export.so - -noncopyable_import.so: $(OBJ) noncopyable_import.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \ - noncopyable_import.o -o noncopyable_import.so - -ivect.so: $(OBJ) ivect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so - -dvect.so: $(OBJ) dvect.o - $(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so - -richcmp1.so: $(OBJ) richcmp1.o - $(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so - -richcmp2.so: $(OBJ) richcmp2.o - $(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so - -richcmp3.so: $(OBJ) richcmp3.o - $(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so - -.cpp.o: - $(CPP) $(CPPOPTS) -c $*.cpp - -test: - $(PYEXE) comprehensive.py - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - rm -f $(OBJ) libboost_python.a libboost_python.a.input - rm -f comprehensive.o boost_python_test.so - rm -f abstract.o abstract.so - rm -f getting_started1.o getting_started1.so - rm -f getting_started2.o getting_started2.so - rm -f simple_vector.o simple_vector.so - rm -f do_it_yourself_convts.o do_it_yourself_convts.so - rm -f nested.o nested.so - rm -f pickle1.o pickle1.so - rm -f pickle2.o pickle2.so - rm -f pickle3.o pickle3.so - rm -f noncopyable_export.o noncopyable_export.so - rm -f noncopyable_import.o noncopyable_import.so - rm -f ivect.o ivect.so - rm -f dvect.o dvect.so - rm -f richcmp1.o richcmp1.so - rm -f richcmp2.o richcmp2.so - rm -f richcmp3.o richcmp3.so - rm -f so_locations *.pyc - rm -rf cxx_repository - -softlinks: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks - -unlink: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink - -cp: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp - -rm: - $(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm - -depend: - @ cat Makefile.nodepend; \ - for obj in $(DEPOBJ); \ - do \ - bn=`echo "$$obj" | cut -d. -f1`; \ - $(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \ - done - diff --git a/build/vc60.mak b/build/vc60.mak deleted file mode 100644 index 2903c0c7..00000000 --- a/build/vc60.mak +++ /dev/null @@ -1,154 +0,0 @@ -# Usage: -# -# Create a new empty directory anywhere (preferably not in the boost tree). -# Copy this Makefile to that new directory and rename it to "Makefile" -# Adjust the pathnames below. -# -# make copy Copy the sources and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make del Remove the sources and tests -# -# Revision history: -# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve) -# Initial version: R.W. Grosse-Kunstleve - -ROOT=R: -BOOST_WIN="$(ROOT)\boost" -BOOST_UNIX=$(HOME)/boost - -#PYEXE="C:\Program files\Python\python.exe" -#PYINC=/I"C:\Program files\Python\include" -#PYLIB="C:\Program files\Python\libs\python15.lib" -PYEXE="C:\Python21\python.exe" -PYINC=/I"C:\Python21\include" -PYLIB="C:\Python21\libs\python21.lib" - -STDOPTS=/nologo /MD /GR /GX /Zm300 /DBOOST_PYTHON_STATIC_LIB -WARNOPTS= -OPTOPTS= - -CPP=cl.exe -CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) /I$(BOOST_WIN) $(PYINC) \ - $(STDOPTS) $(WARNOPTS) $(OPTOPTS) - -LD=link.exe -LDOPTS=/nologo /dll /incremental:no - -OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \ - init_function.obj module_builder.obj \ - objects.obj types.obj cross_module.obj - -.SUFFIXES: .obj .cpp - -all: boost_python.lib \ - boost_python_test.pyd \ - abstract.pyd \ - getting_started1.pyd getting_started2.pyd \ - simple_vector.pyd \ - do_it_yourself_convts.pyd \ - nested.pyd \ - pickle1.pyd pickle2.pyd pickle3.pyd \ - noncopyable_export.pyd noncopyable_import.pyd \ - ivect.pyd dvect.pyd \ - richcmp1.pyd richcmp2.pyd richcmp3.pyd - -boost_python.lib: $(OBJ) - $(LD) -lib /nologo /out:boost_python.lib $(OBJ) - -boost_python_test.pyd: $(OBJ) comprehensive.obj - $(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) /export:initboost_python_test /out:"boost_python_test.pyd" - -abstract.pyd: $(OBJ) abstract.obj - $(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) /export:initabstract /out:"abstract.pyd" - -getting_started1.pyd: $(OBJ) getting_started1.obj - $(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) /export:initgetting_started1 /out:"getting_started1.pyd" - -getting_started2.pyd: $(OBJ) getting_started2.obj - $(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) /export:initgetting_started2 /out:"getting_started2.pyd" - -simple_vector.pyd: $(OBJ) simple_vector.obj - $(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) /export:initsimple_vector /out:"simple_vector.pyd" - -do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.obj - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.obj $(PYLIB) /export:initdo_it_yourself_convts /out:"do_it_yourself_convts.pyd" - -nested.pyd: $(OBJ) nested.obj - $(LD) $(LDOPTS) $(OBJ) nested.obj $(PYLIB) /export:initnested /out:"nested.pyd" - -pickle1.pyd: $(OBJ) pickle1.obj - $(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) /export:initpickle1 /out:"pickle1.pyd" - -pickle2.pyd: $(OBJ) pickle2.obj - $(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) /export:initpickle2 /out:"pickle2.pyd" - -pickle3.pyd: $(OBJ) pickle3.obj - $(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) /export:initpickle3 /out:"pickle3.pyd" - -noncopyable_export.pyd: $(OBJ) noncopyable_export.obj - $(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) /export:initnoncopyable_export /out:"noncopyable_export.pyd" - -noncopyable_import.pyd: $(OBJ) noncopyable_import.obj - $(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) /export:initnoncopyable_import /out:"noncopyable_import.pyd" - -ivect.pyd: $(OBJ) ivect.obj - $(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) /export:initivect /out:"ivect.pyd" - -dvect.pyd: $(OBJ) dvect.obj - $(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) /export:initdvect /out:"dvect.pyd" - -richcmp1.pyd: $(OBJ) richcmp1.obj - $(LD) $(LDOPTS) $(OBJ) richcmp1.obj $(PYLIB) /export:initrichcmp1 /out:"richcmp1.pyd" - -richcmp2.pyd: $(OBJ) richcmp2.obj - $(LD) $(LDOPTS) $(OBJ) richcmp2.obj $(PYLIB) /export:initrichcmp2 /out:"richcmp2.pyd" - -richcmp3.pyd: $(OBJ) richcmp3.obj - $(LD) $(LDOPTS) $(OBJ) richcmp3.obj $(PYLIB) /export:initrichcmp3 /out:"richcmp3.pyd" - -.cpp.obj: - $(CPP) $(CPPOPTS) /c $*.cpp - -test: - $(PYEXE) comprehensive.py --broken-auto-ptr - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py --broken-auto-ptr - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - -del *.obj - -del *.lib - -del *.exp - -del *.idb - -del *.pyd - -del *.pyc - -softlinks: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks - -unlink: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink - -cp: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp - -rm: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm - -copy: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy - -del: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del diff --git a/build/win32_mwcc.mak b/build/win32_mwcc.mak deleted file mode 100755 index c49af71c..00000000 --- a/build/win32_mwcc.mak +++ /dev/null @@ -1,149 +0,0 @@ -# Usage: -# -# make copy Copy the sources and tests -# make Compile all sources -# make test Run doctest tests -# make clean Remove all object files -# make del Remove the sources and tests -# -# Revision history: -# 14 Dec 01 derived from vc60.mak (R.W. Grosse-Kunstleve) - -ROOT=R: -BOOST_WIN="$(ROOT)\boost" -BOOST_UNIX=$(HOME)/boost - -#PYEXE="C:\Program files\Python\python.exe" -#PYINC=-I"C:\Program files\Python\include" -#PYLIB="C:\Program files\Python\libs\python15.lib" -PYEXE="C:\Python21\python.exe" -PYINC=-I"C:\Python21\include" -PYLIB="C:\Python21\libs\python21.lib" - -STDOPTS=-gccinc -prefix UseDLLPrefix.h -DBOOST_PYTHON_STATIC_LIB -WARNOPTS=-warn on,nounusedexpr,nounused -OPTOPTS=-O - -CPP=mwcc -CPPOPTS=$(STDOPTS) $(WARNOPTS) $(OPTOPTS) \ - $(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) - -LD=mwld -LDOPTS=-export dllexport -shared - -OBJ=classes.obj conversions.obj errors.obj extension_class.obj functions.obj \ - init_function.obj module_builder.obj \ - objects.obj types.obj cross_module.obj - -.SUFFIXES: .obj .cpp - -all: libboost_python.lib \ - boost_python_test.pyd \ - abstract.pyd \ - getting_started1.pyd getting_started2.pyd \ - simple_vector.pyd \ - do_it_yourself_convts.pyd \ - nested.pyd \ - pickle1.pyd pickle2.pyd pickle3.pyd \ - noncopyable_export.pyd noncopyable_import.pyd \ - ivect.pyd dvect.pyd \ - richcmp1.pyd richcmp2.pyd richcmp3.pyd - -libboost_python.lib: $(OBJ) - $(LD) -library -o libboost_python.lib $(OBJ) - -boost_python_test.pyd: $(OBJ) comprehensive.obj - $(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) -o boost_python_test.pyd - -abstract.pyd: $(OBJ) abstract.obj - $(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) -o abstract.pyd - -getting_started1.pyd: $(OBJ) getting_started1.obj - $(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) -o getting_started1.pyd - -getting_started2.pyd: $(OBJ) getting_started2.obj - $(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) -o getting_started2.pyd - -simple_vector.pyd: $(OBJ) simple_vector.obj - $(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) -o simple_vector.pyd - -do_it_yourself_convts.pyd: $(OBJ) do_it_yourself_convts.obj - $(LD) $(LDOPTS) $(OBJ) do_it_yourself_convts.obj $(PYLIB) -o do_it_yourself_convts.pyd - -nested.pyd: $(OBJ) nested.obj - $(LD) $(LDOPTS) $(OBJ) nested.obj $(PYLIB) -o nested.pyd - -pickle1.pyd: $(OBJ) pickle1.obj - $(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) -o pickle1.pyd - -pickle2.pyd: $(OBJ) pickle2.obj - $(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) -o pickle2.pyd - -pickle3.pyd: $(OBJ) pickle3.obj - $(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) -o pickle3.pyd - -noncopyable_export.pyd: $(OBJ) noncopyable_export.obj - $(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) -o noncopyable_export.pyd - -noncopyable_import.pyd: $(OBJ) noncopyable_import.obj - $(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) -o noncopyable_import.pyd - -ivect.pyd: $(OBJ) ivect.obj - $(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) -o ivect.pyd - -dvect.pyd: $(OBJ) dvect.obj - $(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) -o dvect.pyd - -richcmp1.pyd: $(OBJ) richcmp1.obj - $(LD) $(LDOPTS) $(OBJ) richcmp1.obj $(PYLIB) -o richcmp1.pyd - -richcmp2.pyd: $(OBJ) richcmp2.obj - $(LD) $(LDOPTS) $(OBJ) richcmp2.obj $(PYLIB) -o richcmp2.pyd - -richcmp3.pyd: $(OBJ) richcmp3.obj - $(LD) $(LDOPTS) $(OBJ) richcmp3.obj $(PYLIB) -o richcmp3.pyd - -.cpp.obj: - $(CPP) $(CPPOPTS) -c $*.cpp - -test: - $(PYEXE) comprehensive.py - $(PYEXE) test_abstract.py - $(PYEXE) test_getting_started1.py - $(PYEXE) test_getting_started2.py - $(PYEXE) test_simple_vector.py - $(PYEXE) test_do_it_yourself_convts.py - $(PYEXE) test_nested.py - $(PYEXE) test_pickle1.py - $(PYEXE) test_pickle2.py - $(PYEXE) test_pickle3.py - $(PYEXE) test_cross_module.py - $(PYEXE) test_richcmp1.py - $(PYEXE) test_richcmp2.py - $(PYEXE) test_richcmp3.py - -clean: - -del *.obj - -del *.lib - -del *.exp - -del *.idb - -del *.pyd - -del *.pyc - -softlinks: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks - -unlink: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink - -cp: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp - -rm: - python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm - -copy: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy - -del: - $(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del diff --git a/build/win32_mwcc_setup.bat b/build/win32_mwcc_setup.bat deleted file mode 100755 index 30f84be8..00000000 --- a/build/win32_mwcc_setup.bat +++ /dev/null @@ -1,2 +0,0 @@ -call "c:\program files\metrowerks\codewarrior\other metrowerks tools\command line tools\cwenv.bat" -set MWWinx86LibraryFiles=MSL_All-DLL_x86.lib;gdi32.lib;user32.lib;kernel32.lib diff --git a/example/Attic/project.zip b/example/Attic/project.zip deleted file mode 100644 index d863defdb784ca6864f83a6ca22443b65259bda6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1469 zcmWIWW@Zs#U|`^2aL-z=bNJRCn;-@ThExUy25|-khJvE}tkmQZ{iOW-;u77Y(#)I` zy{yFC;4lt758rb>t3xzAbWR3noDA1E=@II2>b$;QpoiAkGoFDO>vZ%y&pv%x^yxc4 zUnl>k@BD!qLN8pt%&yFu9jCV;DYheN#*RAAx;np&b}kpB7!c0*nYCVr<@xLNO-u|7 zuB;3U{7BC5O3Y2m%t>txiS@tjAW+jk<^Kk+Ul+V?bbRY|TC!w8Q-~ekh-xlMm~)Kl=XCCX%Bmwa zJ??+)J&)AN_8(iU8IzDV_4v92v(_w~TPV$OD&OGBa;Aste>_*2dg_PFg{y5cQ!%Rh;e%O!zHU z=F3kDH@6Qzefsy)th(=i|JmH!B-`b*$vxC-=A2VOmUAN>{}8zTWaDk!$KUtun%1&q|%IrgyH9vOj*qP|t9e>?k zFKqkgr&rZ)=3f@CZ~a^S+L2c_Zrg(XKX1?Vxa&_iygRr-^U9SUF(ID>E`5=h9~v2H z^Y8j1ZnYwte|bH}C*99faoZGAP~-2sW!0nU(Uph0k3XLozOVP?ksFmeq_%bC&wZlx z#<*WBw0E;HU#Oa(=H{Lbd1rAq{wp&~XO}0e=BVKH+tvNuB6N59$@3-acLx1=R(1St z&C%39I}|HonO-?@wsdOR1YDk~87f`weBlK5xqm--J!ejv{Cw-PmbIaqT=qWNSE$sR zZZk>ZT47qup$oiRUE+`U5y^FB)_R@1rIH!yj0_A985tM^P?Kv>X-;afYk+U|VFRAM z;=knOQZ{_O@MYg!w%t5#$7cO55ZZdNU`dkp%U|!))is&pb@uA-W!f6|AXBNo+`Q#t z@SVJEvzgqLW~}OOPfNKk8)5ZJw_4i9PwGOZHJ{3}p3qa)M+Hh1J``L`@Z(8e-}`w+ zOu}`Q+z*`BF7xi4?IFi|j=ktEFYiPJwZ>=D7$fs~L>5fipHV6?r=xoH_8i&c}HD)t{a<}NprJAG4!c6I;i(?P6q^Ws*&im0y- z4c#04)?z_I=HDBFdgp!#ah9!HeV(ObbNh~xzpu*oTdv+ZYgSUC<@wb<$24CU{Etw} zeeUqWA|P8Th<%qr^S>o0Ydo?ng}-Mn|NryDoT4?JW$l|{4{>p_9a#Q*{V+3R&c zGz@bf1!{mdBa;XN?jj4Mhmk>nVOt}Jg`)sNHUwLN1JVjHq#em>Xz_!r8C&!tG@CIa ticqh_TySE5=*I0&kZw>i`tR7yg3uk{&B_LnVPRll_{PA%u#pAC0|1J>SqlIF diff --git a/example/Jamfile b/example/Jamfile index 05b97e14..83664cc2 100644 --- a/example/Jamfile +++ b/example/Jamfile @@ -22,6 +22,8 @@ subproject libs/python/example ; SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; +# ----- getting_started1 ------- + # Declare a Python extension called getting_started1 extension getting_started1 : # sources @@ -32,8 +34,28 @@ extension getting_started1 ; # Declare a test for the extension module -boost-python-runtest my-test +boost-python-runtest test1 : # Python test driver test_getting_started1.py # extension modules to use - getting_started1 ; \ No newline at end of file + getting_started1 ; + + + +# ----- getting_started2 ------- + +# Declare a Python extension called getting_started2 +extension getting_started2 +: # sources + getting_started2.cpp + + # dependencies + ../build/boost_python + ; + +# Declare a test for the extension module +boost-python-runtest test2 + : # Python test driver + test_getting_started2.py + # extension modules to use + getting_started2 ; \ No newline at end of file diff --git a/example/README b/example/README index ef7dc78f..ab22de54 100644 --- a/example/README +++ b/example/README @@ -1,21 +1,6 @@ To get started with the Boost Python Library, use the examples getting_started1.cpp and getting_started2.cpp. -Examples for providing pickle support can be found in: - pickle1.cpp - pickle2.cpp - pickle3.cpp -See also: libs/python/doc/pickle.html - -Other advanced concepts are introduced by: - abstract.cpp - simple_vector.cpp - do_it_yourself_convts.cpp - -Examples for the cross-module support are provided by: - noncopyable_export.cpp - noncopyable_import.cpp - dvect.cpp - ivect.cpp -See also: libs/python/doc/cross_module.html + bjam -sTOOLS=your-toolset test +in this directory will build and run the examples. diff --git a/example/abstract.cpp b/example/abstract.cpp deleted file mode 100644 index 97e38c2e..00000000 --- a/example/abstract.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Example by Ullrich Koethe -#include "boost/python/class_builder.hpp" -#include - -struct Abstract -{ - virtual std::string test() = 0; -}; - -struct Abstract_callback: Abstract -{ - Abstract_callback(PyObject * self) - : m_self(self) - {} - - std::string test() - { - return boost::python::callback::call_method(m_self, "test"); - } - - PyObject * m_self; -}; - -BOOST_PYTHON_MODULE_INIT(abstract) -{ - boost::python::module_builder a("abstract"); - - boost::python::class_builder - a_class(a, "Abstract"); - a_class.def(boost::python::constructor<>()); // wrap a constructor - a_class.def(&Abstract::test, "test"); -} diff --git a/example/do_it_yourself_convts.cpp b/example/do_it_yourself_convts.cpp deleted file mode 100644 index 427e7688..00000000 --- a/example/do_it_yourself_convts.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -/* - - This example shows how to convert a class from and to native - Python objects, such as tuples. - - We do not want to expose the helper class MillerIndex as an - Extension Class. However, in order to simplify the wrapper code, - we want to define from_python() and to_python() functions for - class MillerIndex. - - Consider the alternatives: - - - Expose MillerIndex as an Extension Class. - We need a constructor MillerIndex(python::tuple). - Python function calls become more complex: - foo(MillerIndex((1,2,3)) instead of foo((1,2,3)) - We need a method such as MillerIndex().as_tuple(). - - - Define a wrapper function for each function that we - want to expose, e.g.: - void add(const IndexingSet& ixset, const python::tuple PyMIx) - - The first alternative introduces a new type that the user has to - deal with. Other modules using Miller indices might organize them in - different ways, for example to increase runtime efficiency for - important procedures. This means, the user has to know how to - convert between the different kinds of Miller index representations. - This can quickly become a nuisance. Relying on native Python data - structures minimizes the number of special types the user has to - learn and convert. Of course, this argument is only valid for - small and relatively simply classes. - - If there are many member functions with MillerIndex arguments, the - second alternative is impractical, and concentrating the conversion - mechanism in one central place is essential for code - maintainability. An added benefit is that more convenient (smarter) - conversion functions can be provided without cluttering the rest of - the wrapper code. - - */ - -#include -#include -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // The helper class. - // - class MillerIndex { - public: - int v[3]; - }; - - // The main class. Imagine that there are MANY member functions - // like add() and get(). - // - class IndexingSet { - private: - std::vector VMIx; - public: - void add(const MillerIndex& MIx) { VMIx.push_back(MIx); } - MillerIndex get(std::size_t i) const { return VMIx[i]; } - }; -} - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - - // Convert a Python tuple to a MillerIndex object. - // - MillerIndex from_python(PyObject* p, python::type) - { - python::tuple tup - = python::tuple(python::ref(p, python::ref::increment_count)); - if (tup.size() != 3) { - PyErr_SetString(PyExc_ValueError, - "expecting exactly 3 values in tuple."); - python::throw_error_already_set(); - } - MillerIndex result; - for (int i = 0; i < 3; i++) - result.v[i] = from_python(tup[i].get(), python::type()); - return result; - } - - // Similar conversion for MillerIndex objects passed by value. - // Not actually used, but included to show the principle. - // - MillerIndex from_python(PyObject* p, python::type) - { - return from_python(p, python::type()); - } - - // Convert a MillerIndex object to a Python tuple. - // - PyObject* to_python(const MillerIndex& hkl) - { - python::tuple result(3); - for (int i = 0; i < 3; i++) - result.set_item(i, python::ref(to_python(hkl.v[i]))); - return result.reference().release(); - } - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -BOOST_PYTHON_MODULE_INIT(do_it_yourself_convts) -{ - // Create an object representing this extension module. - python::module_builder this_module("do_it_yourself_convts"); - - // Create the Python type object for our extension class. - python::class_builder ixset_class(this_module, "IndexingSet"); - - // Add the __init__ function. - ixset_class.def(python::constructor<>()); - // Add the member functions. - ixset_class.def(&IndexingSet::add, "add"); - ixset_class.def(&IndexingSet::get, "get"); -} diff --git a/example/dvect.cpp b/example/dvect.cpp deleted file mode 100644 index fa1506fe..00000000 --- a/example/dvect.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include "dvect.h" -#include "ivect.h" -#include -namespace python = boost::python; - -namespace { - -# include "dvect_conversions.cpp" -# include "ivect_conversions.cpp" - - vects::ivect dvect_as_ivect(const vects::dvect& dv) - { - vects::ivect iv(dv.size()); - vects::ivect::iterator iviter = iv.begin(); - for (int i = 0; i < dv.size(); i++) iviter[i] = static_cast(dv[i]); - return iv; - } -} - -# ifdef BOOST_MSVC // fixes for JIT debugging -# include -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) - = _set_se_translator(structured_exception_translator); -# endif - -BOOST_PYTHON_MODULE_INIT(dvect) -{ - python::module_builder this_module("dvect"); - - python::class_builder dvect_class(this_module, "dvect"); - python::export_converters(dvect_class); - - python::import_converters ivect_converters("ivect", "ivect"); - - dvect_class.def(python::constructor()); - dvect_class.def(&vects::dvect::as_tuple, "as_tuple"); - dvect_class.def(dvect_as_ivect, "as_ivect"); - -# include "dvect_defs.cpp" -# include "ivect_defs.cpp" -} diff --git a/example/dvect.h b/example/dvect.h deleted file mode 100644 index d059f04d..00000000 --- a/example/dvect.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef DVECT_H -#define DVECT_H - -#include -#include - -namespace vects { - - struct dvect : public std::vector - { - dvect() : std::vector() {} - dvect(std::size_t n) : std::vector(n) {} - dvect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (int i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (int i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - }; -} - -#endif // DVECT_H diff --git a/example/dvect_conversions.cpp b/example/dvect_conversions.cpp deleted file mode 100644 index 21527243..00000000 --- a/example/dvect_conversions.cpp +++ /dev/null @@ -1,51 +0,0 @@ - // basics first: const reference converters - boost::python::tuple const_dvect_reference_as_tuple(const vects::dvect& dv) - { - return dv.as_tuple(); - } - - // to_python smart pointer conversions - std::auto_ptr dvect_as_auto_ptr(const vects::dvect& dv) - { - return std::auto_ptr(new vects::dvect(dv)); - } - boost::shared_ptr dvect_as_shared_ptr(const vects::dvect& dv) - { - return boost::shared_ptr(new vects::dvect(dv)); - } - - // smart pointers passed by value - boost::python::ref auto_ptr_value_dvect_as_tuple(std::auto_ptr dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - boost::python::ref shared_ptr_value_dvect_as_tuple(boost::shared_ptr dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - - // smart pointers passed by reference - boost::python::ref auto_ptr_reference_dvect_as_tuple(std::auto_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - boost::python::ref shared_ptr_reference_dvect_as_tuple(boost::shared_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - - // smart pointers passed by const reference - boost::python::ref auto_ptr_const_reference_dvect_as_tuple(const std::auto_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } - boost::python::ref shared_ptr_const_reference_dvect_as_tuple(const boost::shared_ptr& dv) - { - if (dv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return dv->as_tuple().reference(); - } diff --git a/example/dvect_defs.cpp b/example/dvect_defs.cpp deleted file mode 100644 index 2739b219..00000000 --- a/example/dvect_defs.cpp +++ /dev/null @@ -1,13 +0,0 @@ - this_module.def(dvect_as_auto_ptr, "dvect_as_auto_ptr"); - this_module.def(dvect_as_shared_ptr, "dvect_as_shared_ptr"); - - this_module.def(const_dvect_reference_as_tuple, "const_dvect_reference_as_tuple"); - - this_module.def(auto_ptr_value_dvect_as_tuple, "auto_ptr_value_dvect_as_tuple"); - this_module.def(shared_ptr_value_dvect_as_tuple, "shared_ptr_value_dvect_as_tuple"); - - this_module.def(auto_ptr_reference_dvect_as_tuple, "auto_ptr_reference_dvect_as_tuple"); - this_module.def(shared_ptr_reference_dvect_as_tuple, "shared_ptr_reference_dvect_as_tuple"); - - this_module.def(auto_ptr_const_reference_dvect_as_tuple, "auto_ptr_const_reference_dvect_as_tuple"); - this_module.def(shared_ptr_const_reference_dvect_as_tuple, "shared_ptr_const_reference_dvect_as_tuple"); diff --git a/example/getting_started1.cpp b/example/getting_started1.cpp index 91a1f551..bdb79edc 100644 --- a/example/getting_started1.cpp +++ b/example/getting_started1.cpp @@ -9,22 +9,15 @@ namespace { // Avoid cluttering the global namespace. int square(int number) { return number * number; } } -#include +#include +#include namespace python = boost::python; // Python requires an exported function called init in every // extension module. This is where we build the module contents. -BOOST_PYTHON_MODULE_INIT(getting_started1) +BOOST_PYTHON_MODULE(getting_started1) { - try { - // Create an object representing this extension module. - python::module_builder this_module("getting_started1"); - // Add regular functions to the module. - this_module.def(greet, "greet"); - this_module.def(square, "square"); - } - catch(...) { - boost::python::handle_exception(); - } + python::def("greet", greet); + python::def("square", square); } diff --git a/example/getting_started2.cpp b/example/getting_started2.cpp index 04fbcc29..bec7447e 100644 --- a/example/getting_started2.cpp +++ b/example/getting_started2.cpp @@ -21,25 +21,20 @@ namespace { // Avoid cluttering the global namespace. } } -#include -namespace python = boost::python; +#include +#include +#include -BOOST_PYTHON_MODULE_INIT(getting_started2) +BOOST_PYTHON_MODULE(getting_started2) { - // Create an object representing this extension module. - python::module_builder this_module("getting_started2"); - - // Create the Python type object for our extension class. - python::class_builder hello_class(this_module, "hello"); - - // Add the __init__ function. - hello_class.def(python::constructor()); - // Add a regular member function. - hello_class.def(&hello::greet, "greet"); - - // Add invite() as a regular function to the module. - this_module.def(invite, "invite"); - - // Even better, invite() can also be made a member of hello_class!!! - hello_class.def(invite, "invite"); + using namespace boost::python; + class_("hello", init()) + // Add a regular member function. + .def("greet", &hello::greet) + // Add invite() as a member of hello! + .def("invite", invite) + ; + + // Also add invite() as a regular function to the module. + def("invite", invite); } diff --git a/example/ivect.cpp b/example/ivect.cpp deleted file mode 100644 index 35662b10..00000000 --- a/example/ivect.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include "dvect.h" -#include "ivect.h" -#include -namespace python = boost::python; - -namespace { - -# include "dvect_conversions.cpp" -# include "ivect_conversions.cpp" - - vects::dvect ivect_as_dvect(const vects::ivect& iv) - { - vects::dvect dv(iv.size()); - vects::dvect::iterator dviter = dv.begin(); - for (int i = 0; i < iv.size(); i++) dviter[i] = static_cast(iv[i]); - return dv; - } -} - -# ifdef BOOST_MSVC // fixes for JIT debugging -# include -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) - = _set_se_translator(structured_exception_translator); -# endif - -BOOST_PYTHON_MODULE_INIT(ivect) -{ - python::module_builder this_module("ivect"); - - python::class_builder ivect_class(this_module, "ivect"); - python::export_converters(ivect_class); - - python::import_converters dvect_converters("dvect", "dvect"); - - ivect_class.def(python::constructor()); - ivect_class.def(&vects::ivect::as_tuple, "as_tuple"); - ivect_class.def(ivect_as_dvect, "as_dvect"); - -# include "dvect_defs.cpp" -# include "ivect_defs.cpp" -} - diff --git a/example/ivect.h b/example/ivect.h deleted file mode 100644 index b8d52246..00000000 --- a/example/ivect.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef IVECT_H -#define IVECT_H - -#include -#include - -namespace vects { - - struct ivect : public std::vector - { - ivect() : std::vector() {} - ivect(std::size_t n) : std::vector(n) {} - ivect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (int i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (int i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - }; -} - -#endif // IVECT_H diff --git a/example/ivect_conversions.cpp b/example/ivect_conversions.cpp deleted file mode 100644 index 4f59573d..00000000 --- a/example/ivect_conversions.cpp +++ /dev/null @@ -1,51 +0,0 @@ - // basics first: const reference converters - boost::python::tuple const_ivect_reference_as_tuple(const vects::ivect& iv) - { - return iv.as_tuple(); - } - - // to_python smart pointer conversions - std::auto_ptr ivect_as_auto_ptr(const vects::ivect& iv) - { - return std::auto_ptr(new vects::ivect(iv)); - } - boost::shared_ptr ivect_as_shared_ptr(const vects::ivect& iv) - { - return boost::shared_ptr(new vects::ivect(iv)); - } - - // smart pointers passed by value - boost::python::ref auto_ptr_value_ivect_as_tuple(std::auto_ptr iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - boost::python::ref shared_ptr_value_ivect_as_tuple(boost::shared_ptr iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - - // smart pointers passed by reference - boost::python::ref auto_ptr_reference_ivect_as_tuple(std::auto_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - boost::python::ref shared_ptr_reference_ivect_as_tuple(boost::shared_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - - // smart pointers passed by const reference - boost::python::ref auto_ptr_const_reference_ivect_as_tuple(const std::auto_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } - boost::python::ref shared_ptr_const_reference_ivect_as_tuple(const boost::shared_ptr& iv) - { - if (iv.get() == 0) return boost::python::ref(Py_None, boost::python::ref::increment_count); - return iv->as_tuple().reference(); - } diff --git a/example/ivect_defs.cpp b/example/ivect_defs.cpp deleted file mode 100644 index 811c243d..00000000 --- a/example/ivect_defs.cpp +++ /dev/null @@ -1,13 +0,0 @@ - this_module.def(ivect_as_auto_ptr, "ivect_as_auto_ptr"); - this_module.def(ivect_as_shared_ptr, "ivect_as_shared_ptr"); - - this_module.def(const_ivect_reference_as_tuple, "const_ivect_reference_as_tuple"); - - this_module.def(auto_ptr_value_ivect_as_tuple, "auto_ptr_value_ivect_as_tuple"); - this_module.def(shared_ptr_value_ivect_as_tuple, "shared_ptr_value_ivect_as_tuple"); - - this_module.def(auto_ptr_reference_ivect_as_tuple, "auto_ptr_reference_ivect_as_tuple"); - this_module.def(shared_ptr_reference_ivect_as_tuple, "shared_ptr_reference_ivect_as_tuple"); - - this_module.def(auto_ptr_const_reference_ivect_as_tuple, "auto_ptr_const_reference_ivect_as_tuple"); - this_module.def(shared_ptr_const_reference_ivect_as_tuple, "shared_ptr_const_reference_ivect_as_tuple"); diff --git a/example/nested.cpp b/example/nested.cpp deleted file mode 100644 index a5632d16..00000000 --- a/example/nested.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how convert a nested Python tuple. - */ - -#include -#include - -namespace { - - boost::python::list - show_nested_tuples(boost::python::tuple outer) - { - boost::python::list result; - for (int i = 0; i < outer.size(); i++) { - boost::python::tuple inner( - BOOST_PYTHON_CONVERSION::from_python(outer[i].get(), - boost::python::type())); - for (int j = 0; j < inner.size(); j++) { - double x = BOOST_PYTHON_CONVERSION::from_python(inner[j].get(), - boost::python::type()); - char buf[128]; - sprintf(buf, "(%d,%d) %.6g", i, j, x); - result.append(BOOST_PYTHON_CONVERSION::to_python(std::string(buf))); - } - } - return result; - } - -} - -BOOST_PYTHON_MODULE_INIT(nested) -{ - boost::python::module_builder this_module("nested"); - this_module.def(show_nested_tuples, "show_nested_tuples"); -} diff --git a/example/noncopyable.h b/example/noncopyable.h deleted file mode 100644 index de7b3672..00000000 --- a/example/noncopyable.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef NONCOPYABLE_H -#define NONCOPYABLE_H - -class store -{ - private: - store(const store&) { } // Disable the copy constructor. - int number; - public: - store(const int i) : number(i) { } - int recall() const { return number; } -}; - -#endif // NONCOPYABLE_H diff --git a/example/noncopyable_export.cpp b/example/noncopyable_export.cpp deleted file mode 100644 index 3a81db75..00000000 --- a/example/noncopyable_export.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include -namespace python = boost::python; - -#include "noncopyable.h" - -# ifdef BOOST_MSVC // fixes for JIT debugging -# include -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) - = _set_se_translator(structured_exception_translator); -# endif - -BOOST_PYTHON_MODULE_INIT(noncopyable_export) -{ - python::module_builder this_module("noncopyable_export"); - - python::class_builder store_class(this_module, "store"); - python::export_converters_noncopyable(store_class); - - store_class.def(python::constructor()); - store_class.def(&store::recall, "recall"); -} diff --git a/example/noncopyable_import.cpp b/example/noncopyable_import.cpp deleted file mode 100644 index d4227642..00000000 --- a/example/noncopyable_import.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// See root/libs/python/doc/cross_module.html for an introduction. - -#include -namespace python = boost::python; - -#include "noncopyable.h" - -namespace { // Avoid cluttering the global namespace. - - // A function with store objects as both input and output parameters. - // Because the copy constructor is disabled, we cannot pass a store - // object by value. Instead, we pass a smart pointer. - std::auto_ptr add_stores(const store& s1, const store& s2) - { - int sum = s1.recall() + s2.recall(); - std::auto_ptr ss = std::auto_ptr(new store(sum)); - return ss; - } -} - -# ifdef BOOST_MSVC // fixes for JIT debugging -# include -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -{ - throw; -} -extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*) - = _set_se_translator(structured_exception_translator); -# endif - -BOOST_PYTHON_MODULE_INIT(noncopyable_import) -{ - python::module_builder this_module("noncopyable_import"); - - python::import_converters - dvect_converters("noncopyable_export", "store"); - - // Imagine all the additional classes with member functions - // that have store objects as input and output parameters. - // Lots and lots of them. - // However, to keep this example simple, we only define a - // module-level function. - this_module.def(add_stores, "add_stores"); -} diff --git a/example/pickle1.cpp b/example/pickle1.cpp deleted file mode 100644 index af041e72..00000000 --- a/example/pickle1.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below can be fully restored by passing the - appropriate argument to the constructor. Therefore it is sufficient - to define the pickle interface method __getinitargs__. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - private: - std::string country; - int secret_number; - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - }; - - // Support for pickle. - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); - } -} - -BOOST_PYTHON_MODULE_INIT(pickle1) -{ - // Create an object representing this extension module. - python::module_builder this_module("pickle1"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); -} diff --git a/example/pickle2.cpp b/example/pickle2.cpp deleted file mode 100644 index 781615cd..00000000 --- a/example/pickle2.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below contains member data (secret_number) that - cannot be restored by any of the constructors. Therefore it is - necessary to provide the __getstate__/__setstate__ pair of pickle - interface methods. - - For simplicity, the __dict__ is not included in the result of - __getstate__. This is not generally recommended, but a valid - approach if it is anticipated that the object's __dict__ will - always be empty. Note that safety guard are provided to catch the - cases where this assumption is not true. - - pickle3.cpp shows how to include the object's __dict__ in the - result of __getstate__. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - private: - std::string country; - int secret_number; - }; - - // Support for pickle. - - using BOOST_PYTHON_CONVERSION::from_python; - - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); // returning the reference avoids the copying. - } - - python::ref world_getstate(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_secret_number()); - return result.reference(); // returning the reference avoids the copying. - } - - void world_setstate(world& w, python::tuple state) { - if (state.size() != 1) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); - python::throw_error_already_set(); - } - int number = from_python(state[0].get(), python::type()); - if (number != 42) - w.set_secret_number(number); - } -} - -BOOST_PYTHON_MODULE_INIT(pickle2) -{ - // Create an object representing this extension module. - python::module_builder this_module("pickle2"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - world_class.def(&world::get_secret_number, "get_secret_number"); - world_class.def(&world::set_secret_number, "set_secret_number"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - world_class.def(world_getstate, "__getstate__"); - world_class.def(world_setstate, "__setstate__"); -} diff --git a/example/pickle3.cpp b/example/pickle3.cpp deleted file mode 100644 index 5f32b1f3..00000000 --- a/example/pickle3.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -/* - This example shows how to make an Extension Class "pickleable". - - The world class below contains member data (secret_number) that - cannot be restored by any of the constructors. Therefore it is - necessary to provide the __getstate__/__setstate__ pair of pickle - interface methods. - - The object's __dict__ is included in the result of __getstate__. - This requires more code (compare with pickle2.cpp), but is - unavoidable if the object's __dict__ is not always empty. - - For more information refer to boost/libs/python/doc/pickle.html. - */ - -#include - -#include -namespace python = boost::python; - -namespace boost { namespace python { - - ref getattr(PyObject* o, const std::string& attr_name) { - return ref(PyObject_GetAttrString(o, const_cast(attr_name.c_str()))); - } - ref getattr(const ref& r, const std::string& attr_name) { - return getattr(r.get(), attr_name); - } - -}} - -namespace { // Avoid cluttering the global namespace. - - // A friendly class. - class world - { - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - private: - std::string country; - int secret_number; - }; - - // Support for pickle. - python::ref world_getinitargs(const world& w) { - python::tuple result(1); - result.set_item(0, w.get_country()); - return result.reference(); // returning the reference avoids the copying. - } - - python::ref world_getstate(python::tuple const & args, - python::dictionary const & keywords); - - PyObject* world_setstate(python::tuple const & args, - python::dictionary const & keywords); -} - -BOOST_PYTHON_MODULE_INIT(pickle3) -{ - // Create an object representing this extension module. - python::module_builder this_module("pickle3"); - - // Create the Python type object for our extension class. - python::class_builder world_class(this_module, "world"); - - // Add the __init__ function. - world_class.def(python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - world_class.def(&world::get_secret_number, "get_secret_number"); - world_class.def(&world::set_secret_number, "set_secret_number"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - world_class.def_raw(world_getstate, "__getstate__"); - world_class.def_raw(world_setstate, "__setstate__"); - world_class.getstate_manages_dict(); -} - -namespace { - - using BOOST_PYTHON_CONVERSION::from_python; - using boost::python::type; - using boost::python::ref; - using boost::python::tuple; - using boost::python::list; - using boost::python::dictionary; - using boost::python::getattr; - - ref world_getstate(tuple const & args, dictionary const & keywords) - { - if(args.size() != 1 || keywords.size() != 0) { - PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - boost::python::throw_error_already_set(); - } - const world& w = from_python(args[0].get(), type()); - ref mydict = getattr(args[0], "__dict__"); - tuple result(2); - // store the object's __dict__ - result.set_item(0, mydict); - // store the internal state of the C++ object - result.set_item(1, w.get_secret_number()); - return result.reference(); // returning the reference avoids the copying. - } - - PyObject* world_setstate(tuple const & args, dictionary const & keywords) - { - if(args.size() != 2 || keywords.size() != 0) { - PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - boost::python::throw_error_already_set(); - } - world& w = from_python(args[0].get(), type()); - ref mydict = getattr(args[0], "__dict__"); - tuple state = from_python(args[1].get(), type()); - if (state.size() != 2) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); - python::throw_error_already_set(); - } - // restore the object's __dict__ - dictionary odict = from_python(mydict.get(), type()); - const dictionary& pdict = from_python(state[0].get(), type()); - list pkeys(pdict.keys()); - for (int i = 0; i < pkeys.size(); i++) { - ref k(pkeys[i]); - //odict[k] = pdict[k]; // XXX memory leak! - odict[k] = pdict.get_item(k); // this does not leak. - } - // restore the internal state of the C++ object - int number = from_python(state[1].get(), type()); - if (number != 42) - w.set_secret_number(number); - return python::detail::none(); - } -} diff --git a/example/project.zip b/example/project.zip deleted file mode 100644 index d863defdb784ca6864f83a6ca22443b65259bda6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1469 zcmWIWW@Zs#U|`^2aL-z=bNJRCn;-@ThExUy25|-khJvE}tkmQZ{iOW-;u77Y(#)I` zy{yFC;4lt758rb>t3xzAbWR3noDA1E=@II2>b$;QpoiAkGoFDO>vZ%y&pv%x^yxc4 zUnl>k@BD!qLN8pt%&yFu9jCV;DYheN#*RAAx;np&b}kpB7!c0*nYCVr<@xLNO-u|7 zuB;3U{7BC5O3Y2m%t>txiS@tjAW+jk<^Kk+Ul+V?bbRY|TC!w8Q-~ekh-xlMm~)Kl=XCCX%Bmwa zJ??+)J&)AN_8(iU8IzDV_4v92v(_w~TPV$OD&OGBa;Aste>_*2dg_PFg{y5cQ!%Rh;e%O!zHU z=F3kDH@6Qzefsy)th(=i|JmH!B-`b*$vxC-=A2VOmUAN>{}8zTWaDk!$KUtun%1&q|%IrgyH9vOj*qP|t9e>?k zFKqkgr&rZ)=3f@CZ~a^S+L2c_Zrg(XKX1?Vxa&_iygRr-^U9SUF(ID>E`5=h9~v2H z^Y8j1ZnYwte|bH}C*99faoZGAP~-2sW!0nU(Uph0k3XLozOVP?ksFmeq_%bC&wZlx z#<*WBw0E;HU#Oa(=H{Lbd1rAq{wp&~XO}0e=BVKH+tvNuB6N59$@3-acLx1=R(1St z&C%39I}|HonO-?@wsdOR1YDk~87f`weBlK5xqm--J!ejv{Cw-PmbIaqT=qWNSE$sR zZZk>ZT47qup$oiRUE+`U5y^FB)_R@1rIH!yj0_A985tM^P?Kv>X-;afYk+U|VFRAM z;=knOQZ{_O@MYg!w%t5#$7cO55ZZdNU`dkp%U|!))is&pb@uA-W!f6|AXBNo+`Q#t z@SVJEvzgqLW~}OOPfNKk8)5ZJw_4i9PwGOZHJ{3}p3qa)M+Hh1J``L`@Z(8e-}`w+ zOu}`Q+z*`BF7xi4?IFi|j=ktEFYiPJwZ>=D7$fs~L>5fipHV6?r=xoH_8i&c}HD)t{a<}NprJAG4!c6I;i(?P6q^Ws*&im0y- z4c#04)?z_I=HDBFdgp!#ah9!HeV(ObbNh~xzpu*oTdv+ZYgSUC<@wb<$24CU{Etw} zeeUqWA|P8Th<%qr^S>o0Ydo?ng}-Mn|NryDoT4?JW$l|{4{>p_9a#Q*{V+3R&c zGz@bf1!{mdBa;XN?jj4Mhmk>nVOt}Jg`)sNHUwLN1JVjHq#em>Xz_!r8C&!tG@CIa ticqh_TySE5=*I0&kZw>i`tR7yg3uk{&B_LnVPRll_{PA%u#pAC0|1J>SqlIF diff --git a/example/richcmp1.cpp b/example/richcmp1.cpp deleted file mode 100644 index 884fdfda..00000000 --- a/example/richcmp1.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve & Nicholas K. Sauter -// This example shows how to use rich comparisons for a vector type. -// It also shows how to template the entire wrapping of a std::vector. -// See vector_wrapper.h. - -#include -#include "vector_wrapper.h" - -namespace vects { - - struct dvect : public std::vector - { - dvect() : std::vector() {} - dvect(size_t n) : std::vector(n) {} - dvect(boost::python::tuple tuple) : std::vector(tuple.size()) - { - std::vector::iterator v_it = begin(); - for (std::size_t i = 0; i < tuple.size(); i++) - v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - - boost::python::tuple as_tuple() const - { - boost::python::tuple t(size()); - for (std::size_t i = 0; i < size(); i++) - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i]))); - return t; - } - -# define DVECT_BINARY_OPERATORS(oper) \ - friend std::vector \ - operator##oper(const dvect& lhs, const dvect& rhs) \ - { \ - if (lhs.size() != rhs.size()) { \ - PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \ - boost::python::throw_error_already_set(); \ - } \ - std::vector result(lhs.size()); \ - for (std::size_t i=0; i) - DVECT_BINARY_OPERATORS(>=) -# undef VECTOR_BINARY_OPERATORS - }; - -} // namespace - - -namespace { - - void init_module(boost::python::module_builder& this_module) - { - (void) example::wrap_vector(this_module, "vector_of_bool", bool()); - - boost::python::class_builder py_dvect(this_module, "dvect"); - - py_dvect.def(boost::python::constructor()); - py_dvect.def(&vects::dvect::as_tuple, "as_tuple"); - - const long - comp_operators = ( boost::python::op_lt | boost::python::op_le - | boost::python::op_eq | boost::python::op_ne - | boost::python::op_gt | boost::python::op_ge); - py_dvect.def(boost::python::operators()); - } - -} // namespace - -BOOST_PYTHON_MODULE_INIT(richcmp1) -{ - boost::python::module_builder this_module("richcmp1"); - // The actual work is done in a separate function in order - // to suppress a bogus VC60 warning. - init_module(this_module); -} diff --git a/example/richcmp2.cpp b/example/richcmp2.cpp deleted file mode 100644 index 993c6800..00000000 --- a/example/richcmp2.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve -// This example shows how to use rich comparisons for a type that -// does not support all six operators (<, <=, ==, !=, >, >=). -// To keep the example simple, we are using a "code" type does -// not really require rich comparisons. __cmp__ would be sufficient. -// However, with a more complicated type the main point of this -// example would be in danger of getting lost. - -#include - -namespace { - - // suppose operator< and operator> are not meaningful for code - class code { - public: - code(int c = 0) : m_code(c) {} - inline friend bool operator==(const code& lhs, const code& rhs) { - return lhs.m_code == rhs.m_code; - } - inline friend bool operator!=(const code& lhs, const code& rhs) { - return lhs.m_code != rhs.m_code; - } - private: - int m_code; - }; - -#if PYTHON_API_VERSION >= 1010 - boost::python::ref - NotImplemented(const code&, const code&) { - return - boost::python::ref(Py_NotImplemented, boost::python::ref::increment_count); - } -#endif -} - -namespace { - - void init_module(boost::python::module_builder& this_module) - { - boost::python::class_builder py_code(this_module, "code"); - - py_code.def(boost::python::constructor<>()); - py_code.def(boost::python::constructor()); - py_code.def(boost::python::operators<( boost::python::op_eq - | boost::python::op_ne)>()); -#if PYTHON_API_VERSION >= 1010 - py_code.def(NotImplemented, "__lt__"); - py_code.def(NotImplemented, "__le__"); - py_code.def(NotImplemented, "__gt__"); - py_code.def(NotImplemented, "__ge__"); -#endif - } - -} // namespace - -BOOST_PYTHON_MODULE_INIT(richcmp2) -{ - boost::python::module_builder this_module("richcmp2"); - // The actual work is done in a separate function in order - // to suppress a bogus VC60 warning. - init_module(this_module); -} diff --git a/example/richcmp3.cpp b/example/richcmp3.cpp deleted file mode 100644 index 02a2ebcb..00000000 --- a/example/richcmp3.cpp +++ /dev/null @@ -1,175 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve & Nicholas K. Sauter. -// Comprehensive operator overloading for two vector types and scalars. - -#include -#include "vector_wrapper.h" -#include "dvect.h" -#include "ivect.h" - -#define VECT_VECT_OPERATORS(result_type, vect_type1, oper, vect_type2) \ -namespace vects { \ - result_type \ - operator##oper (const vect_type1& lhs, const vect_type2& rhs) { \ - if (lhs.size() != rhs.size()) { \ - PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \ - boost::python::throw_error_already_set(); \ - } \ - result_type result(lhs.size()); \ - for (std::size_t i=0; i, vect_type1, <, vect_type2) \ - VECT_VECT_OPERATORS(std::vector, vect_type1, <=, vect_type2) \ - VECT_VECT_OPERATORS(std::vector, vect_type1, ==, vect_type2) \ - VECT_VECT_OPERATORS(std::vector, vect_type1, !=, vect_type2) \ - VECT_VECT_OPERATORS(std::vector, vect_type1, >, vect_type2) \ - VECT_VECT_OPERATORS(std::vector, vect_type1, >=, vect_type2) - -#define MATH_VECT_SCALAR_OPERATORS(result_type, vect_type, scalar_type) \ - VECT_SCALAR_OPERATORS(result_type, vect_type, +, scalar_type) \ - VECT_SCALAR_OPERATORS(result_type, vect_type, -, scalar_type) \ - VECT_SCALAR_OPERATORS(result_type, vect_type, *, scalar_type) \ - VECT_SCALAR_OPERATORS(result_type, vect_type, /, scalar_type) - -#define COMP_VECT_SCALAR_OPERATORS(vect_type, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, <, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, <=, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, ==, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, !=, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, >, scalar_type) \ - VECT_SCALAR_OPERATORS(std::vector, vect_type, >=, scalar_type) - -#define MATH_SCALAR_VECT_OPERATORS(result_type, scalar_type, vect_type) \ - SCALAR_VECT_OPERATORS(result_type, scalar_type, +, vect_type) \ - SCALAR_VECT_OPERATORS(result_type, scalar_type, -, vect_type) \ - SCALAR_VECT_OPERATORS(result_type, scalar_type, *, vect_type) \ - SCALAR_VECT_OPERATORS(result_type, scalar_type, /, vect_type) - -MATH_VECT_VECT_OPERATORS(dvect, dvect, dvect) -COMP_VECT_VECT_OPERATORS( dvect, dvect) -MATH_VECT_SCALAR_OPERATORS(dvect, dvect, double) -COMP_VECT_SCALAR_OPERATORS( dvect, double) -MATH_SCALAR_VECT_OPERATORS(dvect, double, dvect) -// comparison operators not needed since Python uses reflection - -MATH_VECT_VECT_OPERATORS(ivect, ivect, ivect) -COMP_VECT_VECT_OPERATORS( ivect, ivect) -MATH_VECT_SCALAR_OPERATORS(ivect, ivect, int) -COMP_VECT_SCALAR_OPERATORS( ivect, int) -MATH_SCALAR_VECT_OPERATORS(ivect, int, ivect) -// comparison operators not needed since Python uses reflection - -MATH_VECT_VECT_OPERATORS(dvect, dvect, ivect) -COMP_VECT_VECT_OPERATORS( dvect, ivect) -MATH_VECT_VECT_OPERATORS(dvect, ivect, dvect) -COMP_VECT_VECT_OPERATORS( ivect, dvect) - -#undef VECT_VECT_OPERATORS -#undef SCALAR_VECT_OPERATORS -#undef VECT_SCALAR_OPERATORS -#undef MATH_VECT_VECT_OPERATORS -#undef COMP_VECT_VECT_OPERATORS -#undef MATH_VECT_SCALAR_OPERATORS -#undef COMP_VECT_SCALAR_OPERATORS -#undef MATH_SCALAR_VECT_OPERATORS - -namespace { - - void init_module(boost::python::module_builder& this_module) - { - (void) example::wrap_vector(this_module, "vector_of_bool", bool()); - - const long - math_operators ( boost::python::op_mul | boost::python::op_add - | boost::python::op_div | boost::python::op_sub); - const long - comp_operators = ( boost::python::op_lt | boost::python::op_le - | boost::python::op_eq | boost::python::op_ne - | boost::python::op_gt | boost::python::op_ge); - - boost::python::class_builder - dvect_class(this_module, "dvect"); - boost::python::class_builder - ivect_class(this_module, "ivect"); - - dvect_class.def(boost::python::constructor()); - dvect_class.def(&vects::dvect::as_tuple,"as_tuple"); - - dvect_class.def(boost::python::operators()); - dvect_class.def(boost::python::operators(), - boost::python::right_operand() ); - dvect_class.def(boost::python::operators(), - boost::python::left_operand() ); - dvect_class.def(boost::python::operators(), - boost::python::right_operand() ); - - dvect_class.def(boost::python::operators()); - dvect_class.def(boost::python::operators(), - boost::python::right_operand() ); - // left_operand not needed since Python uses reflection - dvect_class.def(boost::python::operators(), - boost::python::right_operand() ); - - ivect_class.def(boost::python::constructor()); - ivect_class.def(&vects::ivect::as_tuple,"as_tuple"); - - ivect_class.def(boost::python::operators()); - ivect_class.def(boost::python::operators(), - boost::python::right_operand() ); - ivect_class.def(boost::python::operators(), - boost::python::left_operand() ); - ivect_class.def(boost::python::operators(), - boost::python::right_operand() ); - - ivect_class.def(boost::python::operators()); - ivect_class.def(boost::python::operators(), - boost::python::right_operand() ); - // left_operand not needed since Python uses reflection - ivect_class.def(boost::python::operators(), - boost::python::right_operand() ); - } - -} // namespace - -BOOST_PYTHON_MODULE_INIT(richcmp3) -{ - boost::python::module_builder this_module("richcmp3"); - // The actual work is done in a separate function in order - // to suppress a bogus VC60 warning. - init_module(this_module); -} diff --git a/example/simple_vector.cpp b/example/simple_vector.cpp deleted file mode 100644 index bc6e3408..00000000 --- a/example/simple_vector.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// Example by Ralf W. Grosse-Kunstleve - -#include -namespace python = boost::python; - -namespace { // Avoid cluttering the global namespace. - - // A wrapper is used to define additional constructors. - // - struct vector_double_wrapper: std::vector - { - // Tell the compiler how to convert a base class object to - // this wrapper object. - vector_double_wrapper(PyObject*, const std::vector& vd) - : std::vector(vd) {} - - vector_double_wrapper(PyObject* self) - : std::vector() {} - - vector_double_wrapper(PyObject* self, int n) - : std::vector(n) {} - - vector_double_wrapper(PyObject* self, python::tuple tuple) - : std::vector(tuple.size()) - { - std::vector::iterator vd = begin(); - for (int i = 0; i < tuple.size(); i++) - vd[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - python::type()); - } - }; - - void raise_vector_IndexError() { - PyErr_SetString(PyExc_IndexError, "vector index out of range"); - python::throw_error_already_set(); - } - - double getitem(const std::vector& vd, std::size_t key) { - if (key >= vd.size()) raise_vector_IndexError(); - return vd[key]; - } - - void setitem(std::vector& vd, std::size_t key, double d) { - if (key >= vd.size()) raise_vector_IndexError(); - std::vector::iterator vditer = vd.begin(); - vditer[key] = d; - } - - void delitem(std::vector& vd, std::size_t key) { - if (key >= vd.size()) raise_vector_IndexError(); - std::vector::iterator vditer = vd.begin(); - vd.erase(vditer + key); - } - - // Convert vector_double to a regular Python tuple. - // - python::tuple as_tuple(const std::vector& vd) - { - python::tuple t(vd.size()); - for (int i = 0; i < vd.size(); i++) t.set_item(i, - python::ref(BOOST_PYTHON_CONVERSION::to_python(vd[i]))); - return t; - } - - // Function returning a vector_double object to Python. - // - std::vector foo(int n) - { - std::vector vd(n); - std::vector::iterator vditer = vd.begin(); - for (int i = 0; i < n; i++) vditer[i] = double(i); - return vd; - } - - // Same as foo(), but avoid copying on return. - // - std::auto_ptr > bar(int n) - { - std::auto_ptr > vdptr(new std::vector(n)); - std::vector::iterator vditer = vdptr->begin(); - for (int i = 0; i < n; i++) vditer[i] = double(10 * i); - return vdptr; - } -} - -BOOST_PYTHON_MODULE_INIT(simple_vector) -{ - python::module_builder this_module("simple_vector"); - - python::class_builder, vector_double_wrapper> - vector_double(this_module, "vector_double"); - - vector_double.def(python::constructor()); - vector_double.def(python::constructor<>()); - vector_double.def(python::constructor()); - vector_double.def(&std::vector::size, "__len__"); - vector_double.def(getitem, "__getitem__"); - vector_double.def(setitem, "__setitem__"); - vector_double.def(delitem, "__delitem__"); - vector_double.def(as_tuple, "as_tuple"); - - this_module.def(foo, "foo"); - this_module.def(bar, "bar"); -} diff --git a/example/test_abstract.py b/example/test_abstract.py deleted file mode 100644 index a48aff1b..00000000 --- a/example/test_abstract.py +++ /dev/null @@ -1,24 +0,0 @@ -# Example by Ullrich Koethe -r'''>>> from abstract import * - >>> class A(Abstract): - ... def __init__(self, text): - ... Abstract.__init__(self) # call the base class constructor - ... self.text = text - ... def test(self): # implement abstract function - ... return self.text - ... - >>> a = A("Hello") - >>> a.test() - 'Hello' -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_abstract - return doctest.testmod(test_abstract) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_cross_module.py b/example/test_cross_module.py deleted file mode 100644 index c5e2bef6..00000000 --- a/example/test_cross_module.py +++ /dev/null @@ -1,140 +0,0 @@ -r'''>>> import tst_noncopyable - >>> tst_noncopyable.f() - 1 - 2 - 3 - >>> import tst_dvect1 - >>> tst_dvect1.f() - (1.0, 2.0, 3.0, 4.0, 5.0) - (1, 2, 3, 4, 5) - (1, 2, 3, 4, 5) - (1, 2, 3, 4, 5) - (1, 2, 3, 4, 5) - (1, 2, 3, 4, 5) - (1, 2, 3, 4, 5) - >>> import tst_ivect1 - >>> tst_ivect1.f() - (1, 2, 3, 4, 5) - (1.0, 2.0, 3.0, 4.0, 5.0) - (1.0, 2.0, 3.0, 4.0, 5.0) - (1.0, 2.0, 3.0, 4.0, 5.0) - (1.0, 2.0, 3.0, 4.0, 5.0) - (1.0, 2.0, 3.0, 4.0, 5.0) - (1.0, 2.0, 3.0, 4.0, 5.0) - >>> import sys - >>> if ("--broken-auto-ptr" in sys.argv): - ... broken_auto_ptr = 1 - ... else: - ... broken_auto_ptr = 0 - >>> import tst_dvect2 - >>> tst_dvect2.f(broken_auto_ptr) - 1. auto_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_value_ivect_as_tuple - None - 1. auto_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_value_dvect_as_tuple - None - 1. shared_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. shared_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. auto_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. auto_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. shared_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. shared_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. auto_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. auto_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. shared_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. shared_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - >>> import tst_ivect2 - >>> tst_ivect2.f(broken_auto_ptr) - 1. auto_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_value_dvect_as_tuple - None - 1. auto_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_value_ivect_as_tuple - None - 1. shared_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_value_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. shared_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_value_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. auto_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. auto_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. shared_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. shared_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. auto_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. auto_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. auto_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. auto_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 1. shared_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 2. shared_ptr_const_reference_dvect_as_tuple - (1.0, 2.0, 3.0, 4.0, 5.0) - 1. shared_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) - 2. shared_ptr_const_reference_ivect_as_tuple - (1, 2, 3, 4, 5) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_cross_module - return doctest.testmod(test_cross_module) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_do_it_yourself_convts.py b/example/test_do_it_yourself_convts.py deleted file mode 100644 index 6f5fa5a0..00000000 --- a/example/test_do_it_yourself_convts.py +++ /dev/null @@ -1,23 +0,0 @@ -r'''>>> import do_it_yourself_convts - >>> ixset = do_it_yourself_convts.IndexingSet() - >>> ixset.add((1,2,3)) - >>> ixset.add((4,5,6)) - >>> ixset.add((7,8,9)) - >>> print ixset.get(0) - (1, 2, 3) - >>> print ixset.get(1) - (4, 5, 6) - >>> print ixset.get(2) - (7, 8, 9) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_do_it_yourself_convts - return doctest.testmod(test_do_it_yourself_convts) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_example1.py b/example/test_example1.py deleted file mode 100644 index 3a30cb5b..00000000 --- a/example/test_example1.py +++ /dev/null @@ -1,51 +0,0 @@ -r''' -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -That's it! If we build this shared library and put it on our PYTHONPATH we can -now access our C++ class and function from Python. - - >>> import hello - >>> hi_world = hello.world(3) - >>> hi_world.get() - 'hi, world' - >>> hello.length(hi_world) - 9 - -We can even make a subclass of hello.world: - - - >>> class my_subclass(hello.world): - ... def get(self): - ... return 'hello, world' - ... - >>> y = my_subclass(2) - >>> y.get() - 'hello, world' - -Pretty cool! You can't do that with an ordinary Python extension type! - - >>> hello.length(y) - 9 - -Of course, you may now have a slightly empty feeling in the pit of your little -pythonic stomach. Perhaps you feel your subclass deserves to have a length() of -12? If so, read on... -''' -from hello import * - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_example1 - return doctest.testmod(test_example1) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_getting_started1.py b/example/test_getting_started1.py deleted file mode 100644 index cd8fb59e..00000000 --- a/example/test_getting_started1.py +++ /dev/null @@ -1,18 +0,0 @@ -r'''>>> import getting_started1 - >>> print getting_started1.greet() - hello, world - >>> number = 11 - >>> print number, '*', number, '=', getting_started1.square(number) - 11 * 11 = 121 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_getting_started1 - return doctest.testmod(test_getting_started1) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_getting_started2.py b/example/test_getting_started2.py deleted file mode 100644 index ccfaa4f1..00000000 --- a/example/test_getting_started2.py +++ /dev/null @@ -1,31 +0,0 @@ -r'''>>> from getting_started2 import * - >>> hi = hello('California') - >>> hi.greet() - 'Hello from California' - >>> invite(hi) - 'Hello from California! Please come soon!' - >>> hi.invite() - 'Hello from California! Please come soon!' - - >>> class wordy(hello): - ... def greet(self): - ... return hello.greet(self) + ', where the weather is fine' - ... - >>> hi2 = wordy('Florida') - >>> hi2.greet() - 'Hello from Florida, where the weather is fine' - >>> invite(hi2) - 'Hello from Florida! Please come soon!' -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_getting_started2 - return doctest.testmod(test_getting_started2) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) - diff --git a/example/test_nested.py b/example/test_nested.py deleted file mode 100644 index e9abbf0f..00000000 --- a/example/test_nested.py +++ /dev/null @@ -1,23 +0,0 @@ -r'''>>> import nested - >>> s = nested.show_nested_tuples(((1,2,3), (4,5,6,7))) - >>> for l in s: - ... print l - (0,0) 1 - (0,1) 2 - (0,2) 3 - (1,0) 4 - (1,1) 5 - (1,2) 6 - (1,3) 7 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_nested - return doctest.testmod(test_nested) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_pickle1.py b/example/test_pickle1.py deleted file mode 100644 index 48c76a5f..00000000 --- a/example/test_pickle1.py +++ /dev/null @@ -1,33 +0,0 @@ -r'''>>> import pickle1 - >>> import re - >>> import pickle - >>> pickle1.world.__module__ - 'pickle1' - >>> pickle1.world.__safe_for_unpickling__ - 1 - >>> pickle1.world.__reduce__() - 'world' - >>> assert re.match( - ... "\(, \('Hello',\)\)", - ... repr(pickle1.world('Hello').__reduce__())) - >>> - >>> wd = pickle1.world('California') - >>> pstr = pickle.dumps(wd) - >>> wl = pickle.loads(pstr) - >>> print wd.greet() - Hello from California! - >>> print wl.greet() - Hello from California! -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_pickle1 - return doctest.testmod(test_pickle1) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) - diff --git a/example/test_pickle2.py b/example/test_pickle2.py deleted file mode 100644 index bafa9875..00000000 --- a/example/test_pickle2.py +++ /dev/null @@ -1,47 +0,0 @@ -r'''>>> import pickle2 - >>> import re - >>> import pickle - >>> pickle2.world.__module__ - 'pickle2' - >>> pickle2.world.__safe_for_unpickling__ - 1 - >>> pickle2.world.__reduce__() - 'world' - >>> assert re.match( - ... "\(, \('Hello',\), \(0,\)\)", - ... repr(pickle2.world('Hello').__reduce__())) - >>> - >>> for number in (24, 42): - ... wd = pickle2.world('California') - ... wd.set_secret_number(number) - ... pstr = pickle.dumps(wd) - ... wl = pickle.loads(pstr) - ... print wd.greet(), wd.get_secret_number() - ... print wl.greet(), wl.get_secret_number() - Hello from California! 24 - Hello from California! 24 - Hello from California! 42 - Hello from California! 0 - -# Now show that the __dict__ is not taken care of. - >>> wd = pickle2.world('California') - >>> wd.x = 1 - >>> wd.__dict__ - {'x': 1} - >>> try: pstr = pickle.dumps(wd) - ... except RuntimeError, err: print err[0] - ... - Incomplete pickle support (__getstate_manages_dict__ not set) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_pickle2 - return doctest.testmod(test_pickle2) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) - diff --git a/example/test_pickle3.py b/example/test_pickle3.py deleted file mode 100644 index 6ac83b18..00000000 --- a/example/test_pickle3.py +++ /dev/null @@ -1,39 +0,0 @@ -r'''>>> import pickle3 - >>> import re - >>> import pickle - >>> pickle3.world.__module__ - 'pickle3' - >>> pickle3.world.__safe_for_unpickling__ - 1 - >>> pickle3.world.__reduce__() - 'world' - >>> assert re.match( - ... "\(, \('Hello',\), \(\{\}, 0\)\)", - ... repr(pickle3.world('Hello').__reduce__())) - >>> - >>> for number in (24, 42): - ... wd = pickle3.world('California') - ... wd.set_secret_number(number) - ... wd.x = 2 * number - ... wd.y = 'y' * number - ... wd.z = 3. * number - ... pstr = pickle.dumps(wd) - ... wl = pickle.loads(pstr) - ... print wd.greet(), wd.get_secret_number(), wd.x, wd.y, wd.z - ... print wl.greet(), wl.get_secret_number(), wl.x, wl.y, wl.z - Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0 - Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0 - Hello from California! 42 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0 - Hello from California! 0 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_pickle3 - return doctest.testmod(test_pickle3) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) diff --git a/example/test_richcmp1.py b/example/test_richcmp1.py deleted file mode 100644 index d25fcc9c..00000000 --- a/example/test_richcmp1.py +++ /dev/null @@ -1,40 +0,0 @@ -r'''>>> import richcmp1 - >>> d1 = richcmp1.dvect((0, 1, 3, 3, 6, 7)) - >>> d2 = richcmp1.dvect((1, 2, 3, 4, 5, 6)) - >>> print d1.as_tuple() - (0.0, 1.0, 3.0, 3.0, 6.0, 7.0) - >>> print d2.as_tuple() - (1.0, 2.0, 3.0, 4.0, 5.0, 6.0) - >>> print (d1 < d2).as_tuple() - (1, 1, 0, 1, 0, 0) - >>> print (d1 <= d2).as_tuple() - (1, 1, 1, 1, 0, 0) - >>> print (d1 == d2).as_tuple() - (0, 0, 1, 0, 0, 0) - >>> print (d1 != d2).as_tuple() - (1, 1, 0, 1, 1, 1) - >>> print (d1 > d2).as_tuple() - (0, 0, 0, 0, 1, 1) - >>> print (d1 >= d2).as_tuple() - (0, 0, 1, 0, 1, 1) - >>> try: d1 == richcmp1.dvect((1, 2, 3, 4, 5)) - ... except ValueError, e: print str(e) - ... - vectors have different sizes -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_richcmp1 - return doctest.testmod(test_richcmp1) - -if __name__ == '__main__': - import sys - if ( hasattr(sys, 'version_info') - and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1) - or sys.version_info[0] > 2)): - sys.exit(run()[0]) - else: - print "Python version 2.1 or higher required. Test skipped." diff --git a/example/test_richcmp2.py b/example/test_richcmp2.py deleted file mode 100644 index 859928c3..00000000 --- a/example/test_richcmp2.py +++ /dev/null @@ -1,41 +0,0 @@ -r'''>>> import richcmp2 - >>> c1 = richcmp2.code(1) - >>> c2 = richcmp2.code(2) - >>> c3 = richcmp2.code(2) - >>> print c1 == c2 - 0 - >>> print c1 != c2 - 1 - >>> print c2 == c3 - 1 - >>> print c2 != c3 - 0 - >>> print c1 < c2 - 1 - >>> print c1 <= c2 - 1 - >>> print c1 == c2 - 0 - >>> print c1 != c2 - 1 - >>> print c1 > c2 - 0 - >>> print c1 >= c2 - 0 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_richcmp1 - return doctest.testmod(test_richcmp1) - -if __name__ == '__main__': - import sys - if ( hasattr(sys, 'version_info') - and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1) - or sys.version_info[0] > 2)): - sys.exit(run()[0]) - else: - print "Python version 2.1 or higher required. Test skipped." diff --git a/example/test_richcmp3.py b/example/test_richcmp3.py deleted file mode 100644 index a769af17..00000000 --- a/example/test_richcmp3.py +++ /dev/null @@ -1,77 +0,0 @@ -r'''>>> import richcmp3 - >>> - >>> iv = richcmp3.ivect((1,2,3,4,5)) - >>> print iv.as_tuple() - (1, 2, 3, 4, 5) - >>> dv = richcmp3.dvect((2,-2,3,8,-5)) - >>> print dv.as_tuple() - (2.0, -2.0, 3.0, 8.0, -5.0) - >>> - >>> print (iv+dv).as_tuple() - (3.0, 0.0, 6.0, 12.0, 0.0) - >>> print (iv+3).as_tuple() - (4, 5, 6, 7, 8) - >>> print (3+iv).as_tuple() - (4, 5, 6, 7, 8) - >>> - >>> print "vect vs. vect Comparisons:" - vect vs. vect Comparisons: - >>> print (iv < dv).as_tuple() - (1, 0, 0, 1, 0) - >>> print (iv <= dv).as_tuple() - (1, 0, 1, 1, 0) - >>> print (iv == dv).as_tuple() - (0, 0, 1, 0, 0) - >>> print (iv != dv).as_tuple() - (1, 1, 0, 1, 1) - >>> print (iv > dv).as_tuple() - (0, 1, 0, 0, 1) - >>> print (iv >= dv).as_tuple() - (0, 1, 1, 0, 1) - >>> - >>> print "vect vs. scalar Comparisons:" - vect vs. scalar Comparisons: - >>> print (iv < 3).as_tuple() - (1, 1, 0, 0, 0) - >>> print (iv <= 3).as_tuple() - (1, 1, 1, 0, 0) - >>> print (iv == 3).as_tuple() - (0, 0, 1, 0, 0) - >>> print (iv != 3).as_tuple() - (1, 1, 0, 1, 1) - >>> print (iv > 3).as_tuple() - (0, 0, 0, 1, 1) - >>> print (iv >= 3).as_tuple() - (0, 0, 1, 1, 1) - >>> - >>> print "scalar vs. vect Comparisons:" - scalar vs. vect Comparisons: - >>> print (3 < iv).as_tuple() - (0, 0, 0, 1, 1) - >>> print (3 <= iv).as_tuple() - (0, 0, 1, 1, 1) - >>> print (3 == iv).as_tuple() - (0, 0, 1, 0, 0) - >>> print (3 != iv).as_tuple() - (1, 1, 0, 1, 1) - >>> print (3 > iv).as_tuple() - (1, 1, 0, 0, 0) - >>> print (3 >= iv).as_tuple() - (1, 1, 1, 0, 0) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_richcmp3 - return doctest.testmod(test_richcmp3) - -if __name__ == '__main__': - import sys - if ( hasattr(sys, 'version_info') - and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1) - or sys.version_info[0] > 2)): - sys.exit(run()[0]) - else: - print "Python version 2.1 or higher required. Test skipped." diff --git a/example/test_rwgk1.py b/example/test_rwgk1.py deleted file mode 100644 index 631eea3e..00000000 --- a/example/test_rwgk1.py +++ /dev/null @@ -1,19 +0,0 @@ -r'''>>> import rwgk1 - >>> print rwgk1.greet() - hello, world - >>> number = 11 - >>> print number, '*', number, '=', rwgk1.square(number) - 11 * 11 = 121 -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_rwgk1 - return doctest.testmod(test_rwgk1) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) - diff --git a/example/test_simple_vector.py b/example/test_simple_vector.py deleted file mode 100644 index c6a2cd59..00000000 --- a/example/test_simple_vector.py +++ /dev/null @@ -1,42 +0,0 @@ -r'''>>> import simple_vector - >>> v=simple_vector.vector_double() - >>> print v.as_tuple() - () - >>> v=simple_vector.vector_double(5) - >>> print v.as_tuple() - (0.0, 0.0, 0.0, 0.0, 0.0) - >>> print len(v) - 5 - >>> v=simple_vector.vector_double((3,4,5)) - >>> print v.as_tuple() - (3.0, 4.0, 5.0) - >>> print v[1] - 4.0 - >>> v[1] = 40 - >>> print v.as_tuple() - (3.0, 40.0, 5.0) - >>> for e in v: - ... print e - 3.0 - 40.0 - 5.0 - >>> del v[1] - >>> print v.as_tuple() - (3.0, 5.0) - >>> print simple_vector.foo(11).as_tuple() - (0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0) - >>> print simple_vector.bar(12).as_tuple() - (0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0) -''' - -def run(args = None): - if args is not None: - import sys - sys.argv = args - import doctest, test_simple_vector - return doctest.testmod(test_simple_vector) - -if __name__ == '__main__': - import sys - sys.exit(run()[0]) - diff --git a/example/tst_dvect1.py b/example/tst_dvect1.py deleted file mode 100644 index 22315528..00000000 --- a/example/tst_dvect1.py +++ /dev/null @@ -1,20 +0,0 @@ -def f(): - import dvect - dv = dvect.dvect((1,2,3,4,5)) - print dv.as_tuple() - iv = dv.as_ivect() - print iv.as_tuple() - print dvect.const_ivect_reference_as_tuple(iv) - aiv = dvect.ivect_as_auto_ptr(iv) - print dvect.const_ivect_reference_as_tuple(aiv) - siv = dvect.ivect_as_shared_ptr(iv) - print dvect.const_ivect_reference_as_tuple(siv) - print aiv.as_tuple() - print siv.as_tuple() - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() diff --git a/example/tst_dvect2.py b/example/tst_dvect2.py deleted file mode 100644 index 90d381a7..00000000 --- a/example/tst_dvect2.py +++ /dev/null @@ -1,104 +0,0 @@ -def f(broken_auto_ptr): - import dvect - import ivect - # - dv = dvect.dvect((1,2,3,4,5)) - iv = dv.as_ivect() - # - aiv = dvect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_value_ivect_as_tuple' - print ivect.auto_ptr_value_ivect_as_tuple(aiv) - print '2. auto_ptr_value_ivect_as_tuple' - if (not broken_auto_ptr): - print ivect.auto_ptr_value_ivect_as_tuple(aiv) - else: - print None - # - adv = dvect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_value_dvect_as_tuple' - print ivect.auto_ptr_value_dvect_as_tuple(adv) - print '2. auto_ptr_value_dvect_as_tuple' - if (not broken_auto_ptr): - print ivect.auto_ptr_value_dvect_as_tuple(adv) - else: - print None - # - siv = dvect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_value_ivect_as_tuple' - print ivect.shared_ptr_value_ivect_as_tuple(siv) - print '2. shared_ptr_value_ivect_as_tuple' - print ivect.shared_ptr_value_ivect_as_tuple(siv) - # - sdv = dvect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_value_dvect_as_tuple' - print ivect.shared_ptr_value_dvect_as_tuple(sdv) - print '2. shared_ptr_value_dvect_as_tuple' - print ivect.shared_ptr_value_dvect_as_tuple(sdv) - # - aiv = dvect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_reference_ivect_as_tuple' - print ivect.auto_ptr_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_reference_ivect_as_tuple' - print ivect.auto_ptr_reference_ivect_as_tuple(aiv) - # - adv = dvect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_reference_dvect_as_tuple' - print ivect.auto_ptr_reference_dvect_as_tuple(adv) - print '2. auto_ptr_reference_dvect_as_tuple' - print ivect.auto_ptr_reference_dvect_as_tuple(adv) - # - siv = dvect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_reference_ivect_as_tuple' - print ivect.shared_ptr_reference_ivect_as_tuple(siv) - print '2. shared_ptr_reference_ivect_as_tuple' - print ivect.shared_ptr_reference_ivect_as_tuple(siv) - # - sdv = dvect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_reference_dvect_as_tuple' - print ivect.shared_ptr_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_reference_dvect_as_tuple' - print ivect.shared_ptr_reference_dvect_as_tuple(sdv) - # - aiv = dvect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_const_reference_ivect_as_tuple' - print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_const_reference_ivect_as_tuple' - print ivect.auto_ptr_const_reference_ivect_as_tuple(aiv) - # - adv = dvect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_const_reference_dvect_as_tuple' - print ivect.auto_ptr_const_reference_dvect_as_tuple(adv) - print '2. auto_ptr_const_reference_dvect_as_tuple' - print ivect.auto_ptr_const_reference_dvect_as_tuple(adv) - # - siv = dvect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_const_reference_ivect_as_tuple' - print ivect.shared_ptr_const_reference_ivect_as_tuple(siv) - print '2. shared_ptr_const_reference_ivect_as_tuple' - print ivect.shared_ptr_const_reference_ivect_as_tuple(siv) - # - sdv = dvect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_const_reference_dvect_as_tuple' - print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_const_reference_dvect_as_tuple' - print ivect.shared_ptr_const_reference_dvect_as_tuple(sdv) - -if (__name__ == "__main__"): - import sys, string - broken_auto_ptr = 0 - n = 1 - - if len(sys.argv) > 1: - argv = [] - - for x in sys.argv: - if x != '--broken-auto-ptr': - argv.append(x) - broken_auto_ptr = argv != sys.argv - sys.argv = argv - - if len(sys.argv) > 1: - n = string.atoi(sys.argv[1]) - - for i in xrange(n): - f(broken_auto_ptr) diff --git a/example/tst_ivect1.py b/example/tst_ivect1.py deleted file mode 100644 index 7369fdbf..00000000 --- a/example/tst_ivect1.py +++ /dev/null @@ -1,20 +0,0 @@ -def f(): - import ivect - iv = ivect.ivect((1,2,3,4,5)) - print iv.as_tuple() - dv = iv.as_dvect() - print dv.as_tuple() - print ivect.const_dvect_reference_as_tuple(dv) - adv = ivect.dvect_as_auto_ptr(dv) - print ivect.const_dvect_reference_as_tuple(adv) - sdv = ivect.dvect_as_shared_ptr(dv) - print ivect.const_dvect_reference_as_tuple(sdv) - print adv.as_tuple() - print sdv.as_tuple() - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() diff --git a/example/tst_ivect2.py b/example/tst_ivect2.py deleted file mode 100644 index a9e6aeef..00000000 --- a/example/tst_ivect2.py +++ /dev/null @@ -1,104 +0,0 @@ -def f(broken_auto_ptr): - import ivect - import dvect - # - iv = ivect.ivect((1,2,3,4,5)) - dv = iv.as_dvect() - # - adv = ivect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_value_dvect_as_tuple' - print dvect.auto_ptr_value_dvect_as_tuple(adv) - print '2. auto_ptr_value_dvect_as_tuple' - if (not broken_auto_ptr): - print dvect.auto_ptr_value_dvect_as_tuple(adv) - else: - print None - # - aiv = ivect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_value_ivect_as_tuple' - print dvect.auto_ptr_value_ivect_as_tuple(aiv) - print '2. auto_ptr_value_ivect_as_tuple' - if (not broken_auto_ptr): - print dvect.auto_ptr_value_ivect_as_tuple(aiv) - else: - print None - # - sdv = ivect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_value_dvect_as_tuple' - print dvect.shared_ptr_value_dvect_as_tuple(sdv) - print '2. shared_ptr_value_dvect_as_tuple' - print dvect.shared_ptr_value_dvect_as_tuple(sdv) - # - siv = ivect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_value_ivect_as_tuple' - print dvect.shared_ptr_value_ivect_as_tuple(siv) - print '2. shared_ptr_value_ivect_as_tuple' - print dvect.shared_ptr_value_ivect_as_tuple(siv) - # - adv = ivect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_reference_dvect_as_tuple' - print dvect.auto_ptr_reference_dvect_as_tuple(adv) - print '2. auto_ptr_reference_dvect_as_tuple' - print dvect.auto_ptr_reference_dvect_as_tuple(adv) - # - aiv = ivect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_reference_ivect_as_tuple' - print dvect.auto_ptr_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_reference_ivect_as_tuple' - print dvect.auto_ptr_reference_ivect_as_tuple(aiv) - # - sdv = ivect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_reference_dvect_as_tuple' - print dvect.shared_ptr_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_reference_dvect_as_tuple' - print dvect.shared_ptr_reference_dvect_as_tuple(sdv) - # - siv = ivect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_reference_ivect_as_tuple' - print dvect.shared_ptr_reference_ivect_as_tuple(siv) - print '2. shared_ptr_reference_ivect_as_tuple' - print dvect.shared_ptr_reference_ivect_as_tuple(siv) - # - adv = ivect.dvect_as_auto_ptr(dv) - print '1. auto_ptr_const_reference_dvect_as_tuple' - print dvect.auto_ptr_const_reference_dvect_as_tuple(adv) - print '2. auto_ptr_const_reference_dvect_as_tuple' - print dvect.auto_ptr_const_reference_dvect_as_tuple(adv) - # - aiv = ivect.ivect_as_auto_ptr(iv) - print '1. auto_ptr_const_reference_ivect_as_tuple' - print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv) - print '2. auto_ptr_const_reference_ivect_as_tuple' - print dvect.auto_ptr_const_reference_ivect_as_tuple(aiv) - # - sdv = ivect.dvect_as_shared_ptr(dv) - print '1. shared_ptr_const_reference_dvect_as_tuple' - print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv) - print '2. shared_ptr_const_reference_dvect_as_tuple' - print dvect.shared_ptr_const_reference_dvect_as_tuple(sdv) - # - siv = ivect.ivect_as_shared_ptr(iv) - print '1. shared_ptr_const_reference_ivect_as_tuple' - print dvect.shared_ptr_const_reference_ivect_as_tuple(siv) - print '2. shared_ptr_const_reference_ivect_as_tuple' - print dvect.shared_ptr_const_reference_ivect_as_tuple(siv) - -if (__name__ == "__main__"): - import sys, string - broken_auto_ptr = 0 - n = 1 - - if len(sys.argv) > 1: - argv = [] - - for x in sys.argv: - if x != '--broken-auto-ptr': - argv.append(x) - broken_auto_ptr = argv != sys.argv - sys.argv = argv - - if len(sys.argv) > 1: - n = string.atoi(sys.argv[1]) - - for i in xrange(n): - f(broken_auto_ptr) diff --git a/example/tst_noncopyable.py b/example/tst_noncopyable.py deleted file mode 100644 index 155910a5..00000000 --- a/example/tst_noncopyable.py +++ /dev/null @@ -1,16 +0,0 @@ -def f(): - import noncopyable_export - import noncopyable_import - s1 = noncopyable_export.store(1) - print s1.recall() - s2 = noncopyable_export.store(2) - print s2.recall() - s3 = noncopyable_import.add_stores(s1, s2) - print s3.recall() - -if (__name__ == "__main__"): - import sys, string - n = 1 - if (len(sys.argv) > 1): n = string.atoi(sys.argv[1]) - for i in xrange(n): - f() diff --git a/example/vector_wrapper.h b/example/vector_wrapper.h deleted file mode 100644 index 6a571343..00000000 --- a/example/vector_wrapper.h +++ /dev/null @@ -1,117 +0,0 @@ -// Based on wrapVector.hh by Mike Owen and Jeff Johnson. -// http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/spheral/src/src/BPLWraps/CXXWraps/ - -#ifndef BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H -#define BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H - -#include - -namespace example { - - // A wrapper is used to define additional constructors. This wrapper - // is templated on the template parameter for its corresponding vector. - template - struct vector_wrapper: std::vector - { - // Tell the compiler how to convert a base class object to - // this wrapper object. - vector_wrapper(PyObject*, - const std::vector& vec): - std::vector(vec) {} - - vector_wrapper(PyObject* self): - std::vector() {} - - vector_wrapper(PyObject* self, - std::size_t n): - std::vector(n) {} - - vector_wrapper(PyObject* self, - boost::python::tuple tuple): - std::vector(tuple.size()) - { - std::vector::iterator vec = begin(); - for (std::size_t i = 0; i < tuple.size(); i++) - vec[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(), - boost::python::type()); - } - }; - - void raise_vector_IndexError() { - PyErr_SetString(PyExc_IndexError, "vector index out of range"); - boost::python::throw_error_already_set(); - } - - template - struct vector_access - { - static - T - getitem(const std::vector& vec, - std::size_t key) - { - if (key >= vec.size()) raise_vector_IndexError(); - return vec[key]; - } - - static - void - setitem(std::vector& vec, - std::size_t key, - const T &value) - { - if (key >= vec.size()) raise_vector_IndexError(); - vec[key] = value; - } - - static - void - delitem(std::vector& vec, - std::size_t key) - { - if (key >= vec.size()) raise_vector_IndexError(); - vec.erase(vec.begin() + key); - } - - // Convert vector to a regular Python tuple. - static - boost::python::tuple - as_tuple(const std::vector& vec) - { - // Create a python type of size vec.size(). - boost::python::tuple t(vec.size()); - for (std::size_t i = 0; i < vec.size(); i++) { - t.set_item(i, - boost::python::ref(BOOST_PYTHON_CONVERSION::to_python(vec[i]))); - } - return t; - } - }; - - // This function will build a vector and add it to the given - // module with the given name. - template - boost::python::class_builder, vector_wrapper > - wrap_vector(boost::python::module_builder& module, - const std::string& vector_name, - const T&) - { - // Add the vector to the module. - boost::python::class_builder, vector_wrapper > - py_vector(module, vector_name.c_str()); - - // Define constructors and methods for the vector. - py_vector.def(boost::python::constructor<>()); - py_vector.def(boost::python::constructor()); - py_vector.def(boost::python::constructor()); - py_vector.def(&std::vector::size, "__len__"); - py_vector.def(&vector_access::getitem, "__getitem__"); - py_vector.def(&vector_access::setitem, "__setitem__"); - py_vector.def(&vector_access::delitem, "__delitem__"); - py_vector.def(&vector_access::as_tuple, "as_tuple"); - - return py_vector; - } -} - -#endif // BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H diff --git a/include/boost/python/callback.hpp b/include/boost/python/callback.hpp deleted file mode 100644 index 7240b5b7..00000000 --- a/include/boost/python/callback.hpp +++ /dev/null @@ -1,829 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file was generated for 10-argument python callbacks by gen_callback.python - -#ifndef CALLBACK_DWA_052100_H_ -# define CALLBACK_DWA_052100_H_ - -# include -# include - -namespace boost { namespace python { - -namespace detail { - template - inline void callback_adjust_refcount(PyObject*, type) {} - - inline void callback_adjust_refcount(PyObject* p, type) - { Py_INCREF(p); } -} - -// Calling Python from C++ -template -struct callback -{ - static R call_method(PyObject* self, const char* name) - { - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("()"))); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - static R call(PyObject* self) - { - ref result(PyEval_CallFunction(self, const_cast("()"))); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1) - { - ref p1(to_python(a1)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(O)"), - p1.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1) - { - ref p1(to_python(a1)); - ref result(PyEval_CallFunction(self, const_cast("(O)"), - p1.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OO)"), - p1.get(), - p2.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref result(PyEval_CallFunction(self, const_cast("(OO)"), - p1.get(), - p2.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOO)"), - p1.get(), - p2.get(), - p3.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref result(PyEval_CallFunction(self, const_cast("(OOO)"), - p1.get(), - p2.get(), - p3.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref result(PyEval_CallFunction(self, const_cast("(OOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get(), - p10.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - - template - static R call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get(), - p10.get())); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } -}; - -// This specialization wouldn't be needed, but MSVC6 doesn't correctly allow the following: -// void g(); -// void f() { return g(); } -template <> -struct callback -{ - - static void call_method(PyObject* self, const char* name) - { - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("()"))); - } - - static void call(PyObject* self) - { - ref result(PyEval_CallFunction(self, const_cast("()"))); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1) - { - ref p1(to_python(a1)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(O)"), - p1.get())); - } - - template - static void call(PyObject* self, const A1& a1) - { - ref p1(to_python(a1)); - ref result(PyEval_CallFunction(self, const_cast("(O)"), - p1.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OO)"), - p1.get(), - p2.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref result(PyEval_CallFunction(self, const_cast("(OO)"), - p1.get(), - p2.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOO)"), - p1.get(), - p2.get(), - p3.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref result(PyEval_CallFunction(self, const_cast("(OOO)"), - p1.get(), - p2.get(), - p3.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref result(PyEval_CallFunction(self, const_cast("(OOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get())); - } - - template - static void call_method(PyObject* self, const char* name, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(OOOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get(), - p10.get())); - } - - template - static void call(PyObject* self, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) - { - ref p1(to_python(a1)); - ref p2(to_python(a2)); - ref p3(to_python(a3)); - ref p4(to_python(a4)); - ref p5(to_python(a5)); - ref p6(to_python(a6)); - ref p7(to_python(a7)); - ref p8(to_python(a8)); - ref p9(to_python(a9)); - ref p10(to_python(a10)); - ref result(PyEval_CallFunction(self, const_cast("(OOOOOOOOOO)"), - p1.get(), - p2.get(), - p3.get(), - p4.get(), - p5.get(), - p6.get(), - p7.get(), - p8.get(), - p9.get(), - p10.get())); - } -}; - -// Make it a compile-time error to try to return a const char* from a virtual -// function. The standard conversion -// -// from_python(PyObject* string, boost::python::type) -// -// returns a pointer to the character array which is internal to string. The -// problem with trying to do this in a standard callback function is that the -// Python string would likely be destroyed upon return from the calling function -// (boost::python::callback::call[_method]) when its reference count is -// decremented. If you absolutely need to do this and you're sure it's safe (it -// usually isn't), you can use -// -// boost::python::string result(boost::python::callback::call[_method](...args...)); -// ...result.c_str()... // access the char* array -template <> -struct callback -{ - // Try hard to generate a readable error message - typedef struct unsafe_since_python_string_may_be_destroyed {} call, call_method; -}; - -}} // namespace boost::python - -#endif // CALLBACK_DWA_052100_H_ diff --git a/include/boost/python/caller.hpp b/include/boost/python/caller.hpp deleted file mode 100644 index 35b2d618..00000000 --- a/include/boost/python/caller.hpp +++ /dev/null @@ -1,1279 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file generated for 10-argument member functions and 11-argument free -// functions by gen_caller.python - -#ifndef CALLER_DWA05090_H_ -# define CALLER_DWA05090_H_ - -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// Calling C++ from Python -template -struct caller -{ - template - static PyObject* call(R (T::*pmf)(), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)()); - } - - template - static PyObject* call(R (T::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type()))); - } - - - template - static PyObject* call(R (T::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)()); - } - - template - static PyObject* call(R (T::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()))); - } - - template - static PyObject* call(R (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type()))); - } - - // Free functions - static PyObject* call(R (*f)(), PyObject* args, PyObject* /* keywords */ ) { - if (!PyArg_ParseTuple(args, const_cast(""))) - return 0; - return to_python(f()); - } - - template - static PyObject* call(R (*f)(A1), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("O"), &a1)) - return 0; - return to_python(f(from_python(a1, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OO"), &a1, &a2)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &a1, &a2, &a3)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &a1, &a2, &a3, &a4)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &a1, &a2, &a3, &a4, &a5)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6, A7), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6, A7, A8), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type()))); - } - - template - static PyObject* call(R (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - PyObject* a11; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11)) - return 0; - return to_python(f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type()), - from_python(a11, type()))); - } - -}; - -template <> -struct caller -{ - template - static PyObject* call(void (T::*pmf)(), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type())); - return detail::none(); - } - - - template - static PyObject* call(void (T::*pmf)() const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &a1)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &self, &a1, &a2, &a3, &a4)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &self, &a1, &a2, &a3, &a4, &a5)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type())); - return detail::none(); - } - - template - static PyObject* call(void (T::*pmf)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &self, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - T& target = from_python(self, type()); - (target.*pmf)(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type())); - return detail::none(); - } - - - // Free functions - static PyObject* call(void (*f)(), PyObject* args, PyObject* /* keywords */ ) { - if (!PyArg_ParseTuple(args, const_cast(""))) - return 0; - f(); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("O"), &a1)) - return 0; - f(from_python(a1, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OO"), &a1, &a2)) - return 0; - f(from_python(a1, type()), - from_python(a2, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &a1, &a2, &a3)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &a1, &a2, &a3, &a4)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &a1, &a2, &a3, &a4, &a5)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6, A7), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6, A7, A8), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type())); - return detail::none(); - } - - template - static PyObject* call(void (*f)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11), PyObject* args, PyObject* /* keywords */ ) { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - PyObject* a11; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11)) - return 0; - f(from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()), - from_python(a4, type()), - from_python(a5, type()), - from_python(a6, type()), - from_python(a7, type()), - from_python(a8, type()), - from_python(a9, type()), - from_python(a10, type()), - from_python(a11, type())); - return detail::none(); - } - -}; - -}} // namespace boost::python - -#endif diff --git a/include/boost/python/class_builder.hpp b/include/boost/python/class_builder.hpp deleted file mode 100644 index fe2a7b74..00000000 --- a/include/boost/python/class_builder.hpp +++ /dev/null @@ -1,182 +0,0 @@ -// Revision History: -// Mar 03 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve) - -#ifndef CLASS_WRAPPER_DWA101000_H_ -# define CLASS_WRAPPER_DWA101000_H_ - -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { - -// Syntactic sugar to make wrapping classes more convenient -template > -class class_builder - : python_extension_class_converters // Works around MSVC6.x/GCC2.95.2 bug described below -{ - public: - class_builder(module_builder& module, const char* name) - : m_class(new detail::extension_class(name)) - { - module.add(ref(as_object(m_class.get()), ref::increment_count), name); - } - - template - class_builder(class_builder& cls, const char* name) - : m_class(new detail::extension_class(name)) - { - cls.add(ref(as_object(m_class.get()), ref::increment_count), name); - } - - template - class_builder(detail::extension_class* cls, - const char* name) - : m_class(new detail::extension_class(name)) - { - cls->set_attribute(name, - ref(as_object(m_class.get()), ref::increment_count)); - } - - ~class_builder() - {} - - inline void dict_defines_state() { - add(ref(BOOST_PYTHON_CONVERSION::to_python(1)), "__dict_defines_state__"); - } - inline void getstate_manages_dict() { - add(ref(BOOST_PYTHON_CONVERSION::to_python(1)), "__getstate_manages_dict__"); - } - - // define constructors - template - void def(const signature& s) - { m_class->def(s); } - - // export heterogeneous reverse-argument operators - // (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::left_operand()); - template - void def(operators o1, left_operand o2) - { m_class->def(o1, o2); } - - // export heterogeneous operators (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::right_operand()); - template - void def(operators o1, right_operand o2) - { m_class->def(o1, o2); } - - // define a function that passes Python arguments and keywords - // to C++ verbatim (as a 'tuple const &' and 'dictionary const &' - // respectively). This is useful for manual argument passing. - // It's also the only possibility to pass keyword arguments to C++. - // Fn must have a signatur that is compatible to - // PyObject * (*)(PyObject * aTuple, PyObject * aDictionary) - template - void def_raw(Fn fn, const char* name) - { m_class->def_raw(fn, name); } - - // define member functions. In fact this works for free functions, too - - // they act like static member functions, or if they start with the - // appropriate self argument (as a pointer or reference), they can be used - // just like ordinary member functions -- just like Python! - template - void def(Fn fn, const char* name) - { m_class->def(fn, name); } - - // Define a virtual member function with a default implementation. - // default_fn should be a function which provides the default implementation. - // Be careful that default_fn does not in fact call fn virtually! - template - void def(Fn fn, const char* name, DefaultFn default_fn) - { m_class->def(fn, name, default_fn); } - - // Provide a function which implements x., reading from the given - // member (pm) of the T obj - template - void def_getter(MemberType T::*pm, const char* name) - { m_class->def_getter(pm, name); } - - // Provide a function which implements assignment to x., writing to - // the given member (pm) of the T obj - template - void def_setter(MemberType T::*pm, const char* name) - { m_class->def_getter(pm, name); } - - // Expose the given member (pm) of the T obj as a read-only attribute - template - void def_readonly(MemberType T::*pm, const char* name) - { m_class->def_readonly(pm, name); } - - // Expose the given member (pm) of the T obj as a read/write attribute - template - void def_read_write(MemberType T::*pm, const char* name) - { m_class->def_read_write(pm, name); } - - // define the standard coercion needed for operator overloading - void def_standard_coerce() - { m_class->def_standard_coerce(); } - - // declare the given class a base class of this one and register - // conversion functions - template - void declare_base(class_builder const & base) - { - m_class->declare_base(base.get_extension_class()); - } - - // declare the given class a base class of this one and register - // upcast conversion function - template - void declare_base(class_builder const & base, without_downcast_t) - { - m_class->declare_base(base.get_extension_class(), without_downcast); - } - - // get the embedded ExtensioClass object - detail::extension_class * get_extension_class() const - { - return m_class.get(); - } - - // set an arbitrary attribute. Useful for non-function class data members, - // e.g. enums - void add(PyObject* x, const char* name) - { m_class->set_attribute(name, x); } - void add(ref x, const char* name) - { m_class->set_attribute(name, x); } - private: - // declare the given class a base class of this one and register - // conversion functions - template - void declare_base(detail::extension_class * base) - { - m_class->declare_base(base); - } - - // declare the given class a base class of this one and register - // upcast conversion function - template - void declare_base(detail::extension_class * base, without_downcast_t) - { - m_class->declare_base(base, without_downcast); - } - - reference > m_class; -}; - -// The bug mentioned at the top of this file is that on certain compilers static -// global functions declared within the body of a class template will only be -// generated when the class template is constructed, and when (for some reason) -// the construction does not occur via a new-expression. Otherwise, we could -// rely on the initialization of the m_class data member to cause all of the -// to_/from_python functions to come into being. - -}} // namespace boost::python - -#endif // CLASS_WRAPPER_DWA101000_H_ diff --git a/include/boost/python/classes.hpp b/include/boost/python/classes.hpp deleted file mode 100644 index 22fcb3d2..00000000 --- a/include/boost/python/classes.hpp +++ /dev/null @@ -1,677 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef SUBCLASS_DWA051500_H_ -# define SUBCLASS_DWA051500_H_ - -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// A simple type which acts something like a built-in Python class obj. -class BOOST_PYTHON_DECL instance - : public boost::python::detail::python_object -{ - public: - instance(PyTypeObject* class_); - ~instance(); - - // Standard Python functions. - PyObject* repr(); - int compare(PyObject*); - PyObject* str(); - long hash(); - PyObject* call(PyObject* args, PyObject* keywords); - PyObject* getattr(const char* name, bool use_special_function = true); - int setattr(const char* name, PyObject* value); - - // Mapping methods - int length(); - PyObject* get_subscript(PyObject* key); - void set_subscript(PyObject* key, PyObject* value); - - // Sequence methods - PyObject* get_slice(int start, int finish); - void set_slice(int start, int finish, PyObject* value); - - // Number methods - PyObject* add(PyObject* other); - PyObject* subtract(PyObject* other); - PyObject* multiply(PyObject* other); - PyObject* divide(PyObject* other); - PyObject* remainder(PyObject* other); - PyObject* divmod(PyObject* other); - PyObject* power(PyObject*, PyObject*); - PyObject* negative(); - PyObject* positive(); - PyObject* absolute(); - int nonzero(); - PyObject* invert(); - PyObject* lshift(PyObject* other); - PyObject* rshift(PyObject* other); - PyObject* do_and(PyObject* other); - PyObject* do_xor(PyObject* other); - PyObject* do_or(PyObject* other); - int coerce(PyObject**, PyObject**); - PyObject* as_int(); - PyObject* as_long(); - PyObject* as_float(); - PyObject* oct(); - PyObject* hex(); - - // Rich comparisons - PyObject* lt(PyObject* other); - PyObject* le(PyObject* other); - PyObject* eq(PyObject* other); - PyObject* ne(PyObject* other); - PyObject* gt(PyObject* other); - PyObject* ge(PyObject* other); - - // Inplace operations. - PyObject* inplace_add(PyObject* other); - PyObject* inplace_subtract(PyObject* other); - PyObject* inplace_multiply(PyObject* other); - PyObject* inplace_divide(PyObject* other); - PyObject* inplace_remainder(PyObject* other); - PyObject* inplace_power(PyObject* exponent, PyObject* modulus); - PyObject* inplace_lshift(PyObject* other); - PyObject* inplace_rshift(PyObject* other); - PyObject* inplace_and(PyObject* other); - PyObject* inplace_or(PyObject* other); - PyObject* inplace_xor(PyObject* other); - - private: // noncopyable, without the size bloat - instance(const instance&); - void operator=(const instance&); - - private: // helper functions - int setattr_dict(PyObject* value); - - private: - dictionary m_name_space; -}; - -template class meta_class; - -namespace detail { - class BOOST_PYTHON_DECL class_base : public type_object_base - { - public: - class_base(PyTypeObject* meta_class_obj, string name, tuple bases, const dictionary& name_space); - tuple bases() const; - string name() const; - dictionary& dict(); - - // Standard Python functions. - PyObject* getattr(const char* name); - int setattr(const char* name, PyObject* value); - PyObject* repr() const; - void add_base(ref base); - - protected: - bool initialize_instance(instance* obj, PyObject* args, PyObject* keywords); - - private: // virtual functions - // Subclasses should override this to delete the particular obj type - virtual void delete_instance(PyObject*) const = 0; - - private: // boost::python::type_object_base required interface implementation - void instance_dealloc(PyObject*) const; // subclasses should not override this - - private: // noncopyable, without the size bloat - class_base(const class_base&); - void operator=(const class_base&); - - private: - string m_name; - tuple m_bases; - dictionary m_name_space; - }; - - void enable_named_method(class_base* type_obj, const char* name); -} - -// A type which acts a lot like a built-in Python class. T is the obj type, -// so class_t is a very simple "class-alike". -template -class class_t : public boost::python::detail::class_base -{ - public: - class_t(meta_class* meta_class_obj, string name, tuple bases, const dictionary& name_space); - ~class_t(); - - // Standard Python functions. - PyObject* call(PyObject* args, PyObject* keywords); - - private: // Implement mapping methods on instances - PyObject* instance_repr(PyObject*) const; - int instance_compare(PyObject*, PyObject* other) const; - PyObject* instance_str(PyObject*) const; - long instance_hash(PyObject*) const; - int instance_mapping_length(PyObject*) const; - PyObject* instance_mapping_subscript(PyObject*, PyObject*) const; - int instance_mapping_ass_subscript(PyObject*, PyObject*, PyObject*) const; - - private: // Implement sequence methods on instances - int instance_sequence_length(PyObject*) const; - PyObject* instance_sequence_item(PyObject* obj, int n) const; - int instance_sequence_ass_item(PyObject* obj, int n, PyObject* value) const; - PyObject* instance_sequence_slice(PyObject*, int start, int finish) const; - int instance_sequence_ass_slice(PyObject*, int start, int finish, PyObject* value) const; - - private: // Implement number methods on instances - PyObject* instance_number_add(PyObject*, PyObject*) const; - PyObject* instance_number_subtract(PyObject*, PyObject*) const; - PyObject* instance_number_multiply(PyObject*, PyObject*) const; - PyObject* instance_number_divide(PyObject*, PyObject*) const; - PyObject* instance_number_remainder(PyObject*, PyObject*) const; - PyObject* instance_number_divmod(PyObject*, PyObject*) const; - PyObject* instance_number_power(PyObject*, PyObject*, PyObject*) const; - PyObject* instance_number_negative(PyObject*) const; - PyObject* instance_number_positive(PyObject*) const; - PyObject* instance_number_absolute(PyObject*) const; - int instance_number_nonzero(PyObject*) const; - PyObject* instance_number_invert(PyObject*) const; - PyObject* instance_number_lshift(PyObject*, PyObject*) const; - PyObject* instance_number_rshift(PyObject*, PyObject*) const; - PyObject* instance_number_and(PyObject*, PyObject*) const; - PyObject* instance_number_xor(PyObject*, PyObject*) const; - PyObject* instance_number_or(PyObject*, PyObject*) const; - int instance_number_coerce(PyObject*, PyObject**, PyObject**) const; - PyObject* instance_number_int(PyObject*) const; - PyObject* instance_number_long(PyObject*) const; - PyObject* instance_number_float(PyObject*) const; - PyObject* instance_number_oct(PyObject*) const; - PyObject* instance_number_hex(PyObject*) const; - - PyObject* instance_number_inplace_add(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const; - PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_and(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_or(PyObject*, PyObject*) const; - PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const; - - private: // Implement rich comparisons - PyObject* instance_lt(PyObject*, PyObject*) const; - PyObject* instance_le(PyObject*, PyObject*) const; - PyObject* instance_eq(PyObject*, PyObject*) const; - PyObject* instance_ne(PyObject*, PyObject*) const; - PyObject* instance_gt(PyObject*, PyObject*) const; - PyObject* instance_ge(PyObject*, PyObject*) const; - - private: // Miscellaneous "special" methods - PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* keywords) const; - PyObject* instance_getattr(PyObject* obj, const char* name) const; - int instance_setattr(PyObject* obj, const char* name, PyObject* value) const; - - private: // Implementation of boost::python::detail::class_base required interface - void delete_instance(PyObject*) const; -}; - -// The type of a class_t object. -template -class meta_class - : public boost::python::detail::reprable< - boost::python::detail::callable< - boost::python::detail::getattrable< - boost::python::detail::setattrable< - boost::python::detail::type_object > > > > >, - private boost::noncopyable -{ - public: - meta_class(); - - // Standard Python functions. - PyObject* call(PyObject* args, PyObject* keywords); - - struct type_object - : boost::python::detail::singleton > > - { - type_object() : singleton_base(&PyType_Type) {} - }; -}; - -// -// Member function implementations. -// -template -meta_class::meta_class() - : properties(type_object::instance()) -{ -} - -template -class_t::class_t(meta_class* meta_class_obj, string name, tuple bases, const dictionary& name_space) - : boost::python::detail::class_base(meta_class_obj, name, bases, name_space) -{ -} - -template -class_t::~class_t() -{ -} - -template -void class_t::delete_instance(PyObject* obj) const -{ - delete downcast(obj); -} - -template -PyObject* class_t::call(PyObject* args, PyObject* keywords) -{ - reference result(new T(this)); - if (!this->initialize_instance(result.get(), args, keywords)) - return 0; - else - return result.release(); -} - -template -PyObject* class_t::instance_repr(PyObject* obj) const -{ - return downcast(obj)->repr(); -} - -template -int class_t::instance_compare(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->compare(other); -} - -template -PyObject* class_t::instance_str(PyObject* obj) const -{ - return downcast(obj)->str(); -} - -template -long class_t::instance_hash(PyObject* obj) const -{ - return downcast(obj)->hash(); -} - -template -int class_t::instance_mapping_length(PyObject* obj) const -{ - return downcast(obj)->length(); -} - -template -int class_t::instance_sequence_length(PyObject* obj) const -{ - return downcast(obj)->length(); -} - -template -PyObject* class_t::instance_mapping_subscript(PyObject* obj, PyObject* key) const -{ - return downcast(obj)->get_subscript(key); -} - -template -PyObject* class_t::instance_sequence_item(PyObject* obj, int n) const -{ - ref key(to_python(n)); - return downcast(obj)->get_subscript(key.get()); -} - -template -int class_t::instance_sequence_ass_item(PyObject* obj, int n, PyObject* value) const -{ - ref key(to_python(n)); - downcast(obj)->set_subscript(key.get(), value); - return 0; -} - -template -int class_t::instance_mapping_ass_subscript(PyObject* obj, PyObject* key, PyObject* value) const -{ - downcast(obj)->set_subscript(key, value); - return 0; -} - -bool BOOST_PYTHON_DECL adjust_slice_indices(PyObject* obj, int& start, int& finish); - -template -PyObject* class_t::instance_sequence_slice(PyObject* obj, int start, int finish) const -{ - if (!adjust_slice_indices(obj, start, finish)) - return 0; - return downcast(obj)->get_slice(start, finish); -} - -template -int class_t::instance_sequence_ass_slice(PyObject* obj, int start, int finish, PyObject* value) const -{ - if (!adjust_slice_indices(obj, start, finish)) - return -1; - downcast(obj)->set_slice(start, finish, value); - return 0; -} - -template -PyObject* class_t::instance_call(PyObject* obj, PyObject* args, PyObject* keywords) const -{ - return downcast(obj)->call(args, keywords); -} - -template -PyObject* class_t::instance_getattr(PyObject* obj, const char* name) const -{ - return downcast(obj)->getattr(name); -} - - -template -int class_t::instance_setattr(PyObject* obj, const char* name, PyObject* value) const -{ - return downcast(obj)->setattr(name, value); -} - -template -PyObject* class_t::instance_number_add(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->add(other); -} - -template -PyObject* class_t::instance_number_subtract(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->subtract(other); -} - -template -PyObject* class_t::instance_number_multiply(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->multiply(other); -} - -template -PyObject* class_t::instance_number_divide(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->divide(other); -} - -template -PyObject* class_t::instance_number_remainder(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->remainder(other); -} - -template -PyObject* class_t::instance_number_divmod(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->divmod(other); -} - -template -PyObject* class_t::instance_number_power(PyObject* obj, PyObject* exponent, PyObject* modulus) const -{ - return downcast(obj)->power(exponent, modulus); -} - -template -PyObject* class_t::instance_number_negative(PyObject* obj) const -{ - return downcast(obj)->negative(); -} - -template -PyObject* class_t::instance_number_positive(PyObject* obj) const -{ - return downcast(obj)->positive(); -} - -template -PyObject* class_t::instance_number_absolute(PyObject* obj) const -{ - return downcast(obj)->absolute(); -} - -template -int class_t::instance_number_nonzero(PyObject* obj) const -{ - return downcast(obj)->nonzero(); -} - -template -PyObject* class_t::instance_number_invert(PyObject* obj) const -{ - return downcast(obj)->invert(); -} - -template -PyObject* class_t::instance_number_lshift(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->lshift(other); -} - -template -PyObject* class_t::instance_number_rshift(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->rshift(other); -} - -template -PyObject* class_t::instance_number_and(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->do_and(other); -} - -template -PyObject* class_t::instance_number_xor(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->do_xor(other); -} - -template -PyObject* class_t::instance_number_or(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->do_or(other); -} - -template -int class_t::instance_number_coerce(PyObject* obj, PyObject** x, PyObject** y) const -{ - return downcast(obj)->coerce(x, y); -} - -template -PyObject* class_t::instance_number_int(PyObject* obj) const -{ - return downcast(obj)->as_int(); -} - -template -PyObject* class_t::instance_number_long(PyObject* obj) const -{ - return downcast(obj)->as_long(); -} - -template -PyObject* class_t::instance_number_float(PyObject* obj) const -{ - return downcast(obj)->as_float(); -} - -template -PyObject* class_t::instance_number_oct(PyObject* obj) const -{ - return downcast(obj)->oct(); -} - -template -PyObject* class_t::instance_number_hex(PyObject* obj) const -{ - return downcast(obj)->hex(); -} - -template -PyObject* class_t::instance_number_inplace_add(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_add(other); -} - -template -PyObject* class_t::instance_number_inplace_subtract(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_subtract(other); -} - -template -PyObject* class_t::instance_number_inplace_multiply(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_multiply(other); -} - -template -PyObject* class_t::instance_number_inplace_divide(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_divide(other); -} - -template -PyObject* class_t::instance_number_inplace_remainder(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_remainder(other); -} - -template -PyObject* class_t::instance_number_inplace_power(PyObject* obj, PyObject* exponent, PyObject* modulus) const -{ - return downcast(obj)->inplace_power(exponent, modulus); -} - -template -PyObject* class_t::instance_number_inplace_lshift(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_lshift(other); -} - -template -PyObject* class_t::instance_number_inplace_rshift(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_rshift(other); -} - -template -PyObject* class_t::instance_number_inplace_and(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_and(other); -} - -template -PyObject* class_t::instance_number_inplace_or(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_or(other); -} - -template -PyObject* class_t::instance_number_inplace_xor(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->inplace_xor(other); -} - -template -PyObject* class_t::instance_lt(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->lt(other); -} - -template -PyObject* class_t::instance_le(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->le(other); -} - -template -PyObject* class_t::instance_eq(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->eq(other); -} - -template -PyObject* class_t::instance_ne(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->ne(other); -} - -template -PyObject* class_t::instance_gt(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->gt(other); -} - -template -PyObject* class_t::instance_ge(PyObject* obj, PyObject* other) const -{ - return downcast(obj)->ge(other); -} - -namespace detail { - inline dictionary& class_base::dict() - { - return m_name_space; - } - - inline tuple class_base::bases() const - { - return m_bases; - } -} - -template -PyObject* meta_class::call(PyObject* args, PyObject* /*keywords*/) -{ - PyObject* name; - PyObject* bases; - PyObject* name_space; - - if (!PyArg_ParseTuple(args, const_cast("O!O!O!"), - &PyString_Type, &name, - &PyTuple_Type, &bases, - &PyDict_Type, &name_space)) - { - return 0; - } - - return as_object( - new class_t(this, string(ref(name, ref::increment_count)), - tuple(ref(bases, ref::increment_count)), - dictionary(ref(name_space, ref::increment_count))) - ); -} - -namespace detail { - const string& setattr_string(); - const string& getattr_string(); - const string& delattr_string(); - - inline string class_base::name() const - { - return m_name; - } -} - - -}} // namespace boost::python -#endif diff --git a/include/boost/python/conversions.hpp b/include/boost/python/conversions.hpp deleted file mode 100644 index 83823494..00000000 --- a/include/boost/python/conversions.hpp +++ /dev/null @@ -1,415 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// 31 Jul 01 convert int/double to complex (Peter Bienstman) -// 04 Mar 01 Fixed std::complex<> stuff to work with MSVC (David Abrahams) -// 03 Mar 01 added: converters for [plain] char and std::complex -// (Ralf W. Grosse-Kunstleve) - -#ifndef METHOD_DWA122899_H_ -# define METHOD_DWA122899_H_ - -# include -# include -# include -# include -# include -# include -# include - -# ifdef BOOST_MSVC6_OR_EARLIER -# pragma warning(push) -# pragma warning(disable:4275) // disable a bogus warning caused by -# endif - -# include - -# ifdef BOOST_MSVC6_OR_EARLIER -# pragma warning(pop) -# endif - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround - -// This can be instantiated on an enum to provide the to_python/from_python -// conversions, provided the values can fit in a long. -template -class py_enum_as_int_converters -{ - friend EnumType from_python(PyObject* x, boost::python::type) - { - return static_cast( - from_python(x, boost::python::type())); - } - - friend EnumType from_python(PyObject* x, boost::python::type) - { - return static_cast( - from_python(x, boost::python::type())); - } - - friend PyObject* to_python(EnumType x) - { - return to_python(static_cast(x)); - } -}; -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { -template class enum_as_int_converters - : public BOOST_PYTHON_CONVERSION::py_enum_as_int_converters {}; - -template class wrapped_pointer; - -//#pragma warn_possunwant off -inline void decref_impl(PyObject* p) { Py_DECREF(p); } -inline void xdecref_impl(PyObject* p) { Py_XDECREF(p); } -//#pragma warn_possunwant reset - -template -inline void decref(T* p) -{ - char* const raw_p = reinterpret_cast(p); - char* const p_base = raw_p - offsetof(PyObject, ob_refcnt); - decref_impl(reinterpret_cast(p_base)); -} - -template -inline void xdecref(T* p) -{ - char* const raw_p = reinterpret_cast(p); - char* const p_base = raw_p - offsetof(PyObject, ob_refcnt); - xdecref_impl(reinterpret_cast(p_base)); -} - -namespace detail { - - void expect_complex(PyObject*); - - template - std::complex complex_from_python(PyObject* p, boost::python::type) - { - if (PyInt_Check(p)) return std::complex(PyInt_AS_LONG(p)); - if (PyLong_Check(p)) return std::complex(PyLong_AsDouble(p)); - if (PyFloat_Check(p)) return std::complex(PyFloat_AS_DOUBLE(p)); - - expect_complex(p); - - return std::complex( - static_cast(PyComplex_RealAsDouble(p)), - static_cast(PyComplex_ImagAsDouble(p))); - } - - template - PyObject* complex_to_python(const std::complex& sc) { - Py_complex pcc; - pcc.real = sc.real(); - pcc.imag = sc.imag(); - return PyComplex_FromCComplex(pcc); - } - -} - -}} // namespace boost::python - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -// -// Converters -// -PyObject* to_python(long); -BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type); -long from_python(PyObject* p, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(unsigned long); -BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type); -unsigned long from_python(PyObject* p, boost::python::type); - -PyObject* to_python(int); -BOOST_PYTHON_DECL int from_python(PyObject*, boost::python::type); -int from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(unsigned int); -BOOST_PYTHON_DECL unsigned int from_python(PyObject*, boost::python::type); -unsigned int from_python(PyObject*, boost::python::type); - -PyObject* to_python(short); -BOOST_PYTHON_DECL short from_python(PyObject*, boost::python::type); -short from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(unsigned short); -BOOST_PYTHON_DECL unsigned short from_python(PyObject*, boost::python::type); -unsigned short from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(char); -BOOST_PYTHON_DECL char from_python(PyObject*, boost::python::type); -char from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(signed char); -BOOST_PYTHON_DECL signed char from_python(PyObject*, boost::python::type); -signed char from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(unsigned char); -BOOST_PYTHON_DECL unsigned char from_python(PyObject*, boost::python::type); -unsigned char from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL float from_python(PyObject*, boost::python::type); -BOOST_PYTHON_DECL double from_python(PyObject*, boost::python::type); - -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 -PyObject* to_python(float); -PyObject* to_python(double); -# else -BOOST_PYTHON_DECL PyObject* to_python(float); -BOOST_PYTHON_DECL PyObject* to_python(double); -# endif -float from_python(PyObject*, boost::python::type); - -double from_python(PyObject*, boost::python::type); - -PyObject* to_python(bool); -BOOST_PYTHON_DECL bool from_python(PyObject*, boost::python::type); -bool from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(void); -BOOST_PYTHON_DECL void from_python(PyObject*, boost::python::type); - -PyObject* to_python(const char* s); -BOOST_PYTHON_DECL const char* from_python(PyObject*, boost::python::type); - -BOOST_PYTHON_DECL PyObject* to_python(const std::string& s); -BOOST_PYTHON_DECL std::string from_python(PyObject*, boost::python::type); -std::string from_python(PyObject*, boost::python::type); - -inline PyObject* to_python(const std::complex& x) -{ - return boost::python::detail::complex_to_python(x); -} - -inline PyObject* to_python(const std::complex& x) -{ - return boost::python::detail::complex_to_python(x); -} - -inline std::complex from_python(PyObject* p, - boost::python::type >) { - return boost::python::detail::complex_from_python(p, boost::python::type()); -} - -inline std::complex from_python(PyObject* p, - boost::python::type&>) { - return boost::python::detail::complex_from_python(p, boost::python::type()); -} - -inline std::complex from_python(PyObject* p, - boost::python::type >) { - return boost::python::detail::complex_from_python(p, boost::python::type()); -} - -inline std::complex from_python(PyObject* p, - boost::python::type&>) { - return boost::python::detail::complex_from_python(p, boost::python::type()); -} - -// For when your C++ function really wants to pass/return a PyObject* -PyObject* to_python(PyObject*); -PyObject* from_python(PyObject*, boost::python::type); - -// Some standard conversions to/from smart pointer types. You can add your own -// from these examples. These are not generated using the friend technique from -// wrapped_pointer because: -// -// 1. We want to be able to extend conversion to/from WrappedPointers using -// arbitrary smart pointer types. -// -// 2. It helps with compilation independence. This way, code which creates -// wrappers for functions accepting and returning smart_ptr does not -// have to have already seen the invocation of wrapped_type. -// - -// Unfortunately, MSVC6 is so incredibly lame that we have to rely on the friend -// technique to auto_generate standard pointer conversions for wrapped -// types. This means that you need to write a non-templated function for each -// specific smart_ptr which you want to convert from_python. For example, -// -// namespace boost { namespace python { -// #ifdef MUST_SUPPORT_MSVC -// -// MyPtr from_python(PyObject*p, type >) -// { return smart_ptr_from_python(p, type >(), type());} -// } -// -// MyPtr from_python(PyObject*p, type >) -// { return smart_ptr_from_python(p, type >(), type());} -// -// ... // definitions for MyPtr, MyPtr, etc. -// -// #else -// -// // Just once for all MyPtr -// template -// MyPtr from_python(PyObject*p, type >) -// { -// return smart_ptr_from_python(p, type >(), type()); -// } -// -// #endif -// }} // namespace boost::python - -#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) -template -boost::shared_ptr from_python(PyObject*p, boost::python::type >) -{ - return smart_ptr_from_python(p, boost::python::type >(), boost::python::type()); -} -#endif - -#if 0 -template -PyObject* to_python(std::auto_ptr p) -{ - return new boost::python::wrapped_pointer, T>(p); -} - -template -PyObject* to_python(boost::shared_ptr p) -{ - return new boost::python::wrapped_pointer, T>(p); -} -#endif - -// -// inline implementations -// - -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 -inline PyObject* to_python(double d) -{ - return PyFloat_FromDouble(d); -} - -inline PyObject* to_python(float f) -{ - return PyFloat_FromDouble(f); -} -#endif - -inline PyObject* to_python(long l) -{ - return PyInt_FromLong(l); -} - -inline PyObject* to_python(int x) -{ - return PyInt_FromLong(x); -} - -inline PyObject* to_python(short x) -{ - return PyInt_FromLong(x); -} - -inline PyObject* to_python(bool b) -{ - return PyInt_FromLong(b); -} - -inline PyObject* to_python(void) -{ - return boost::python::detail::none(); -} - -inline PyObject* to_python(const char* s) -{ - return PyString_FromString(s); -} - -inline std::string from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline PyObject* to_python(PyObject* p) -{ - Py_INCREF(p); - return p; -} - -inline PyObject* from_python(PyObject* p, boost::python::type) -{ - return p; -} - -inline const char* from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline double from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline float from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline int from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline short from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline long from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline bool from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline unsigned int from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline unsigned short from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline char from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline signed char from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline unsigned char from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -inline unsigned long from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -#endif // METHOD_DWA122899_H_ diff --git a/include/boost/python/cross_module.hpp b/include/boost/python/cross_module.hpp deleted file mode 100644 index c6ac8c22..00000000 --- a/include/boost/python/cross_module.hpp +++ /dev/null @@ -1,329 +0,0 @@ -/* (C) Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, use, - modify, sell and distribute this software is granted provided this - copyright notice appears in all copies. This software is provided - "as is" without express or implied warranty, and with no claim as to - its suitability for any purpose. - - Revision History: - 17 Apr 01 merged into boost CVS trunk (Ralf W. Grosse-Kunstleve) -*/ - -/* Implementation of Boost.Python cross-module support. - See root/libs/python/doc/cross_module.html for details. -*/ - -#ifndef CROSS_MODULE_HPP -# define CROSS_MODULE_HPP - -# include - -namespace boost { namespace python { - -struct BOOST_PYTHON_DECL import_error: error_already_set {}; -struct BOOST_PYTHON_DECL export_error : error_already_set {}; - -void BOOST_PYTHON_DECL throw_import_error(); -void BOOST_PYTHON_DECL throw_export_error(); - -namespace detail -{ - -// Concept: throw exception if api_major is changed -// show warning on stderr if api_minor is changed - const int export_converters_api_major = 4; - const int export_converters_api_minor = 1; - extern BOOST_PYTHON_DECL const char* converters_attribute_name; - BOOST_PYTHON_DECL void* import_converter_object(const std::string& module_name, - const std::string& py_class_name, - const std::string& attribute_name); - BOOST_PYTHON_DECL void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor); - -} - -}} // namespace boost::python - -// forward declaration -namespace boost { namespace python { namespace detail { -template class import_extension_class; -}}} - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -/* This class template is instantiated by import_converters. - This class is a look-alike of class python_extension_class_converters. - The converters in this class are wrappers that call converters - imported from another module. - To ensure that the dynamic loader resolves all symbols in the - intended way, the signature of all friend functions is changed with - respect to the original functions in class - python_extension_class_converters by adding an arbitrary additional - parameter with a default value, in this case "bool sig = false". - See also: comments for class export_converter_object_base below. - */ -template -class python_import_extension_class_converters -{ - public: - - friend python_import_extension_class_converters py_extension_class_converters(boost::python::type, bool sig = false) { - return python_import_extension_class_converters(); - } - - PyObject* to_python(const T& x) const { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } - - friend T* from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_Ts(p, t); - } - friend const T* from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_cTs(p, t); - } - friend const T* from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_cTscr(p, t); - } - friend T* from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_Tscr(p, t); - } - friend T& from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_Tr(p, t); - } - friend const T& from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_cTr(p, t); - } - friend const T& from_python(PyObject* p, boost::python::type t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_T(p, t); - } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_aTr(p, t); - } - friend std::auto_ptr from_python(PyObject* p, boost::python::type > t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_aT(p, t); - } - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_caTr(p, t); - } - friend PyObject* to_python(std::auto_ptr x, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_sTr(p, t); - } - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type > t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_sT(p, t); - } - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&> t, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->from_python_csTr(p, t); - } - friend PyObject* to_python(boost::shared_ptr x, bool sig = false) { - return boost::python::detail::import_extension_class::get_converters()->to_python(x); - } -}; - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -BOOST_PYTHON_IMPORT_CONVERSION(python_import_extension_class_converters); - -/* This class template is instantiated by export_converters(). - A pointer to this class is exported/imported via the Python API. - Using the Python API ensures maximum portability. - All member functions are virtual. This is, what we export/import - is essentially just a pointer to a vtbl. - To work around a deficiency of Visual C++ 6.0, the name of each - from_python() member functions is made unique by appending a few - characters (derived in a ad-hoc manner from the corresponding type). - */ -template -struct export_converter_object_base -{ - virtual int get_api_major() const { return detail::export_converters_api_major; } - virtual int get_api_minor() const { return detail::export_converters_api_minor; } - - virtual PyObject* to_python(const T& x) = 0; - - virtual T* from_python_Ts(PyObject* p, boost::python::type t) = 0; - virtual const T* from_python_cTs(PyObject* p, boost::python::type t) = 0; - virtual const T* from_python_cTscr(PyObject* p, boost::python::type t) = 0; - virtual T* from_python_Tscr(PyObject* p, boost::python::type t) = 0; - virtual T& from_python_Tr(PyObject* p, boost::python::type t) = 0; - virtual const T& from_python_cTr(PyObject* p, boost::python::type t) = 0; - virtual const T& from_python_T(PyObject* p, boost::python::type t) = 0; - - virtual std::auto_ptr& from_python_aTr(PyObject* p, boost::python::type&> t) = 0; - virtual std::auto_ptr from_python_aT(PyObject* p, boost::python::type > t) = 0; - virtual const std::auto_ptr& from_python_caTr(PyObject* p, boost::python::type&> t) = 0; - virtual PyObject* to_python(std::auto_ptr x) = 0; - - virtual boost::shared_ptr& from_python_sTr(PyObject* p, boost::python::type&> t) = 0; - virtual const boost::shared_ptr& from_python_sT(PyObject* p, boost::python::type > t) = 0; - virtual const boost::shared_ptr& from_python_csTr(PyObject* p, boost::python::type&> t) = 0; - virtual PyObject* to_python(boost::shared_ptr x) = 0; -}; - -// Converters to be used if T is not copyable. -template -struct export_converter_object_noncopyable : export_converter_object_base -{ - virtual PyObject* to_python(const T& x) { - PyErr_SetString(PyExc_RuntimeError, - "to_python(const T&) converter not exported"); - throw_import_error(); - return 0; - } - - virtual T* from_python_Ts(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const T* from_python_cTs(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const T* from_python_cTscr(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual T* from_python_Tscr(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual T& from_python_Tr(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const T& from_python_cTr(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const T& from_python_T(PyObject* p, boost::python::type t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - - virtual std::auto_ptr& from_python_aTr(PyObject* p, boost::python::type&> t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual std::auto_ptr from_python_aT(PyObject* p, boost::python::type > t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const std::auto_ptr& from_python_caTr(PyObject* p, boost::python::type&> t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual PyObject* to_python(std::auto_ptr x) { - return BOOST_PYTHON_CONVERSION::to_python(x); - } - - virtual boost::shared_ptr& from_python_sTr(PyObject* p, boost::python::type&> t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const boost::shared_ptr& from_python_sT(PyObject* p, boost::python::type > t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual const boost::shared_ptr& from_python_csTr(PyObject* p, boost::python::type&> t) { - return BOOST_PYTHON_CONVERSION::from_python(p, t); - } - virtual PyObject* to_python(boost::shared_ptr x) { - return BOOST_PYTHON_CONVERSION::to_python(x); - } -}; - -// The addditional to_python() converter that can be used if T is copyable. -template -struct export_converter_object : export_converter_object_noncopyable -{ - virtual PyObject* to_python(const T& x) { - return BOOST_PYTHON_CONVERSION::py_extension_class_converters(boost::python::type()).to_python(x); - } -}; - -namespace detail -{ - -/* This class template is instantiated by import_converters. - Its purpose is to import the converter_object via the Python API. - The actual import is only done once. The pointer to the - imported converter object is kept in the static data member - imported_converters. -*/ - template - class import_extension_class - : public python_import_extension_class_converters - { - public: - inline import_extension_class(const char* module, const char* py_class) { - m_module = module; - m_py_class = py_class; - } - - static boost::python::export_converter_object_base* get_converters(); - - private: - static std::string m_module; - static std::string m_py_class; - static boost::python::export_converter_object_base* imported_converters; - }; - - template std::string import_extension_class::m_module; - template std::string import_extension_class::m_py_class; - template - boost::python::export_converter_object_base* - import_extension_class::imported_converters = 0; - - template - boost::python::export_converter_object_base* - import_extension_class::get_converters() { - if (imported_converters == 0) { - void* cobject - = import_converter_object(m_module, m_py_class, - converters_attribute_name); - imported_converters - = static_cast*>(cobject); - check_export_converters_api( - export_converters_api_major, - export_converters_api_minor, - imported_converters->get_api_major(), - imported_converters->get_api_minor()); - } - return imported_converters; - } -}}} // namespace boost::python::detail - -namespace boost { namespace python { - -// Implementation of export_converters(). -template -void export_converters(class_builder& cb) -{ - static export_converter_object export_cvts; - cb.add( - ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), - detail::converters_attribute_name); -} - -// Implementation of export_converters_noncopyable(). -template -void export_converters_noncopyable(class_builder& cb) -{ - static export_converter_object_noncopyable export_cvts; - cb.add( - ref(PyCObject_FromVoidPtr(reinterpret_cast(&export_cvts), NULL)), - detail::converters_attribute_name); -} - -// Implementation of import_converters. -template -class import_converters - : python_import_extension_class_converters // Works around MSVC6.x/GCC2.95.2 bug described - // at the bottom of class_builder.hpp. -{ - public: - import_converters(const char* module, const char* py_class) - : m_class(new detail::import_extension_class(module, py_class)) - { } - private: - boost::shared_ptr > m_class; -}; - -}} // namespace boost::python - -#endif // CROSS_MODULE_HPP diff --git a/include/boost/python/detail/base_object.hpp b/include/boost/python/detail/base_object.hpp deleted file mode 100644 index d92b3972..00000000 --- a/include/boost/python/detail/base_object.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// Mar 01 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) - -#ifndef BASE_OBJECT_DWA051600_H_ -# define BASE_OBJECT_DWA051600_H_ - -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// base_object - adds a constructor and non-virtual destructor to a -// base Python type (e.g. PyObject, PyTypeObject). -template -struct base_object : PythonType -{ - typedef PythonType base_python_type; - - // Initializes type and reference count. All other fields of base_python_type are 0 - base_object(PyTypeObject* type_obj); - - // Decrements reference count on the type - ~base_object(); -}; - -// Easy typedefs for common usage -typedef base_object python_object; -typedef base_object python_type; - - -// -// base_object member function implementations -// -template -base_object::base_object(PyTypeObject* type_obj) -{ - base_python_type* bp = this; - BOOST_CSTD_::memset(bp, 0, sizeof(base_python_type)); - Py_INCREF(type_obj); - PyObject_INIT(bp, type_obj); -} - -template -inline base_object::~base_object() -{ - Py_DECREF(ob_type); -} - -}}} // namespace boost::python::detail - -#endif // BASE_OBJECT_DWA051600_H_ diff --git a/include/boost/python/detail/cast.hpp b/include/boost/python/detail/cast.hpp deleted file mode 100644 index 367f1f14..00000000 --- a/include/boost/python/detail/cast.hpp +++ /dev/null @@ -1,81 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef CAST_DWA052500_H_ -# define CAST_DWA052500_H_ - -# ifndef BOOST_PYTHON_V2 -# include -# include - -namespace boost { namespace python { - -namespace detail { - inline PyTypeObject* as_base_object(const PyTypeObject*, PyObject* p) - { - return reinterpret_cast(p); - } - - inline PyObject* as_base_object(const PyObject*, PyObject* p) - { - return p; - } - - inline const PyTypeObject* as_base_object(const PyTypeObject*, const PyObject* p) - { - return reinterpret_cast(p); - } - - inline const PyObject* as_base_object(const PyObject*, const PyObject* p) - { - return p; - } -} // namespace detail - -// Convert a pointer to any type derived from PyObject or PyTypeObject to a PyObject* -inline PyObject* as_object(PyObject* p) { return p; } -inline PyObject* as_object(PyTypeObject* p) { return reinterpret_cast(p); } - -// If I didn't have to support stupid MSVC6 we could just use a simple template function: -// template T* downcast(PyObject*). -template -struct downcast -{ - downcast(PyObject* p) - : m_p(static_cast(detail::as_base_object((T*)0, p))) - {} - - downcast(const PyObject* p) - : m_p(static_cast(detail::as_base_object((const T*)0, p))) - {} - - downcast(PyTypeObject* p) - : m_p(static_cast(p)) - {} - - downcast(const PyTypeObject* p) - : m_p(static_cast(p)) - {} - - operator T*() const { return m_p; } - - // MSVC doesn't like boost::dereferencable unless T has a default - // constructor, so operator-> must be defined by hand :( - T* operator->() const { return &**this; } - - T* get() const { return m_p; } - T& operator*() const { return *m_p; } - private: - T* m_p; -}; - -}} // namespace boost::python - -# endif // BOOST_PYTHON_V2 - -#endif // CAST_DWA052500_H_ diff --git a/include/boost/python/detail/extension_class.hpp b/include/boost/python/detail/extension_class.hpp deleted file mode 100644 index f92bb83b..00000000 --- a/include/boost/python/detail/extension_class.hpp +++ /dev/null @@ -1,1002 +0,0 @@ -// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file automatically generated for 10-argument constructors by -// gen_extclass.python - -// Revision History: -// 17 Apr 01 Comment added with reference to cross_module.hpp (R.W. Grosse-Kunstleve) -// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted -// to_python (Dave Abrahams) - -#ifndef EXTENSION_CLASS_DWA052000_H_ -# define EXTENSION_CLASS_DWA052000_H_ - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// forward declarations -template struct operators; -template struct left_operand; -template struct right_operand; - -enum without_downcast_t { without_downcast }; - -namespace detail -{ - -// forward declarations - class extension_instance; - class extension_class_base; - template class instance_holder; - template class instance_value_holder; - template class instance_ptr_holder; - template struct operand_select; - template struct choose_op; - template struct choose_rop; - template struct choose_unary_op; - template struct define_operator; - - class BOOST_PYTHON_DECL extension_instance : public instance - { - public: - extension_instance(PyTypeObject* class_); - ~extension_instance(); - - void add_implementation(std::auto_ptr holder); - - typedef std::vector held_objects; - const held_objects& wrapped_objects() const - { return m_wrapped_objects; } - private: - held_objects m_wrapped_objects; - }; - -} // namespace detail - -BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(class_t); -BOOST_PYTHON_EXPORT_CLASS_TEMPLATE(meta_class); - -namespace detail { - -BOOST_PYTHON_DECL meta_class* extension_meta_class(); -BOOST_PYTHON_DECL extension_instance* get_extension_instance(PyObject* p); -BOOST_PYTHON_DECL void report_missing_instance_data(extension_instance*, class_t*, const std::type_info&); -BOOST_PYTHON_DECL void report_missing_ptr_data(extension_instance*, class_t*, const std::type_info&); -BOOST_PYTHON_DECL void report_missing_class_object(const std::type_info&); -BOOST_PYTHON_DECL void report_released_smart_pointer(const std::type_info&); - -template -T* check_non_null(T* p) -{ - if (p == 0) - report_released_smart_pointer(typeid(T)); - return p; -} - -template class held_instance; - -typedef void* (*conversion_function_ptr)(void*); - -struct BOOST_PYTHON_DECL base_class_info -{ - base_class_info(extension_class_base* t, conversion_function_ptr f) - :class_object(t), convert(f) - {} - - extension_class_base* class_object; - conversion_function_ptr convert; -}; - -typedef base_class_info derived_class_info; - -struct add_operator_base; - -class BOOST_PYTHON_DECL extension_class_base : public class_t -{ - public: - extension_class_base(const char* name); - - public: - // the purpose of try_class_conversions() and its related functions - // is explained in extclass.cpp - void* try_class_conversions(instance_holder_base*) const; - void* try_base_class_conversions(instance_holder_base*) const; - void* try_derived_class_conversions(instance_holder_base*) const; - - void set_attribute(const char* name, PyObject* x); - void set_attribute(const char* name, ref x); - - private: - virtual void* extract_object_from_holder(instance_holder_base* v) const = 0; - virtual std::vector const& base_classes() const = 0; - virtual std::vector const& derived_classes() const = 0; - - protected: - friend struct add_operator_base; - void add_method(reference method, const char* name); - void add_method(function* method, const char* name); - - void add_constructor_object(function*); - void add_setter_method(function*, const char* name); - void add_getter_method(function*, const char* name); -}; - -template -class class_registry -{ - public: - static extension_class_base* class_object() - { return static_class_object; } - - // Register/unregister the Python class object corresponding to T - static void register_class(extension_class_base*); - static void unregister_class(extension_class_base*); - - // Establish C++ inheritance relationships - static void register_base_class(base_class_info const&); - static void register_derived_class(derived_class_info const&); - - // Query the C++ inheritance relationships - static std::vector const& base_classes(); - static std::vector const& derived_classes(); - private: - static extension_class_base* static_class_object; - static std::vector static_base_class_info; - static std::vector static_derived_class_info; -}; - -template -struct is_null_helper -{ - template - static bool test(Ptr x) { return x == 0; } -}; - -template <> -struct is_null_helper -{ - template - static bool test(const Ptr& x) { return x.get() == 0; } -}; - -template -bool is_null(const Ptr& x) -{ - return is_null_helper<(is_pointer::value)>::test(x); -} - -}}} // namespace boost::python::detail - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -// This class' only job is to define from_python and to_python converters for T -// and U. T is the class the user really intends to wrap. U is a class derived -// from T with some virtual function overriding boilerplate, or if there are no -// virtual functions, U = held_instance. -// -// A look-alike of this class in root/boost/python/cross_module.hpp -// is used for the implementation of the cross-module support -// (export_converters and import_converters). If from_python -// and to_python converters are added or removed from the class -// below, the class python_import_extension_class_converters has -// to be modified accordingly. -// -template > -class python_extension_class_converters -{ - public: - // Get an object which can be used to convert T to/from python. This is used - // as a kind of concept check by the global template - // - // PyObject* to_python(const T& x) - // - // below this class, to prevent the confusing messages that would otherwise - // pop up. Now, if T hasn't been wrapped as an extension class, the user - // will see an error message about the lack of an eligible - // py_extension_class_converters() function. - friend python_extension_class_converters py_extension_class_converters(boost::python::type) - { - return python_extension_class_converters(); - } - - // This is a member function because in a conforming implementation, friend - // funcitons defined inline in the class body are all instantiated as soon - // as the enclosing class is instantiated. If T is not copyable, that causes - // a compiler error. Instead, we access this function through the global - // template - // - // PyObject* to_python(const T& x) - // - // defined below this class. Since template functions are instantiated only - // on demand, errors will be avoided unless T is noncopyable and the user - // writes code which causes us to try to copy a T. - PyObject* to_python(const T& x) const - { - boost::python::reference result(create_instance()); - result->add_implementation( - std::auto_ptr( - new boost::python::detail::instance_value_holder(result.get(), x))); - return result.release(); - } - - friend - T* non_null_from_python(PyObject* obj, boost::python::type) - { - // downcast to an extension_instance, then find the actual T - boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); - typedef std::vector::const_iterator iterator; - for (iterator p = self->wrapped_objects().begin(); - p != self->wrapped_objects().end(); ++p) - { - boost::python::detail::instance_holder* held = dynamic_cast*>(*p); - if (held != 0) - return held->target(); - - // see extclass.cpp for an explanation of try_class_conversions() - void* target = boost::python::detail::class_registry::class_object()->try_class_conversions(*p); - if(target) - return static_cast(target); - } - boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); - boost::python::throw_argument_error(); - return 0; - } - - // Convert to T* - friend T* from_python(PyObject* obj, boost::python::type) - { - if (obj == Py_None) - return 0; - else - return non_null_from_python(obj, boost::python::type()); - } - - // Extract from obj a mutable reference to the PtrType object which is holding a T. - template - static PtrType& smart_ptr_reference(PyObject* obj, boost::python::type) - { - // downcast to an extension_instance, then find the actual T - boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); - typedef std::vector::const_iterator iterator; - for (iterator p = self->wrapped_objects().begin(); - p != self->wrapped_objects().end(); ++p) - { - boost::python::detail::instance_ptr_holder* held = - dynamic_cast*>(*p); - if (held != 0) - return held->ptr(); - } - boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); - boost::python::throw_argument_error(); - - return *(PtrType*)obj; - } - - // Extract from obj a reference to the PtrType object which is holding a - // T. If it weren't for auto_ptr, it would be a constant reference. Do not - // modify the referent except by copying an auto_ptr! If obj is None, the - // reference denotes a default-constructed PtrType - template - static PtrType& smart_ptr_value(PyObject* obj, boost::python::type) - { - if (obj == Py_None) - { - static PtrType null_ptr; - return null_ptr; - } - return smart_ptr_reference(obj, boost::python::type()); - } - - template - static PyObject* smart_ptr_to_python(PtrType x) - { - if (boost::python::detail::is_null(x)) - { - return boost::python::detail::none(); - } - - boost::python::reference result(create_instance()); - result->add_implementation( - std::auto_ptr( - new boost::python::detail::instance_ptr_holder(x))); - return result.release(); - } - - static boost::python::reference create_instance() - { - PyTypeObject* class_object = boost::python::detail::class_registry::class_object(); - if (class_object == 0) - boost::python::detail::report_missing_class_object(typeid(T)); - - return boost::python::reference( - new boost::python::detail::extension_instance(class_object)); - } - - // Convert to const T* - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to const T* const& - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T* const& - friend T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T& - friend T& from_python(PyObject* p, boost::python::type) - { return *boost::python::detail::check_non_null(non_null_from_python(p, boost::python::type())); } - - // Convert to const T& - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_reference(p, boost::python::type >()); } - - friend std::auto_ptr from_python(PyObject* p, boost::python::type >) - { return smart_ptr_value(p, boost::python::type >()); } - - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_value(p, boost::python::type >()); } - - friend PyObject* to_python(std::auto_ptr x) - { return smart_ptr_to_python(x); } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_reference(p, boost::python::type >()); } - - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type >) - { return smart_ptr_value(p, boost::python::type >()); } - - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_value(p, boost::python::type >()); } - - friend PyObject* to_python(boost::shared_ptr x) - { return smart_ptr_to_python(x); } -}; - -// Convert T to_python, instantiated on demand and only if there isn't a -// non-template overload for this function. This version is the one invoked when -// T is a wrapped class. See the first 2 functions declared in -// python_extension_class_converters above for more info. -template -PyObject* to_python(const T& x) -{ - return py_extension_class_converters(boost::python::type()).to_python(x); -} - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -BOOST_PYTHON_IMPORT_CONVERSION(python_extension_class_converters); - -namespace detail { - -template class instance_holder; - -class BOOST_PYTHON_DECL read_only_setattr_function : public function -{ - public: - read_only_setattr_function(const char* name); - PyObject* do_call(PyObject* args, PyObject* keywords) const; - const char* description() const; - private: - string m_name; -}; - - template - struct define_conversion - { - static void* upcast_ptr(void* v) - { - return static_cast(static_cast(v)); - } - - static void* downcast_ptr(void* v) - { - return dynamic_cast(static_cast(v)); - } - }; - -// An easy way to make an extension base class which wraps T. Note that Python -// subclasses of this class will simply be class_t objects. -// -// U should be a class derived from T which overrides virtual functions with -// boilerplate code to call back into Python. See extclass_demo.h for examples. -// -// U is optional, but you won't be able to override any member functions in -// Python which are called from C++ if you don't supply it. If you just want to -// be able to use T in python without overriding member functions, you can omit -// U. -template > -class extension_class - : public python_extension_class_converters, // This generates the to_python/from_python functions - public extension_class_base -{ - public: - typedef T wrapped_type; - typedef U callback_type; - - // Construct with a name that comes from typeid(T).name(). The name only - // affects the objects of this class are represented through repr() - extension_class(); - - // Construct with the given name. The name only affects the objects of this - // class are represented through repr() - extension_class(const char* name); - - ~extension_class(); - - // define constructors - template - inline void def(constructor) - // The following incantation builds a signature1, signature2,... object. It - // should _all_ get optimized away. - { add_constructor( - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - prepend(type::id(), - signature0()))))))))))); - } - - - // export homogeneous operators (type of both lhs and rhs is 'operator') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>()); - - // export homogeneous operators (type of both lhs and rhs is 'T const&') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>()); - template - inline void def(operators) - { - typedef typename operand_select::template wrapped::type true_operand; - def_operators(operators()); - } - - // export heterogeneous operators (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::right_operand()); - - // export heterogeneous operators (type of lhs: 'T const&', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), - // boost::python::right_operand()); - template - inline void def(operators, right_operand r) - { - typedef typename operand_select::template wrapped::type true_left; - def_operators(operators(), r); - } - - // export heterogeneous reverse-argument operators - // (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::left_operand()); - - // export heterogeneous reverse-argument operators - // (type of lhs: 'left', of rhs: 'T const&') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), - // boost::python::left_operand()); - template - inline void def(operators, left_operand l) - { - typedef typename operand_select::template wrapped::type true_right; - def_operators(operators(), l); - } - - // define a function that passes Python arguments and keywords - // to C++ verbatim (as a 'tuple const&' and 'dictionary const&' - // respectively). This is useful for manual argument passing. - // It's also the only possibility to pass keyword arguments to C++. - // Fn must have a signatur that is compatible to - // PyObject* (*)(PyObject* aTuple, PyObject* aDictionary) - template - inline void def_raw(Fn fn, const char* name) - { - this->add_method(new_raw_arguments_function(fn), name); - } - - // define member functions. In fact this works for free functions, too - - // they act like static member functions, or if they start with the - // appropriate self argument (as a pointer), they can be used just like - // ordinary member functions -- just like Python! - template - inline void def(Fn fn, const char* name) - { - this->add_method(new_wrapped_function(fn), name); - } - - // Define a virtual member function with a default implementation. - // default_fn should be a function which provides the default implementation. - // Be careful that default_fn does not in fact call fn virtually! - template - inline void def(Fn fn, const char* name, DefaultFn default_fn) - { - this->add_method(new_virtual_function(type(), fn, default_fn), name); - } - - // Provide a function which implements x., reading from the given - // member (pm) of the T obj - template - inline void def_getter(MemberType T::*pm, const char* name) - { - this->add_getter_method(new getter_function(pm), name); - } - - // Provide a function which implements assignment to x., writing to - // the given member (pm) of the T obj - template - inline void def_setter(MemberType T::*pm, const char* name) - { - this->add_setter_method(new setter_function(pm), name); - } - - // Expose the given member (pm) of the T obj as a read-only attribute - template - inline void def_readonly(MemberType T::*pm, const char* name) - { - this->add_setter_method(new read_only_setattr_function(name), name); - this->def_getter(pm, name); - } - - // Expose the given member (pm) of the T obj as a read/write attribute - template - inline void def_read_write(MemberType T::*pm, const char* name) - { - this->def_getter(pm, name); - this->def_setter(pm, name); - } - - // define the standard coercion needed for operator overloading - void def_standard_coerce(); - - // declare the given class a base class of this one and register - // up and down conversion functions - template - void declare_base(extension_class* base) - { - // see extclass.cpp for an explanation of why we need to register - // conversion functions - base_class_info baseInfo(base, - &define_conversion::downcast_ptr); - class_registry::register_base_class(baseInfo); - add_base(ref(as_object(base), ref::increment_count)); - - derived_class_info derivedInfo(this, - &define_conversion::upcast_ptr); - class_registry::register_derived_class(derivedInfo); - } - - // declare the given class a base class of this one and register - // only up conversion function - template - void declare_base(extension_class* base, without_downcast_t) - { - // see extclass.cpp for an explanation of why we need to register - // conversion functions - base_class_info baseInfo(base, 0); - class_registry::register_base_class(baseInfo); - add_base(ref(as_object(base), ref::increment_count)); - - derived_class_info derivedInfo(this, - &define_conversion::upcast_ptr); - class_registry::register_derived_class(derivedInfo); - } - - private: // types - typedef instance_value_holder holder; - - private: // extension_class_base virtual function implementations - std::vector const& base_classes() const; - std::vector const& derived_classes() const; - void* extract_object_from_holder(instance_holder_base* v) const; - - private: // Utility functions - template - inline void def_operators(operators) - { - def_standard_coerce(); - - // for some strange reason, this prevents MSVC from having an - // "unrecoverable block scoping error"! - typedef choose_op<(which & op_add)> choose_add; - - choose_op<(which & op_add)>::template args::add(this); - choose_op<(which & op_sub)>::template args::add(this); - choose_op<(which & op_mul)>::template args::add(this); - choose_op<(which & op_div)>::template args::add(this); - choose_op<(which & op_mod)>::template args::add(this); - choose_op<(which & op_divmod)>::template args::add(this); - choose_op<(which & op_pow)>::template args::add(this); - choose_op<(which & op_lshift)>::template args::add(this); - choose_op<(which & op_rshift)>::template args::add(this); - choose_op<(which & op_and)>::template args::add(this); - choose_op<(which & op_xor)>::template args::add(this); - choose_op<(which & op_or)>::template args::add(this); - choose_op<(which & op_gt)>::template args::add(this); - choose_op<(which & op_ge)>::template args::add(this); - choose_op<(which & op_lt)>::template args::add(this); - choose_op<(which & op_le)>::template args::add(this); - choose_op<(which & op_eq)>::template args::add(this); - choose_op<(which & op_ne)>::template args::add(this); - choose_unary_op<(which & op_neg)>::template args::add(this); - choose_unary_op<(which & op_pos)>::template args::add(this); - choose_unary_op<(which & op_abs)>::template args::add(this); - choose_unary_op<(which & op_invert)>::template args::add(this); - choose_unary_op<(which & op_int)>::template args::add(this); - choose_unary_op<(which & op_long)>::template args::add(this); - choose_unary_op<(which & op_float)>::template args::add(this); - choose_op<(which & op_cmp)>::template args::add(this); - choose_unary_op<(which & op_str)>::template args::add(this); - } - - template - inline void def_operators(operators, right_operand) - { - def_standard_coerce(); - - choose_op<(which & op_add)>::template args::add(this); - choose_op<(which & op_sub)>::template args::add(this); - choose_op<(which & op_mul)>::template args::add(this); - choose_op<(which & op_div)>::template args::add(this); - choose_op<(which & op_mod)>::template args::add(this); - choose_op<(which & op_divmod)>::template args::add(this); - choose_op<(which & op_pow)>::template args::add(this); - choose_op<(which & op_lshift)>::template args::add(this); - choose_op<(which & op_rshift)>::template args::add(this); - choose_op<(which & op_and)>::template args::add(this); - choose_op<(which & op_xor)>::template args::add(this); - choose_op<(which & op_or)>::template args::add(this); - choose_op<(which & op_cmp)>::template args::add(this); - choose_op<(which & op_gt)>::template args::add(this); - choose_op<(which & op_ge)>::template args::add(this); - choose_op<(which & op_lt)>::template args::add(this); - choose_op<(which & op_le)>::template args::add(this); - choose_op<(which & op_eq)>::template args::add(this); - choose_op<(which & op_ne)>::template args::add(this); - } - - template - inline void def_operators(operators, left_operand) - { - def_standard_coerce(); - - choose_rop<(which & op_add)>::template args::add(this); - choose_rop<(which & op_sub)>::template args::add(this); - choose_rop<(which & op_mul)>::template args::add(this); - choose_rop<(which & op_div)>::template args::add(this); - choose_rop<(which & op_mod)>::template args::add(this); - choose_rop<(which & op_divmod)>::template args::add(this); - choose_rop<(which & op_pow)>::template args::add(this); - choose_rop<(which & op_lshift)>::template args::add(this); - choose_rop<(which & op_rshift)>::template args::add(this); - choose_rop<(which & op_and)>::template args::add(this); - choose_rop<(which & op_xor)>::template args::add(this); - choose_rop<(which & op_or)>::template args::add(this); - choose_rop<(which & op_cmp)>::template args::add(this); - } - - template - void add_constructor(signature sig) - { - this->add_constructor_object(init_function::create(sig)); - } -}; - -// A simple wrapper over a T which allows us to use extension_class with a -// single template parameter only. See extension_class, above. -template -class held_instance : public Held -{ - // There are no member functions: we want to avoid inadvertently overriding - // any virtual functions in Held. -public: - held_instance(PyObject*) : Held() {} - template - held_instance(PyObject*, A1 a1) : Held( - typename unwrap_parameter::type(a1)) {} - template - held_instance(PyObject*, A1 a1, A2 a2) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5) - , typename unwrap_parameter::type(a6)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5) - , typename unwrap_parameter::type(a6) - , typename unwrap_parameter::type(a7)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5) - , typename unwrap_parameter::type(a6) - , typename unwrap_parameter::type(a7) - , typename unwrap_parameter::type(a8)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5) - , typename unwrap_parameter::type(a6) - , typename unwrap_parameter::type(a7) - , typename unwrap_parameter::type(a8) - , typename unwrap_parameter::type(a9)) {} - template - held_instance(PyObject*, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : Held( - typename unwrap_parameter::type(a1) - , typename unwrap_parameter::type(a2) - , typename unwrap_parameter::type(a3) - , typename unwrap_parameter::type(a4) - , typename unwrap_parameter::type(a5) - , typename unwrap_parameter::type(a6) - , typename unwrap_parameter::type(a7) - , typename unwrap_parameter::type(a8) - , typename unwrap_parameter::type(a9) - , typename unwrap_parameter::type(a10)) {} -}; - -// Abstract base class for all obj holders. Base for template class -// instance_holder<>, below. -class BOOST_PYTHON_DECL instance_holder_base -{ -public: - virtual ~instance_holder_base() {} - virtual bool held_by_value() = 0; -}; - -// Abstract base class which holds a Held, somehow. Provides a uniform way to -// get a pointer to the held object -template -class instance_holder : public instance_holder_base -{ -public: - virtual Held*target() = 0; -}; - -// Concrete class which holds a Held by way of a wrapper class Wrapper. If Held -// can be constructed with arguments (A1...An), Wrapper must have a -// corresponding constructor for arguments (PyObject*, A1...An). Wrapper is -// neccessary to implement virtual function callbacks (there must be a -// back-pointer to the actual Python object so that we can call any -// overrides). held_instance (above) is used as a default Wrapper class when -// there are no virtual functions. -template -class instance_value_holder : public instance_holder -{ -public: - Held* target() { return &m_held; } - Wrapper* value_target() { return &m_held; } - - instance_value_holder(extension_instance* p) : - m_held(p) {} - template - instance_value_holder(extension_instance* p, A1 a1) : - m_held(p, a1) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2) : - m_held(p, a1, a2) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3) : - m_held(p, a1, a2, a3) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4) : - m_held(p, a1, a2, a3, a4) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : - m_held(p, a1, a2, a3, a4, a5) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : - m_held(p, a1, a2, a3, a4, a5, a6) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : - m_held(p, a1, a2, a3, a4, a5, a6, a7) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} - - public: // implementation of instance_holder_base required interface - bool held_by_value() { return true; } - - private: - Wrapper m_held; -}; - -// Concrete class which holds a HeldType by way of a (possibly smart) pointer -// PtrType. By default, these are only generated for PtrType == -// std::auto_ptr and PtrType == boost::shared_ptr. -template -class instance_ptr_holder : public instance_holder -{ - public: - HeldType* target() { return &*m_ptr; } - PtrType& ptr() { return m_ptr; } - - instance_ptr_holder(PtrType ptr) : m_ptr(ptr) {} - - public: // implementation of instance_holder_base required interface - bool held_by_value() { return false; } - private: - PtrType m_ptr; -}; - -// -// Template function implementations -// - -template -extension_class::extension_class() - : extension_class_base(typeid(T).name()) -{ - class_registry::register_class(this); -} - -template -extension_class::extension_class(const char* name) - : extension_class_base(name) -{ - class_registry::register_class(this); -} - -template -void extension_class::def_standard_coerce() -{ - ref coerce_fct = dict().get_item(string("__coerce__")); - - if(coerce_fct.get() == 0) // not yet defined - this->def(&standard_coerce, "__coerce__"); -} - -template -inline -std::vector const& -extension_class::base_classes() const -{ - return class_registry::base_classes(); -} - -template -inline -std::vector const& -extension_class::derived_classes() const -{ - return class_registry::derived_classes(); -} - -template -void* extension_class::extract_object_from_holder(instance_holder_base* v) const -{ - instance_holder* held = dynamic_cast*>(v); - if(held) - return held->target(); - return 0; -} - -template -extension_class::~extension_class() -{ - class_registry::unregister_class(this); -} - -template -inline void class_registry::register_class(extension_class_base* p) -{ - // You're not expected to create more than one of these! - assert(static_class_object == 0); - static_class_object = p; -} - -template -inline void class_registry::unregister_class(extension_class_base* p) -{ - // The user should be destroying the same object they created. - assert(static_class_object == p); - (void)p; // unused in shipping version - static_class_object = 0; -} - -template -void class_registry::register_base_class(base_class_info const& i) -{ - static_base_class_info.push_back(i); -} - -template -void class_registry::register_derived_class(derived_class_info const& i) -{ - static_derived_class_info.push_back(i); -} - -template -std::vector const& class_registry::base_classes() -{ - return static_base_class_info; -} - -template -std::vector const& class_registry::derived_classes() -{ - return static_derived_class_info; -} - -// -// Static data member declaration. -// -template -extension_class_base* class_registry::static_class_object; -template -std::vector class_registry::static_base_class_info; -template -std::vector class_registry::static_derived_class_info; - -}}} // namespace boost::python::detail - -#endif // EXTENSION_CLASS_DWA052000_H_ diff --git a/include/boost/python/detail/functions.hpp b/include/boost/python/detail/functions.hpp deleted file mode 100644 index 486d73f9..00000000 --- a/include/boost/python/detail/functions.hpp +++ /dev/null @@ -1,311 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef FUNCTIONS_DWA051400_H_ -# define FUNCTIONS_DWA051400_H_ - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// forward declaration -class extension_instance; - - -// function -- -// the common base class for all overloadable function and method objects -// supplied by the library. -class BOOST_PYTHON_DECL function : public python_object -{ - public: - function(); - // function objects are reasonably rare, so we guess we can afford a virtual table. - // This cuts down on the number of distinct type objects which need to be defined. - virtual ~function() {} - - PyObject* call(PyObject* args, PyObject* keywords) const; - static void add_to_namespace(reference f, const char* name, PyObject* dict); - - private: - virtual PyObject* do_call(PyObject* args, PyObject* keywords) const = 0; - virtual const char* description() const = 0; - private: - struct type_object; - private: - reference m_overloads; // A linked list of the function overloads -}; - -// wrapped_function_pointer<> -- -// A single function or member function pointer wrapped and presented to -// Python as a callable object. -// -// Template parameters: -// R - the return type of the function pointer -// F - the complete type of the wrapped function pointer -template -struct wrapped_function_pointer : function -{ - typedef F ptr_fun; // pointer-to--function or pointer-to-member-function - - wrapped_function_pointer(ptr_fun pf) - : m_pf(pf) {} - - private: - PyObject* do_call(PyObject* args, PyObject* keywords) const - { - // This is where the boundary between the uniform Python function - // interface and the statically-checked C++ function interface is - // crossed. - return caller::call(m_pf, args, keywords); - } - - const char* description() const - { return typeid(F).name(); } - - private: - const ptr_fun m_pf; -}; - -// raw_arguments_function -// A function that passes the Python argument tuple and keyword dictionary -// verbatim to C++ (useful for customized argument parsing and variable -// argument lists) -template -struct raw_arguments_function : function -{ - typedef Ret (*ptr_fun)(Args, Keywords); - - raw_arguments_function(ptr_fun pf) - : m_pf(pf) {} - - private: - PyObject* do_call(PyObject* args, PyObject* keywords) const - { - ref dict(keywords ? - ref(keywords, ref::increment_count) : - ref(PyDict_New())); - - return to_python( - (*m_pf)(from_python(args, boost::python::type()), - from_python(dict.get(), boost::python::type()))); - } - - const char* description() const - { return typeid(ptr_fun).name(); } - - private: - const ptr_fun m_pf; -}; - -// virtual_function<> -- -// A virtual function with a default implementation wrapped and presented -// to Python as a callable object. -// -// Template parameters: -// T - the type of the target class -// R - the return type of the function pointer -// V - the virtual function pointer being wrapped -// (should be of the form R(T::*)(), or R (*)(T, )) -// D - a function which takes a T&, const T&, T*, or const T* first -// parameter and calls T::f on it /non-virtually/, where V -// approximates &T::f. -template -class virtual_function : public function -{ - public: - virtual_function(V virtual_function_ptr, D default_implementation) - : m_virtual_function_ptr(virtual_function_ptr), - m_default_implementation(default_implementation) - {} - - private: - PyObject* do_call(PyObject* args, PyObject* keywords) const; - - const char* description() const - { return typeid(V).name(); } - - private: - const V m_virtual_function_ptr; - const D m_default_implementation; -}; - -// A helper function for new_member_function(), below. Implements the core -// functionality once the return type has already been deduced. R is expected to -// be type, where X is the actual return type of pmf. -template -function* new_wrapped_function_aux(R, F pmf) -{ - // We can't just use "typename R::Type" below because MSVC (incorrectly) pukes. - typedef typename R::type return_type; - return new wrapped_function_pointer(pmf); -} - -// Create and return a new member function object wrapping the given -// pointer-to-member function -template -inline function* new_wrapped_function(F pmf) -{ - // Deduce the return type and pass it off to the helper function above - return new_wrapped_function_aux(return_value(pmf), pmf); -} - -template -function* new_raw_arguments_function(R (*pmf)(Args, keywords)) -{ - return new raw_arguments_function(pmf); -} - - -// A helper function for new_virtual_function(), below. Implements the core -// functionality once the return type has already been deduced. R is expected to -// be type, where X is the actual return type of V. -template -inline function* new_virtual_function_aux( - type, R, V virtual_function_ptr, D default_implementation - ) -{ - // We can't just use "typename R::Type" below because MSVC (incorrectly) pukes. - typedef typename R::type return_type; - return new virtual_function( - virtual_function_ptr, default_implementation); -} - -// Create and return a new virtual_function object wrapping the given -// virtual_function_ptr and default_implementation -template -inline function* new_virtual_function( - type, V virtual_function_ptr, D default_implementation - ) -{ - // Deduce the return type and pass it off to the helper function above - return new_virtual_function_aux( - type(), return_value(virtual_function_ptr), - virtual_function_ptr, default_implementation); -} - -// A function with a bundled "bound target" object. This is what is produced by -// the expression a.b where a is an instance or extension_instance object and b -// is a callable object not found in the obj namespace but on its class or -// a base class. -class BOOST_PYTHON_DECL bound_function : public python_object -{ - public: - static bound_function* create(const ref& target, const ref& fn); - - bound_function(const ref& target, const ref& fn); - PyObject* call(PyObject*args, PyObject* keywords) const; - PyObject* getattr(const char* name) const; - - private: - struct type_object; - friend struct type_object; - - ref m_target; - ref m_unbound_function; - - private: // data members for allocation/deallocation optimization - bound_function* m_free_list_link; - - static bound_function* free_list; -}; - -// Special functions designed to access data members of a wrapped C++ object. -template -class getter_function : public function -{ - public: - typedef MemberType ClassType::* pointer_to_member; - - getter_function(pointer_to_member pm) - : m_pm(pm) {} - - private: - PyObject* do_call(PyObject* args, PyObject* keywords) const; - - const char* description() const - { return typeid(MemberType (*)(const ClassType&)).name(); } - private: - pointer_to_member m_pm; -}; - -template -class setter_function : public function -{ - public: - typedef MemberType ClassType::* pointer_to_member; - - setter_function(pointer_to_member pm) - : m_pm(pm) {} - - private: - PyObject* do_call(PyObject* args, PyObject* keywords) const; - - const char* description() const - { return typeid(void (*)(const ClassType&, const MemberType&)).name(); } - private: - pointer_to_member m_pm; -}; - -template -PyObject* getter_function::do_call( - PyObject* args, PyObject* /* keywords */) const -{ - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - - return to_python( - from_python(self, type())->*m_pm); -} - -template -PyObject* setter_function::do_call( - PyObject* args, PyObject* /* keywords */) const -{ - PyObject* self; - PyObject* value; - if (!PyArg_ParseTuple(args, const_cast("OO"), &self, &value)) - return 0; - - typedef typename boost::call_traits::const_reference extract_type; - from_python(self, type())->*m_pm - = from_python(value, type()); - - return none(); -} - -template -PyObject* virtual_function::do_call(PyObject* args, PyObject* keywords) const -{ - // If the target object is held by pointer, we must call through the virtual - // function pointer to the most-derived override. - PyObject* target = PyTuple_GetItem(args, 0); - if (target != 0) - { - extension_instance* self = get_extension_instance(target); - if (self->wrapped_objects().size() == 1 - && !self->wrapped_objects()[0]->held_by_value()) - { - return caller::call(m_virtual_function_ptr, args, keywords); - } - } - return caller::call(m_default_implementation, args, keywords); -} - -}}} // namespace boost::python::detail - -#endif // FUNCTIONS_DWA051400_H_ diff --git a/include/boost/python/detail/init_function.hpp b/include/boost/python/detail/init_function.hpp deleted file mode 100644 index 928159c2..00000000 --- a/include/boost/python/detail/init_function.hpp +++ /dev/null @@ -1,562 +0,0 @@ -// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file was generated for %d-argument constructors by gen_init_function.python - -#ifndef INIT_FUNCTION_DWA052000_H_ -# define INIT_FUNCTION_DWA052000_H_ - -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail { - - // parameter_traits - so far, this is a way to pass a const T& when we can be - // sure T is not a reference type, and a raw T otherwise. This should be - // rolled into boost::call_traits. Ordinarily, parameter_traits would be - // written: - // - // template struct parameter_traits - // { - // typedef const T& const_reference; - // }; - // - // template struct parameter_traits - // { - // typedef T& const_reference; - // }; - // - // template <> struct parameter_traits - // { - // typedef void const_reference; - // }; - // - // ...but since we can't partially specialize on reference types, we need this - // long-winded but equivalent incantation. - - // const_ref_selector -- an implementation detail of parameter_traits (below). This uses - // the usual "poor man's partial specialization" hack for MSVC. - template - struct const_ref_selector - { - template - struct const_ref - { - typedef const T& type; - }; - }; - - template <> - struct const_ref_selector - { - template - struct const_ref - { - typedef T type; - }; - }; - -# ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable: 4181) -# endif // BOOST_MSVC - template - struct parameter_traits - { - private: - enum { is_ref = boost::is_reference::value }; - typedef const_ref_selector selector; - public: - typedef typename selector::template const_ref::type const_reference; - }; -# ifdef BOOST_MSVC -# pragma warning(pop) -# endif // BOOST_MSVC - - // Full spcialization for void - template <> - struct parameter_traits - { - typedef void const_reference; - }; - - struct reference_parameter_base {}; - - template - class reference_parameter - : public reference_parameter_base - { - public: - typedef typename parameter_traits::const_reference const_reference; - reference_parameter(const_reference value) - : value(value) {} - operator const_reference() { return value; } - private: - const_reference value; - }; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct unwrap_parameter - { - typedef typename boost::add_reference::type type; - }; - - template - struct unwrap_parameter > - { - typedef typename reference_parameter::const_reference type; - }; -# else - template - struct unwrap_parameter_helper - { - template - struct apply - { - typedef typename T::const_reference type; - }; - }; - - template <> - struct unwrap_parameter_helper - { - template - struct apply - { - typedef typename add_reference::type type; - }; - }; - - template - struct unwrap_parameter - { - BOOST_STATIC_CONSTANT( - bool, is_wrapped = (is_base_and_derived::value)); - - typedef typename unwrap_parameter_helper< - is_wrapped - >::template apply::type type; - }; -# endif - -class extension_instance; -class instance_holder_base; - -class init; -template struct init0; -template struct init1; -template struct init2; -template struct init3; -template struct init4; -template struct init5; -template struct init6; -template struct init7; -template struct init8; -template struct init9; -template struct init10; - -template -struct init_function -{ -# ifdef BOOST_MSVC6_OR_EARLIER -# define typename -# endif - static init* create(signature0) { - return new init0; - } - - template - static init* create(signature1) { - return new init1::const_reference>; - } - - template - static init* create(signature2) { - return new init2::const_reference, - typename detail::parameter_traits::const_reference>; - } - - template - static init* create(signature3) { - return new init3::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference>; - } - - template - static init* create(signature4) { - return new init4::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference>; - } - - template - static init* create(signature5) { - return new init5::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference>; - } - - template - static init* create(signature6) { - return new init6::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference>; - } - - template - static init* create(signature7) { - return new init7::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference>; - } - - template - static init* create(signature8) { - return new init8::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference>; - } - - template - static init* create(signature9) { - return new init9::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference>; - } - - template - static init* create(signature10) { - return new init10::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference, - typename detail::parameter_traits::const_reference>; - } -#ifdef BOOST_MSVC6_OR_EARLIER -# undef typename -#endif -}; - -class BOOST_PYTHON_DECL init : public function -{ -private: // override function hook - PyObject* do_call(PyObject* args, PyObject* keywords) const; -private: - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* tail_args, PyObject* keywords) const = 0; -}; - - -template -struct init0 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - if (!PyArg_ParseTuple(args, const_cast(""))) - throw_argument_error(); - return new T(self - ); - } - const char* description() const - { return typeid(void (*)(T&)).name(); } -}; - -template -struct init1 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - if (!PyArg_ParseTuple(args, const_cast("O"), &a1)) - throw_argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1)).name(); } -}; - -template -struct init2 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OO"), &a1, &a2)) - throw_argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2)).name(); } -}; - -template -struct init3 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &a1, &a2, &a3)) - throw_argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3)).name(); } -}; - -template -struct init4 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &a1, &a2, &a3, &a4)) - throw_argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4)).name(); } -}; - -template -struct init5 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - if (!PyArg_ParseTuple(args, const_cast("OOOOO"), &a1, &a2, &a3, &a4, &a5)) - throw_argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5)).name(); } -}; - -template -struct init6 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - if (!PyArg_ParseTuple(args, const_cast("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6)) - throw_argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())), - boost::python::detail::reference_parameter(from_python(a6, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6)).name(); } -}; - -template -struct init7 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7)) - throw_argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())), - boost::python::detail::reference_parameter(from_python(a6, type())), - boost::python::detail::reference_parameter(from_python(a7, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7)).name(); } -}; - -template -struct init8 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8)) - throw_argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())), - boost::python::detail::reference_parameter(from_python(a6, type())), - boost::python::detail::reference_parameter(from_python(a7, type())), - boost::python::detail::reference_parameter(from_python(a8, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8)).name(); } -}; - -template -struct init9 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9)) - throw_argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())), - boost::python::detail::reference_parameter(from_python(a6, type())), - boost::python::detail::reference_parameter(from_python(a7, type())), - boost::python::detail::reference_parameter(from_python(a8, type())), - boost::python::detail::reference_parameter(from_python(a9, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8, A9)).name(); } -}; - -template -struct init10 : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - PyObject* a1; - PyObject* a2; - PyObject* a3; - PyObject* a4; - PyObject* a5; - PyObject* a6; - PyObject* a7; - PyObject* a8; - PyObject* a9; - PyObject* a10; - if (!PyArg_ParseTuple(args, const_cast("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10)) - throw_argument_error(); - return new T(self, - boost::python::detail::reference_parameter(from_python(a1, type())), - boost::python::detail::reference_parameter(from_python(a2, type())), - boost::python::detail::reference_parameter(from_python(a3, type())), - boost::python::detail::reference_parameter(from_python(a4, type())), - boost::python::detail::reference_parameter(from_python(a5, type())), - boost::python::detail::reference_parameter(from_python(a6, type())), - boost::python::detail::reference_parameter(from_python(a7, type())), - boost::python::detail::reference_parameter(from_python(a8, type())), - boost::python::detail::reference_parameter(from_python(a9, type())), - boost::python::detail::reference_parameter(from_python(a10, type())) - ); - } - const char* description() const - { return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)).name(); } -}; - -}}} // namespace boost::python::detail - -#endif // INIT_FUNCTION_DWA052000_H_ diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp index 144c1d93..39056d63 100644 --- a/include/boost/python/detail/module_base.hpp +++ b/include/boost/python/detail/module_base.hpp @@ -1,3 +1,4 @@ +#error obsolete // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided diff --git a/include/boost/python/detail/module_info.hpp b/include/boost/python/detail/module_info.hpp deleted file mode 100644 index ba3f91cc..00000000 --- a/include/boost/python/detail/module_info.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright David Hawkes 2002. -// Permission is hereby granted to copy, use and modify this software -// for any purpose, including commercial distribution, provided this -// copyright notice is not removed. No warranty WHATSOEVER is provided with this -// software. Any user(s) accepts this software "as is" and as such they will not -// bind the author(s) to any claim of suitabilty for any purpose. - -#ifndef MODULE_INFO -# define MODULE_INFO - -#include - -namespace boost { namespace python { namespace detail { - -class module_info -{ -public: - module_info(const char *name) - { - m_module_name = name; - } - void set_module(object const& m) - { - if(!m_primary_module) - m_primary_module = m; - } - object const& get_module() const - { - return m_primary_module; - } - void set_prior_module(object const& m) - { - m_prior_module = m; - } - object const& get_prior_module() const - { - return m_prior_module; - } - const char* get_module_name() const - { - return m_module_name; - } -private: - object m_primary_module; - object m_prior_module; - const char* m_module_name; -}; - -}}} - -#endif // MODULE_INFO diff --git a/include/boost/python/detail/signatures.hpp b/include/boost/python/detail/signatures.hpp deleted file mode 100644 index e216f688..00000000 --- a/include/boost/python/detail/signatures.hpp +++ /dev/null @@ -1,251 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file automatically generated by gen_signatures.python for 10 arguments. -#ifndef SIGNATURES_DWA050900_H_ -# define SIGNATURES_DWA050900_H_ - -# include - -namespace boost { namespace python { - -namespace detail { -// A stand-in for the built-in void. This one can be passed to functions and -// (under MSVC, which has a bug, be used as a default template type parameter). -struct BOOST_PYTHON_DECL void_t {}; -} - -// An envelope in which type information can be delivered for the purposes -// of selecting an overloaded from_python() function. This is needed to work -// around MSVC's lack of partial specialiation/ordering. Where normally we'd -// want to form a function call like void f(), We instead pass -// type as one of the function parameters to select a particular -// overload. -// -// The id typedef helps us deal with the lack of partial ordering by generating -// unique types for constructor signatures. In general, type::id is type, -// but type::id is just void_t. -template -struct type -{ - typedef type id; -}; - -template <> -struct type -{ - typedef boost::python::detail::void_t id; -}; - -namespace detail { -// These basically encapsulate a chain of types, , used to make the syntax of -// add(constructor()) work. We need to produce a unique type for each number -// of non-default parameters to constructor<>. Q: why not use a recursive -// formulation for infinite extensibility? A: MSVC6 seems to choke on constructs -// that involve recursive template nesting. -// -// signature chaining -template -struct signature10 {}; - -template -struct signature9 {}; - -template -inline signature10 prepend(type, signature9) - { return signature10(); } - -template -struct signature8 {}; - -template -inline signature9 prepend(type, signature8) - { return signature9(); } - -template -struct signature7 {}; - -template -inline signature8 prepend(type, signature7) - { return signature8(); } - -template -struct signature6 {}; - -template -inline signature7 prepend(type, signature6) - { return signature7(); } - -template -struct signature5 {}; - -template -inline signature6 prepend(type, signature5) - { return signature6(); } - -template -struct signature4 {}; - -template -inline signature5 prepend(type, signature4) - { return signature5(); } - -template -struct signature3 {}; - -template -inline signature4 prepend(type, signature3) - { return signature4(); } - -template -struct signature2 {}; - -template -inline signature3 prepend(type, signature2) - { return signature3(); } - -template -struct signature1 {}; - -template -inline signature2 prepend(type, signature1) - { return signature2(); } - -struct signature0 {}; - -template -inline signature1 prepend(type, signature0) - { return signature1(); } - - -// This one terminates the chain. Prepending void_t to the head of a void_t -// signature results in a void_t signature again. -inline signature0 prepend(void_t, signature0) { return signature0(); } - -} // namespace detail - -template -struct constructor -{ -}; - -namespace detail { -// Return value extraction: - -// This is just another little envelope for carrying a typedef (see type, -// above). I could have re-used type, but that has a very specific purpose. I -// thought this would be clearer. -template -struct return_value_select { typedef T type; }; - -// free functions -template -return_value_select return_value(R (*)()) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5, A6)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5, A6, A7)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { return return_value_select(); } - -template -return_value_select return_value(R (*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { return return_value_select(); } - -// TODO(?): handle 'const void' - -// member functions -template -return_value_select return_value(R (T::*)()) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)() const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const) { return return_value_select(); } - -template -return_value_select return_value(R (T::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const) { return return_value_select(); } - -}}} // namespace boost::python::detail - -#endif diff --git a/include/boost/python/detail/singleton.hpp b/include/boost/python/detail/singleton.hpp deleted file mode 100644 index 3e7d91af..00000000 --- a/include/boost/python/detail/singleton.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef SINGLETON_DWA051900_H_ -# define SINGLETON_DWA051900_H_ - -# include - -namespace boost { namespace python { namespace detail { - -struct BOOST_PYTHON_DECL empty {}; -template -struct singleton : Base -{ - typedef singleton singleton_base; // Convenience type for derived class constructors - - static Derived* instance(); - - // Pass-through constructors - singleton() : Base() {} - - template - singleton(const A1& a1) : Base(a1) {} - - template - singleton(const A1& a1, const A2& a2) : Base(a1, a2) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3) : Base(a1, a2, a3) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4) : Base(a1, a2, a3, a4) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) : Base(a1, a2, a3, a4, a5) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) : Base(a1, a2, a3, a4, a5, a6) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) : Base(a1, a2, a3, a4, a5, a6, a7) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) : Base(a1, a2, a3, a4, a5, a6, a7, a8) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) : Base(a1, a2, a3, a4, a5, a6, a7, a8, a9) {} - - template - singleton(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) : Base(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} - -}; - -template -Derived* singleton::instance() -{ - static Derived x; - return &x; -} - -}}} // namespace boost::python::detail - -#endif diff --git a/include/boost/python/detail/types.hpp b/include/boost/python/detail/types.hpp deleted file mode 100644 index 2e69d24e..00000000 --- a/include/boost/python/detail/types.hpp +++ /dev/null @@ -1,413 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef TYPES_DWA051800_H_ -# define TYPES_DWA051800_H_ - -// Usage: -// class X : public -// boost::python::callable< -// boost::python::getattrable < -// boost::python::setattrable > > -// { -// public: -// ref call(args, kw); -// ref getattr(args, kw); -// ref setattr(args, kw); -// }; - -# include -# include // really just for type<> -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail { - -class BOOST_PYTHON_DECL type_object_base : public python_type -{ - public: - explicit type_object_base(PyTypeObject* type_type); - virtual ~type_object_base(); - - public: - enum capability { - hash, call, str, getattr, setattr, compare, repr, richcompare, - - mapping_length, mapping_subscript, mapping_ass_subscript, - - sequence_length, sequence_item, sequence_ass_item, - sequence_concat, sequence_repeat, sequence_slice, sequence_ass_slice, - - number_add, number_subtract, number_multiply, number_divide, - number_remainder, number_divmod, number_power, number_negative, - number_positive, number_absolute, number_nonzero, number_invert, - number_lshift, number_rshift, number_and, number_xor, number_or, - number_coerce, number_int, number_long, number_float, number_oct, - number_hex, number_inplace_add, number_inplace_subtract, - number_inplace_multiply, number_inplace_divide, - number_inplace_remainder, number_inplace_power, - number_inplace_lshift, number_inplace_rshift, - number_inplace_and, number_inplace_or, number_inplace_xor - }; - - void enable(capability); - - // - // type behaviors - // - public: // Callbacks for basic type functionality. - virtual PyObject* instance_repr(PyObject*) const; - virtual int instance_compare(PyObject*, PyObject* other) const; - virtual PyObject* instance_str(PyObject*) const; - virtual long instance_hash(PyObject*) const; - virtual PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* kw) const; - virtual PyObject* instance_getattr(PyObject* obj, const char* name) const; - virtual int instance_setattr(PyObject* obj, const char* name, PyObject* value) const; - - // Dealloc is a special case, since every type needs a nonzero tp_dealloc slot. - virtual void instance_dealloc(PyObject*) const = 0; - - public: // Callbacks for mapping methods - virtual int instance_mapping_length(PyObject*) const; - virtual PyObject* instance_mapping_subscript(PyObject*, PyObject*) const ; - virtual int instance_mapping_ass_subscript(PyObject*, PyObject*, PyObject*) const; - - public: // Callbacks for sequence methods - virtual int instance_sequence_length(PyObject* obj) const; - virtual PyObject* instance_sequence_concat(PyObject* obj, PyObject* other) const; - virtual PyObject* instance_sequence_repeat(PyObject* obj, int n) const; - virtual PyObject* instance_sequence_item(PyObject* obj, int n) const; - virtual PyObject* instance_sequence_slice(PyObject* obj, int start, int finish) const; - virtual int instance_sequence_ass_item(PyObject* obj, int n, PyObject* value) const; - virtual int instance_sequence_ass_slice(PyObject* obj, int start, int finish, PyObject* value) const; - - public: // Callbacks for number methods - virtual PyObject* instance_number_add(PyObject*, PyObject*) const; - virtual PyObject* instance_number_subtract(PyObject*, PyObject*) const; - virtual PyObject* instance_number_multiply(PyObject*, PyObject*) const; - virtual PyObject* instance_number_divide(PyObject*, PyObject*) const; - virtual PyObject* instance_number_remainder(PyObject*, PyObject*) const; - virtual PyObject* instance_number_divmod(PyObject*, PyObject*) const; - virtual PyObject* instance_number_power(PyObject*, PyObject*, PyObject*) const; - virtual PyObject* instance_number_negative(PyObject*) const; - virtual PyObject* instance_number_positive(PyObject*) const; - virtual PyObject* instance_number_absolute(PyObject*) const; - virtual int instance_number_nonzero(PyObject*) const; - virtual PyObject* instance_number_invert(PyObject*) const; - virtual PyObject* instance_number_lshift(PyObject*, PyObject*) const; - virtual PyObject* instance_number_rshift(PyObject*, PyObject*) const; - virtual PyObject* instance_number_and(PyObject*, PyObject*) const; - virtual PyObject* instance_number_xor(PyObject*, PyObject*) const; - virtual PyObject* instance_number_or(PyObject*, PyObject*) const; - virtual int instance_number_coerce(PyObject*, PyObject**, PyObject**) const; - virtual PyObject* instance_number_int(PyObject*) const; - virtual PyObject* instance_number_long(PyObject*) const; - virtual PyObject* instance_number_float(PyObject*) const; - virtual PyObject* instance_number_oct(PyObject*) const; - virtual PyObject* instance_number_hex(PyObject*) const; - - virtual PyObject* instance_number_inplace_add(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_subtract(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_multiply(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_divide(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_remainder(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_lshift(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_rshift(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_and(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_or(PyObject*, PyObject*) const; - virtual PyObject* instance_number_inplace_xor(PyObject*, PyObject*) const; - - public: // Callbacks for rich comparisons - virtual PyObject* instance_lt(PyObject*, PyObject*) const; - virtual PyObject* instance_le(PyObject*, PyObject*) const; - virtual PyObject* instance_eq(PyObject*, PyObject*) const; - virtual PyObject* instance_ne(PyObject*, PyObject*) const; - virtual PyObject* instance_gt(PyObject*, PyObject*) const; - virtual PyObject* instance_ge(PyObject*, PyObject*) const; -}; - -template -class type_object : public type_object_base -{ - public: - typedef T instance; - - type_object(PyTypeObject* type_type, const char* name) - : type_object_base(type_type) - { - assert(name != 0); - this->tp_name = const_cast(name); - } - - type_object(PyTypeObject* type_type) - : type_object_base(type_type) - { - this->tp_name = const_cast(typeid(instance).name()); - } - - private: // Overridable behaviors. - // Called when the reference count goes to zero. The default implementation - // is "delete p". If you have not allocated your object with operator new or - // you have other constraints, you'll need to override this - virtual void dealloc(T* p) const; - - private: // Implementation of type_object_base hooks. Do not reimplement in derived classes. - void instance_dealloc(PyObject*) const; -}; - -// -// type objects -// -template -class callable : public Base -{ - public: - typedef callable properties; // Convenience for derived class construction - typedef typename Base::instance instance; - callable(PyTypeObject* type_type, const char* name); - callable(PyTypeObject* type_type); - private: - PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* kw) const; -}; - -template -class getattrable : public Base -{ - public: - typedef getattrable properties; // Convenience for derived class construction - typedef typename Base::instance instance; - getattrable(PyTypeObject* type_type, const char* name); - getattrable(PyTypeObject* type_type); - private: - PyObject* instance_getattr(PyObject* obj, const char* name) const; -}; - -template -class setattrable : public Base -{ - public: - typedef setattrable properties; // Convenience for derived class construction - typedef typename Base::instance instance; - setattrable(PyTypeObject* type_type, const char* name); - setattrable(PyTypeObject* type_type); - private: - int instance_setattr(PyObject* obj, const char* name, PyObject* value) const; -}; - -template -class reprable : public Base -{ - public: - typedef reprable properties; // Convenience for derived class construction - typedef typename Base::instance instance; - reprable(PyTypeObject* type_type, const char* name); - reprable(PyTypeObject* type_type); - private: - PyObject* instance_repr(PyObject* obj) const; -}; - -// -// Member function definitions -// - -// type_object<> -template -void type_object::instance_dealloc(PyObject* obj) const -{ - this->dealloc(downcast(obj).get()); -} - -template -void type_object::dealloc(T* obj) const -{ - delete obj; -} - -// callable -template -callable::callable(PyTypeObject* type_type, const char* name) - : Base(type_type, name) -{ - this->enable(call); -} - -template -callable::callable(PyTypeObject* type_type) - : Base(type_type) -{ - this->enable(call); -} - -template -PyObject* callable::instance_call(PyObject* obj, PyObject* args, PyObject* kw) const -{ - return downcast(obj)->call(args, kw); -} - -// getattrable -template -getattrable::getattrable(PyTypeObject* type_type, const char* name) - : Base(type_type, name) -{ - this->enable(getattr); -} - -template -getattrable::getattrable(PyTypeObject* type_type) - : Base(type_type) -{ - this->enable(getattr); -} - -template -PyObject* getattrable::instance_getattr(PyObject* obj, const char* name) const -{ - return downcast(obj)->getattr(name); -} - -// setattrable -template -setattrable::setattrable(PyTypeObject* type_type, const char* name) - : Base(type_type, name) -{ - this->enable(setattr); -} - -template -setattrable::setattrable(PyTypeObject* type_type) - : Base(type_type) -{ - this->enable(setattr); -} - -template -int setattrable::instance_setattr(PyObject* obj, const char* name, PyObject* value) const -{ - return downcast(obj)->setattr(name, value); -} - -// reprable -template -reprable::reprable(PyTypeObject* type_type, const char* name) - : Base(type_type, name) -{ - this->enable(repr); -} - -template -reprable::reprable(PyTypeObject* type_type) - : Base(type_type) -{ - this->enable(repr); -} - -template -PyObject* reprable::instance_repr(PyObject* obj) const -{ - return downcast(obj)->repr(); -} - - // Helper class for optimized allocation of PODs: If two PODs - // happen to contain identical byte patterns, they may share their - // memory. Reference counting is used to free unused memory. - // This is useful because method tables of related extension classes tend - // to be identical, so less memory is needed for them. - class BOOST_PYTHON_DECL shared_pod_manager - { - typedef std::pair holder; - typedef std::vector storage; - - public: - static shared_pod_manager& obj(); - ~shared_pod_manager(); - - // Allocate memory for POD T and fill it with zeros. - // This memory is initially not shared. - template - static void create(T*& t) - { - t = reinterpret_cast(obj().create(sizeof(T))); - } - - // Decrement the refcount for the memory t points to. If the count - // goes to zero, the memory is freed. - template - static void dispose(T* t) - { - obj().dec_ref(t, sizeof(T)); - } - - // Attempt to share the memory t points to. If memory with the same - // contents already exists, t is replaced by a pointer to this memory, - // and t's old memory is disposed. Otherwise, t will be registered for - // potential future sharing. - template - static void replace_if_equal(T*& t) - { - t = reinterpret_cast(obj().replace_if_equal(t, sizeof(T))); - } - - // Create a copy of t's memory that is guaranteed to be private to t. - // Afterwards t points to the new memory, unless it was already private, in - // which case there is no change (except that t's memory will no longer - // be considered for future sharing - see raplade_if_equal()) - // This function *must* be called before the contents of (*t) can - // be overwritten. Otherwise, inconsistencies and crashes may result. - template - static void make_unique_copy(T*& t) - { - t = reinterpret_cast(obj().make_unique_copy(t, sizeof(T))); - } - - private: - void* replace_if_equal(void* pod, std::size_t size); - void* make_unique_copy(void* pod, std::size_t size); - void* create(std::size_t size); - void dec_ref(void* pod, std::size_t size); - void erase_from_list(void* pod); - - struct compare; - struct identical; - - private: - shared_pod_manager() {} // instance - -#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST - public: -#endif - storage m_storage; - }; - - - BOOST_PYTHON_DECL void add_capability(type_object_base::capability capability, - PyTypeObject* dest); - -// This macro gets the length of an array as a compile-time constant, and will -// fail to compile if the parameter is a pointer. -#ifdef __BORLANDC__ // smart implementation doesn't work for borland; maybe someone knows a workaround? -# define PY_ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0])) -#else -# define PY_ARRAY_LENGTH(a) \ - (sizeof(::boost::python::detail::countof_validate(a, &(a))) ? sizeof(a) / sizeof((a)[0]) : 0) -#endif - - template - inline void countof_validate(T* const, T* const*); - - template - inline int countof_validate(const void*, T); - -}}} // namespace boost::python::detail - -#endif // TYPES_DWA051800_H_ diff --git a/include/boost/python/detail/void_adaptor.hpp b/include/boost/python/detail/void_adaptor.hpp deleted file mode 100644 index 3b4b2124..00000000 --- a/include/boost/python/detail/void_adaptor.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. - -#ifndef VOID_ADAPTOR_DWA20011112_HPP -# define VOID_ADAPTOR_DWA20011112_HPP - -namespace boost { namespace python { namespace detail { - - extern BOOST_PYTHON_DECL PyObject arbitrary_object; - - template - struct void_adaptor - { - typedef PyObject* result_type; - - void_adaptor(T const& f) - : m_f(f) - {} - - PyObject* operator()() const - { - m_f(); - return &arbitrary_object; - } - private: - T m_f; - }; - - template - void_adaptor make_void_adaptor(T const& f) - { - return void_adaptor(f); - } -}}} // namespace boost::python::detail - -#endif // VOID_ADAPTOR_DWA20011112_HPP - diff --git a/include/boost/python/module_builder.hpp b/include/boost/python/module_builder.hpp deleted file mode 100644 index 222b28d7..00000000 --- a/include/boost/python/module_builder.hpp +++ /dev/null @@ -1,76 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef MODULE_DWA051000_H_ -# define MODULE_DWA051000_H_ - -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -class BOOST_PYTHON_DECL module_builder_base -{ - public: - // Create a module. REQUIRES: only one module_builder is created per module. - module_builder_base(const char* name); - ~module_builder_base(); - - // Add elements to the module - void add(detail::function* x, const char* name); - void add(PyTypeObject* x, const char* name = 0); - void add(ref x, const char*name); - - // Return true iff a module is currently being built. - static bool initializing(); - - // Return the name of the module currently being built. - // REQUIRES: initializing() == true - static string name(); - - // Return a pointer to the Python module object being built - PyObject* module() const; - - private: - PyObject* m_module; - static PyMethodDef initial_methods[1]; -}; - -class module_builder : public module_builder_base -{ - public: - module_builder(const char* name) - : module_builder_base(name) {} - - template - void def_raw(Fn fn, const char* name) - { - add(detail::new_raw_arguments_function(fn), name); - } - - template - void def(Fn fn, const char* name) - { - add(detail::new_wrapped_function(fn), name); - } -}; - -// -// inline implementations -// -inline PyObject* module_builder_base::module() const -{ - return m_module; -} - -}} // namespace boost::python - -#endif diff --git a/include/boost/python/objects.hpp b/include/boost/python/objects.hpp deleted file mode 100644 index f2adb65b..00000000 --- a/include/boost/python/objects.hpp +++ /dev/null @@ -1,396 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef OBJECTS_DWA051100_H_ -# define OBJECTS_DWA051100_H_ - -# ifdef BOOST_PYTHON_V2 -# error obsolete -# else -# include -# include -# include -# include "boost/operators.hpp" -# include - -namespace boost { namespace python { - -class BOOST_PYTHON_DECL object -{ - public: - explicit object(ref p); - - // Return a reference to the held object - ref reference() const; - - // Return a raw pointer to the held object - PyObject* get() const; - - private: - ref m_p; -}; - -class tuple; - -class BOOST_PYTHON_DECL tuple_base : public object -{ - public: - explicit tuple_base(std::size_t n = 0); - explicit tuple_base(ref p); - - static PyTypeObject* type_obj(); - static bool accepts(ref p); - std::size_t size() const; - ref operator[](std::size_t pos) const; - - void set_item(std::size_t pos, const ref& rhs); - - tuple slice(int low, int high) const; - - friend BOOST_PYTHON_DECL tuple operator+(const tuple&, const tuple&); - friend BOOST_PYTHON_DECL tuple& operator+=(tuple&, const tuple&); -}; - -class tuple : public tuple_base -{ - public: - explicit tuple(std::size_t n = 0) : tuple_base(n) {} - explicit tuple(ref p) : tuple_base(p) {} - - template - tuple(const std::pair& x) - : tuple_base(ref(PyTuple_New(2))) - { - set_item(0, x.first); - set_item(1, x.second); - } - - template - tuple(const First& first, const Second& second) - : tuple_base(ref(PyTuple_New(2))) - { - set_item(0, first); - set_item(1, second); - } - - template - tuple(const First& first, const Second& second, const Third& third) - : tuple_base(ref(PyTuple_New(3))) - { - set_item(0, first); - set_item(1, second); - set_item(2, third); - } - - template - tuple(const First& first, const Second& second, const Third& third, const Fourth& fourth) - : tuple_base(ref(PyTuple_New(4))) - { - set_item(0, first); - set_item(1, second); - set_item(2, third); - set_item(3, fourth); - } - - template - void set_item(std::size_t pos, const T& rhs) - { - this->set_item(pos, make_ref(rhs)); - } - - void set_item(std::size_t pos, const ref& rhs) - { - tuple_base::set_item(pos, rhs); - } -}; - -class list; - -struct BOOST_PYTHON_DECL list_proxy; -struct BOOST_PYTHON_DECL list_slice_proxy; - -class BOOST_PYTHON_DECL list_base : public object -{ - protected: - typedef list_proxy proxy; - typedef list_slice_proxy slice_proxy; - public: - explicit list_base(ref p); - explicit list_base(std::size_t sz = 0); - static PyTypeObject* type_obj(); - static bool accepts(ref p); - std::size_t size() const; - ref operator[](std::size_t pos) const; - proxy operator[](std::size_t pos); - ref get_item(std::size_t pos) const; - - void set_item(std::size_t pos, const ref& ); - -// void set_item(std::size_t pos, const object& ); - - void insert(std::size_t index, const ref& item); - - void push_back(const ref& item); - - void append(const ref& item); - - list slice(int low, int high) const; - slice_proxy slice(int low, int high); - void sort(); - void reverse(); - tuple as_tuple() const; -}; - -class list : public list_base -{ - public: - explicit list(ref p) : list_base(p) {} - explicit list(std::size_t sz = 0) : list_base(sz) {} - template - void set_item(std::size_t pos, const T& x) - { this->set_item(pos, make_ref(x)); } - template - void insert(std::size_t index, const T& x) - { this->insert(index, make_ref(x)); } - template - void push_back(const T& item) - { this->push_back(make_ref(item)); } - template - void append(const T& item) - { this->append(make_ref(item)); } - - void set_item(std::size_t pos, const ref& x) { list_base::set_item(pos, x); } - void insert(std::size_t index, const ref& item) { list_base::insert(index, item); } - void push_back(const ref& item) { list_base::push_back(item); } - void append(const ref& item) { list_base::append(item); } -}; - -class BOOST_PYTHON_DECL string - : public object, public boost::multipliable2 -{ - public: - // Construct from an owned PyObject*. - // Precondition: p must point to a python string. - explicit string(ref p); - explicit string(const char* s); - string(const char* s, std::size_t length); - string(const string& rhs); - - enum interned_t { interned }; - string(const char* s, interned_t); - - // Get the type object for Strings - static PyTypeObject* type_obj(); - - // Return true if the given object is a python string - static bool accepts(ref o); - - // Return the length of the string. - std::size_t size() const; - - // Returns a null-terminated representation of the contents of string. - // The pointer refers to the internal buffer of string, not a copy. - // The data must not be modified in any way. It must not be de-allocated. - const char* c_str() const; - - string& operator*=(unsigned int repeat_count); - string& operator+=(const string& rhs); - friend string operator+(string x, string y); - string& operator+=(const char* rhs); - friend string operator+(string x, const char* y); - friend string operator+(const char* x, string y); - - void intern(); - - friend string operator%(const string& format, const tuple& args); -}; - -class dictionary; - -struct BOOST_PYTHON_DECL dictionary_proxy; - -class BOOST_PYTHON_DECL dictionary_base : public object -{ - protected: - typedef dictionary_proxy proxy; - - public: - explicit dictionary_base(ref p); - dictionary_base(); - void clear(); - - static PyTypeObject* type_obj(); - static bool accepts(ref p); - - public: - proxy operator[](ref key); - ref operator[](ref key) const; - ref get_item(const ref& key) const; - ref get_item(const ref& key, const ref& default_) const; - - void set_item(const ref& key, const ref& value); - - void erase(ref key); - -// proxy operator[](const object& key); -// ref operator[](const object& key) const; - -// ref get_item(const object& key, ref default_ = ref()) const; -// void set_item(const object& key, const ref& value); - -// void erase(const object& key); - - list items() const; - list keys() const; - list values() const; - - std::size_t size() const; - // TODO: iterator support -}; - -struct BOOST_PYTHON_DECL dictionary_proxy -{ - template - const ref& operator=(const T& rhs) - { return (*this) = make_ref(rhs); } - const ref& operator=(const ref& rhs); - - operator ref() const; - private: - friend class dictionary_base; - dictionary_proxy(const ref& dict, const ref& key); - - // This is needed to work around the very strange MSVC error report that the - // return type of the built-in operator= differs from that of the ones - // defined above. Couldn't hurt to make these un-assignable anyway, though. - const ref& operator=(const dictionary_proxy&); // Not actually implemented - private: - ref m_dict; - ref m_key; -}; - -class dictionary : public dictionary_base -{ - typedef dictionary_proxy proxy; - public: - explicit dictionary(ref p) : dictionary_base(p) {} - dictionary() : dictionary_base() {} - - template - proxy operator[](const Key& key) - { return this->operator[](make_ref(key)); } - proxy operator[](ref key) - { return dictionary_base::operator[](key); } - - template - ref operator[](const Key& key) const - { return this->operator[](make_ref(key)); } - ref operator[](ref key) const - { return dictionary_base::operator[](key); } - - template - ref get_item(const Key& key) const - { return this->get_item(make_ref(key)); } - ref get_item(const ref& key) const - { return dictionary_base::get_item(key); } - - template - ref get_item(const Key& key, const Default& default_) const - { return this->get_item(make_ref(key), make_ref(default_)); } - ref get_item(const ref& key, const ref& default_) const - { return dictionary_base::get_item(key, default_); } - - template - void set_item(const Key& key, const Value& value) - { this->set_item(make_ref(key), make_ref(value)); } - void set_item(const ref& key, const ref& value) - { dictionary_base::set_item(key, value); } - - template - void erase(const Key& key) - { this->erase(make_ref(key)); } - void erase(ref key) - { dictionary_base::erase(key); } -}; - -struct BOOST_PYTHON_DECL list_proxy -{ - template - const ref& operator=(const T& rhs) - { return (*this) = make_ref(rhs); } - const ref& operator=(const ref& rhs); - - operator ref() const; - - private: - friend class list_base; - list_proxy(const ref& list, std::size_t index); - - // This is needed to work around the very strange MSVC error report that the - // return type of the built-in operator= differs from that of the ones - // defined above. Couldn't hurt to make these un-assignable anyway, though. - const ref& operator=(const list_proxy&); // Not actually implemented - private: - list m_list; - std::size_t m_index; -}; - -struct BOOST_PYTHON_DECL list_slice_proxy -{ - const list& operator=(const list& rhs); - operator ref() const; - operator list() const; - std::size_t size() const; - ref operator[](std::size_t pos) const; - private: - friend class list_base; - list_slice_proxy(const ref& list, int low, int high); - private: - ref m_list; - int m_low, m_high; -}; - -}} // namespace boost::python - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::tuple&); -BOOST_PYTHON_DECL boost::python::tuple from_python(PyObject* p, boost::python::type); - -inline boost::python::tuple from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::list&); -BOOST_PYTHON_DECL boost::python::list from_python(PyObject* p, boost::python::type); - -inline boost::python::list from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::string&); -BOOST_PYTHON_DECL boost::python::string from_python(PyObject* p, boost::python::type); - -inline boost::python::string from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::dictionary&); -BOOST_PYTHON_DECL boost::python::dictionary from_python(PyObject* p, boost::python::type); - -inline boost::python::dictionary from_python(PyObject* p, boost::python::type) -{ - return from_python(p, boost::python::type()); -} - -BOOST_PYTHON_END_CONVERSION_NAMESPACE -# endif // !BOOST_PYTHON_V2 -#endif // OBJECTS_DWA051100_H_ diff --git a/include/boost/python/py_interface.hpp b/include/boost/python/py_interface.hpp deleted file mode 100644 index c1416d5c..00000000 --- a/include/boost/python/py_interface.hpp +++ /dev/null @@ -1,700 +0,0 @@ -// Automatically generated from py_api_gen.py -#ifndef PY_INTERFACE_HPP -#define PY_INTERFACE_HPP - -#include -#include - -namespace boost { namespace python { namespace api { - -enum call_dict_usage { use_new_dict, use_local_dict, use_global_dict }; - -namespace api_detail { - -BOOST_PYTHON_DECL object get_func(const char* name); -BOOST_PYTHON_DECL object call_statement(const char *stmt, int n, ...); -BOOST_PYTHON_DECL object call_statement_du(const char *stmt, call_dict_usage cdu, int n, ...); - -template -struct get_arg -{ - get_arg(A const &a) : h(a) {} - object h; - operator object const& () { return h; } - operator object const* () { return &h; } -}; - -template<> -struct get_arg -{ - get_arg(object const &a) : h(a) {} - object const &h; - operator object const& () { return h; } - operator object const* () { return &h; } -}; - -template<> -struct get_arg -{ - get_arg(PyObject* a) : h((python::detail::borrowed_reference)a) {} - object h; - operator object const& () { return h; } - operator object const* () { return &h; } -}; - -} - -BOOST_PYTHON_DECL object locals(); - - -template -object abs(A0 const& a0) -{ - return api_detail::get_func("abs")(api_detail::get_arg(a0)); -} -BOOST_PYTHON_DECL object abs(object const& a0); -BOOST_PYTHON_DECL object abs(short a0); -BOOST_PYTHON_DECL object abs(int a0); -BOOST_PYTHON_DECL object abs(long a0); -BOOST_PYTHON_DECL object abs(double const & a0); -BOOST_PYTHON_DECL object apply(object const& a0, object const& a1); -BOOST_PYTHON_DECL object apply(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL bool callable(object const& a0); -template -object chr(A0 const& a0) -{ - return api_detail::get_func("chr")(api_detail::get_arg(a0)); -} -BOOST_PYTHON_DECL object chr(object const& a0); -BOOST_PYTHON_DECL object chr(short a0); -BOOST_PYTHON_DECL object chr(int a0); -BOOST_PYTHON_DECL object chr(long a0); -template -int cmp(A0 const& a0, A1 const& a1) -{ - int rslt; - int r = ::PyObject_Cmp(api_detail::get_arg(a0), api_detail::get_arg(a1), &rslt); - if(r == -1) - throw_error_already_set(); - return rslt; -} -BOOST_PYTHON_DECL int cmp(object const& a0, object const& a1); -BOOST_PYTHON_DECL object coerce(object const& a0, object const& a1); -BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2); -BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2, object const& a3); -BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2, int a3); -BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); -BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2, int a3, int a4); -template -object complex(A0 const& a0) -{ - return api_detail::get_func("complex")(api_detail::get_arg(a0)); -} -BOOST_PYTHON_DECL object complex(object const& a0); -BOOST_PYTHON_DECL object complex(double const& a0); -template -object complex(A0 const& a0, A1 const& a1) -{ - return api_detail::get_func("complex")(api_detail::get_arg(a0), api_detail::get_arg(a1)); -} -BOOST_PYTHON_DECL object complex(object const& a0, object const& a1); -BOOST_PYTHON_DECL object complex(double const& a0, double const& a1); -BOOST_PYTHON_DECL object dict(); -BOOST_PYTHON_DECL object dict(object const& a0); -BOOST_PYTHON_DECL object dir(); -BOOST_PYTHON_DECL object dir(object const& a0); -template -object divmod(A0 const& a0, A1 const& a1) -{ - return api_detail::get_func("divmod")(api_detail::get_arg(a0), api_detail::get_arg(a1)); -} -BOOST_PYTHON_DECL object divmod(object const& a0, object const& a1); -BOOST_PYTHON_DECL object divmod(int a0, int a1); -BOOST_PYTHON_DECL object divmod(long a0, long a1); -BOOST_PYTHON_DECL object divmod(double const& a0, double const& a1); -BOOST_PYTHON_DECL object eval(const char* a0); -BOOST_PYTHON_DECL object eval(const char* a0, object const& a2); -BOOST_PYTHON_DECL object eval(const char* a0, object const& a2, object const& a3); -BOOST_PYTHON_DECL object exec(const char* a0); -BOOST_PYTHON_DECL object exec(const char* a0, object const& a2); -BOOST_PYTHON_DECL object exec(const char* a0, object const& a2, object const& a3); -BOOST_PYTHON_DECL object execfile(object const& a0); -BOOST_PYTHON_DECL object execfile(object const& a0, object const& a1); -BOOST_PYTHON_DECL object execfile(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object file(object const& a0); -BOOST_PYTHON_DECL object file(const char* a0); -BOOST_PYTHON_DECL object file(object const& a0, object const& a1); -BOOST_PYTHON_DECL object file(const char* a0, const char* a1); -BOOST_PYTHON_DECL object file(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object file(const char* a0, const char* a1, int a2); -BOOST_PYTHON_DECL object filter(object const& a0, object const& a1); -BOOST_PYTHON_DECL object float_(object const& a0); -BOOST_PYTHON_DECL object float_(const char* a0); -BOOST_PYTHON_DECL object float_(double const& a0); -BOOST_PYTHON_DECL object getattr(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object getattr(object const& a0, const char * a1, object const& a2); -BOOST_PYTHON_DECL object globals(); -BOOST_PYTHON_DECL bool hasattr(object const& a0, object const& a1); -BOOST_PYTHON_DECL bool hasattr(object const& a0, const char* a1); -BOOST_PYTHON_DECL long hash(object const& a0); -template -object hex(A0 const& a0) -{ - return api_detail::get_func("hex")(api_detail::get_arg(a0)); -} -BOOST_PYTHON_DECL object hex(object const& a0); -BOOST_PYTHON_DECL object hex(char a0); -BOOST_PYTHON_DECL object hex(short a0); -BOOST_PYTHON_DECL object hex(int a0); -BOOST_PYTHON_DECL object hex(long a0); -BOOST_PYTHON_DECL long id(object const& a0); -BOOST_PYTHON_DECL object input(); -BOOST_PYTHON_DECL object input(object const& a0); -BOOST_PYTHON_DECL object input(const char* a0); -BOOST_PYTHON_DECL object int_(object const& a0); -BOOST_PYTHON_DECL object int_(long a0); -BOOST_PYTHON_DECL object int_(const char* a0); -BOOST_PYTHON_DECL object intern(object const& a0); -BOOST_PYTHON_DECL object intern(const char* a0); -BOOST_PYTHON_DECL bool isinstance(object const& a0, object const& a1); -BOOST_PYTHON_DECL bool issubclass(object const& a0, object const& a1); -BOOST_PYTHON_DECL object iter(object const& a0); -BOOST_PYTHON_DECL object iter(object const& a0, object const& a1); -BOOST_PYTHON_DECL long len(object const& a0); -BOOST_PYTHON_DECL object list(); -BOOST_PYTHON_DECL object list(object const& a0); -BOOST_PYTHON_DECL object long_(object const& a0); -BOOST_PYTHON_DECL object long_(long a0); -BOOST_PYTHON_DECL object long_(const char* a0); -BOOST_PYTHON_DECL object map(object const& a0); -BOOST_PYTHON_DECL object map(object const& a0, object const& a1); -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3); -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); -template -object max(A0 const& a0) -{ - return api_detail::get_func("max")(api_detail::get_arg(a0)); -} -template -object max(A0 const& a0, A1 const& a1) -{ - return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1)); -} -template -object max(A0 const& a0, A1 const& a1, A2 const& a2) -{ - return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2)); -} -template -object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3) -{ - return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3)); -} -template -object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) -{ - return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4)); -} -template -object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) -{ - return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5)); -} -template -object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) -{ - return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6)); -} -template -object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) -{ - return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7)); -} -template -object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) -{ - return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7), api_detail::get_arg(a8)); -} -template -object max(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) -{ - return api_detail::get_func("max")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7), api_detail::get_arg(a8), api_detail::get_arg(a9)); -} -BOOST_PYTHON_DECL object max(object const& a0); -BOOST_PYTHON_DECL object max(object const& a0, object const& a1); -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3); -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); -template -object min(A0 const& a0) -{ - return api_detail::get_func("min")(api_detail::get_arg(a0)); -} -template -object min(A0 const& a0, A1 const& a1) -{ - return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1)); -} -template -object min(A0 const& a0, A1 const& a1, A2 const& a2) -{ - return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2)); -} -template -object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3) -{ - return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3)); -} -template -object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) -{ - return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4)); -} -template -object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) -{ - return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5)); -} -template -object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) -{ - return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6)); -} -template -object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) -{ - return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7)); -} -template -object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) -{ - return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7), api_detail::get_arg(a8)); -} -template -object min(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) -{ - return api_detail::get_func("min")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2), api_detail::get_arg(a3), api_detail::get_arg(a4), api_detail::get_arg(a5), api_detail::get_arg(a6), api_detail::get_arg(a7), api_detail::get_arg(a8), api_detail::get_arg(a9)); -} -BOOST_PYTHON_DECL object min(object const& a0); -BOOST_PYTHON_DECL object min(object const& a0, object const& a1); -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3); -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); -template -object oct(A0 const& a0) -{ - return api_detail::get_func("oct")(api_detail::get_arg(a0)); -} -BOOST_PYTHON_DECL object oct(object const& a0); -BOOST_PYTHON_DECL object oct(char a0); -BOOST_PYTHON_DECL object oct(short a0); -BOOST_PYTHON_DECL object oct(int a0); -BOOST_PYTHON_DECL object oct(long a0); -BOOST_PYTHON_DECL object open(object const& a0); -BOOST_PYTHON_DECL object open(const char* a0); -BOOST_PYTHON_DECL object open(object const& a0, object const& a1); -BOOST_PYTHON_DECL object open(const char* a0, const char* a1); -BOOST_PYTHON_DECL object open(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object open(const char* a0, const char* a1, int a2); -BOOST_PYTHON_DECL long ord(object const& a0); -BOOST_PYTHON_DECL long ord(const char* a0); -template -object pow(A0 const& a0, A1 const& a1) -{ - return api_detail::get_func("pow")(api_detail::get_arg(a0), api_detail::get_arg(a1)); -} -BOOST_PYTHON_DECL object pow(object const& a0, object const& a1); -BOOST_PYTHON_DECL object pow(double const& a0, double const& a1); -BOOST_PYTHON_DECL object pow(double const& a0, double const& a1, double const& a2); -template -object print(A0 const& a0) -{ - return api_detail::call_statement_du("print _1", use_new_dict, 1, (object const*)api_detail::get_arg(a0)); -} -template -object print(A0 const& a0, A1 const& a1) -{ - return api_detail::call_statement_du("print _1, _2", use_new_dict, 2, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1)); -} -template -object print(A0 const& a0, A1 const& a1, A2 const& a2) -{ - return api_detail::call_statement_du("print _1, _2, _3", use_new_dict, 3, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2)); -} -template -object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3) -{ - return api_detail::call_statement_du("print _1, _2, _3, _4", use_new_dict, 4, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3)); -} -template -object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) -{ - return api_detail::call_statement_du("print _1, _2, _3, _4, _5", use_new_dict, 5, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4)); -} -template -object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) -{ - return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6", use_new_dict, 6, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5)); -} -template -object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) -{ - return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7", use_new_dict, 7, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6)); -} -template -object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) -{ - return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8", use_new_dict, 8, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7)); -} -template -object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) -{ - return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8, _9", use_new_dict, 9, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8)); -} -template -object print(A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) -{ - return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8, _9, _10", use_new_dict, 10, (object const*)api_detail::get_arg(a0), (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9)); -} -BOOST_PYTHON_DECL object print(object const& a0); -BOOST_PYTHON_DECL object print(object const& a0, object const& a1); -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3); -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); -template -object print_file(object const& a0, A1 const& a1) -{ - return api_detail::call_statement_du("print >>_1, _2", use_new_dict, 2, a0, (object const*)api_detail::get_arg(a1)); -} -template -object print_file(object const& a0, A1 const& a1, A2 const& a2) -{ - return api_detail::call_statement_du("print >>_1, _2, _3", use_new_dict, 3, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2)); -} -template -object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3) -{ - return api_detail::call_statement_du("print >>_1, _2, _3, _4", use_new_dict, 4, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3)); -} -template -object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) -{ - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5", use_new_dict, 5, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4)); -} -template -object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) -{ - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6", use_new_dict, 6, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5)); -} -template -object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) -{ - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7", use_new_dict, 7, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6)); -} -template -object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) -{ - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8", use_new_dict, 8, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7)); -} -template -object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) -{ - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9", use_new_dict, 9, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8)); -} -template -object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) -{ - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9, _10", use_new_dict, 10, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9)); -} -template -object print_file(object const& a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9, A10 const& a10) -{ - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11", use_new_dict, 11, a0, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9), (object const*)api_detail::get_arg(a10)); -} -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1); -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3); -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10); -template -object range(A0 const& a0) -{ - return api_detail::get_func("range")(api_detail::get_arg(a0)); -} -BOOST_PYTHON_DECL object range(object const& a0); -BOOST_PYTHON_DECL object range(int a0); -template -object range(A0 const& a0, A1 const& a1) -{ - return api_detail::get_func("range")(api_detail::get_arg(a0), api_detail::get_arg(a1)); -} -BOOST_PYTHON_DECL object range(object const& a0, object const& a1); -BOOST_PYTHON_DECL object range(int a0, int a1); -template -object range(A0 const& a0, A1 const& a1, A2 const& a2) -{ - return api_detail::get_func("range")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2)); -} -BOOST_PYTHON_DECL object range(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object range(int a0, int a1, int a2); -BOOST_PYTHON_DECL object raw_input(); -BOOST_PYTHON_DECL object raw_input(object const& a0); -BOOST_PYTHON_DECL object raw_input(const char* a0); -BOOST_PYTHON_DECL object reduce(object const& a0, object const& a1); -BOOST_PYTHON_DECL object reduce(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object reload(object const& a0); -BOOST_PYTHON_DECL object repr(object const& a0); -template -object round(A0 const& a0) -{ - return api_detail::get_func("round")(api_detail::get_arg(a0)); -} -BOOST_PYTHON_DECL object round(object const& a0); -BOOST_PYTHON_DECL object round(double const& a0); -template -object round(A0 const& a0, A1 const& a1) -{ - return api_detail::get_func("round")(api_detail::get_arg(a0), api_detail::get_arg(a1)); -} -BOOST_PYTHON_DECL object round(object const& a0, object const& a1); -BOOST_PYTHON_DECL object round(double const& a0, double const& a1); -template -object slice(A0 const& a0) -{ - return api_detail::get_func("slice")(api_detail::get_arg(a0)); -} -BOOST_PYTHON_DECL object slice(object const& a0); -BOOST_PYTHON_DECL object slice(int a0); -template -object slice(A0 const& a0, A1 const& a1) -{ - return api_detail::get_func("slice")(api_detail::get_arg(a0), api_detail::get_arg(a1)); -} -BOOST_PYTHON_DECL object slice(object const& a0, object const& a1); -BOOST_PYTHON_DECL object slice(int a0, int a1); -template -object slice(A0 const& a0, A1 const& a1, A2 const& a2) -{ - return api_detail::get_func("slice")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2)); -} -BOOST_PYTHON_DECL object slice(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object slice(int a0, int a1, int a2); -BOOST_PYTHON_DECL object str(object const& a0); -BOOST_PYTHON_DECL object tuple(); -BOOST_PYTHON_DECL object tuple(object const& a0); -BOOST_PYTHON_DECL object type_(object const& a0); -template -object unichr(A0 const& a0) -{ - return api_detail::get_func("unichr")(api_detail::get_arg(a0)); -} -BOOST_PYTHON_DECL object unichr(object const& a0); -BOOST_PYTHON_DECL object unichr(short a0); -BOOST_PYTHON_DECL object unichr(int a0); -BOOST_PYTHON_DECL object unichr(long a0); -BOOST_PYTHON_DECL object unicode(object const& a0); -BOOST_PYTHON_DECL object unicode(object const& a0, object const& a1); -BOOST_PYTHON_DECL object unicode(object const& a0, const char* a1); -BOOST_PYTHON_DECL object unicode(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object unicode(object const& a0, const char* a1, const char* a2); -BOOST_PYTHON_DECL object vars(); -BOOST_PYTHON_DECL object vars(object const& a0); -template -object xrange(A0 const& a0) -{ - return api_detail::get_func("xrange")(api_detail::get_arg(a0)); -} -BOOST_PYTHON_DECL object xrange(object const& a0); -BOOST_PYTHON_DECL object xrange(int a0); -template -object xrange(A0 const& a0, A1 const& a1) -{ - return api_detail::get_func("xrange")(api_detail::get_arg(a0), api_detail::get_arg(a1)); -} -BOOST_PYTHON_DECL object xrange(object const& a0, object const& a1); -BOOST_PYTHON_DECL object xrange(int a0, int a1); -template -object xrange(A0 const& a0, A1 const& a1, A2 const& a2) -{ - return api_detail::get_func("xrange")(api_detail::get_arg(a0), api_detail::get_arg(a1), api_detail::get_arg(a2)); -} -BOOST_PYTHON_DECL object xrange(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object xrange(int a0, int a1, int a2); -BOOST_PYTHON_DECL object zip(object const& a0); -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1); -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3); -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4); -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); -BOOST_PYTHON_DECL object compile_string(const char* a0, const char* a1, int a2); -BOOST_PYTHON_DECL int import_append_inittab(const char* a0, void(*a1)(void)); -BOOST_PYTHON_DECL object import_add_module(const char* a0); -BOOST_PYTHON_DECL object import_get_module_dict(); -BOOST_PYTHON_DECL object import_import(object const& a0); -BOOST_PYTHON_DECL object import_import(const char* a0); -BOOST_PYTHON_DECL object import_import_module(const char* a0); -BOOST_PYTHON_DECL object import_import_module_ex(const char* a0, object const& a1, object const& a2, object const& a3); -BOOST_PYTHON_DECL object module_get_dict(object const& a0); -BOOST_PYTHON_DECL int object_print(object const& a0, FILE* a1, int a2); -BOOST_PYTHON_DECL object run_file(FILE* a0, const char* a1, int a2, object const& a3, object const& a4); -BOOST_PYTHON_DECL int run_simple_file(FILE* a0, const char* a1); -BOOST_PYTHON_DECL int run_simple_string(const char* a0); -BOOST_PYTHON_DECL object run_string(const char* a0, int a1, object const& a2, object const& a3); -BOOST_PYTHON_DECL object call_statement(const char* a0); -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1); -template -object call_statement(const char* a0, A1 const& a1) -{ - return api_detail::call_statement(a0, 1, (object const*)api_detail::get_arg(a1)); -} -template -object call_statement(const char* a0, A1 const& a1, A2 const& a2) -{ - return api_detail::call_statement(a0, 2, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2)); -} -template -object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3) -{ - return api_detail::call_statement(a0, 3, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3)); -} -template -object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) -{ - return api_detail::call_statement(a0, 4, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4)); -} -template -object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) -{ - return api_detail::call_statement(a0, 5, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5)); -} -template -object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) -{ - return api_detail::call_statement(a0, 6, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6)); -} -template -object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) -{ - return api_detail::call_statement(a0, 7, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7)); -} -template -object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) -{ - return api_detail::call_statement(a0, 8, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8)); -} -template -object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) -{ - return api_detail::call_statement(a0, 9, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9)); -} -template -object call_statement(const char* a0, A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9, A10 const& a10) -{ - return api_detail::call_statement(a0, 10, (object const*)api_detail::get_arg(a1), (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9), (object const*)api_detail::get_arg(a10)); -} -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1); -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2); -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3); -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4); -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5); -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10); -template -object call_statement(const char* a0, call_dict_usage a1, A2 const& a2) -{ - return api_detail::call_statement_du(a0, a1, 1, (object const*)api_detail::get_arg(a2)); -} -template -object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3) -{ - return api_detail::call_statement_du(a0, a1, 2, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3)); -} -template -object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4) -{ - return api_detail::call_statement_du(a0, a1, 3, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4)); -} -template -object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) -{ - return api_detail::call_statement_du(a0, a1, 4, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5)); -} -template -object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6) -{ - return api_detail::call_statement_du(a0, a1, 5, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6)); -} -template -object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7) -{ - return api_detail::call_statement_du(a0, a1, 6, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7)); -} -template -object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8) -{ - return api_detail::call_statement_du(a0, a1, 7, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8)); -} -template -object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9) -{ - return api_detail::call_statement_du(a0, a1, 8, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9)); -} -template -object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9, A10 const& a10) -{ - return api_detail::call_statement_du(a0, a1, 9, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9), (object const*)api_detail::get_arg(a10)); -} -template -object call_statement(const char* a0, call_dict_usage a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5, A6 const& a6, A7 const& a7, A8 const& a8, A9 const& a9, A10 const& a10, A11 const& a11) -{ - return api_detail::call_statement_du(a0, a1, 10, (object const*)api_detail::get_arg(a2), (object const*)api_detail::get_arg(a3), (object const*)api_detail::get_arg(a4), (object const*)api_detail::get_arg(a5), (object const*)api_detail::get_arg(a6), (object const*)api_detail::get_arg(a7), (object const*)api_detail::get_arg(a8), (object const*)api_detail::get_arg(a9), (object const*)api_detail::get_arg(a10), (object const*)api_detail::get_arg(a11)); -} -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2); -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3); -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4); -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5); -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6); -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7); -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8); -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9); -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10); -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10, object const& a11); - -}}} - -#endif // PY_INTERFACE_HPP - diff --git a/include/boost/python/reference.hpp b/include/boost/python/reference.hpp deleted file mode 100644 index f070f114..00000000 --- a/include/boost/python/reference.hpp +++ /dev/null @@ -1,236 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef PYPTR_DWA050400_H_ -# define PYPTR_DWA050400_H_ - -# ifdef BOOST_PYTHON_V2 - -# error obsolete - -# else - -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# include - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -template -struct py_ptr_conversions : Base -{ - inline friend T from_python(PyObject* x, boost::python::type) - { return T(boost::python::downcast(x).get(), T::increment_count); } - - inline friend T from_python(PyObject* x, boost::python::type) - { return T(boost::python::downcast(x).get(), T::increment_count); } - - inline friend PyObject* to_python(T x) - { return boost::python::as_object(x.release()); } - -}; - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -BOOST_PYTHON_IMPORT_CONVERSION(py_ptr_conversions); - -template -class reference - : public py_ptr_conversions, T> -{ -public: - typedef T value_type; - - reference(const reference& rhs) - : m_p(rhs.m_p) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(m_p); - } - - reference() : m_p(0) {} - - // These are two ways of spelling the same thing, that we need to increment - // the reference count on the pointer when we're initialized. - enum increment_count_t { increment_count }; - - enum allow_null { null_ok }; - - template - explicit reference(T2* x) - : m_p(expect_non_null(x)) - { - assert(m_p->ob_refcnt > 0); - } - - template - reference(T2* x, increment_count_t) - : m_p(expect_non_null(x)) - { - assert(m_p->ob_refcnt > 0); - Py_INCREF(m_p); - } - - template - reference(T2* x, allow_null) - : m_p(x) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - } - - template - reference(T2* x, allow_null, increment_count_t) - : m_p(x) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(m_p); - } - - template - reference(T2* x, increment_count_t, allow_null) - : m_p(x) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(m_p); - } - - reference& operator=(const reference& rhs) - { - assert(rhs.m_p == 0 || rhs.m_p->ob_refcnt > 0); - Py_XINCREF(static_cast(rhs.m_p)); - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XDECREF(m_p); - m_p = rhs.m_p; - return *this; - } - - ~reference() - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XDECREF(m_p); - } - - T& operator*() const - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - return *m_p; - } - - // MSVC doesn't like boost::dereferencable unless T has a default - // constructor, so operator-> must be defined by hand :( - T* operator->() const - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - return &**this; - } - - T* get() const - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - return m_p; - } - - T* release() - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - T* p = m_p; - m_p = 0; - return p; - } - - void reset() - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XDECREF(m_p); - m_p = 0; - } - - template - void reset(T2* x) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XDECREF(m_p); - m_p = expect_non_null(x); - assert(m_p == 0 || m_p->ob_refcnt > 0); - } - - template - void reset(T2* x, increment_count_t) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(x); - Py_XDECREF(m_p); - m_p = expect_non_null(x); - assert(m_p->ob_refcnt > 0); - } - - template - void reset(T2* x, allow_null) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XDECREF(m_p); - m_p = x; - assert(m_p == 0 || m_p->ob_refcnt > 0); - } - - template - void reset(T2* x, allow_null, increment_count_t) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(x); - Py_XDECREF(m_p); - m_p = x; - assert(m_p == 0 || m_p->ob_refcnt > 0); - } - - template - void reset(T2* x, increment_count_t, allow_null) - { - assert(m_p == 0 || m_p->ob_refcnt > 0); - Py_XINCREF(x); - Py_XDECREF(m_p); - m_p = x; - assert(m_p == 0 || m_p->ob_refcnt > 0); - } - -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) -private: - template friend class shared_ptr; -#endif - - inline PyObject* object() const - { - return as_object(m_p); - } - - T* m_p; -}; - -typedef reference ref; - -template -ref make_ref(const T& x) -{ - return ref(to_python(x)); -} - -}} // namespace boost::python - -#endif // BOOST_PYTHON_V2 - -#endif // PYPTR_DWA050400_H_ diff --git a/src/classes.cpp b/src/classes.cpp deleted file mode 100644 index 440fe6a7..00000000 --- a/src/classes.cpp +++ /dev/null @@ -1,1047 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// 04 Mar 01 Rolled in const_cast from Dragon fork (Dave Abrahams) -// 03 Mar 01 added: pickle safety measures (Ralf W. Grosse-Kunstleve) -// 03 Mar 01 bug fix: use bound_function::create() (instead of new bound_function) - -#define BOOST_PYTHON_SOURCE - -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { - -namespace detail { - void enable_named_method(boost::python::detail::class_base* type_obj, const char* name); -} - -namespace { - // Add the name of the module currently being loaded to the name_space with the - // key "__module__". If no module is being loaded, or if name_space already has - // a key "__module", has no effect. This is not really a useful public - // interface; it's just used for class_t<>::class_t() below. - void add_current_module_name(dictionary&); - - bool is_prefix(const char* s1, const char* s2); - bool is_special_name(const char* name); - void enable_special_methods(boost::python::detail::class_base* derived, const tuple& bases, const dictionary& name_space); - - void report_ignored_exception(PyObject* source) - { - // This bit of code copied wholesale from classobject.c in the Python source. - PyObject *f, *t, *v, *tb; - PyErr_Fetch(&t, &v, &tb); - f = PySys_GetObject(const_cast("stderr")); - if (f != NULL) - { - PyFile_WriteString(const_cast("Exception "), f); - if (t) { - PyFile_WriteObject(t, f, Py_PRINT_RAW); - if (v && v != Py_None) { - PyFile_WriteString(const_cast(": "), f); - PyFile_WriteObject(v, f, 0); - } - } - PyFile_WriteString(const_cast(" in "), f); - PyFile_WriteObject(source, f, 0); - PyFile_WriteString(const_cast(" ignored\n"), f); - PyErr_Clear(); /* Just in case */ - } - Py_XDECREF(t); - Py_XDECREF(v); - Py_XDECREF(tb); - } - - // - // pickle support courtesy of "Ralf W. Grosse-Kunstleve" - // - PyObject* class_reduce(PyObject* klass) - { - return PyObject_GetAttrString(klass, const_cast("__name__")); - } - - ref global_class_reduce() - { - return ref(detail::new_wrapped_function(class_reduce)); - } - - - tuple instance_reduce(PyObject* obj) - { - ref instance_class(PyObject_GetAttrString(obj, const_cast("__class__"))); - - ref getinitargs(PyObject_GetAttrString(obj, const_cast("__getinitargs__")), - ref::null_ok); - PyErr_Clear(); - ref initargs; - if (getinitargs.get() != 0) - { - initargs = ref(PyEval_CallObject(getinitargs.get(), NULL)); - initargs = ref(PySequence_Tuple(initargs.get())); - } - else - { - initargs = ref(PyTuple_New(0)); - } - - ref getstate(PyObject_GetAttrString(obj, const_cast("__getstate__")), - ref::null_ok); - PyErr_Clear(); - - ref dict(PyObject_GetAttrString(obj, const_cast("__dict__")), ref::null_ok); - PyErr_Clear(); - - if (getstate.get() != 0) - { - if (dict.get() != 0 && dictionary(dict).size() > 0) - { - ref getstate_manages_dict(PyObject_GetAttrString(instance_class.get(), const_cast("__getstate_manages_dict__")), ref::null_ok); - PyErr_Clear(); - if (getstate_manages_dict.get() == 0) - { - PyErr_SetString(PyExc_RuntimeError, "Incomplete pickle support (__getstate_manages_dict__ not set)"); - throw_error_already_set(); - } - } - - ref state = ref(PyEval_CallObject(getstate.get(), NULL)); - return tuple(instance_class, initargs, state); - } - - if (getinitargs.get() == 0) - { - ref dict_defines_state(PyObject_GetAttrString(instance_class.get(), const_cast("__dict_defines_state__")), ref::null_ok); - PyErr_Clear(); - if (dict_defines_state.get() == 0) - { - PyErr_SetString(PyExc_RuntimeError, "Incomplete pickle support (__dict_defines_state__ not set)"); - throw_error_already_set(); - } - } - - if (dict.get() != 0 && dictionary(dict).size() > 0) - { - return tuple(instance_class, initargs, dict); - } - - return tuple(instance_class, initargs); - } - - ref global_instance_reduce() - { - return ref(detail::new_wrapped_function(instance_reduce)); - } -} - - -namespace detail { - - class_base::class_base(PyTypeObject* meta_class_obj, string name, tuple bases, const dictionary& name_space) - : type_object_base(meta_class_obj), - m_name(name), - m_bases(bases), - m_name_space(name_space) - { - this->tp_name = const_cast(name.c_str()); - enable(type_object_base::getattr); - enable(type_object_base::setattr); - add_current_module_name(m_name_space); - static const boost::python::string docstr("__doc__", boost::python::string::interned); - if (PyDict_GetItem(m_name_space.get(), docstr.get())== 0) - { - PyDict_SetItem(m_name_space.get(), docstr.get(), Py_None); - } - enable_special_methods(this, bases, name_space); - } - - void class_base::add_base(ref base) - { - tuple new_bases(m_bases.size() + 1); - for (std::size_t i = 0; i < m_bases.size(); ++i) - new_bases.set_item(i, m_bases[i]); - new_bases.set_item(m_bases.size(), base); - m_bases = new_bases; - } - - PyObject* class_base::getattr(const char* name) - { - if (!BOOST_CSTD_::strcmp(name, "__dict__")) - { - PyObject* result = m_name_space.get(); - Py_INCREF(result); - return result; - } - - if (!BOOST_CSTD_::strcmp(name, "__bases__")) - { - PyObject* result = m_bases.get(); - Py_INCREF(result); - return result; - } - - if (!BOOST_CSTD_::strcmp(name, "__name__")) - { - PyObject* result = m_name.get(); - Py_INCREF(result); - return result; - } - - // pickle support courtesy of "Ralf W. Grosse-Kunstleve" - if (!BOOST_CSTD_::strcmp(name, "__safe_for_unpickling__")) - { - return PyInt_FromLong(1); - } - if (!BOOST_CSTD_::strcmp(name, "__reduce__")) - { - PyObject* self = as_object(this); - ref target(self, ref::increment_count); - return bound_function::create(target, global_class_reduce()); - } - - ref local_attribute = m_name_space.get_item(string(name).reference()); - - if (local_attribute.get()) - return local_attribute.release(); - - // In case there are no bases... - PyErr_SetString(PyExc_AttributeError, name); - - // Check bases - for (std::size_t i = 0; i < m_bases.size(); ++i) - { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) - PyErr_Clear(); // we're going to try a base class - else if (PyErr_Occurred()) - break; // Other errors count, though! - - PyObject* base_attribute = PyObject_GetAttrString(m_bases[i].get(), const_cast(name)); - - if (base_attribute != 0) - { - // Unwind the actual underlying function from unbound Python class - // methods in case of multiple inheritance from real Python - // classes. Python stubbornly insists that the first argument to a - // method must be a true Python instance object otherwise. Do not - // unwrap bound methods; that would interfere with intended semantics. - if (PyMethod_Check(base_attribute) - && reinterpret_cast(base_attribute)->im_self == 0) - { - PyObject* function - = reinterpret_cast(base_attribute)->im_func; - Py_INCREF(function); - Py_DECREF(base_attribute); - return function; - } - else - { - return base_attribute; - } - } - } - return 0; - } - - // Mostly copied wholesale from Python's classobject.c - PyObject* class_base::repr() const - { - PyObject *mod = PyDict_GetItemString( - m_name_space.get(), const_cast("__module__")); - unsigned long address = reinterpret_cast(this); - string result = (mod == NULL || !PyString_Check(mod)) - ? string("") % tuple(m_name, address) - : string("") % tuple(ref(mod, ref::increment_count), m_name, address); - return result.reference().release(); - } - - - int class_base::setattr(const char* name, PyObject* value) - { - if (is_special_name(name) - && BOOST_CSTD_::strcmp(name, "__doc__") != 0 - && BOOST_CSTD_::strcmp(name, "__name__") != 0) - { - boost::python::string message("Special attribute names other than '__doc__' and '__name__' are read-only, in particular: "); - PyErr_SetObject(PyExc_TypeError, (message + name).get()); - throw_error_already_set(); - } - - if (PyCallable_Check(value)) - detail::enable_named_method(this, name); - - return PyDict_SetItemString( - m_name_space.reference().get(), const_cast(name), value); - } - - bool class_base::initialize_instance(instance* obj, PyObject* args, PyObject* keywords) - { - // Getting the init function off the obj should result in a - // bound method. - PyObject* const init_function = obj->getattr("__init__", false); - - if (init_function == 0) - { - if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); // no __init__? That's legal. - } - else { - return false; // Something else? Keep the error - } - } - else - { - // Manage the reference to the bound function - ref init_function_holder(init_function); - - // Declare a ref to manage the result of calling __init__ (which should be None). - ref init_result( - PyEval_CallObjectWithKeywords(init_function, args, keywords)); - } - return true; - } - - void class_base::instance_dealloc(PyObject* obj) const - { - Py_INCREF(obj); // This allows a __del__ function to revive the obj - - PyObject* exc_type; - PyObject* exc_value; - PyObject* exc_traceback; - PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); - - // This scope ensures that the reference held by del_function doesn't release - // the last reference and delete the object recursively (infinitely). - { - ref del_function; - try { - instance* const target = boost::python::downcast(obj); - del_function = ref(target->getattr("__del__", false), ref::null_ok); - } - catch(...) { - } - - if (del_function.get() != 0) - { - ref result(PyEval_CallObject(del_function.get(), (PyObject *)NULL), ref::null_ok); - - if (result.get() == NULL) - report_ignored_exception(del_function.get()); - } - } - PyErr_Restore(exc_type, exc_value, exc_traceback); - - if (--obj->ob_refcnt <= 0) - delete_instance(obj); - } - - -} - -instance::instance(PyTypeObject* class_) - : boost::python::detail::base_object(class_) -{ -} - -instance::~instance() -{ -} - -PyObject* instance::getattr(const char* name, bool use_special_function) -{ - if (!BOOST_CSTD_::strcmp(name, "__dict__")) - { - if (PyEval_GetRestricted()) { - PyErr_SetString(PyExc_RuntimeError, - "instance.__dict__ not accessible in restricted mode"); - return 0; - } - Py_INCREF(m_name_space.get()); - return m_name_space.get(); - } - - if (!BOOST_CSTD_::strcmp(name, "__class__")) - { - Py_INCREF(this->ob_type); - return as_object(this->ob_type); - } - - if (!BOOST_CSTD_::strcmp(name, "__reduce__")) - { - return detail::bound_function::create(ref(this, ref::increment_count), global_instance_reduce()); - } - - ref local_attribute = m_name_space.get_item(string(name).reference()); - - if (local_attribute.get()) - return local_attribute.release(); - - // Check its class. - PyObject* function = - PyObject_GetAttrString(as_object(this->ob_type), const_cast(name)); - - if (function == 0 && !use_special_function) - { - return 0; - } - - ref class_attribute; - if (function != 0) - { - // This will throw if the attribute wasn't found - class_attribute = ref(function); - } - else - { - // Clear the error while we try special methods method (if any). - PyErr_Clear(); - - // First we try the special method that comes from concatenating - // "__getattr__" and and 2 trailing underscores. This is an - // extension to regular Python class functionality. - const string specific_getattr_name(detail::getattr_string() + name + "__"); - PyObject* getattr_method = PyObject_GetAttr( - as_object(this->ob_type), specific_getattr_name.get()); - - // Use just the first arg to PyEval_CallFunction if found - char* arg_format = const_cast("(O)"); - - // Try for the regular __getattr__ method if not found - if (getattr_method == 0) - { - PyErr_Clear(); - getattr_method = PyObject_GetAttrString( - as_object(this->ob_type), const_cast("__getattr__")); - - // Use both args to PyEval_CallFunction - arg_format = const_cast("(Os)"); - } - - // If there is no such method, throw now. - if (PyErr_Occurred()) - { - PyErr_SetString(PyExc_AttributeError, name); - return 0; - } - - // Take ownership of the method - ref owner(getattr_method); - - // Call it to get the attribute. - return PyEval_CallFunction(getattr_method, arg_format, this, name); - } - - if (!PyCallable_Check(class_attribute.get())) - { - PyErr_Clear(); - return class_attribute.release(); - } - else - { - return detail::bound_function::create(ref(this, ref::increment_count), class_attribute); - } -} - -// instance::setattr_dict -// -// Implements setattr() functionality for the "__dict__" attribute -// -int instance::setattr_dict(PyObject* value) -{ - if (PyEval_GetRestricted()) - { - PyErr_SetString(PyExc_RuntimeError, - "__dict__ not accessible in restricted mode"); - return -1; - } - - if (value == 0 || !PyDict_Check(value)) - { - PyErr_SetString(PyExc_TypeError, - "__dict__ must be set to a dictionary"); - return -1; - } - m_name_space = dictionary(ref(value, ref::increment_count)); - return 0; -} - -// instance::setattr - -// -// Implements the setattr() and delattr() functionality for our own instance -// objects, using the standard Python interface: if value == 0, we are deleting -// the attribute, and returns 0 unless an error occurred. -int instance::setattr(const char* name, PyObject* value) -{ - if (BOOST_CSTD_::strcmp(name, "__class__") == 0) - { - PyErr_SetString(PyExc_TypeError, "__class__ attribute is read-only"); - throw_error_already_set(); - } - - if (BOOST_CSTD_::strcmp(name, "__dict__") == 0) - return setattr_dict(value); - - // Try to find an appropriate "specific" setter or getter method, either - // __setattr____(value) or __delattr____(). This is an extension - // to regular Python class functionality. - const string& base_name = value ? detail::setattr_string() : detail::delattr_string(); - const string specific_method_name(base_name + name + "__"); - - ref special_method( - PyObject_GetAttr(as_object(this->ob_type), specific_method_name.get()), - ref::null_ok); - - PyObject* result_object = 0; - if (special_method.get() != 0) - { - // The specific function was found; call it now. Note that if value is - // not included in the format string, it is ignored. - char* format_string = const_cast(value ? "(OO)" : "(O)"); - result_object = PyEval_CallFunction(special_method.get(), format_string, this, value); - } - else - { - // If not found, try the usual __setattr__(name, value) or - // __delattr__(name) functions. - PyErr_Clear(); - special_method.reset( - PyObject_GetAttr(as_object(this->ob_type), base_name.get()), - ref::null_ok); - - if (special_method.get() != 0) - { - // The special function was found; call it now. Note that if value - // is not included in the format string, it is ignored. - char* format_string = const_cast(value ? "(OsO)" : "(Os)"); - result_object = PyEval_CallFunction( - special_method.get(), format_string, this, name, value); - } - } - - // If we found an appropriate special method, handle the return value. - if (special_method.get() != 0) - { - ref manage_result(result_object); - return 0; - } - - PyErr_Clear(); // Nothing was found; clear the python error state - - if (value == 0) // Try to remove the attribute from our name space - { - const int result = PyDict_DelItemString(m_name_space.reference().get(), - const_cast(name)); - if (result < 0) - { - PyErr_Clear(); - PyErr_SetString(PyExc_AttributeError, "delete non-existing instance attribute"); - } - return result; - } - else // Change the specified item in our name space - { - return PyDict_SetItemString(m_name_space.reference().get(), - const_cast(name), value); - } -} - -PyObject* instance::call(PyObject* args, PyObject* keywords) -{ - return PyEval_CallObjectWithKeywords( - ref(getattr("__call__")).get(), // take possession of the result from getattr() - args, keywords); -} - -PyObject* instance::repr() -{ - return callback::call_method(this, "__repr__"); -} - -int instance::compare(PyObject* other) -{ - return callback::call_method(this, "__cmp__", other); -} - -PyObject* instance::str() -{ - return callback::call_method(this, "__str__"); -} - -long instance::hash() -{ - return callback::call_method(this, "__hash__"); -} - -int instance::length() -{ - return callback::call_method(this, "__len__"); -} - -PyObject* instance::get_subscript(PyObject* key) -{ - return callback::call_method(this, "__getitem__", key); -} - -void instance::set_subscript(PyObject* key, PyObject* value) -{ - if (value == 0) - callback::call_method(this, "__delitem__", key); - else - callback::call_method(this, "__setitem__", key, value); -} - -PyObject* instance::get_slice(int start, int finish) -{ - return callback::call_method(this, "__getslice__", start, finish); -} - -void instance::set_slice(int start, int finish, PyObject* value) -{ - if (value == 0) - callback::call_method(this, "__delslice__", start, finish); - else - callback::call_method(this, "__setslice__", start, finish, value); -} - -PyObject* instance::add(PyObject* other) -{ - return callback::call_method(this, "__add__", other); -} - -PyObject* instance::subtract(PyObject* other) -{ - return callback::call_method(this, "__sub__", other); -} - -PyObject* instance::multiply(PyObject* other) -{ - return callback::call_method(this, "__mul__", other); -} - -PyObject* instance::divide(PyObject* other) -{ - return callback::call_method(this, "__div__", other); -} - -PyObject* instance::remainder(PyObject* other) -{ - return callback::call_method(this, "__mod__", other); -} - -PyObject* instance::divmod(PyObject* other) -{ - return callback::call_method(this, "__divmod__", other); -} - -PyObject* instance::power(PyObject* exponent, PyObject* modulus) -{ - if (as_object(modulus) == Py_None) - return callback::call_method(this, "__pow__", exponent); - else - return callback::call_method(this, "__pow__", exponent, modulus); -} - -PyObject* instance::negative() -{ - return callback::call_method(this, "__neg__"); -} - -PyObject* instance::positive() -{ - return callback::call_method(this, "__pos__"); -} - -PyObject* instance::absolute() -{ - return callback::call_method(this, "__abs__"); -} - -int instance::nonzero() -{ - return callback::call_method(this, "__nonzero__"); -} - -PyObject* instance::invert() -{ - return callback::call_method(this, "__invert__"); -} - -PyObject* instance::lshift(PyObject* other) -{ - return callback::call_method(this, "__lshift__", other); -} - -PyObject* instance::rshift(PyObject* other) -{ - return callback::call_method(this, "__rshift__", other); -} - -PyObject* instance::do_and(PyObject* other) -{ - return callback::call_method(this, "__and__", other); -} - -PyObject* instance::do_xor(PyObject* other) -{ - return callback::call_method(this, "__xor__", other); -} - -PyObject* instance::do_or(PyObject* other) -{ - return callback::call_method(this, "__or__", other); -} - -int instance::coerce(PyObject** x, PyObject** y) -{ - assert(this == *x); - - // Coerce must return a tuple - tuple result(callback::call_method(this, "__coerce__", *y)); - - *x = result[0].release(); - *y = result[1].release(); - return 0; -} - -PyObject* instance::as_int() -{ - return callback::call_method(this, "__int__"); -} - -PyObject* instance::as_long() -{ - return callback::call_method(this, "__long__"); -} - -PyObject* instance::as_float() -{ - return callback::call_method(this, "__float__"); -} - -PyObject* instance::oct() -{ - return callback::call_method(this, "__oct__"); -} - -PyObject* instance::hex() -{ - return callback::call_method(this, "__hex__"); -} - -PyObject* instance::lt(PyObject* other) -{ - return callback::call_method(this, "__lt__", other); -} - -PyObject* instance::le(PyObject* other) -{ - return callback::call_method(this, "__le__", other); -} - -PyObject* instance::eq(PyObject* other) -{ - return callback::call_method(this, "__eq__", other); -} - -PyObject* instance::ne(PyObject* other) -{ - return callback::call_method(this, "__ne__", other); -} - -PyObject* instance::gt(PyObject* other) -{ - return callback::call_method(this, "__gt__", other); -} - -PyObject* instance::ge(PyObject* other) -{ - return callback::call_method(this, "__ge__", other); -} - -PyObject* instance::inplace_add(PyObject* other) -{ - return callback::call_method(this, "__iadd__", other); -} - -PyObject* instance::inplace_subtract(PyObject* other) -{ - return callback::call_method(this, "__isub__", other); -} - -PyObject* instance::inplace_multiply(PyObject* other) -{ - return callback::call_method(this, "__imul__", other); -} - -PyObject* instance::inplace_divide(PyObject* other) -{ - return callback::call_method(this, "__idiv__", other); -} - -PyObject* instance::inplace_remainder(PyObject* other) -{ - return callback::call_method(this, "__imod__", other); -} - -PyObject* instance::inplace_power(PyObject* exponent, PyObject* modulus) -{ - if (modulus == Py_None) - return callback::call_method(this, "__ipow__", exponent); - else - return callback::call_method(this, "__ipow__", exponent, modulus); -} - -PyObject* instance::inplace_lshift(PyObject* other) -{ - return callback::call_method(this, "__ilshift__", other); -} - -PyObject* instance::inplace_rshift(PyObject* other) -{ - return callback::call_method(this, "__irshift__", other); -} - -PyObject* instance::inplace_and(PyObject* other) -{ - return callback::call_method(this, "__iand__", other); -} - -PyObject* instance::inplace_or(PyObject* other) -{ - return callback::call_method(this, "__ior__", other); -} - -PyObject* instance::inplace_xor(PyObject* other) -{ - return callback::call_method(this, "__ixor__", other); -} - -namespace { - struct named_capability - { - const char* name; - detail::type_object_base::capability capability; - }; - - const named_capability enablers[] = - { - { "__hash__", detail::type_object_base::hash }, - { "__cmp__", detail::type_object_base::compare }, - { "__gt__", detail::type_object_base::richcompare }, - { "__ge__", detail::type_object_base::richcompare }, - { "__lt__", detail::type_object_base::richcompare }, - { "__le__", detail::type_object_base::richcompare }, - { "__eq__", detail::type_object_base::richcompare }, - { "__ne__", detail::type_object_base::richcompare }, - { "__iadd__", detail::type_object_base::number_inplace_add }, - { "__isub__", detail::type_object_base::number_inplace_subtract }, - { "__imul__", detail::type_object_base::number_inplace_multiply }, - { "__idiv__", detail::type_object_base::number_inplace_divide }, - { "__imod__", detail::type_object_base::number_inplace_remainder }, - { "__ipow__", detail::type_object_base::number_inplace_power }, - { "__ilshift__", detail::type_object_base::number_inplace_lshift }, - { "__irshift__", detail::type_object_base::number_inplace_rshift }, - { "__iand__", detail::type_object_base::number_inplace_and }, - { "__ixor__", detail::type_object_base::number_inplace_xor }, - { "__ior__", detail::type_object_base::number_inplace_or }, - { "__repr__", detail::type_object_base::repr }, - { "__str__", detail::type_object_base::str }, - { "__call__", detail::type_object_base::call }, - { "__getattr__", detail::type_object_base::getattr }, - { "__setattr__", detail::type_object_base::setattr }, - { "__len__", detail::type_object_base::mapping_length }, - { "__len__", detail::type_object_base::sequence_length }, - { "__getitem__", detail::type_object_base::mapping_subscript }, - { "__getitem__", detail::type_object_base::sequence_item }, - { "__setitem__", detail::type_object_base::mapping_ass_subscript }, - { "__setitem__", detail::type_object_base::sequence_ass_item }, - { "__delitem__", detail::type_object_base::mapping_ass_subscript }, - { "__delitem__", detail::type_object_base::sequence_ass_item }, - { "__getslice__", detail::type_object_base::sequence_slice }, - { "__setslice__", detail::type_object_base::sequence_ass_slice }, - { "__delslice__", detail::type_object_base::sequence_ass_slice }, - { "__add__", detail::type_object_base::number_add }, - { "__sub__", detail::type_object_base::number_subtract }, - { "__mul__", detail::type_object_base::number_multiply }, - { "__div__", detail::type_object_base::number_divide }, - { "__mod__", detail::type_object_base::number_remainder }, - { "__divmod__", detail::type_object_base::number_divmod }, - { "__pow__", detail::type_object_base::number_power }, - { "__neg__", detail::type_object_base::number_negative }, - { "__pos__", detail::type_object_base::number_positive }, - { "__abs__", detail::type_object_base::number_absolute }, - { "__nonzero__", detail::type_object_base::number_nonzero }, - { "__invert__", detail::type_object_base::number_invert }, - { "__lshift__", detail::type_object_base::number_lshift }, - { "__rshift__", detail::type_object_base::number_rshift }, - { "__and__", detail::type_object_base::number_and }, - { "__xor__", detail::type_object_base::number_xor }, - { "__or__", detail::type_object_base::number_or }, - { "__coerce__", detail::type_object_base::number_coerce }, - { "__int__", detail::type_object_base::number_int }, - { "__long__", detail::type_object_base::number_long }, - { "__float__", detail::type_object_base::number_float }, - { "__oct__", detail::type_object_base::number_oct }, - { "__hex__", detail::type_object_base::number_hex } - }; - - bool is_prefix(const char* s1, const char* s2) - { - while (*s1 != 0 && *s2 != 0 && *s1 == *s2) - ++s1, ++s2; - return *s1 == 0; - } - - bool is_special_name(const char* name) - { - if (name[0] != '_' || name[1] != '_' || name[2] == 0 || name[3] == 0) - return false; - - std::size_t name_length = BOOST_CSTD_::strlen(name); - return name[name_length - 1] == '_' && name[name_length - 2] == '_'; - } -} - -namespace detail { - // Enable the special handler for methods of the given name, if any. - void enable_named_method(boost::python::detail::class_base* type_obj, const char* name) - { - const std::size_t num_enablers = PY_ARRAY_LENGTH(enablers); - - // Make sure this ends with "__" since we'll only compare the head of the - // string. This is done to make the __getattr____/__setattr____ - // extension work. - if (!is_special_name(name)) - return; - - for (std::size_t i = 0; i < num_enablers; ++i) - { - if (is_prefix(enablers[i].name + 2, name + 2)) - { - type_obj->enable(enablers[i].capability); - } - } - } -} - -namespace { - // Enable any special methods which are enabled in the base class. - void enable_special_methods(boost::python::detail::class_base* derived, const tuple& bases, const dictionary& name_space) - { - for (std::size_t i = 0; i < bases.size(); ++i) - { - PyObject* base = bases[i].get(); - - for (std::size_t n = 0; n < PY_ARRAY_LENGTH(enablers); ++n) - { - ref attribute( - PyObject_GetAttrString(base, const_cast(enablers[n].name)), - ref::null_ok); - PyErr_Clear(); - if (attribute.get() != 0 && PyCallable_Check(attribute.get())) - detail::add_capability(enablers[n].capability, derived); - } - } - - list keys(name_space.keys()); - for (std::size_t j = 0, len = keys.size(); j < len; ++j) - { - string name_obj(keys.get_item(j)); - const char* name = name_obj.c_str(); - - if (!is_special_name(name)) - continue; - - for (std::size_t i = 0; i < PY_ARRAY_LENGTH(enablers); ++i) - { - if (is_prefix(enablers[i].name + 2, name + 2)) - { - detail::add_capability(enablers[i].capability, derived); - } - } - } - } - - void add_current_module_name(dictionary& name_space) - { - static string module_key("__module__", string::interned); - - // If the user didn't specify a __module__ attribute already - if (name_space.get_item(module_key).get() == 0) - { - if (module_builder::initializing()) - { - // The global __name__ is not properly set in this case - name_space.set_item(module_key, module_builder::name()); - } - else - { - // Get the module name from the global __name__ - PyObject *globals = PyEval_GetGlobals(); - if (globals != NULL) - { - PyObject *module_name = PyDict_GetItemString(globals, const_cast("__name__")); - if (module_name != NULL) - name_space.set_item(module_key, module_name); - } - } - } - } -} - -BOOST_PYTHON_DECL bool adjust_slice_indices(PyObject* obj, int& start, int& finish) -{ - ref len(PyEval_CallMethod(obj, "__len__", "()") - , ref::null_ok); - - if (len.get() == 0) - return false; - - int length = PyInt_AsLong(len.get()); - - // This is standard Python class behavior. - if (start < 0) - start += length; - if (finish < 0) - finish += length; - - // This is not - if (start < 0) - start = 0; - if (finish < 0) - finish = 0; - - return true; -} - -namespace detail { -const string& setattr_string() -{ - static string x("__setattr__", string::interned); - return x; -} - -const string& getattr_string() -{ - static string x("__getattr__", string::interned); - return x; -} - -const string& delattr_string() -{ - static string x("__delattr__", string::interned); - return x; -} -} - -}} // namespace boost::python diff --git a/src/conversions.cpp b/src/conversions.cpp deleted file mode 100644 index 3c5edad5..00000000 --- a/src/conversions.cpp +++ /dev/null @@ -1,223 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// 05 Apr 01 added: from_python std::string type checking (rwgk) -// 12 Mar 01 Python 1.5.2 fixes (Ralf W. Grosse-Kunstleve) -// 11 Mar 01 std::string *MAY* include nulls (Alex Martelli) -// 04 Mar 01 std::complex<> fixes for MSVC (Dave Abrahams) -// 03 Mar 01 added: converters for [plain] char (Ralf W. Grosse-Kunstleve) - -#define BOOST_PYTHON_SOURCE - -#include -#include -#include -#include -#include - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -BOOST_PYTHON_DECL long from_python(PyObject* p, boost::python::type) -{ - // Why am I clearing the error here before trying to convert? I know there's a reason... - long result; - { - result = PyInt_AsLong(p); - if (PyErr_Occurred()) - boost::python::throw_argument_error(); - } - return result; -} - -BOOST_PYTHON_DECL double from_python(PyObject* p, boost::python::type) -{ - double result; - { - result = PyFloat_AsDouble(p); - if (PyErr_Occurred()) - boost::python::throw_argument_error(); - } - return result; -} - -template -T integer_from_python(PyObject* p, boost::python::type) -{ - const long long_result = from_python(p, boost::python::type()); - - try - { - return boost::numeric_cast(long_result); - } - catch(const boost::bad_numeric_cast&) - { - char buffer[256]; - const char message[] = "%ld out of range for %s"; - sprintf(buffer, message, long_result, typeid(T).name()); - PyErr_SetString(PyExc_ValueError, buffer); - boost::python::throw_argument_error(); - } - return 0; // Not smart enough to know that the catch clause always rethrows -} - -template -PyObject* integer_to_python(T value) -{ - long value_as_long; - - try - { - value_as_long = boost::numeric_cast(value); - } - catch(const boost::bad_numeric_cast&) - { - const char message[] = "value out of range for Python int"; - PyErr_SetString(PyExc_ValueError, message); - boost::python::throw_error_already_set(); - } - - return to_python(value_as_long); -} - -BOOST_PYTHON_DECL int from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(unsigned int i) -{ - return integer_to_python(i); -} - -BOOST_PYTHON_DECL unsigned int from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL short from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL float from_python(PyObject* p, boost::python::type) -{ - return static_cast(from_python(p, boost::python::type())); -} - -BOOST_PYTHON_DECL PyObject* to_python(unsigned short i) -{ - return integer_to_python(i); -} - -BOOST_PYTHON_DECL unsigned short from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(char c) -{ - if (c == '\0') return PyString_FromString(""); - return PyString_FromStringAndSize(&c, 1); -} - -BOOST_PYTHON_DECL char from_python(PyObject* p, boost::python::type) -{ - int l = -1; - if (PyString_Check(p)) l = PyString_Size(p); - if (l < 0 || l > 1) { - PyErr_SetString(PyExc_TypeError, "expected string of length 0 or 1"); - boost::python::throw_argument_error(); - } - if (l == 0) return '\0'; - return PyString_AsString(p)[0]; -} - -BOOST_PYTHON_DECL PyObject* to_python(unsigned char i) -{ - return integer_to_python(i); -} - -BOOST_PYTHON_DECL unsigned char from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(signed char i) -{ - return integer_to_python(i); -} - -BOOST_PYTHON_DECL signed char from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(unsigned long x) -{ - return integer_to_python(x); -} - -BOOST_PYTHON_DECL unsigned long from_python(PyObject* p, boost::python::type type) -{ - return integer_from_python(p, type); -} - -BOOST_PYTHON_DECL void from_python(PyObject* p, boost::python::type) -{ - if (p != Py_None) { - PyErr_SetString(PyExc_TypeError, "expected argument of type None"); - boost::python::throw_argument_error(); - } -} - -BOOST_PYTHON_DECL const char* from_python(PyObject* p, boost::python::type) -{ - const char* s = PyString_AsString(p); - if (!s) - boost::python::throw_argument_error(); - return s; -} - -BOOST_PYTHON_DECL PyObject* to_python(const std::string& s) -{ - return PyString_FromStringAndSize(s.data(), s.size()); -} - -BOOST_PYTHON_DECL std::string from_python(PyObject* p, boost::python::type) -{ - if (! PyString_Check(p)) { - PyErr_SetString(PyExc_TypeError, "expected a string"); - boost::python::throw_argument_error(); - } - return std::string(PyString_AsString(p), PyString_Size(p)); -} - -BOOST_PYTHON_DECL bool from_python(PyObject* p, boost::python::type) -{ - int value = from_python(p, boost::python::type()); - if (value == 0) - return false; - return true; -} - -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 -// An optimizer bug prevents these from being inlined. -BOOST_PYTHON_DECL PyObject* to_python(double d) -{ - return PyFloat_FromDouble(d); -} - -BOOST_PYTHON_DECL PyObject* to_python(float f) -{ - return PyFloat_FromDouble(f); -} -#endif - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - diff --git a/src/cross_module.cpp b/src/cross_module.cpp deleted file mode 100644 index d339c4a7..00000000 --- a/src/cross_module.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* (C) Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, use, - modify, sell and distribute this software is granted provided this - copyright notice appears in all copies. This software is provided - "as is" without express or implied warranty, and with no claim as to - its suitability for any purpose. - - Revision History: - 17 Apr 01 merged into boost CVS trunk (Ralf W. Grosse-Kunstleve) -*/ - -#define BOOST_PYTHON_SOURCE - -# include -namespace python = boost::python; -# include // MSVC6.0SP4 does not know std::fprintf -# include // MSVC6.0SP4 does not know std::strcmp - -namespace -{ - - PyObject* get_module_dict(const char* module_name) - { - python::ref module_obj(PyImport_ImportModule((char*) module_name)); - PyObject* module_dict = PyModule_GetDict(module_obj.get()); - if (module_dict == 0) python::throw_import_error(); - return module_dict; - } -} - -namespace boost { namespace python { - -void BOOST_PYTHON_DECL throw_import_error() -{ - throw import_error(); -} - -void BOOST_PYTHON_DECL throw_export_error() -{ - throw export_error(); -} - -namespace detail -{ - BOOST_PYTHON_DECL const char* converters_attribute_name = "__converters__"; - - BOOST_PYTHON_DECL void* import_converter_object(const std::string& module_name, - const std::string& py_class_name, - const std::string& attribute_name) - { - static std::string err; - PyObject* module_dict = get_module_dict(const_cast(module_name.c_str())); - PyObject* py_class = PyDict_GetItemString(module_dict, const_cast(py_class_name.c_str())); - if (py_class == 0) { - err = std::string("module ") + module_name + " has no attribute " + py_class_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - python::throw_import_error(); - } - python::ref c_obj(PyObject_GetAttrString(py_class, const_cast(attribute_name.c_str())), ref::null_ok); - if (c_obj.get() == 0) { - err = std::string("object ") + module_name + "." + py_class_name - + " has no attribute " + attribute_name; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - python::throw_import_error(); - } - if (! PyCObject_Check(c_obj.get())) { - err = std::string("object ") + module_name + "." + py_class_name + "." - + attribute_name + " is not a PyCObject"; - PyErr_SetString(PyExc_RuntimeError, const_cast(err.c_str())); - python::throw_import_error(); - } - return PyCObject_AsVoidPtr(c_obj.get()); - } - - BOOST_PYTHON_DECL void check_export_converters_api(const int importing_major, - const int importing_minor, - const int imported_major, - const int imported_minor) - { - if (importing_major != imported_major) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Fatal: export_converters_api mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - PyErr_SetString(PyExc_RuntimeError, - "Fatal: export_converters_api mismatch"); - throw_import_error(); - } - if (importing_minor != imported_minor) { - // Python uses fprintf(stderr, ...) for API warnings. - fprintf(stderr, - "Warning: export_converters_api mismatch:" - " Importing module = %d.%d" - " Imported module = %d.%d\n", - importing_major, importing_minor, - imported_major, imported_minor); - } - } - -} - -}} // namespace boost::python::detail diff --git a/src/extension_class.cpp b/src/extension_class.cpp deleted file mode 100644 index 5dc6ec23..00000000 --- a/src/extension_class.cpp +++ /dev/null @@ -1,685 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// 04 Mar 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) - -#define BOOST_PYTHON_SOURCE -#define BOOST_PYTHON_EXPORT - -#include -#include -#include -#include -#include - -namespace boost { namespace python { -namespace detail { - - struct operator_dispatcher - : public PyObject - { - static PyTypeObject type_obj; - static PyNumberMethods number_methods; - - static operator_dispatcher* create(const ref& o, const ref& s); - - ref m_object; - ref m_self; - - // data members for allocation/deallocation optimization - operator_dispatcher* m_free_list_link; - static operator_dispatcher* free_list; - - private: - // only accessible through create() - operator_dispatcher(const ref& o, const ref& s); - }; - - operator_dispatcher* operator_dispatcher::free_list = 0; - -}}} // namespace boost::python::detail - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -inline PyObject* to_python(boost::python::detail::operator_dispatcher* n) { return n; } - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - - -namespace boost { namespace python { - -BOOST_PYTHON_DECL tuple standard_coerce(ref l, ref r) -{ - // Introduced sequence points for exception-safety. - ref first(detail::operator_dispatcher::create(l, l)); - - ref second(r->ob_type == &detail::operator_dispatcher::type_obj - ? r - : ref(detail::operator_dispatcher::create(r, ref()))); - - return tuple(first, second); -} - -namespace detail { - - enum { unwrap_exception_code = -1000 }; - - int unwrap_args(PyObject* left, PyObject* right, PyObject*& self, PyObject*& other) - { - if (left->ob_type != &operator_dispatcher::type_obj || - right->ob_type != &operator_dispatcher::type_obj) - { - PyErr_SetString(PyExc_RuntimeError, "operator_dispatcher::unwrap_args(): expecting operator_dispatcher arguments only!"); - return unwrap_exception_code; - } - - typedef reference DPtr; - DPtr lwrapper(static_cast(left), DPtr::increment_count); - DPtr rwrapper(static_cast(right), DPtr::increment_count); - - if (lwrapper->m_self.get() != 0) - { - self = lwrapper->m_self.get(); - other = rwrapper->m_object.get(); - return 0; - } - else - { - self = rwrapper->m_self.get(); - other = lwrapper->m_object.get(); - return 1; - } - } - - int unwrap_pow_args(PyObject* left, PyObject* right, PyObject* m, - PyObject*& self, PyObject*& first, PyObject*& second) - { - if (left->ob_type != &operator_dispatcher::type_obj || - right->ob_type != &operator_dispatcher::type_obj || - m->ob_type != &operator_dispatcher::type_obj) - { - PyErr_SetString(PyExc_RuntimeError, "operator_dispatcher::unwrap_pow_args(): expecting operator_dispatcher arguments only!"); - return unwrap_exception_code; - } - - typedef reference DPtr; - DPtr lwrapper(static_cast(left), DPtr::increment_count); - DPtr rwrapper(static_cast(right), DPtr::increment_count); - DPtr mwrapper(static_cast(m), DPtr::increment_count); - - if (lwrapper->m_self.get() != 0) - { - self = lwrapper->m_self.get(); - first = rwrapper->m_object.get(); - second = mwrapper->m_object.get(); - return 0; - } - else if (rwrapper->m_self.get() != 0) - { - self = rwrapper->m_self.get(); - first = lwrapper->m_object.get(); - second = mwrapper->m_object.get(); - return 1; - } - else - { - self = mwrapper->m_self.get(); - first = lwrapper->m_object.get(); - second = rwrapper->m_object.get(); - return 2; - } - } - -extension_instance* get_extension_instance(PyObject* p) -{ - // The object's type will just be some class_t object, - // but if its meta-type is right, then it is an extension_instance. - if (p->ob_type->ob_type != extension_meta_class()) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - boost::python::throw_argument_error(); - } - return static_cast(p); -} - -void -extension_instance::add_implementation(std::auto_ptr holder) -{ - for (held_objects::const_iterator p = m_wrapped_objects.begin(); - p != m_wrapped_objects.end(); ++p) - { - if (typeid(*holder) == typeid(**p)) - { - PyErr_SetString(PyExc_RuntimeError, "Base class already initialized"); - throw_error_already_set(); - } - } - m_wrapped_objects.push_back(holder.release()); -} - -extension_instance::extension_instance(PyTypeObject* class_) - : instance(class_) -{ -} - -extension_instance::~extension_instance() -{ - for (held_objects::const_iterator p = m_wrapped_objects.begin(), - finish = m_wrapped_objects.end(); - p != finish; ++p) - { - delete *p; - } -} - -BOOST_PYTHON_DECL meta_class* extension_meta_class() -{ - static meta_class result; - return &result; -} - -typedef class_t extension_class_t; - -bool is_subclass(const extension_class_t* derived, - const PyObject* possible_base) -{ - - tuple bases = derived->bases(); - - for (std::size_t i = 0, size = bases.size(); i < size; ++i) - { - const PyObject* base = bases[i].get(); - - if (base == possible_base) - return true; - - if (base->ob_type == extension_meta_class()) - { - const extension_class_t* base_class = downcast(base); - if (is_subclass(base_class, possible_base)) - return true; - } - } - return false; -} - -// Return true iff obj is an obj of target_class -bool is_instance(extension_instance* obj, - class_t* target_class) -{ - if (obj->ob_type == target_class) - return true; - else - { - return is_subclass( - downcast >(obj->ob_type).get(), - as_object(target_class)); - } -} - -void two_string_error(PyObject* exception_object, const char* format, const char* s1, const char* s2) -{ - char buffer[256]; - std::size_t format_length = BOOST_CSTD_::strlen(format); - std::size_t length1 = BOOST_CSTD_::strlen(s1); - std::size_t length2 = BOOST_CSTD_::strlen(s2); - - std::size_t additional_length = length1 + length2; - if (additional_length + format_length > format_length - 1) - { - std::size_t difference = sizeof(buffer) - 1 - additional_length; - length1 -= difference / 2; - additional_length -= difference / 2; - } - - sprintf(buffer, format, length1, s1, length2, s2); - - PyErr_SetString(exception_object, buffer); - if (exception_object == PyExc_TypeError) - throw_argument_error(); - else - throw_error_already_set(); -} - -// This is called when an attempt has been made to convert the given obj to -// a C++ type for which it doesn't have any obj data. In that case, either -// the obj was not derived from the target_class, or the appropriate -// __init__ function wasn't called to initialize the obj data of the target class. -void report_missing_instance_data( - extension_instance* obj, // The object being converted - class_t* target_class, // the extension class of the C++ type - const std::type_info& target_typeid, // The typeid of the C++ type - bool target_is_ptr) -{ - char buffer[256]; - if (is_instance(obj, target_class)) - { - if (target_is_ptr) - { - two_string_error(PyExc_RuntimeError, - "Object of extension class '%.*s' does not wrap <%.*s>.", - obj->ob_type->tp_name, target_typeid.name()); - } - else - { - const char message[] = "__init__ function for extension class '%.*s' was never called."; - sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, - target_class->tp_name); - } - PyErr_SetString(PyExc_RuntimeError, buffer); - } - else if (target_class == 0) - { - const char message[] = "Cannot convert to <%.*s>; its Python class was never created or has been deleted."; - sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, target_typeid.name()); - PyErr_SetString(PyExc_RuntimeError, buffer); - } - else - { - two_string_error(PyExc_TypeError, "extension class '%.*s' is not convertible into '%.*s'.", - obj->ob_type->tp_name, target_class->tp_name); - } -} - -void report_missing_instance_data( - extension_instance* obj, // The object being converted - class_t* target_class, // the extension class of the C++ type - const std::type_info& target_typeid) // The typeid of the C++ type -{ - report_missing_instance_data(obj, target_class, target_typeid, false); -} - -void report_missing_ptr_data( - extension_instance* obj, // The object being converted - class_t* target_class, // the extension class of the C++ type - const std::type_info& target_typeid) // The typeid of the C++ type -{ - report_missing_instance_data(obj, target_class, target_typeid, true); -} - -void report_missing_class_object(const std::type_info& info) -{ - char buffer[256]; - const char message[] = "Cannot convert <%.*s> to python; its Python class was never created or has been deleted."; - sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, info.name()); - PyErr_SetString(PyExc_RuntimeError, buffer); - throw_error_already_set(); -} - -void report_released_smart_pointer(const std::type_info& info) -{ - char buffer[256]; - const char message[] = "Converting from python, pointer or smart pointer to <%.*s> is NULL."; - sprintf(buffer, message, sizeof(buffer) - sizeof(message) - 1, info.name()); - PyErr_SetString(PyExc_RuntimeError, buffer); - throw_argument_error(); -} - -read_only_setattr_function::read_only_setattr_function(const char* name) - : m_name(name) -{ -} - -PyObject* read_only_setattr_function::do_call(PyObject* /*args*/, PyObject* /*keywords*/) const -{ - PyErr_SetObject(PyExc_AttributeError, ("'" + m_name + "' attribute is read-only").get()); - return 0; -} - -const char* read_only_setattr_function::description() const -{ - return "uncallable"; -} - -extension_class_base::extension_class_base(const char* name) - : class_t( - extension_meta_class(), string(name), tuple(), dictionary()) -{ -} - -// This function is used in from_python() to convert wrapped classes that are -// related by inheritance. The problem is this: although C++ provides all necessary -// conversion operators, source and target of a conversion must be known at compile -// time. However, in Python we want to convert classes at runtime. The solution is to -// generate conversion functions at compile time, register them within the appropriate -// class objects and call them when a particular runtime conversion is required. - -// If functions for any possible conversion have to be stored, their number will grow -// qudratically. To reduce this number, we actually store only conversion functions -// between adjacent levels in the inheritance tree. By traversing the tree recursively, -// we can build any allowed conversion as a concatenation of simple conversions. This -// traversal is done in the functions try_base_class_conversions() and -// try_derived_class_conversions(). If a particular conversion is impossible, all -// conversion functions will return a NULL pointer. - -// The function extract_object_from_holder() attempts to actually extract the pointer -// to the contained object from an instance_holder_base (a wrapper class). A conversion -// of the held object to 'T *' is allowed when the conversion -// 'dynamic_cast *>(an_instance_holder_base)' succeeds. -void* extension_class_base::try_class_conversions(instance_holder_base* object) const -{ - void* result = try_derived_class_conversions(object); - if (result) - return result; - - if (!object->held_by_value()) - return try_base_class_conversions(object); - else - return 0; -} - -void* extension_class_base::try_base_class_conversions(instance_holder_base* object) const -{ - for (std::size_t i = 0; i < base_classes().size(); ++i) - { - if (base_classes()[i].convert == 0) - continue; - void* result1 = base_classes()[i].class_object->extract_object_from_holder(object); - if (result1) - return (*base_classes()[i].convert)(result1); - - void* result2 = base_classes()[i].class_object->try_base_class_conversions(object); - if (result2) - return (*base_classes()[i].convert)(result2); - } - return 0; -} - -void* extension_class_base::try_derived_class_conversions(instance_holder_base* object) const -{ - for (std::size_t i = 0; i < derived_classes().size(); ++i) - { - void* result1 = derived_classes()[i].class_object->extract_object_from_holder(object); - if (result1) - return (*derived_classes()[i].convert)(result1); - - void* result2 = derived_classes()[i].class_object->try_derived_class_conversions(object); - if (result2) - return (*derived_classes()[i].convert)(result2); - } - return 0; -} - -void extension_class_base::add_method(function* method, const char* name) -{ - add_method(reference(method), name); -} - -void extension_class_base::add_method(reference method, const char* name) -{ - // Add the attribute to the computed target - function::add_to_namespace(method, name, this->dict().get()); - - // If it is a special member function it should be enabled both here and there. - detail::enable_named_method(this, name); -} - -void extension_class_base::add_constructor_object(function* init_fn) -{ - add_method(init_fn, "__init__"); -} - -void extension_class_base::add_setter_method(function* setter_, const char* name) -{ - reference setter(setter_); - add_method(setter, (detail::setattr_string() + name + "__").c_str()); -} - -void extension_class_base::add_getter_method(function* getter_, const char* name) -{ - reference getter(getter_); - add_method(getter, (detail::getattr_string() + name + "__").c_str()); -} - -void extension_class_base::set_attribute(const char* name, PyObject* x_) -{ - ref x(x_); - set_attribute(name, x); -} - -void extension_class_base::set_attribute(const char* name, ref x) -{ - dict().set_item(string(name), x); - if (PyCallable_Check(x.get())) - detail::enable_named_method(this, name); -} - -operator_dispatcher::operator_dispatcher(const ref& o, const ref& s) - : m_object(o), m_self(s), m_free_list_link(0) - -{ - PyObject* self = this; - PyObject_INIT(self, &type_obj); -} - -operator_dispatcher* -operator_dispatcher::create(const ref& object, const ref& self) -{ - operator_dispatcher* const result = free_list; - if (result == 0) - return new operator_dispatcher(object, self); - - free_list = result->m_free_list_link; - result->m_object = object; - result->m_self = self; - - PyObject* result_as_pyobject = result; - PyObject_INIT(result_as_pyobject, &type_obj); - return result; -} - -extern "C" -{ - -void operator_dispatcher_dealloc(PyObject* self) -{ - operator_dispatcher* obj = static_cast(self); - obj->m_free_list_link = operator_dispatcher::free_list; - operator_dispatcher::free_list = obj; - obj->m_object.reset(); - obj->m_self.reset(); -} - -int operator_dispatcher_coerce(PyObject** l, PyObject** r) -{ - Py_INCREF(*l); - - return handle_exception( - bind_return( - *r - , bind(operator_dispatcher::create, - ref(*r, ref::increment_count), - ref()))) - ? -1 : 0; -} - -#define PY_DEFINE_OPERATOR(id, symbol) \ - PyObject* operator_dispatcher_call_##id(PyObject* left, PyObject* right) \ - { \ - /* unwrap the arguments from their OperatorDispatcher */ \ - PyObject* self; \ - PyObject* other; \ - int reverse = unwrap_args(left, right, self, other); \ - if (reverse == unwrap_exception_code) \ - return 0; \ - \ - /* call the function */ \ - PyObject* result = \ - PyEval_CallMethod(self, \ - const_cast(reverse ? "__r" #id "__" : "__" #id "__"), \ - const_cast("(O)"), \ - other); \ - if (result == 0 && PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_AttributeError)) \ - { \ - PyErr_Clear(); \ - PyErr_SetString(PyExc_TypeError, "bad operand type(s) for " #symbol); \ - } \ - return result; \ - } - -PY_DEFINE_OPERATOR(add, +) -PY_DEFINE_OPERATOR(sub, -) -PY_DEFINE_OPERATOR(mul, *) -PY_DEFINE_OPERATOR(div, /) -PY_DEFINE_OPERATOR(mod, %) -PY_DEFINE_OPERATOR(divmod, divmod) -PY_DEFINE_OPERATOR(lshift, <<) -PY_DEFINE_OPERATOR(rshift, >>) -PY_DEFINE_OPERATOR(and, &) -PY_DEFINE_OPERATOR(xor, ^) -PY_DEFINE_OPERATOR(or, |) - -/* coercion rules for heterogeneous pow(): - pow(Foo, int): left, right coerced; m: None => reverse = 0 - pow(int, Foo): left, right coerced; m: None => reverse = 1 - pow(Foo, int, int): left, right, m coerced => reverse = 0 - pow(int, Foo, int): left, right, m coerced => reverse = 1 - pow(int, int, Foo): left, right, m coerced => reverse = 2 - pow(Foo, Foo, int): left, right coerced; m coerced twice => reverse = 0 - pow(Foo, int, Foo): left, right, m coerced => reverse = 0 - pow(int, Foo, Foo): left, right, m coerced => reverse = 1 -*/ -PyObject* operator_dispatcher_call_pow(PyObject* left, PyObject* right, PyObject* m) -{ - int reverse; - PyObject* self; - PyObject* first; - PyObject* second; - - if (m->ob_type == Py_None->ob_type) - { - reverse = unwrap_args(left, right, self, first); - second = m; - } - else - { - reverse = unwrap_pow_args(left, right, m, self, first, second); - } - - if (reverse == unwrap_exception_code) - return 0; - - // call the function - PyObject* result = - PyEval_CallMethod(self, - const_cast((reverse == 0) - ? "__pow__" - : (reverse == 1) - ? "__rpow__" - : "__rrpow__"), - const_cast("(OO)"), - first, second); - if (result == 0 && - (PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_TypeError) || - PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_AttributeError))) - { - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError, "bad operand type(s) for pow()"); - } - return result; -} - -int operator_dispatcher_call_cmp(PyObject* left, PyObject* right) -{ - // unwrap the arguments from their OperatorDispatcher - PyObject* self; - PyObject* other; - int reverse = unwrap_args(left, right, self, other); - if (reverse == unwrap_exception_code) - return -1; - - // call the function - PyObject* result = - PyEval_CallMethod(self, - const_cast(reverse ? "__rcmp__" : "__cmp__"), - const_cast("(O)"), - other); - if (result == 0) - { - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError, "bad operand type(s) for cmp() or <"); - return -1; - } - else - { - try - { - return BOOST_PYTHON_CONVERSION::from_python(result, type()); - } - catch(...) - { - PyErr_Clear(); - PyErr_SetString(PyExc_TypeError, "cmp() didn't return int"); - return -1; - } - } -} - -} // extern "C" - -PyTypeObject operator_dispatcher::type_obj = -{ - PyObject_HEAD_INIT(&PyType_Type) - 0, - const_cast("operator_dispatcher"), - sizeof(operator_dispatcher), - 0, - &operator_dispatcher_dealloc, - 0, - 0, - 0, - &operator_dispatcher_call_cmp, - 0, - &operator_dispatcher::number_methods, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - -PyNumberMethods operator_dispatcher::number_methods = -{ - &operator_dispatcher_call_add, - &operator_dispatcher_call_sub, - &operator_dispatcher_call_mul, - &operator_dispatcher_call_div, - &operator_dispatcher_call_mod, - &operator_dispatcher_call_divmod, - &operator_dispatcher_call_pow, - 0, - 0, - 0, - 0, - 0, - &operator_dispatcher_call_lshift, - &operator_dispatcher_call_rshift, - &operator_dispatcher_call_and, - &operator_dispatcher_call_xor, - &operator_dispatcher_call_or, - &operator_dispatcher_coerce, - 0, - 0, - 0, - 0, - 0 -}; - -} // namespace detail - -}} // namespace boost::python diff --git a/src/functions.cpp b/src/functions.cpp deleted file mode 100644 index cb9b067d..00000000 --- a/src/functions.cpp +++ /dev/null @@ -1,181 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// Mar 01 01 Use PyObject_INIT() instead of trying to hand-initialize (David Abrahams) - -#define BOOST_PYTHON_SOURCE - -#include -#include -#include -#include -#include - -namespace boost { namespace python { namespace detail { - -struct function::type_object : - singleton > > -{ - type_object() : singleton_base(&PyType_Type) {} -}; - - -void function::add_to_namespace(reference new_function, const char* name, PyObject* dict) -{ - dictionary d(ref(dict, ref::increment_count)); - string key(name); - - ref existing_object = d.get_item(key.reference()); - if (existing_object.get() == 0) - { - d[key] = ref(new_function.get(), ref::increment_count); - } - else - { - if (existing_object->ob_type == type_object::instance()) - { - function* f = static_cast(existing_object.get()); - while (f->m_overloads.get() != 0) - f = f->m_overloads.get(); - f->m_overloads = new_function; - } - else - { - PyErr_SetObject(PyExc_RuntimeError, - (string("Attempt to overload ") + name - + " failed. The existing attribute has type " - + existing_object->ob_type->tp_name).get()); - throw_error_already_set(); - } - } -} - -function::function() - : python_object(type_object::instance()) -{ -} - -PyObject* function::call(PyObject* args, PyObject* keywords) const -{ - // Traverse the linked list of function overloads until we find one that - // matches. - for (const function* f = this; f != 0; f = f->m_overloads.get()) - { - PyErr_Clear(); - try - { - PyObject* const result = f->do_call(args, keywords); - if (result != 0) - return result; - } - catch(const argument_error&) - { - } - } - - // If we get here, no overloads matched the arguments - - // Allow the single-function error-reporting to take effect unless there was - // an overload - if (m_overloads.get() == 0) - return 0; - - // Synthesize a more-explicit error message - PyErr_Clear(); - string message("No overloaded functions match ("); - tuple arguments(ref(args, ref::increment_count)); - for (std::size_t i = 0; i < arguments.size(); ++i) - { - if (i != 0) - message += ", "; - message += arguments[i]->ob_type->tp_name; - } - - message += "). Candidates are:\n"; - for (const function* f1 = this; f1 != 0; f1 = f1->m_overloads.get()) - { - if (f1 != this) - message += "\n"; - message += f1->description(); - } - - PyErr_SetObject(PyExc_TypeError, message.get()); - return 0; -} - -// The instance class whose obj represents the type of bound_function -// objects in Python. bound_functions must be GetAttrable so the __doc__ -// attribute of built-in Python functions can be accessed when bound. -struct bound_function::type_object : - singleton > > > -{ - type_object() : singleton_base(&PyType_Type) {} - -private: // type_object hook override - void dealloc(bound_function*) const; -}; - -bound_function* bound_function::create(const ref& target, const ref& fn) -{ - bound_function* const result = free_list; - if (result == 0) - return new bound_function(target, fn); - - free_list = result->m_free_list_link; - result->m_target = target; - result->m_unbound_function = fn; - - PyObject* self = result; - PyObject_INIT(self, type_object::instance()); - return result; -} - -bound_function::bound_function(const ref& target, const ref& fn) - : python_object(type_object::instance()), - m_target(target), - m_unbound_function(fn), - m_free_list_link(0) -{ -} - -PyObject* -bound_function::call(PyObject* args, PyObject* keywords) const -{ - // Build a new tuple which prepends the target to the arguments - tuple tail_arguments(ref(args, ref::increment_count)); - ref all_arguments(PyTuple_New(tail_arguments.size() + 1)); - - PyTuple_SET_ITEM(all_arguments.get(), 0, m_target.get()); - Py_INCREF(m_target.get()); - for (std::size_t i = 0; i < tail_arguments.size(); ++i) - { - PyTuple_SET_ITEM(all_arguments.get(), i + 1, tail_arguments[i].get()); - Py_INCREF(tail_arguments[i].get()); - } - - return PyEval_CallObjectWithKeywords(m_unbound_function.get(), all_arguments.get(), keywords); -} - -PyObject* bound_function::getattr(const char* name) const -{ - return PyObject_GetAttrString(m_unbound_function.get(), const_cast(name)); -} - -void bound_function::type_object::dealloc(bound_function* obj) const -{ - obj->m_free_list_link = free_list; - free_list = obj; - obj->m_target.reset(); - obj->m_unbound_function.reset(); -} - -bound_function* bound_function::free_list; - -}}} // namespace boost::python::detail diff --git a/src/gen_all.py b/src/gen_all.py deleted file mode 100644 index 3877d181..00000000 --- a/src/gen_all.py +++ /dev/null @@ -1,26 +0,0 @@ -from gen_callback import * -from gen_caller import * -from gen_init_function import * -from gen_signatures import * -from gen_singleton import * -from gen_extclass import * - -def gen_all(args): - open('callback.hpp', 'w').write(gen_callback(args)) - open('caller.hpp', 'w').write(gen_caller(args)) - open('init_function.hpp', 'w').write(gen_init_function(args)) - open('signatures.hpp', 'w').write(gen_signatures(args)) - open('singleton.hpp', 'w').write(gen_singleton(args)) - open('extension_class.hpp', 'w').write(gen_extclass(args)) - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 10 - else: - args = int(sys.argv[1]) - - print gen_all(args) - - diff --git a/src/gen_arg_tuple_size.py b/src/gen_arg_tuple_size.py deleted file mode 100644 index 9de332ab..00000000 --- a/src/gen_arg_tuple_size.py +++ /dev/null @@ -1,139 +0,0 @@ -# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# This work was funded in part by Lawrence Berkeley National Labs - -from gen_function import * -import string - -header = '''// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for %d-argument member functions and %d-argument free -// functions by gen_arg_tuple_size.python -''' - -_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') - -_suffix = { - '': ''' -// Metrowerks thinks this creates ambiguities -# if !defined(__MWERKS__) || __MWERKS__ > 0x2406 -''', ' const volatile': ''' -# endif // __MWERKS__ -''' - }; - -def gen_arg_tuple_size(member_function_args, free_function_args = None): - if free_function_args is None: - free_function_args = member_function_args + 1 - - return_none = '''; - return detail::none();''' - - return (header % (member_function_args, free_function_args) - + ''' -#ifndef ARG_TUPLE_SIZE_DWA20011201_HPP -# define ARG_TUPLE_SIZE_DWA20011201_HPP - -# include - -namespace boost { namespace python { namespace detail { - -// Computes (at compile-time) the number of elements that a Python -// argument tuple must have in order to be passed to a wrapped C++ -// (member) function of the given type. -template struct arg_tuple_size; - -# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__BORLANDC__) - -''' - + gen_functions( -'''template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = %n); -}; - -''', free_function_args) - - + '\n' - - + reduce(lambda x,y: x+'\n'+y - , map( - lambda cv: gen_functions( -'''template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = %+); -}; - -''' - , member_function_args, cv) + _suffix.get(cv, '') - , _cv_qualifiers)) - - + -'''# else - -// We will use the "sizeof() trick" to work around the lack of -// partial specialization in MSVC6 and its broken-ness in borland. -// See http://opensource.adobe.com or -// http://groups.yahoo.com/group/boost/message/5441 for -// more examples - -// The following helper functions are never actually called, since -// they are only used within a sizeof() expression, but the type of -// their return value is used to discriminate between various free -// and member function pointers at compile-time. - -''' - + gen_functions( -'''template -char_array<%n> arg_tuple_size_helper(R (*)(%(A%+%:, %))); - -''', free_function_args) - - + reduce(lambda x,y: x+'\n'+y - , map( - lambda cv: gen_functions( -'''template -char_array<%+> arg_tuple_size_helper(R (A0::*)(%(A%+%:, %))%1); - -''', member_function_args, cv) - , _cv_qualifiers)) - + ''' -template -struct arg_tuple_size -{ - // The sizeof() magic happens here - BOOST_STATIC_CONSTANT(std::size_t, value - = sizeof(arg_tuple_size_helper(F(0)).elements) - 1); -}; -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -}}} // namespace boost::python::detail - -#endif // ARG_TUPLE_SIZE_DWA20011201_HPP -''') - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - member_function_args = 5 - free_function_args = 6 - else: - member_function_args = int(sys.argv[1]) - if len(sys.argv) > 2: - free_function_args = int(sys.argv[2]) - else: - free_function_args = member_function_args - - print gen_arg_tuple_size(member_function_args, free_function_args) - - diff --git a/src/gen_call.py b/src/gen_call.py deleted file mode 100644 index f609c0ae..00000000 --- a/src/gen_call.py +++ /dev/null @@ -1,82 +0,0 @@ -# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# This work was funded in part by Lawrence Berkeley National Labs - -from gen_function import * -import string - -header = '''// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for %d-argument member functions and %d-argument free -// functions by gen_call.py - -#ifndef CALL_DWA20011214_HPP -# define CALL_DWA20011214_HPP - -# include - -namespace boost { namespace python { - -''' -_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') - -def gen_call(member_function_args, free_function_args = None): - if free_function_args is None: - free_function_args = member_function_args + 1 - - return (header % (member_function_args, free_function_args) - + gen_functions( -'''template -inline PyObject* call(R (*f)(%(A%n%:, %)), PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -''', free_function_args) - + -'''// Member functions -''' - + reduce(lambda x,y: x+y - , map(lambda cv: - gen_functions( -'''template -inline PyObject* call(R (A0::*f)(%(A%+%:, %))%1, PyObject* args, PyObject* keywords) -{ - return detail::returning::call(f, args, keywords); -} - -''' - , member_function_args, cv) - , _cv_qualifiers)) - + -''' -}} // namespace boost::python - -#endif // CALL_DWA20011214_HPP -''') - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - member_function_args = 5 - free_function_args = 6 - else: - member_function_args = int(sys.argv[1]) - if len(sys.argv) > 2: - free_function_args = int(sys.argv[2]) - else: - free_function_args = member_function_args - - print gen_call(member_function_args, free_function_args) - - diff --git a/src/gen_callback.py b/src/gen_callback.py deleted file mode 100644 index f178212b..00000000 --- a/src/gen_callback.py +++ /dev/null @@ -1,124 +0,0 @@ -from gen_function import * -import string - -def gen_callback(args): - return ( -"""// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file was generated for %d-argument python callbacks by gen_callback.python - -#ifndef CALLBACK_DWA_052100_H_ -# define CALLBACK_DWA_052100_H_ - -# include -# include - -namespace boost { namespace python { - -namespace detail { - template - inline void callback_adjust_refcount(PyObject*, type) {} - - inline void callback_adjust_refcount(PyObject* p, type) - { Py_INCREF(p); } -} - -// Calling Python from C++ -template -struct callback -{""" % args - - + gen_functions(''' -%{ template <%(class A%n%:, %)> -%} static R call_method(PyObject* self, const char* name%(, const A%n& a%n%)) - {%( - ref p%n(to_python(a%n));%) - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(%(O%))")%(, - p%n.get()%))); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } - -%{ template <%(class A%n%:, %)> -%} static R call(PyObject* self%(, const A%n& a%n%)) - {%( - ref p%n(to_python(a%n));%) - ref result(PyEval_CallFunction(self, const_cast("(%(O%))")%(, - p%n.get()%))); - detail::callback_adjust_refcount(result.get(), type()); - return from_python(result.get(), type()); - } -''', args) - + -"""}; - -// This specialization wouldn't be needed, but MSVC6 doesn't correctly allow the following: -// void g(); -// void f() { return g(); } -template <> -struct callback -{ -""" - + gen_functions(''' -%{ template <%(class A%n%:, %)> -%} static void call_method(PyObject* self, const char* name%(, const A%n& a%n%)) - {%( - ref p%n(to_python(a%n));%) - ref result(PyEval_CallMethod(self, const_cast(name), - const_cast("(%(O%))")%(, - p%n.get()%))); - } - -%{ template <%(class A%n%:, %)> -%} static void call(PyObject* self%(, const A%n& a%n%)) - {%( - ref p%n(to_python(a%n));%) - ref result(PyEval_CallFunction(self, const_cast("(%(O%))")%(, - p%n.get()%))); - } -''', args) - + -"""}; - -// Make it a compile-time error to try to return a const char* from a virtual -// function. The standard conversion -// -// from_python(PyObject* string, boost::python::type) -// -// returns a pointer to the character array which is internal to string. The -// problem with trying to do this in a standard callback function is that the -// Python string would likely be destroyed upon return from the calling function -// (boost::python::callback::call[_method]) when its reference count is -// decremented. If you absolutely need to do this and you're sure it's safe (it -// usually isn't), you can use -// -// boost::python::string result(boost::python::callback::call[_method](...args...)); -// ...result.c_str()... // access the char* array -template <> -struct callback -{ - // Try hard to generate a readable error message - typedef struct unsafe_since_python_string_may_be_destroyed {} call, call_method; -}; - -}} // namespace boost::python - -#endif // CALLBACK_DWA_052100_H_ -""") - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 5 - else: - args = int(sys.argv[1]) - - print gen_callback(args) diff --git a/src/gen_caller.py b/src/gen_caller.py deleted file mode 100644 index 26bd88c6..00000000 --- a/src/gen_caller.py +++ /dev/null @@ -1,138 +0,0 @@ -# (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# The author gratefully acknowleges the support of Dragon Systems, Inc., in -# producing this work. - -from gen_function import * -import string - -header = '''// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file generated for %d-argument member functions and %d-argument free -// functions by gen_caller.python -''' - -body_sections = ( -''' -#ifndef CALLER_DWA05090_H_ -# define CALLER_DWA05090_H_ - -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// Calling C++ from Python -template -struct caller -{ -''', -''' -''', -''' // Free functions -''', -'''}; - -template <> -struct caller -{ -''', -''' -''', -''' - // Free functions -''', -'''}; - -}} // namespace boost::python - -#endif -''') - -#' - -member_function = ''' template - static PyObject* call(%1 (T::*pmf)(%(A%n%:, %))%2, PyObject* args, PyObject* /* keywords */ ) { - PyObject* self; -%( PyObject* a%n; -%) if (!PyArg_ParseTuple(args, const_cast("O%(O%)"), &self%(, &a%n%))) - return 0; - T& target = from_python(self, type()); - %3(target.*pmf)(%(from_python(a%n, type())%:, - %))%4 - } - -''' - -free_function = '''%{ template <%(class A%n%:, %)> -%} static PyObject* call(%1 (*f)(%(A%n%:, %)), PyObject* args, PyObject* /* keywords */ ) { -%( PyObject* a%n; -%) if (!PyArg_ParseTuple(args, const_cast("%(O%)")%(, &a%n%))) - return 0; - %2f(%(from_python(a%n, type())%:, - %))%3 - } - -''' - -def gen_caller(member_function_args, free_function_args = None): - if free_function_args is None: - free_function_args = member_function_args + 1 - - return_none = '''; - return detail::none();''' - - return (header % (member_function_args, free_function_args) - + body_sections[0] - + gen_functions(member_function, member_function_args, - 'R', '', 'return to_python(', ');') - + body_sections[1] - + gen_functions(member_function, member_function_args, - 'R', ' const', 'return to_python(', ');') - + body_sections[2] - - + gen_functions(free_function, free_function_args, - 'R', 'return to_python(', ');') - + body_sections[3] - - # specialized part for void return values begins here - + gen_functions(member_function, member_function_args, - 'void', '', '', return_none) - + body_sections[4] - + gen_functions(member_function, member_function_args, - 'void', ' const', '', return_none) - + body_sections[5] - - + gen_functions(free_function, free_function_args, - 'void', '', return_none) - + body_sections[6] - ) - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - member_function_args = 5 - free_function_args = 6 - else: - member_function_args = int(sys.argv[1]) - if len(sys.argv) > 2: - free_function_args = int(sys.argv[2]) - else: - free_function_args = member_function_args - - print gen_caller(member_function_args, free_function_args) - - diff --git a/src/gen_extclass.py b/src/gen_extclass.py deleted file mode 100644 index 787e262e..00000000 --- a/src/gen_extclass.py +++ /dev/null @@ -1,948 +0,0 @@ -from gen_function import * -import string - -def gen_extclass(args): - return ( -"""// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file automatically generated for %d-argument constructors by -// gen_extclass.python - -// Revision History: -// 17 Apr 01 Comment added with reference to cross_module.hpp (R.W. Grosse-Kunstleve) -// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted -// to_python (Dave Abrahams) - -#ifndef EXTENSION_CLASS_DWA052000_H_ -# define EXTENSION_CLASS_DWA052000_H_ - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -// forward declarations -template struct operators; -template struct left_operand; -template struct right_operand; - -enum without_downcast_t { without_downcast }; - -namespace detail -{ - -// forward declarations - class extension_instance; - class extension_class_base; - template class instance_holder; - template class instance_value_holder; - template class instance_ptr_holder; - template struct operand_select; - template struct choose_op; - template struct choose_rop; - template struct choose_unary_op; - template struct define_operator; - - class BOOST_PYTHON_DECL extension_instance : public instance - { - public: - extension_instance(PyTypeObject* class_); - ~extension_instance(); - - void add_implementation(std::auto_ptr holder); - - typedef std::vector held_objects; - const held_objects& wrapped_objects() const - { return m_wrapped_objects; } - private: - held_objects m_wrapped_objects; - }; - -} // namespace detail - -# ifndef BOOST_PYTHON_NO_TEMPLATE_EXPORT -BOOST_PYTHON_EXPORT_TEMPLATE_CLASS class_t; -BOOST_PYTHON_EXPORT_TEMPLATE_CLASS meta_class; -# endif - -namespace detail { - -BOOST_PYTHON_DECL meta_class* extension_meta_class(); -BOOST_PYTHON_DECL extension_instance* get_extension_instance(PyObject* p); -BOOST_PYTHON_DECL void report_missing_instance_data(extension_instance*, class_t*, const std::type_info&); -BOOST_PYTHON_DECL void report_missing_ptr_data(extension_instance*, class_t*, const std::type_info&); -BOOST_PYTHON_DECL void report_missing_class_object(const std::type_info&); -BOOST_PYTHON_DECL void report_released_smart_pointer(const std::type_info&); - -template -T* check_non_null(T* p) -{ - if (p == 0) - report_released_smart_pointer(typeid(T)); - return p; -} - -template class held_instance; - -typedef void* (*conversion_function_ptr)(void*); - -struct BOOST_PYTHON_DECL base_class_info -{ - base_class_info(extension_class_base* t, conversion_function_ptr f) - :class_object(t), convert(f) - {} - - extension_class_base* class_object; - conversion_function_ptr convert; -}; - -typedef base_class_info derived_class_info; - -struct add_operator_base; - -class BOOST_PYTHON_DECL extension_class_base : public class_t -{ - public: - extension_class_base(const char* name); - - public: - // the purpose of try_class_conversions() and its related functions - // is explained in extclass.cpp - void* try_class_conversions(instance_holder_base*) const; - void* try_base_class_conversions(instance_holder_base*) const; - void* try_derived_class_conversions(instance_holder_base*) const; - - void set_attribute(const char* name, PyObject* x); - void set_attribute(const char* name, ref x); - - private: - virtual void* extract_object_from_holder(instance_holder_base* v) const = 0; - virtual std::vector const& base_classes() const = 0; - virtual std::vector const& derived_classes() const = 0; - - protected: - friend struct add_operator_base; - void add_method(reference method, const char* name); - void add_method(function* method, const char* name); - - void add_constructor_object(function*); - void add_setter_method(function*, const char* name); - void add_getter_method(function*, const char* name); -}; - -template -class class_registry -{ - public: - static extension_class_base* class_object() - { return static_class_object; } - - // Register/unregister the Python class object corresponding to T - static void register_class(extension_class_base*); - static void unregister_class(extension_class_base*); - - // Establish C++ inheritance relationships - static void register_base_class(base_class_info const&); - static void register_derived_class(derived_class_info const&); - - // Query the C++ inheritance relationships - static std::vector const& base_classes(); - static std::vector const& derived_classes(); - private: - static extension_class_base* static_class_object; - static std::vector static_base_class_info; - static std::vector static_derived_class_info; -}; - -template -struct is_null_helper -{ - template - static bool test(Ptr x) { return x == 0; } -}; - -template <> -struct is_null_helper -{ - template - static bool test(const Ptr& x) { return x.get() == 0; } -}; - -template -bool is_null(const Ptr& x) -{ - return is_null_helper<(is_pointer::value)>::test(x); -} - -}}} // namespace boost::python::detail - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -// This class' only job is to define from_python and to_python converters for T -// and U. T is the class the user really intends to wrap. U is a class derived -// from T with some virtual function overriding boilerplate, or if there are no -// virtual functions, U = held_instance. -// -// A look-alike of this class in root/boost/python/cross_module.hpp -// is used for the implementation of the cross-module support -// (export_converters and import_converters). If from_python -// and to_python converters are added or removed from the class -// below, the class python_import_extension_class_converters has -// to be modified accordingly. -// -template > -class python_extension_class_converters -{ - public: - // Get an object which can be used to convert T to/from python. This is used - // as a kind of concept check by the global template - // - // PyObject* to_python(const T& x) - // - // below this class, to prevent the confusing messages that would otherwise - // pop up. Now, if T hasn't been wrapped as an extension class, the user - // will see an error message about the lack of an eligible - // py_extension_class_converters() function. - friend python_extension_class_converters py_extension_class_converters(boost::python::type) - { - return python_extension_class_converters(); - } - - // This is a member function because in a conforming implementation, friend - // funcitons defined inline in the class body are all instantiated as soon - // as the enclosing class is instantiated. If T is not copyable, that causes - // a compiler error. Instead, we access this function through the global - // template - // - // PyObject* to_python(const T& x) - // - // defined below this class. Since template functions are instantiated only - // on demand, errors will be avoided unless T is noncopyable and the user - // writes code which causes us to try to copy a T. - PyObject* to_python(const T& x) const - { - boost::python::reference result(create_instance()); - result->add_implementation( - std::auto_ptr( - new boost::python::detail::instance_value_holder(result.get(), x))); - return result.release(); - } - - friend - T* non_null_from_python(PyObject* obj, boost::python::type) - { - // downcast to an extension_instance, then find the actual T - boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); - typedef std::vector::const_iterator iterator; - for (iterator p = self->wrapped_objects().begin(); - p != self->wrapped_objects().end(); ++p) - { - boost::python::detail::instance_holder* held = dynamic_cast*>(*p); - if (held != 0) - return held->target(); - - // see extclass.cpp for an explanation of try_class_conversions() - void* target = boost::python::detail::class_registry::class_object()->try_class_conversions(*p); - if(target) - return static_cast(target); - } - boost::python::detail::report_missing_instance_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); - boost::python::throw_argument_error(); -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 - return 0; -#endif - } - - // Convert to T* - friend T* from_python(PyObject* obj, boost::python::type) - { - if (obj == Py_None) - return 0; - else - return non_null_from_python(obj, boost::python::type()); - } - - // Extract from obj a mutable reference to the PtrType object which is holding a T. - template - static PtrType& smart_ptr_reference(PyObject* obj, boost::python::type) - { - // downcast to an extension_instance, then find the actual T - boost::python::detail::extension_instance* self = boost::python::detail::get_extension_instance(obj); - typedef std::vector::const_iterator iterator; - for (iterator p = self->wrapped_objects().begin(); - p != self->wrapped_objects().end(); ++p) - { - boost::python::detail::instance_ptr_holder* held = - dynamic_cast*>(*p); - if (held != 0) - return held->ptr(); - } - boost::python::detail::report_missing_ptr_data(self, boost::python::detail::class_registry::class_object(), typeid(T)); - boost::python::throw_argument_error(); -#if defined(__MWERKS__) && __MWERKS__ <= 0x2406 - return *(PtrType*)0; -#endif - } - - // Extract from obj a reference to the PtrType object which is holding a - // T. If it weren't for auto_ptr, it would be a constant reference. Do not - // modify the referent except by copying an auto_ptr! If obj is None, the - // reference denotes a default-constructed PtrType - template - static PtrType& smart_ptr_value(PyObject* obj, boost::python::type) - { - if (obj == Py_None) - { - static PtrType null_ptr; - return null_ptr; - } - return smart_ptr_reference(obj, boost::python::type()); - } - - template - static PyObject* smart_ptr_to_python(PtrType x) - { - if (boost::python::detail::is_null(x)) - { - return boost::python::detail::none(); - } - - boost::python::reference result(create_instance()); - result->add_implementation( - std::auto_ptr( - new boost::python::detail::instance_ptr_holder(x))); - return result.release(); - } - - static boost::python::reference create_instance() - { - PyTypeObject* class_object = boost::python::detail::class_registry::class_object(); - if (class_object == 0) - boost::python::detail::report_missing_class_object(typeid(T)); - - return boost::python::reference( - new boost::python::detail::extension_instance(class_object)); - } - - // Convert to const T* - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to const T* const& - friend const T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T* const& - friend T* from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T& - friend T& from_python(PyObject* p, boost::python::type) - { return *boost::python::detail::check_non_null(non_null_from_python(p, boost::python::type())); } - - // Convert to const T& - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - // Convert to T - friend const T& from_python(PyObject* p, boost::python::type) - { return from_python(p, boost::python::type()); } - - friend std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_reference(p, boost::python::type >()); } - - friend std::auto_ptr from_python(PyObject* p, boost::python::type >) - { return smart_ptr_value(p, boost::python::type >()); } - - friend const std::auto_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_value(p, boost::python::type >()); } - - friend PyObject* to_python(std::auto_ptr x) - { return smart_ptr_to_python(x); } - - friend boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_reference(p, boost::python::type >()); } - - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type >) - { return smart_ptr_value(p, boost::python::type >()); } - - friend const boost::shared_ptr& from_python(PyObject* p, boost::python::type&>) - { return smart_ptr_value(p, boost::python::type >()); } - - friend PyObject* to_python(boost::shared_ptr x) - { return smart_ptr_to_python(x); } -}; - -// Convert T to_python, instantiated on demand and only if there isn't a -// non-template overload for this function. This version is the one invoked when -// T is a wrapped class. See the first 2 functions declared in -// python_extension_class_converters above for more info. -template -PyObject* to_python(const T& x) -{ - return py_extension_class_converters(boost::python::type()).to_python(x); -} - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -BOOST_PYTHON_IMPORT_CONVERSION(python_extension_class_converters); - -namespace detail { - -template class instance_holder; - -class BOOST_PYTHON_DECL read_only_setattr_function : public function -{ - public: - read_only_setattr_function(const char* name); - PyObject* do_call(PyObject* args, PyObject* keywords) const; - const char* description() const; - private: - string m_name; -}; - - template - struct define_conversion - { - static void* upcast_ptr(void* v) - { - return static_cast(static_cast(v)); - } - - static void* downcast_ptr(void* v) - { - return dynamic_cast(static_cast(v)); - } - }; - -// An easy way to make an extension base class which wraps T. Note that Python -// subclasses of this class will simply be class_t objects. -// -// U should be a class derived from T which overrides virtual functions with -// boilerplate code to call back into Python. See extclass_demo.h for examples. -// -// U is optional, but you won't be able to override any member functions in -// Python which are called from C++ if you don't supply it. If you just want to -// be able to use T in python without overriding member functions, you can omit -// U. -template > -class extension_class - : public python_extension_class_converters, // This generates the to_python/from_python functions - public extension_class_base -{ - public: - typedef T wrapped_type; - typedef U callback_type; - - // Construct with a name that comes from typeid(T).name(). The name only - // affects the objects of this class are represented through repr() - extension_class(); - - // Construct with the given name. The name only affects the objects of this - // class are represented through repr() - extension_class(const char* name); - - ~extension_class(); - - // define constructors -""" % args - + gen_function( -""" template <%(class A%n%:, %)> - inline void def(constructor<%(A%n%:, %)>) - // The following incantation builds a signature1, signature2,... object. It - // should _all_ get optimized away. - { add_constructor( - %(prepend(type::id(), - %) signature0()%()%)); - } -""", args) - + -""" - - // export homogeneous operators (type of both lhs and rhs is 'operator') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>()); - - // export homogeneous operators (type of both lhs and rhs is 'T const&') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>()); - template - inline void def(operators) - { - typedef typename operand_select::template wrapped::type true_operand; - def_operators(operators()); - } - - // export heterogeneous operators (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::right_operand()); - - // export heterogeneous operators (type of lhs: 'T const&', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), - // boost::python::right_operand()); - template - inline void def(operators, right_operand r) - { - typedef typename operand_select::template wrapped::type true_left; - def_operators(operators(), r); - } - - // export heterogeneous reverse-argument operators - // (type of lhs: 'left', of rhs: 'right') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub), Foo>(), - // boost::python::left_operand()); - - // export heterogeneous reverse-argument operators - // (type of lhs: 'left', of rhs: 'T const&') - // usage: foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), - // boost::python::left_operand()); - template - inline void def(operators, left_operand l) - { - typedef typename operand_select::template wrapped::type true_right; - def_operators(operators(), l); - } - - // define a function that passes Python arguments and keywords - // to C++ verbatim (as a 'tuple const&' and 'dictionary const&' - // respectively). This is useful for manual argument passing. - // It's also the only possibility to pass keyword arguments to C++. - // Fn must have a signatur that is compatible to - // PyObject* (*)(PyObject* aTuple, PyObject* aDictionary) - template - inline void def_raw(Fn fn, const char* name) - { - this->add_method(new_raw_arguments_function(fn), name); - } - - // define member functions. In fact this works for free functions, too - - // they act like static member functions, or if they start with the - // appropriate self argument (as a pointer), they can be used just like - // ordinary member functions -- just like Python! - template - inline void def(Fn fn, const char* name) - { - this->add_method(new_wrapped_function(fn), name); - } - - // Define a virtual member function with a default implementation. - // default_fn should be a function which provides the default implementation. - // Be careful that default_fn does not in fact call fn virtually! - template - inline void def(Fn fn, const char* name, DefaultFn default_fn) - { - this->add_method(new_virtual_function(type(), fn, default_fn), name); - } - - // Provide a function which implements x., reading from the given - // member (pm) of the T obj - template - inline void def_getter(MemberType T::*pm, const char* name) - { - this->add_getter_method(new getter_function(pm), name); - } - - // Provide a function which implements assignment to x., writing to - // the given member (pm) of the T obj - template - inline void def_setter(MemberType T::*pm, const char* name) - { - this->add_setter_method(new setter_function(pm), name); - } - - // Expose the given member (pm) of the T obj as a read-only attribute - template - inline void def_readonly(MemberType T::*pm, const char* name) - { - this->add_setter_method(new read_only_setattr_function(name), name); - this->def_getter(pm, name); - } - - // Expose the given member (pm) of the T obj as a read/write attribute - template - inline void def_read_write(MemberType T::*pm, const char* name) - { - this->def_getter(pm, name); - this->def_setter(pm, name); - } - - // define the standard coercion needed for operator overloading - void def_standard_coerce(); - - // declare the given class a base class of this one and register - // up and down conversion functions - template - void declare_base(extension_class* base) - { - // see extclass.cpp for an explanation of why we need to register - // conversion functions - base_class_info baseInfo(base, - &define_conversion::downcast_ptr); - class_registry::register_base_class(baseInfo); - add_base(ref(as_object(base), ref::increment_count)); - - derived_class_info derivedInfo(this, - &define_conversion::upcast_ptr); - class_registry::register_derived_class(derivedInfo); - } - - // declare the given class a base class of this one and register - // only up conversion function - template - void declare_base(extension_class* base, without_downcast_t) - { - // see extclass.cpp for an explanation of why we need to register - // conversion functions - base_class_info baseInfo(base, 0); - class_registry::register_base_class(baseInfo); - add_base(ref(as_object(base), ref::increment_count)); - - derived_class_info derivedInfo(this, - &define_conversion::upcast_ptr); - class_registry::register_derived_class(derivedInfo); - } - - private: // types - typedef instance_value_holder holder; - - private: // extension_class_base virtual function implementations - std::vector const& base_classes() const; - std::vector const& derived_classes() const; - void* extract_object_from_holder(instance_holder_base* v) const; - - private: // Utility functions - template - inline void def_operators(operators) - { - def_standard_coerce(); - - // for some strange reason, this prevents MSVC from having an - // "unrecoverable block scoping error"! - typedef choose_op<(which & op_add)> choose_add; - - choose_op<(which & op_add)>::template args::add(this); - choose_op<(which & op_sub)>::template args::add(this); - choose_op<(which & op_mul)>::template args::add(this); - choose_op<(which & op_div)>::template args::add(this); - choose_op<(which & op_mod)>::template args::add(this); - choose_op<(which & op_divmod)>::template args::add(this); - choose_op<(which & op_pow)>::template args::add(this); - choose_op<(which & op_lshift)>::template args::add(this); - choose_op<(which & op_rshift)>::template args::add(this); - choose_op<(which & op_and)>::template args::add(this); - choose_op<(which & op_xor)>::template args::add(this); - choose_op<(which & op_or)>::template args::add(this); - choose_op<(which & op_gt)>::template args::add(this); - choose_op<(which & op_ge)>::template args::add(this); - choose_op<(which & op_lt)>::template args::add(this); - choose_op<(which & op_le)>::template args::add(this); - choose_op<(which & op_eq)>::template args::add(this); - choose_op<(which & op_ne)>::template args::add(this); - choose_unary_op<(which & op_neg)>::template args::add(this); - choose_unary_op<(which & op_pos)>::template args::add(this); - choose_unary_op<(which & op_abs)>::template args::add(this); - choose_unary_op<(which & op_invert)>::template args::add(this); - choose_unary_op<(which & op_int)>::template args::add(this); - choose_unary_op<(which & op_long)>::template args::add(this); - choose_unary_op<(which & op_float)>::template args::add(this); - choose_op<(which & op_cmp)>::template args::add(this); - choose_unary_op<(which & op_str)>::template args::add(this); - } - - template - inline void def_operators(operators, right_operand) - { - def_standard_coerce(); - - choose_op<(which & op_add)>::template args::add(this); - choose_op<(which & op_sub)>::template args::add(this); - choose_op<(which & op_mul)>::template args::add(this); - choose_op<(which & op_div)>::template args::add(this); - choose_op<(which & op_mod)>::template args::add(this); - choose_op<(which & op_divmod)>::template args::add(this); - choose_op<(which & op_pow)>::template args::add(this); - choose_op<(which & op_lshift)>::template args::add(this); - choose_op<(which & op_rshift)>::template args::add(this); - choose_op<(which & op_and)>::template args::add(this); - choose_op<(which & op_xor)>::template args::add(this); - choose_op<(which & op_or)>::template args::add(this); - choose_op<(which & op_cmp)>::template args::add(this); - choose_op<(which & op_gt)>::template args::add(this); - choose_op<(which & op_ge)>::template args::add(this); - choose_op<(which & op_lt)>::template args::add(this); - choose_op<(which & op_le)>::template args::add(this); - choose_op<(which & op_eq)>::template args::add(this); - choose_op<(which & op_ne)>::template args::add(this); - } - - template - inline void def_operators(operators, left_operand) - { - def_standard_coerce(); - - choose_rop<(which & op_add)>::template args::add(this); - choose_rop<(which & op_sub)>::template args::add(this); - choose_rop<(which & op_mul)>::template args::add(this); - choose_rop<(which & op_div)>::template args::add(this); - choose_rop<(which & op_mod)>::template args::add(this); - choose_rop<(which & op_divmod)>::template args::add(this); - choose_rop<(which & op_pow)>::template args::add(this); - choose_rop<(which & op_lshift)>::template args::add(this); - choose_rop<(which & op_rshift)>::template args::add(this); - choose_rop<(which & op_and)>::template args::add(this); - choose_rop<(which & op_xor)>::template args::add(this); - choose_rop<(which & op_or)>::template args::add(this); - choose_rop<(which & op_cmp)>::template args::add(this); - } - - template - void add_constructor(signature sig) - { - this->add_constructor_object(init_function::create(sig)); - } -}; - -// A simple wrapper over a T which allows us to use extension_class with a -// single template parameter only. See extension_class, above. -template -class held_instance : public Held -{ - // There are no member functions: we want to avoid inadvertently overriding - // any virtual functions in Held. -public:""" - + gen_functions("""%{ - template <%(class A%n%:, %)>%} - held_instance(PyObject*%(, A%n% a%n%)) : Held( - %(typename unwrap_parameter::type(a%n)%: - , %)) {}""", args) - + """ -}; - -// Abstract base class for all obj holders. Base for template class -// instance_holder<>, below. -class BOOST_PYTHON_DECL instance_holder_base -{ -public: - virtual ~instance_holder_base() {} - virtual bool held_by_value() = 0; -}; - -// Abstract base class which holds a Held, somehow. Provides a uniform way to -// get a pointer to the held object -template -class instance_holder : public instance_holder_base -{ -public: - virtual Held*target() = 0; -}; - -// Concrete class which holds a Held by way of a wrapper class Wrapper. If Held -// can be constructed with arguments (A1...An), Wrapper must have a -// corresponding constructor for arguments (PyObject*, A1...An). Wrapper is -// neccessary to implement virtual function callbacks (there must be a -// back-pointer to the actual Python object so that we can call any -// overrides). held_instance (above) is used as a default Wrapper class when -// there are no virtual functions. -template -class instance_value_holder : public instance_holder -{ -public: - Held* target() { return &m_held; } - Wrapper* value_target() { return &m_held; } - - instance_value_holder(extension_instance* p) : - m_held(p) {} - template - instance_value_holder(extension_instance* p, A1 a1) : - m_held(p, a1) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2) : - m_held(p, a1, a2) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3) : - m_held(p, a1, a2, a3) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4) : - m_held(p, a1, a2, a3, a4) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) : - m_held(p, a1, a2, a3, a4, a5) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) : - m_held(p, a1, a2, a3, a4, a5, a6) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) : - m_held(p, a1, a2, a3, a4, a5, a6, a7) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9) {} - template - instance_value_holder(extension_instance* p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) : - m_held(p, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {} - - public: // implementation of instance_holder_base required interface - bool held_by_value() { return true; } - - private: - Wrapper m_held; -}; - -// Concrete class which holds a HeldType by way of a (possibly smart) pointer -// PtrType. By default, these are only generated for PtrType == -// std::auto_ptr and PtrType == boost::shared_ptr. -template -class instance_ptr_holder : public instance_holder -{ - public: - HeldType* target() { return &*m_ptr; } - PtrType& ptr() { return m_ptr; } - - instance_ptr_holder(PtrType ptr) : m_ptr(ptr) {} - - public: // implementation of instance_holder_base required interface - bool held_by_value() { return false; } - private: - PtrType m_ptr; -}; - -// -// Template function implementations -// - -template -extension_class::extension_class() - : extension_class_base(typeid(T).name()) -{ - class_registry::register_class(this); -} - -template -extension_class::extension_class(const char* name) - : extension_class_base(name) -{ - class_registry::register_class(this); -} - -template -void extension_class::def_standard_coerce() -{ - ref coerce_fct = dict().get_item(string("__coerce__")); - - if(coerce_fct.get() == 0) // not yet defined - this->def(&standard_coerce, "__coerce__"); -} - -template -inline -std::vector const& -extension_class::base_classes() const -{ - return class_registry::base_classes(); -} - -template -inline -std::vector const& -extension_class::derived_classes() const -{ - return class_registry::derived_classes(); -} - -template -void* extension_class::extract_object_from_holder(instance_holder_base* v) const -{ - instance_holder* held = dynamic_cast*>(v); - if(held) - return held->target(); - return 0; -} - -template -extension_class::~extension_class() -{ - class_registry::unregister_class(this); -} - -template -inline void class_registry::register_class(extension_class_base* p) -{ - // You're not expected to create more than one of these! - assert(static_class_object == 0); - static_class_object = p; -} - -template -inline void class_registry::unregister_class(extension_class_base* p) -{ - // The user should be destroying the same object they created. - assert(static_class_object == p); - (void)p; // unused in shipping version - static_class_object = 0; -} - -template -void class_registry::register_base_class(base_class_info const& i) -{ - static_base_class_info.push_back(i); -} - -template -void class_registry::register_derived_class(derived_class_info const& i) -{ - static_derived_class_info.push_back(i); -} - -template -std::vector const& class_registry::base_classes() -{ - return static_base_class_info; -} - -template -std::vector const& class_registry::derived_classes() -{ - return static_derived_class_info; -} - -// -// Static data member declaration. -// -template -extension_class_base* class_registry::static_class_object; -template -std::vector class_registry::static_base_class_info; -template -std::vector class_registry::static_derived_class_info; - -}}} // namespace boost::python::detail - -#endif // EXTENSION_CLASS_DWA052000_H_ -""") - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 5 - else: - args = int(sys.argv[1]) - - print gen_extclass(args) diff --git a/src/gen_function.py b/src/gen_function.py deleted file mode 100644 index dba53c3b..00000000 --- a/src/gen_function.py +++ /dev/null @@ -1,243 +0,0 @@ -r""" ->>> template = ''' template -... static PyObject* call( %1(T::*pmf)(%(A%+%:, %))%2, PyObject* args, PyObject* ) { -... PyObject* self; -... %( PyObject* a%+; -... %) if (!PyArg_ParseTuple(args, const_cast("O%(O%)"), &self%(, &a%+%))) -... return 0; -... T& target = from_python(self, type()); -... %3to_python((target.*pmf)(%( -... from_python(a%+, type())%:,%) -... ));%4 -... }''' - ->>> print gen_function(template, 0, 'R ', '', 'return ', '') - template - static PyObject* call( R (T::*pmf)(), PyObject* args, PyObject* ) { - PyObject* self; - if (!PyArg_ParseTuple(args, const_cast("O"), &self)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)( - )); - } - ->>> print gen_function(template, 2, 'R ', '', 'return ', '') - template - static PyObject* call( R (T::*pmf)(A1, A2), PyObject* args, PyObject* ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - if (!PyArg_ParseTuple(args, const_cast("OOO"), &self, &a1, &a2)) - return 0; - T& target = from_python(self, type()); - return to_python((target.*pmf)( - from_python(a1, type()), - from_python(a2, type()) - )); - } - ->>> print gen_function(template, 3, 'void ', ' const', '', '\n'+8*' ' + 'return none();') - template - static PyObject* call( void (T::*pmf)(A1, A2, A3) const, PyObject* args, PyObject* ) { - PyObject* self; - PyObject* a1; - PyObject* a2; - PyObject* a3; - if (!PyArg_ParseTuple(args, const_cast("OOOO"), &self, &a1, &a2, &a3)) - return 0; - T& target = from_python(self, type()); - to_python((target.*pmf)( - from_python(a1, type()), - from_python(a2, type()), - from_python(a3, type()) - )); - return none(); - } -""" -import string - -def _find(s, sub, start=0, end=None): - """Just like string.find, except it returns end or len(s) when not found. - """ - if end == None: - end = len(s) - - pos = string.find(s, sub, start, end) - if pos < 0: - return end - else: - return pos - -def _raise_no_argument(key, n, args): - raise IndexError(str(key) + " extra arg(s) not passed to gen_function") - -def _gen_common_key(key, n, args, fill = _raise_no_argument): - # import sys - # print >> sys.stderr, "_gen_common_key(", repr(key), ",", repr(n), ',', repr(args), ',', fill, ')' - # sys.stderr.flush() - if len(key) > 0 and key in '123456789': - index = int(key) - 1; - - if index >= len(args): - return fill(key, n, args) - - arg = args[index] - if callable(arg): - return str(arg(key, n, args)) - else: - return str(arg) - elif key in ('x','n','-','+'): - return str(n + {'-':-1,'+':+1,'x':0,'n':0}[key]) - else: - return key - -def _gen_arg(template, n, args, fill = _raise_no_argument): - - result = '' - i = 0 - while i < len(template): # until the template is consumed - # consume everything up to the first '%' - delimiter_pos = _find(template, '%', i) - result = result + template[i:delimiter_pos] - - # The start position of whatever comes after the '%'+key - start = delimiter_pos + 2 - key = template[start - 1 : start] # the key character. If there were no - # '%'s left, key will be empty - - if 0 and key == 'n': - result = result + `n` - else: - result = result + _gen_common_key(key, n, args, fill) - - i = start - - return result - -def gen_function(template, n, *args, **keywords): - r"""gen_function(template, n, [args...] ) -> string - - Generate a function declaration based on the given template. - - Sections of the template between '%(', '%)' pairs are repeated n times. If '%:' - appears in the middle, it denotes the beginning of a '%'. - - Sections of the template between '%{', '%}' pairs are ommitted if n == 0. - - %n is transformed into the string representation of 1..n for each - repetition within %(...%). Elsewhere, %n is transformed into the - string representation of n - - %- is transformed into the string representation of 0..n-1 for - each repetition within %(...%). Elsewhere, %- is transformed into the - string representation of n-1. - - %+ is transformed into the string representation of 2..n+1 for - each repetition within %(...%). Elsewhere, %- is transformed into the - string representation of n+1. - - %x is always transformed into the string representation of n - - %z, where z is a digit, selects the corresponding additional - argument. If that argument is callable, it is called with three - arguments: - key - the string representation of 'z' - n - the iteration number - args - a tuple consisting of all the additional arguments to - this function - otherwise, the selected argument is converted to a string representation - - - for example, - - >>> gen_function('%1 abc%x(%(int a%n%:, %));%{ // all args are ints%}', 2, 'void') - 'void abc2(int a0, int a1); // all args are ints' - - >>> gen_function('%1 abc(%(int a%n%:, %));%{ // all args are ints%}', 0, 'x') - 'x abc();' - - >>> gen_function('%1 abc(%(int a%n%:, %));%{ // all args are ints%}', 0, lambda key, n, args: 'abcd'[n]) - 'a abc();' - - >>> gen_function('%2 %1 abc(%(int a%n%:, %));%{ // all args are ints%}', 0, 'x', fill = lambda key, n, args: 'const') - 'const x abc();' - - >>> gen_function('abc%[k%:v%]', 0, fill = lambda key, n, args, value = None: '<' + key + ',' + value + '>') - 'abc' - -""" - expand = (lambda s, n = n: - apply(gen_function, (s, n) + args, keywords)) - - fill = keywords.get('fill', _raise_no_argument); - result = '' - i = 0 - while i < len(template): # until the template is consumed - # consume everything up to the first '%' - delimiter_pos = _find(template, '%', i) - result = result + template[i:delimiter_pos] - - # The start position of whatever comes after the '%'+key - start = delimiter_pos + 2 - key = template[start - 1 : start] # the key character. If there were no - # '%'s left, key will be empty - - pairs = { '(':')', '{':'}', '[':']' } - - if key in pairs.keys(): - end = string.find(template, '%' + pairs[key], start) - assert end >= 0, "Matching '" + '%' + pairs[key] +"' not found!" - delimiter_pos = end - - if key == '{': - if n > 0: - result = result + expand(template[start:end]) - else: - separator_pos = _find(template, '%:', start, end) - remainder = template[separator_pos+2 : end] - - if key == '(': - for x in range(n): - - iteration = expand( - template[start:separator_pos], x) - - result = result + expand(iteration, x) - - if x != n - 1: - result = result + expand(remainder, x) - else: - function_result = fill( - template[start:separator_pos], n, args, value = remainder) - result = result + expand(function_result) - - else: - result = result + expand(_gen_common_key(key, n, args, fill)) - - i = delimiter_pos + 2 - - return result - -def gen_functions(template, n, *args, **keywords): - r"""gen_functions(template, n, [args...]) -> string - - Call gen_function repeatedly with from 0..n and the given optional - arguments. - - >>> print gen_functions('%1 abc(%(int a%n%:, %));%{ // all args are ints%}\n', 2, 'void'), - void abc(); - void abc(int a0); // all args are ints - void abc(int a0, int a1); // all args are ints - - """ - fill = keywords.get('fill', _raise_no_argument); - result = '' - for x in range(n + 1): - result = result + apply(gen_function, (template, x) + args, keywords) - return result - -if __name__ == '__main__': - import doctest - import sys - doctest.testmod(sys.modules.get(__name__)) diff --git a/src/gen_init_function.py b/src/gen_init_function.py deleted file mode 100644 index 69c772c5..00000000 --- a/src/gen_init_function.py +++ /dev/null @@ -1,215 +0,0 @@ -from gen_function import * -import string - -def gen_init_function(args): - - return ( -"""// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file was generated for %d-argument constructors by gen_init_function.python - -#ifndef INIT_FUNCTION_DWA052000_H_ -# define INIT_FUNCTION_DWA052000_H_ - -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail { - - // parameter_traits - so far, this is a way to pass a const T& when we can be - // sure T is not a reference type, and a raw T otherwise. This should be - // rolled into boost::call_traits. Ordinarily, parameter_traits would be - // written: - // - // template struct parameter_traits - // { - // typedef const T& const_reference; - // }; - // - // template struct parameter_traits - // { - // typedef T& const_reference; - // }; - // - // template <> struct parameter_traits - // { - // typedef void const_reference; - // }; - // - // ...but since we can't partially specialize on reference types, we need this - // long-winded but equivalent incantation. - - // const_ref_selector -- an implementation detail of parameter_traits (below). This uses - // the usual "poor man's partial specialization" hack for MSVC. - template - struct const_ref_selector - { - template - struct const_ref - { - typedef const T& type; - }; - }; - - template <> - struct const_ref_selector - { - template - struct const_ref - { - typedef T type; - }; - }; - -# ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable: 4181) -# endif // BOOST_MSVC - template - struct parameter_traits - { - private: - enum { is_ref = boost::is_reference::value }; - typedef const_ref_selector selector; - public: - typedef typename selector::template const_ref::type const_reference; - }; -# ifdef BOOST_MSVC -# pragma warning(pop) -# endif // BOOST_MSVC - - // Full spcialization for void - template <> - struct parameter_traits - { - typedef void const_reference; - }; - - struct reference_parameter_base {}; - - template - class reference_parameter - : public reference_parameter_base - { - public: - typedef typename parameter_traits::const_reference const_reference; - reference_parameter(const_reference value) - : value(value) {} - operator const_reference() { return value; } - private: - const_reference value; - }; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - template - struct unwrap_parameter - { - typedef typename boost::add_reference::type type; - }; - - template - struct unwrap_parameter > - { - typedef typename reference_parameter::const_reference type; - }; -# else - template - struct unwrap_parameter_helper - { - template - struct apply - { - typedef typename T::const_reference type; - }; - }; - - template <> - struct unwrap_parameter_helper - { - template - struct apply - { - typedef typename add_reference::type type; - }; - }; - - template - struct unwrap_parameter - { - BOOST_STATIC_CONSTANT( - bool, is_wrapped = (is_base_and_derived::value)); - - typedef typename unwrap_parameter_helper< - is_wrapped - >::template apply::type type; - }; -# endif - -class extension_instance; -class instance_holder_base; - -class init; -""" - + gen_functions('template struct init%x;\n', args) - + """ -template -struct init_function -{ -""" + gen_functions("""%{ - template <%(class A%n%:, %)> -%} static init* create(signature%x%{<%(A%n%:, %)>%}) { - return new init%x::const_reference%)>; - } -""", args)+"""}; - -class init : public function -{ -private: // override function hook - PyObject* do_call(PyObject* args, PyObject* keywords) const; -private: - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* tail_args, PyObject* keywords) const = 0; -}; -""" + gen_functions(""" - -template -struct init%x : init -{ - virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const - { - %(PyObject* a%n; - %)if (!PyArg_ParseTuple(args, const_cast("%(O%)")%(, &a%n%))) - throw_argument_error(); - return new T(self%(, - boost::python::detail::reference_parameter(from_python(a%n, type()))%) - ); - } - const char* description() const - { return typeid(void (*)(T&%(, A%n%%))).name(); } -};""", args) + """ - -}}} // namespace boost::python::detail - -#endif // INIT_FUNCTION_DWA052000_H_ -""") - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 5 - else: - args = int(sys.argv[1]) - - print gen_init_function(args) - diff --git a/src/gen_py_api.py b/src/gen_py_api.py deleted file mode 100644 index bc965d8f..00000000 --- a/src/gen_py_api.py +++ /dev/null @@ -1,776 +0,0 @@ -# Copyright David Hawkes 2002. -# Permission is hereby granted to copy, use and modify this software -# for any purpose, including commercial distribution, provided this -# copyright notice is not removed. No warranty WHATSOEVER is provided with this -# software. Any user(s) accepts this software "as is" and as such they will not -# bind the author(s) to any claim of suitabilty for any purpose. - -# Build python API wrappers for boost python - -import re - -API_List = [ -'PyObject*{new} abs{direct}(int{template})', -'PyObject*{new} abs{direct}(PyObject*)', -'PyObject*{new} abs{direct}(short)', -'PyObject*{new} abs{direct}(int)', -'PyObject*{new} abs{direct}(long)', -'PyObject*{new} abs{direct}(double const &)', -'PyObject*{new,err=NULL} PyObject_CallObject{decl=apply}(PyObject*,PyObject*)', -'PyObject*{new,err=NULL} PyObject_Call{decl=apply}(PyObject*,PyObject*,PyObject*)', -'bool PyCallable_Check{decl=callable}(PyObject*)', -'PyObject*{new} chr{direct}(int{template})', -'PyObject*{new} chr{direct}(PyObject*)', -'PyObject*{new} chr{direct}(short)', -'PyObject*{new} chr{direct}(int)', -'PyObject*{new} chr{direct}(long)', -'int{err=-1} PyObject_Cmp{decl=cmp}(PyObject*{template},PyObject*{template},int{result})', -'int{err=-1} PyObject_Cmp{decl=cmp}(PyObject*,PyObject*,int{result})', -'PyObject*{new} coerce{direct}(PyObject*,PyObject*)', -'PyObject*{new} compile{direct}(PyObject*,PyObject*,PyObject*)', -'PyObject*{new} compile{direct}(const char*,const char*,const char*)', -'PyObject*{new} compile{direct}(PyObject*,PyObject*,PyObject*,PyObject*)', -'PyObject*{new} compile{direct}(const char*,const char*,const char*,int)', -'PyObject*{new} compile{direct}(PyObject*,PyObject*,PyObject*,PyObject*,PyObject*)', -'PyObject*{new} compile{direct}(const char*,const char*,const char*,int,int)', -'PyObject*{new} complex{direct}(int{template})', -'PyObject*{new} complex{direct}(PyObject*)', -'PyObject*{new} complex{direct}(double const&)', -'PyObject*{new} complex{direct}(int{template},int{template})', -'PyObject*{new} complex{direct}(PyObject*,PyObject*)', -'PyObject*{new} complex{direct}(double const&,double const&)', -'PyObject*{new} dict{direct}()', -'PyObject*{new} dict{direct}(PyObject*)', -'PyObject*{new} PyObject_Dir{decl=dir}(PyObject*{value=NULL})', -'PyObject*{new} PyObject_Dir{decl=dir}(PyObject*)', -'PyObject*{new} divmod{direct}(int{template},int{template})', -'PyObject*{new} divmod{direct}(PyObject*,PyObject*)', -'PyObject*{new} divmod{direct}(int,int)', -'PyObject*{new} divmod{direct}(long,long)', -'PyObject*{new} divmod{direct}(double const&,double const&)', -'PyObject*{new} PyRun_String{decl=eval}(char*{const},int{value=Py_eval_input},PyObject*{value=globals().ptr()},PyObject*{value=globals().ptr()})', -'PyObject*{new} PyRun_String{decl=eval}(char*{const},int{value=Py_eval_input},PyObject*,PyObject*{value=globals().ptr()})', -'PyObject*{new} PyRun_String{decl=eval}(char*{const},int{value=Py_eval_input},PyObject*,PyObject*)', -'PyObject*{new} PyRun_String{decl=exec}(char*{const},int{value=Py_file_input},PyObject*{value=globals().ptr()},PyObject*{value=globals().ptr()})', -'PyObject*{new} PyRun_String{decl=exec}(char*{const},int{value=Py_file_input},PyObject*,PyObject*{value=globals().ptr()})', -'PyObject*{new} PyRun_String{decl=exec}(char*{const},int{value=Py_file_input},PyObject*,PyObject*)', -'PyObject*{new} execfile{direct}(PyObject*)', -'PyObject*{new} execfile{direct}(PyObject*,PyObject*)', -'PyObject*{new} execfile{direct}(PyObject*,PyObject*,PyObject*)', -'PyObject*{new} file{direct}(PyObject*)', -'PyObject*{new} file{direct}(const char*)', -'PyObject*{new} file{direct}(PyObject*,PyObject*)', -'PyObject*{new} file{direct}(const char*,const char*)', -'PyObject*{new} file{direct}(PyObject*,PyObject*,PyObject*)', -'PyObject*{new} file{direct}(const char*,const char*,int)', -'PyObject*{new} filter{direct}(PyObject*,PyObject*)', -'PyObject*{new} float{direct,decl=float_}(PyObject*)', -'PyObject*{new} float{direct,decl=float_}(const char*)', -'PyObject*{new} float{direct,decl=float_}(double const&)', -'PyObject*{new} getattr{direct}(PyObject*,PyObject*,PyObject*)', -'PyObject*{new} getattr{direct}(PyObject*,const char *,PyObject*)', -'PyObject*{borrowed,err=NULL} PyModule_GetDict{decl=globals}(PyObject*{value=PyImport_AddModule("__main__")})', -'bool PyObject_HasAttr{decl=hasattr}(PyObject*,PyObject*)', -'bool PyObject_HasAttrString{decl=hasattr}(PyObject*,char*{const})', -'long{err=-1} PyObject_Hash{decl=hash}(PyObject*)', -'PyObject*{new} hex{direct}(int{template})', -'PyObject*{new} hex{direct}(PyObject*)', -'PyObject*{new} hex{direct}(char)', -'PyObject*{new} hex{direct}(short)', -'PyObject*{new} hex{direct}(int)', -'PyObject*{new} hex{direct}(long)', -'long id{direct}(PyObject*)', -'PyObject*{new} input{direct}()', -'PyObject*{new} input{direct}(PyObject*)', -'PyObject*{new} input{direct}(const char*)', -'PyObject*{new} int{direct,decl=int_}(PyObject*)', -'PyObject*{new} int{direct,decl=int_}(long)', -'PyObject*{new} int{direct,decl=int_}(const char*)', -'PyObject*{new} intern{direct}(PyObject*)', -'PyObject*{new} intern{direct}(const char*)', -'bool PyObject_IsInstance{decl=isinstance}(PyObject*,PyObject*)', -'bool PyObject_IsSubclass{decl=issubclass}(PyObject*,PyObject*)', -'PyObject*{new} PyObject_GetIter{decl=iter}(PyObject*)', -'PyObject*{new} iter{direct}(PyObject*,PyObject*)', -'long{err=-1} PyObject_Length{decl=len}(PyObject*)', -'PyObject*{new} list{direct}()', -'PyObject*{new} list{direct}(PyObject*)', -'PyObject*{new} long{direct,decl=long_}(PyObject*)', -'PyObject*{new} long{direct,decl=long_}(long)', -'PyObject*{new} long{direct,decl=long_}(const char*)', -'PyObject*{new} map{direct,argrepeat}(PyObject*)', -'PyObject*{new} max{direct,argrepeat}(PyObject*{template})', -'PyObject*{new} max{direct,argrepeat}(PyObject*)', -'PyObject*{new} min{direct,argrepeat}(PyObject*{template})', -'PyObject*{new} min{direct,argrepeat}(PyObject*)', -'PyObject*{new} oct{direct}(int{template})', -'PyObject*{new} oct{direct}(PyObject*)', -'PyObject*{new} oct{direct}(char)', -'PyObject*{new} oct{direct}(short)', -'PyObject*{new} oct{direct}(int)', -'PyObject*{new} oct{direct}(long)', -'PyObject*{new} open{direct}(PyObject*)', -'PyObject*{new} open{direct}(const char*)', -'PyObject*{new} open{direct}(PyObject*,PyObject*)', -'PyObject*{new} open{direct}(const char*,const char*)', -'PyObject*{new} open{direct}(PyObject*,PyObject*,PyObject*)', -'PyObject*{new} open{direct}(const char*,const char*,int)', -'long ord{direct}(PyObject*)', -'long ord{direct}(const char*)', -'PyObject*{new} pow{direct}(int{template},int{template})', -'PyObject*{new} pow{direct}(PyObject*,PyObject*)', -'PyObject*{new} pow{direct}(double const&,double const&)', -'PyObject*{new} pow{direct}(double const&,double const&,double const&)', -'PyObject*{new} print{direct,statement=print _1,argrepeat}(int{template})', -'PyObject*{new} print{direct,statement=print _1,argrepeat}(PyObject*)', -'PyObject*{new} print{decl=print_file,direct,statement="print >>_1, _2",argrepeat}(PyObject*,int{template})', -'PyObject*{new} print{decl=print_file,direct,statement="print >>_1, _2",argrepeat}(PyObject*,PyObject*)', -'PyObject*{new} range{direct}(int{template})', -'PyObject*{new} range{direct}(PyObject*)', -'PyObject*{new} range{direct}(int)', -'PyObject*{new} range{direct}(int{template},int{template})', -'PyObject*{new} range{direct}(PyObject*,PyObject*)', -'PyObject*{new} range{direct}(int,int)', -'PyObject*{new} range{direct}(int{template},int{template},int{template})', -'PyObject*{new} range{direct}(PyObject*,PyObject*,PyObject*)', -'PyObject*{new} range{direct}(int,int,int)', -'PyObject*{new} raw_input{direct}()', -'PyObject*{new} raw_input{direct}(PyObject*)', -'PyObject*{new} raw_input{direct}(const char*)', -'PyObject*{new} reduce{direct}(PyObject*,PyObject*)', -'PyObject*{new} reduce{direct}(PyObject*,PyObject*,PyObject*)', -'PyObject*{new,err=NULL} PyImport_ReloadModule{decl=reload}(PyObject*)', -'PyObject*{new} PyObject_Repr{decl=repr}(PyObject*)', -'PyObject*{new} round{direct}(int{template})', -'PyObject*{new} round{direct}(PyObject*)', -'PyObject*{new} round{direct}(double const&)', -'PyObject*{new} round{direct}(int{template},int{template})', -'PyObject*{new} round{direct}(PyObject*,PyObject*)', -'PyObject*{new} round{direct}(double const&,double const&)', -'PyObject*{new} slice{direct}(int{template})', -'PyObject*{new} slice{direct}(PyObject*)', -'PyObject*{new} slice{direct}(int)', -'PyObject*{new} slice{direct}(int{template},int{template})', -'PyObject*{new} slice{direct}(PyObject*,PyObject*)', -'PyObject*{new} slice{direct}(int,int)', -'PyObject*{new} slice{direct}(int{template},int{template},int{template})', -'PyObject*{new} slice{direct}(PyObject*,PyObject*,PyObject*)', -'PyObject*{new} slice{direct}(int,int,int)', -'PyObject*{new} PyObject_Str{decl=str}(PyObject*)', -'PyObject*{new} tuple{direct}()', -'PyObject*{new} tuple{direct}(PyObject*)', -'PyObject*{new,err=NULL} PyObject_Type{decl=type_}(PyObject*)', -'PyObject*{new} unichr{direct}(int{template})', -'PyObject*{new} unichr{direct}(PyObject*)', -'PyObject*{new} unichr{direct}(short)', -'PyObject*{new} unichr{direct}(int)', -'PyObject*{new} unichr{direct}(long)', -'PyObject*{new} PyObject_Unicode{decl=unicode}(PyObject*)', -'PyObject*{new} unicode{direct}(PyObject*,PyObject*)', -'PyObject*{new} unicode{direct}(PyObject*,const char*)', -'PyObject*{new} unicode{direct}(PyObject*,PyObject*,PyObject*)', -'PyObject*{new} unicode{direct}(PyObject*,const char*,const char*)', -'PyObject*{new} vars{direct}()', -'PyObject*{new} vars{direct}(PyObject*)', -'PyObject*{new} xrange{direct}(int{template})', -'PyObject*{new} xrange{direct}(PyObject*)', -'PyObject*{new} xrange{direct}(int)', -'PyObject*{new} xrange{direct}(int{template},int{template})', -'PyObject*{new} xrange{direct}(PyObject*,PyObject*)', -'PyObject*{new} xrange{direct}(int,int)', -'PyObject*{new} xrange{direct}(int{template},int{template},int{template})', -'PyObject*{new} xrange{direct}(PyObject*,PyObject*,PyObject*)', -'PyObject*{new} xrange{direct}(int,int,int)', -'PyObject*{new} zip{direct,argrepeat}(PyObject*)', -'PyObject*{new,err=NULL} Py_CompileString{decl=compile_string}(char*{const},char*{const},int)', -'int{err=-1} PyImport_AppendInittab{decl=import_append_inittab}(char*{const},void(*arg)(void))', -'PyObject*{borrowed,err=NULL} PyImport_AddModule{decl=import_add_module}(char*{const})', -'PyObject*{borrowed,err=NULL} PyImport_GetModuleDict{decl=import_get_module_dict}()', -'PyObject*{new,err=NULL} PyImport_Import{decl=import_import}(PyObject*)', -'PyObject*{new,err=NULL} PyImport_Import{decl=import_import}(const char*{object})', -'PyObject*{new,err=NULL} PyImport_ImportModule{decl=import_import_module}(char*{const})', -'PyObject*{new,err=NULL} PyImport_ImportModuleEx{decl=import_import_module_ex}(char*{const},PyObject*,PyObject*,PyObject*)', -'PyObject*{borrowed,err=NULL} PyModule_GetDict{decl=module_get_dict}(PyObject*)', -'int{err=-1} PyObject_Print{decl=object_print}(PyObject*,FILE*,int)', -'PyObject*{new,err=NULL} PyRun_File{decl=run_file}(FILE*,char*{const},int,PyObject*,PyObject*)', -'int{err=-1} PyRun_SimpleFile{decl=run_simple_file}(FILE*,char*{const})', -'int{err=-1} PyRun_SimpleString{decl=run_simple_string}(char*{const})', -'PyObject*{new,err=NULL} PyRun_String{decl=run_string}(char*{const},int,PyObject*,PyObject*)', -'PyObject*{new} call_statement{statement,direct}(const char*{statement})', -'PyObject*{new} call_statement{statement,direct}(const char*{statement},call_dict_usage{use_gd})', -'PyObject*{new} call_statement{argrepeat,statement,direct}(const char*{statement},int{template})', -'PyObject*{new} call_statement{argrepeat,statement,direct}(const char*{statement},PyObject*)', -'PyObject*{new} call_statement{argrepeat,statement,direct}(const char*{statement},call_dict_usage{use_gd},int{template})', -'PyObject*{new} call_statement{argrepeat,statement,direct}(const char*{statement},call_dict_usage{use_gd},PyObject*)', -] - -DeclFile = '../../../boost/python/py_interface.hpp' -ImplFile = 'py_interface.cpp' - -DeclFileHeader = '''\ -// Automatically generated from py_api_gen.py -#ifndef PY_INTERFACE_HPP -#define PY_INTERFACE_HPP - -#include -#include - -namespace boost { namespace python { namespace api { - -enum call_dict_usage { use_new_dict, use_local_dict, use_global_dict }; - -namespace api_detail { - -BOOST_PYTHON_DECL object get_func(const char* name); -BOOST_PYTHON_DECL object call_statement(const char *stmt, int n, ...); -BOOST_PYTHON_DECL object call_statement_du(const char *stmt, call_dict_usage cdu, int n, ...); - -template -struct get_arg -{ - get_arg(A const &a) : h(a) {} - object h; - operator object const& () { return h; } - operator object const* () { return &h; } -}; - -template<> -struct get_arg -{ - get_arg(object const &a) : h(a) {} - object const &h; - operator object const& () { return h; } - operator object const* () { return &h; } -}; - -template<> -struct get_arg -{ - get_arg(PyObject* a) : h((python::detail::borrowed_reference)a) {} - object h; - operator object const& () { return h; } - operator object const* () { return &h; } -}; - -} - -BOOST_PYTHON_DECL object locals(); - -''' - -DeclFileTrailer = '''\ -}}} - -#endif // PY_INTERFACE_HPP -''' - -ImplFileHeader = '''\ -// Automatically generated from py_api_gen.py - -#include - -namespace boost { namespace python { namespace api { - -namespace api_detail { - -BOOST_PYTHON_DECL object get_func(const char* name) { - object __builtin__((python::detail::borrowed_reference)::PyImport_AddModule(const_cast("__builtin__"))); - return object(__builtin__.attr(name)); -} - -inline handle<> get_current_frame() -{ - return handle<>(allow_null(borrowed((PyObject*)(PyThreadState_Get()->frame)))); -} - -inline object get_global_dict(call_dict_usage cdu, handle<> const& frame) -{ - if(frame.get()) - return object(object(frame).attr("f_globals")); - else - return api::globals(); -} - -object get_local_dict(call_dict_usage cdu, handle<> const& frame, object const& global_dict) -{ - switch(cdu) { - case use_new_dict: - return api::dict(); - case use_global_dict: - return global_dict; - default: - if(frame.get()) - return object(object(frame).attr("f_locals")); - else - return api::dict(); - } -} - -inline object call_statement(const char *stmt, object const& global_dict, object& local_dict) -{ - local_dict["_0"] = object((python::detail::borrowed_reference)Py_None); - api::run_string(stmt, Py_file_input, global_dict, local_dict); - return object(local_dict["_0"]); -} - -object call_statement(const char *stmt) -{ - handle<> frame(get_current_frame()); - if(frame.get()) { - object f(frame); - object gd(f.attr("f_globals")); - object ld(f.attr("f_locals")); - return call_statement(stmt, gd, ld); - } else { - object gd(api::globals()); - object ld(api::dict()); - return call_statement(stmt, gd, ld); - } -} - -object call_statement_du(const char *stmt, call_dict_usage cdu) -{ - handle<> frame(get_current_frame()); - object gd(get_global_dict(cdu, frame)); - return call_statement(stmt, gd, get_local_dict(cdu, frame, gd)); -} - -inline object call_statement(const char *stmt, object const& global_dict, object& local_dict, int n, va_list mk) -{ - static const char *(idx[]) = { "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8", "_9", "_10" }; - local_dict["_0"] = object((python::detail::borrowed_reference)Py_None); - for(int i = 0; i < n; ++i) - { - object const* p_arg = va_arg(mk, object const*); - object const& arg = *p_arg; - if(i < (int) (sizeof(idx) / sizeof(idx[0]))) - local_dict[idx[i]] = arg; - else { - local_dict[object("_") + object((python::detail::new_reference)PyObject_Str(object(i + 1).ptr()))] = arg; - } - } - va_end(mk); - api::run_string(stmt, Py_file_input, global_dict, local_dict); - return object(local_dict["_0"]); -} - -BOOST_PYTHON_DECL object call_statement(const char *stmt, int n, ...) -{ - va_list mk; - va_start(mk, n); - handle<> frame(get_current_frame()); - if(frame.get()) { - object f(frame); - object gd(f.attr("f_globals")); - object ld(f.attr("f_locals")); - return call_statement(stmt, gd, ld, n, mk); - } else { - object gd(api::globals()); - object ld(api::dict()); - return call_statement(stmt, gd, ld, n, mk); - } -} - -BOOST_PYTHON_DECL object call_statement_du(const char *stmt, call_dict_usage cdu, int n, ...) -{ - handle<> frame(get_current_frame()); - object gd(get_global_dict(cdu, frame)); - va_list mk; - va_start(mk, n); - return call_statement(stmt, gd, get_local_dict(cdu, frame, gd), n, mk); -} - -} - -BOOST_PYTHON_DECL object locals() -{ - handle<> frame(api_detail::get_current_frame()); - if(frame.get()) - return object(object(frame).attr("f_locals")); - else - return api::dict(); -} - -''' - -ImplFileTrailer = '''\ -}}} -''' - -def SplitOutList(l): - vals_list = [] - if l == None: - return vals_list - vals_list = re.findall(r'((?:[^,{}]|(?:{[^{}]*}))+),?\s*', l) - return vals_list - -def SplitOutListDict(l): - vals_dict = {} - if l == None: - return vals_dict - vals = re.findall(r'((?:"[^"]+"|[^,"]+)+)\s*,?', l) - for val in vals: - m = re.match(r'(?P[^\s=]+)\s*(=\s*(?P"?)(?P.+)(?P=qt))?', val).groupdict() - vals_dict[m['aname']] = m['aval'] - return vals_dict - -def SplitOutAttrs(a): - soa = {} - m = re.match(r'(?P[^{]+)({(?P[^}]+)})?', a).groupdict() - soa['name'] = m['name'] - soa.update(SplitOutListDict(m['attrs'])) - return soa - -def is_object(name): - if re.match(r'PyObject\s*\*', name['name']): - return 1 - return 0 - -def is_arg_really_const(arg): - return arg.has_key('const') - -def get_actual_rtn_type(rtn, args): - i = 0 - for a in args: - if a.has_key('result'): - true_rtn = dict(rtn) - true_rtn['name'] = a['name'] - true_rtn['arg_number'] = i - return true_rtn - i += 1 - return rtn - -def is_template(name): - return name.has_key('template') - -def decl_func_arg(arg, p): - if arg.has_key('value'): - return '' - elif arg.has_key('result'): - return '' - elif is_object(arg): - if is_template(arg): - sn = str(p) - return 'A' + sn +' const& a' + sn - else: - return 'object const& a' + str(p) - elif is_arg_really_const(arg): - return 'const ' + arg['name'] + ' a' + str(p) - elif re.search(r'arg', arg['name']): - return re.sub(r'arg', 'a' + str(p), arg['name']) - else: - if is_template(arg): - sn = str(p) - return 'A' + sn +' const& a' + sn - else: - return arg['name'] + ' a' + str(p) - -def decl_func_args(name, args): - if not len(args): - return '' - d_args = reduce(lambda x,y : x + (y and (', ' + y) or ''), map(decl_func_arg, args, xrange(len(args)))) - return d_args - -def call_func_arg(arg, p): - if arg.has_key('value'): - return arg['value'] - elif arg.has_key('result'): - return '&rslt' - elif arg.has_key('template'): - sn = str(p) - return 'api_detail::get_arg(a%s)' % (sn, sn) - elif arg.has_key('object'): - return 'object(a%s).ptr()' % str(p) - elif is_object(arg): - return 'a' + str(p) + '.ptr()' - elif is_arg_really_const(arg): - return 'const_cast<%s>(%s)' % (arg['name'], 'a' + str(p)) - else: - return 'a' + str(p) - -def call_func_args(args): - if not len(args): - return '' - d_args = reduce(lambda x,y : x + (y and ((x and ', ' or '') + y) or ''), map(call_func_arg, args, xrange(len(args)))) - return d_args - -def call_func(name, args): - return '::%s(%s)' % (name['name'], call_func_args(args)) - -def call_func_direct_arg(arg, p): - if arg.has_key('use_gd'): - return '' - elif arg.has_key('statement'): - return '' - elif arg.has_key('value'): - return arg['value'] - elif arg.has_key('template'): - sn = str(p) - if arg.has_key('addr'): - return '(object const*)api_detail::get_arg(a%s)' % (sn, sn) - else: - return 'api_detail::get_arg(a%s)' % (sn, sn) - elif is_object(arg): - if arg.has_key('addr'): - return '&a' + str(p) - else: - return 'a' + str(p) - else: - if arg.has_key('addr'): - return '&object(a%s)' % str(p) - else: - return 'object(a%s)' % str(p) - -def call_func_direct_args(args): - if not len(args): - return '' - d_args = reduce(lambda x,y : x + (y and ((x and ', ' or '') + y) or ''), map(call_func_direct_arg, args, xrange(len(args)))) - return d_args - -def get_statement_arg(args): - i = 0 - for arg in args: - if arg.has_key('statement'): - return i - i = i + 1 - return -1 - -def get_use_gd_arg(args): - i = 0 - for arg in args: - if arg.has_key('use_gd'): - return i - i = i + 1 - return -1 - -def call_func_direct(name, args): - if name.has_key('statement'): - na = len(args) - ugd = get_use_gd_arg(args) - sa = get_statement_arg(args) - if ugd >= 0: - ugd = 'a' + str(ugd) - na = na - 1 - else: - if (sa < 0) and (na > 0): - ugd = 'use_new_dict' - else: - ugd = None - if sa >= 0: - na = na - 1 - if na > 0: - if ugd: - return 'api_detail::call_statement_du(%s, %s, %s, %s)' % ('a' + str(sa), ugd, na, call_func_direct_args(args)) - else: - return 'api_detail::call_statement(%s, %s, %s)' % ('a' + str(sa), na, call_func_direct_args(args)) - else: - if ugd: - return 'api_detail::call_statement_du(%s, %s)' % ('a' + str(sa), ugd) - else: - return 'api_detail::call_statement(%s)' % ('a' + str(sa)) - else: - if na > 0: - if ugd: - return 'api_detail::call_statement_du("%s", %s, %s, %s)' % (name['statement'], ugd, na, call_func_direct_args(args)) - else: - return 'api_detail::call_statement("%s", %s, %s)' % (name['statement'], na, call_func_direct_args(args)) - else: - if ugd: - return 'api_detail::call_statement_du("%s", %s)' % (name['statement'], ugd) - else: - return 'api_detail::call_statement("%s")' % (name['statement']) - else: - return 'api_detail::get_func("%s")(%s)' % (name['name'], call_func_direct_args(args)) - -def decl_template_arg(arg, p): - if arg.has_key('value'): - return '' - elif arg.has_key('result'): - return '' - elif is_template(arg): - return 'class A' + str(p) - else: - return '' - -def decl_template_args(args): - if not len(args): - return '' - d_args = reduce(lambda x,y : x + (y and ((x and ', ' or '') + y) or ''), map(decl_template_arg, args, xrange(len(args)))) - return d_args - -def is_rtn_borrowed_object(rtn): - if is_object(rtn): - return rtn.has_key('borrowed') - else: - return 0 - -def is_rtn_new_object(rtn): - if is_object(rtn): - return not rtn.has_key('borrowed') - else: - return 0 - -def is_func_direct(name): - return name.has_key('direct') - -def rtn_call_func_direct(rtn, name, args): - if rtn['name'] == 'void': - direct_code = ' %s;' % call_func_direct(name, args) - elif is_object(rtn): - direct_code = ' return %s;' % call_func_direct(name, args) - else: - r = '''\ - object r(%s); - return boost::python::arg_from_python<%s>(r.ptr())(r.ptr());''' - direct_code = r % (call_func_direct(name, args), rtn['name']) - return direct_code - -def rtn_call_func(rtn, name, args): - if is_func_direct(name): - return rtn_call_func_direct(rtn, name, args) - true_rtn = get_actual_rtn_type(rtn, args) - err = true_rtn.get('err') - arg_number = true_rtn.get('arg_number') - if rtn['name'] == 'void': - return ' %s;' % call_func(name, args) - elif is_rtn_new_object(rtn): - if err and (err != 'NULL'): - r = '''\ - PyObject* r = %s; - if(r == %s) - throw_error_already_set(); - return object((python::detail::new_reference)r);''' - return r % (call_func(name, args), err) - else: - return ' return object((python::detail::new_reference)%s);' % call_func(name, args) - elif is_rtn_borrowed_object(rtn): - if err and (err != 'NULL'): - r = '''\ - PyObject* r = %s; - if(r == %s) - throw_error_already_set(); - return object((python::detail::borrowed_reference)r);''' - return r % (call_func(name, args), err) - else: - return ' return object((python::detail::borrowed_reference)%s);' % call_func(name, args) - else: - if err: - if arg_number == None: - r = '''\ - %s r = %s; - if(r == %s) - throw_error_already_set(); - return r;''' - return r % (rtn['name'], call_func(name, args), err) - else: - r = '''\ - %s rslt; - %s r = %s; - if(r == %s) - throw_error_already_set(); - return rslt;''' - return r % (true_rtn['name'], rtn['name'], call_func(name, args), err) - else: - return ' return %s;' % call_func(name, args) - -def decl_func(name, args): - return '%s(%s)' % (name.get('decl', name['name']), decl_func_args(name, args)) - -def rtn_decl_func(rtn, name, args): - true_rtn = get_actual_rtn_type(rtn, args) - ta = decl_template_args(args) - if ta: - decl = 'template<%s>\n' % ta - else: - decl = 'BOOST_PYTHON_DECL ' - if is_object(true_rtn): - return decl + 'object %s' % decl_func(name, args) - else: - return decl + '%s %s' % (true_rtn['name'], decl_func(name, args)) - -def is_info_template(fn_info): - for arg in fn_info['args']: - if is_template(arg): - return 1 - return 0 - -def parse_func(func): - fn_info = {} - fnm = re.match(r'(?P\S+)\s+(?P[^\s\(\){}]+({[^{}]*})?)\s*\((?P(({[^{}]*})+|(\([^\(\)]*\))+|[^\(\)]+)*)\)', func).groupdict() - fn_info['fname'] = SplitOutAttrs(fnm['fname']) - fn_info['rtn'] = SplitOutAttrs(fnm['rtn']) - fn_info['args'] = map(SplitOutAttrs, SplitOutList(fnm['args'])) - if fn_info['fname'].has_key('statement'): - if is_info_template(fn_info): - for arg in fn_info['args']: - if is_template(arg): - arg['addr'] = None - else: - for arg in fn_info['args']: - if is_object(arg): - arg['addr'] = None - return fn_info - -def get_argrepeat(fn_info): - if fn_info['fname'].has_key('argrepeat'): - argrepeat = fn_info['fname']['argrepeat'] - if argrepeat == None: - argrepeat = 10 - else: - argrepeat = 1 - return argrepeat - -def do_arg_repeat(fn_info): - fn_info['args'] = fn_info['args'] + [fn_info['args'][len(fn_info['args']) - 1],] - if fn_info['fname'].has_key('statement'): - stmt = fn_info['fname']['statement'] - if stmt: - s_args = re.findall(r'[\s,\(](?:_([0-9]+))(?=$|[\s,\)])', stmt) - if s_args: - mx = reduce(max, map(int, s_args), 0) - mx_arg = '_' + str(mx) - next_arg = '_' + str(mx + 1) - stmt = re.sub(r'(?<=[\s,\(])' + mx_arg + '(?=$|[\s,\)])', mx_arg + ', ' + next_arg, stmt, 1) - fn_info['fname']['statement'] = stmt - -def decl_funcs(fn_list): - fn_defs = '' - for fn in fn_list: - fn_info = parse_func(fn) - argrepeat = get_argrepeat(fn_info) - for ar in xrange(argrepeat): - fn_defs += rtn_decl_func(fn_info['rtn'], fn_info['fname'], fn_info['args']) - if is_info_template(fn_info): - fn_defs += '\n{\n' + rtn_call_func(fn_info['rtn'], fn_info['fname'], fn_info['args']) + '\n}\n' - else: - fn_defs += ';\n' - if ar != (argrepeat - 1): - do_arg_repeat(fn_info) - return fn_defs - -def impl_funcs(fn_list): - fn_defs = '' - for fn in fn_list: - fn_info = parse_func(fn) - if is_info_template(fn_info): - continue - argrepeat = get_argrepeat(fn_info) - for ar in xrange(argrepeat): - fn_defs += rtn_decl_func(fn_info['rtn'], fn_info['fname'], fn_info['args']) + ' {\n' - fn_defs += rtn_call_func(fn_info['rtn'], fn_info['fname'], fn_info['args']) + '\n}\n\n' - if ar != (argrepeat - 1): - do_arg_repeat(fn_info) - return fn_defs - -if __name__ == '__main__': - f = file(DeclFile, 'w') - print >>f, DeclFileHeader - print >>f, decl_funcs(API_List) - print >>f, DeclFileTrailer - f.close() - - f = file(ImplFile, 'w') - print >>f, ImplFileHeader - print >>f, impl_funcs(API_List) - print >>f, ImplFileTrailer - f.close() diff --git a/src/gen_returning.py b/src/gen_returning.py deleted file mode 100644 index 8f7c866c..00000000 --- a/src/gen_returning.py +++ /dev/null @@ -1,201 +0,0 @@ -# (C) Copyright David Abrahams 2001,2002. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# This work was funded in part by Lawrence Berkeley National Labs - -from gen_function import * -import string - -header = '''// (C) Copyright David Abrahams 2001,2002. Permission to copy, use, modify, sell -// and distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for %d-argument member functions and %d-argument free -// functions by gen_returning.py -''' - -body_sections = ( -''' -#ifndef RETURNING_DWA20011201_HPP -# define RETURNING_DWA20011201_HPP - -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// Calling C++ from Python -template -struct returning -{ -''', -''' -''', -''' // Free functions -''', -'''}; - -template <> -struct returning -{ - typedef void R; -''', -''' -''', -''' - // Free functions -''', -'''}; - -}}} // namespace boost::python::detail - -#endif // RETURNING_DWA20011201_HPP -''') - -#' - -member_function = ''' template - static PyObject* call(R (A0::*pmf)(%(A%+%:, %))%1, PyObject* args_, PyObject*, P const& policies) - { - // check that each of the arguments is convertible - from_python c0(PyTuple_GET_ITEM(args_, 0)); - if (!c0.convertible()) return 0; -%( from_python c%+(PyTuple_GET_ITEM(args_, %+)); - if (!c%+.convertible()) return 0; -%) -%[r%: // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - -%] if (!policies.precall(args_)) return 0; - - %[r%:PyObject* result = cr( %]((c0(PyTuple_GET_ITEM(args_, 0)))->*pmf)( - %(c%+(PyTuple_GET_ITEM(args_, %+))%: - , %))%[r%: )%]; - - return policies.postcall(args_, %[r%:result%]%[v%:detail::none()%]); - } -''' - -free_function = ''' template - static PyObject* call(R (*pf)(%(A%n%:, %)), PyObject* args_, PyObject*, P const& policies) - {%{ - // check that each of the arguments is convertible -%}%( from_python c%n(PyTuple_GET_ITEM(args_, %n)); - if (!c%n.convertible()) return 0; -%) -%[r%: // find the result converter - typedef typename P::result_converter result_converter; - typename eval::type cr; - if (!cr.convertible()) return 0; - -%]%[not-void-and-0-arg%: if (!policies.precall(args_)) return 0; - -%] %[r%:PyObject* result = cr( %](*pf)( - %(c%n(PyTuple_GET_ITEM(args_, %n))%: - , %))%[r%: )%]; - - return policies.postcall(args_, %[r%:result%]%[v%:detail::none()%]); - } -''' - -def _returns_value(key, n, args, value): - if key != 'v': - return value - else: - return '' - -def _returns_void(key, n, args, value): - if key == 'v' or key == 'not-void-and-0-arg' and n != 0: - return value - else: - return '' - -_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') - -_prefix = { -# ' const': ''' - -# // missing cv-qualified -> cv-unqualified member pointer conversions -# # if defined(__MWERKS__) && __MWERKS__ <=0x2406 || defined(BOOST_MSVC) && BOOST_MSVC <= 1200 || defined(__BORLANDC__) -# ''', - ' const volatile': ''' -// missing const volatile type traits -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -'''}; - -def gen_returning(member_function_args, free_function_args = None): - if free_function_args is None: - free_function_args = member_function_args + 1 - - return_none = '''; - return detail::none();''' - - return (header % (member_function_args, free_function_args) - + body_sections[0] - # - # functions returning results - # - - + reduce(lambda x,y: x+y - , map(lambda cv: - _prefix.get(cv,'') - + gen_functions(member_function, - member_function_args, cv, - fill = _returns_value) + '\n' - , _cv_qualifiers)) - + '''# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -''' -## endif // missing cv-qualified -> cv-unqualified member pointer conversions -#''' - # free functions - + gen_functions(free_function, free_function_args, fill = _returns_value) - + body_sections[3] - - # - # functions returning void - # - - + reduce(lambda x,y: x+y - , map(lambda cv: - _prefix.get(cv,'') - + gen_functions(member_function, - member_function_args, cv, fill = - _returns_void) + '\n' - , _cv_qualifiers)) - - + '''# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -''' -## endif // missing cv-qualified -> cv-unqualified member pointer conversions -#''' - # free functions - + gen_functions(free_function, free_function_args, fill = _returns_void) - + body_sections[6] - ) - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - member_function_args = 5 - free_function_args = 6 - else: - member_function_args = int(sys.argv[1]) - if len(sys.argv) > 2: - free_function_args = int(sys.argv[2]) - else: - free_function_args = member_function_args - - print gen_returning(member_function_args, free_function_args) - - diff --git a/src/gen_signature.py b/src/gen_signature.py deleted file mode 100644 index 1af3437d..00000000 --- a/src/gen_signature.py +++ /dev/null @@ -1,90 +0,0 @@ -# (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -# distribute this software is granted provided this copyright notice appears -# in all copies. This software is provided "as is" without express or implied -# warranty, and with no claim as to its suitability for any purpose. -# -# This work was funded in part by Lawrence Berkeley National Labs - -from gen_function import * -import string - -header = '''// (C) Copyright David Abrahams 2002. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley and Lawrence -// Livermore National Labs -// -// This file generated for %d-argument member functions and %d-argument free -// functions by gen_signature.py -''' - -_cv_qualifiers = ('', ' const', ' volatile', ' const volatile') - -_suffix = { - '': ''' -// Metrowerks thinks this creates ambiguities -# if !defined(__MWERKS__) || __MWERKS__ > 0x2406 -''', ' const volatile': ''' -# endif // __MWERKS__ -''' - }; - -def gen_arg_tuple_size(member_function_args, free_function_args = None): - if free_function_args is None: - free_function_args = member_function_args + 1 - - return_none = '''; - return detail::none();''' - - return (header % (member_function_args, free_function_args) - + ''' -#ifndef SIGNATURE_DWA2002128_HPP -# define SIGNATURE_DWA2002128_HPP - -# include - -namespace boost { namespace python { namespace detail { -''' - - + gen_functions(''' -template -mpl::type_list -signature(R (*)(%(A%n%:, %))) -{ - return mpl::type_list() -} -''', free_function_args) - - + reduce(lambda x,y: x+'\n'+y - , map( - lambda cv: gen_functions( -'''template -mpl::type_list signature(R (A0::*)(%(A%+%:, %))%1) -{ - return mpl::type_list(); -} - -''', member_function_args, cv) - , _cv_qualifiers)) + '''}}} // namespace boost::python::detail - -#endif // SIGNATURE_DWA2002128_HPP -''') - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - member_function_args = 5 - free_function_args = 6 - else: - member_function_args = int(sys.argv[1]) - if len(sys.argv) > 2: - free_function_args = int(sys.argv[2]) - else: - free_function_args = member_function_args - - print gen_arg_tuple_size(member_function_args, free_function_args) - - diff --git a/src/gen_signatures.py b/src/gen_signatures.py deleted file mode 100644 index f5a97b17..00000000 --- a/src/gen_signatures.py +++ /dev/null @@ -1,158 +0,0 @@ -from gen_function import * -import string - -def gen_struct_signatures(args): - result = '' - for n in range(args, -1, -1): - result = ( - result + gen_function("""%{template <%(class T%n%:, %)> -%}struct signature%x {}; - -""", n) -# + ((n == args) and [""] or -# [gen_function(""" -# template -# static inline signature%1 prepend(type) -# { return signature%1(); }""", -# n, (str(n+1),)) -# ] -# )[0] -# -# + ((n != 0) and [""] or -# [""" -# // This one terminates the chain. Prepending void_t to the head of a void_t -# // signature results in a void_t signature again. -# static inline signature0 prepend(void_t) { return signature0(); }"""] -# )[0] -# + """ -#}; -# -#""" - + ((n == args) and [""] or - [gen_function( -"""template <%(class T%n%, %)class X> -inline signature%1 prepend(type, signature%x%{<%(T%n%:, %)>%}) - { return signature%1(); } - -""", n, str(n+1)) - ] - )[0] - ) - return result - -def gen_signatures(args): - return ( -"""// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file automatically generated by gen_signatures.python for %d arguments. -#ifndef SIGNATURES_DWA050900_H_ -# define SIGNATURES_DWA050900_H_ - -# include - -namespace boost { namespace python { - -namespace detail { -// A stand-in for the built-in void. This one can be passed to functions and -// (under MSVC, which has a bug, be used as a default template type parameter). -struct void_t {}; -} - -// An envelope in which type information can be delivered for the purposes -// of selecting an overloaded from_python() function. This is needed to work -// around MSVC's lack of partial specialiation/ordering. Where normally we'd -// want to form a function call like void f(), We instead pass -// type as one of the function parameters to select a particular -// overload. -// -// The id typedef helps us deal with the lack of partial ordering by generating -// unique types for constructor signatures. In general, type::id is type, -// but type::id is just void_t. -template -struct type -{ - typedef type id; -}; - -template <> -struct type -{ - typedef boost::python::detail::void_t id; -}; - -namespace detail { -// These basically encapsulate a chain of types, , used to make the syntax of -// add(constructor()) work. We need to produce a unique type for each number -// of non-default parameters to constructor<>. Q: why not use a recursive -// formulation for infinite extensibility? A: MSVC6 seems to choke on constructs -// that involve recursive template nesting. -// -// signature chaining -""" % args - + gen_struct_signatures(args) - + """ -// This one terminates the chain. Prepending void_t to the head of a void_t -// signature results in a void_t signature again. -inline signature0 prepend(void_t, signature0) { return signature0(); } - -} // namespace detail -""" - + gen_function(""" -template <%(class A%n% = detail::void_t%:, %)> -struct constructor -{ -}; -""", args) - + """ -namespace detail { -// Return value extraction: - -// This is just another little envelope for carrying a typedef (see type, -// above). I could have re-used type, but that has a very specific purpose. I -// thought this would be clearer. -template -struct return_value_select { typedef T type; }; - -// free functions""" - + gen_functions(""" -template -return_value_select return_value(R (*)(%(A%n%:, %))) { return return_value_select(); } -""", args) - - + -""" -// TODO(?): handle 'const void' - -// member functions""" - + gen_functions(""" -template -return_value_select return_value(R (T::*)(%(A%n%:, %))) { return return_value_select(); } -""", args) - - + gen_functions(""" -template -return_value_select return_value(R (T::*)(%(A%n%:, %)) const) { return return_value_select(); } -""", args) - - + """ -}}} // namespace boost::python::detail - -#endif -""") - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 5 - else: - args = int(sys.argv[1]) - - print gen_signatures(args) - diff --git a/src/gen_singleton.py b/src/gen_singleton.py deleted file mode 100644 index 3a5ca7e3..00000000 --- a/src/gen_singleton.py +++ /dev/null @@ -1,58 +0,0 @@ -from gen_function import * -import string - -def gen_singleton(args): - return ( -"""// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef SINGLETON_DWA051900_H_ -# define SINGLETON_DWA051900_H_ - -# include - -namespace boost { namespace python { namespace detail { - -struct empty {}; -template -struct singleton : Base -{ - typedef singleton singleton_base; // Convenience type for derived class constructors - - static Derived* instance(); - - // Pass-through constructors -""" - + gen_functions("""%{ - template <%(class A%n%:, %)> -%} singleton(%(const A%n& a%n%:, %)) : Base(%(a%n%:, %)) {} -""", args) - + """ -}; - -template -Derived* singleton::instance() -{ - static Derived x; - return &x; -} - -}}} // namespace boost::python::detail - -#endif -""") - -if __name__ == '__main__': - import sys - - if len(sys.argv) == 1: - args = 5 - else: - args = int(sys.argv[1]) - - print gen_singleton(args) diff --git a/src/gen_value_holder.py b/src/gen_value_holder.py deleted file mode 100644 index b01e2c0e..00000000 --- a/src/gen_value_holder.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright David Abrahams 2002. Permission to copy, use, modify, -# sell and distribute this software is granted provided this -# copyright notice appears in all copies. This software is provided -# "as is" without express or implied warranty, and with no claim as -# to its suitability for any purpose. -# -# This work was funded in part by Lawrence Livermore National Labs - -from gen_function import * -import string - -def _generate(member_function_args, free_function_args = None): - return ('''// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef VALUE_HOLDER_DWA20011215_HPP -# define VALUE_HOLDER_DWA20011215_HPP - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace objects { - -template -struct value_holder : instance_holder -{ - // Forward construction to the held object -''' - + - gen_functions( diff --git a/src/init_function.cpp b/src/init_function.cpp deleted file mode 100644 index 1ebfa501..00000000 --- a/src/init_function.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#define BOOST_PYTHON_SOURCE - -#include -#include -#include -#include - -namespace boost { namespace python { namespace detail { - - PyObject* init::do_call(PyObject* args_, PyObject* keywords) const - { - tuple args(ref(args_, ref::increment_count)); - if (args[0]->ob_type->ob_type != extension_meta_class()) - { - PyErr_SetString(PyExc_TypeError, "argument 1 to __init__ must be an ExtensionInstance"); - return 0; - } - - extension_instance *self = static_cast(args[0].get()); - - tuple ctor_args = args.slice(1, args.size()); - - std::auto_ptr result( - create_holder(self, ctor_args.get(), keywords)); - - self->add_implementation(result); - return none(); - } - -}}} // namespace boost::python::detail diff --git a/src/module_builder.cpp b/src/module_builder.cpp deleted file mode 100644 index 1e47badb..00000000 --- a/src/module_builder.cpp +++ /dev/null @@ -1,64 +0,0 @@ - // (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#define BOOST_PYTHON_SOURCE - -#include - -namespace boost { namespace python { - -namespace { - ref name_holder; -} - -bool module_builder_base::initializing() -{ - return name_holder.get() != 0; -} - -string module_builder_base::name() -{ - // If this fails, you haven't created a module_builder object - assert(initializing()); - return string(name_holder); -} - -module_builder_base::module_builder_base(const char* name) - : m_module(Py_InitModule(const_cast(name), initial_methods)) -{ - // If this fails, you've created more than 1 module_builder object in your module - assert(name_holder.get() == 0); - name_holder = ref(PyObject_GetAttrString(m_module, const_cast("__name__"))); -} - -module_builder_base::~module_builder_base() -{ - name_holder.reset(); -} - -void -module_builder_base::add(detail::function* x, const char* name) -{ - reference f(x); // First take possession of the object. - detail::function::add_to_namespace(f, name, PyModule_GetDict(m_module)); -} - -void module_builder_base::add(ref x, const char* name) -{ - PyObject* dictionary = PyModule_GetDict(m_module); - PyDict_SetItemString(dictionary, const_cast(name), x.get()); -} - -void module_builder_base::add(PyTypeObject* x, const char* name /*= 0*/) -{ - this->add(ref(as_object(x)), name ? name : x->tp_name); -} - -PyMethodDef module_builder_base::initial_methods[] = { { 0, 0, 0, 0 } }; - -}} // namespace boost::python diff --git a/src/objects.cpp b/src/objects.cpp deleted file mode 100644 index f446919d..00000000 --- a/src/objects.cpp +++ /dev/null @@ -1,488 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -// TODO: Move inline implementations from objects.cpp here - -#ifndef BOOST_PYTHON_SOURCE -# define BOOST_PYTHON_SOURCE -#endif - -#include -#include - -namespace boost { namespace python { - -template -T object_from_python(PyObject* p, type) -{ - ref x(p, ref::increment_count); - if (!T::accepts(x)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw_error_already_set(); - } - return T(x); -} - -inline PyObject* object_to_python(const object& x) -{ - return x.reference().release(); -} - -object::object(ref p) - : m_p(p) {} - -// Return a reference to the held object -ref object::reference() const -{ - return m_p; -} - -// Return a raw pointer to the held object -PyObject* object::get() const -{ - return m_p.get(); -} - -}} // namespace boost::python - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::tuple& x) -{ - return object_to_python(x); -} - -BOOST_PYTHON_DECL boost::python::tuple from_python(PyObject* p, boost::python::type type) -{ - return boost::python::object_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::list& x) -{ - return object_to_python(x); -} - -BOOST_PYTHON_DECL boost::python::list from_python(PyObject* p, boost::python::type type) -{ - return boost::python::object_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::dictionary& x) -{ - return object_to_python(x); -} - -BOOST_PYTHON_DECL boost::python::dictionary from_python(PyObject* p, boost::python::type type) -{ - return boost::python::object_from_python(p, type); -} - -BOOST_PYTHON_DECL PyObject* to_python(const boost::python::string& x) -{ - return object_to_python(x); -} - -BOOST_PYTHON_DECL boost::python::string from_python(PyObject* p, boost::python::type type) -{ - return boost::python::object_from_python(p, type); -} - -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -namespace boost { namespace python { - -tuple_base::tuple_base(std::size_t n) - : object(ref(PyTuple_New(n))) -{ - for (std::size_t i = 0; i < n; ++i) - PyTuple_SET_ITEM(get(), i, detail::none()); -} - -tuple_base::tuple_base(ref p) - : object(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw_error_already_set(); - } -} - -PyTypeObject* tuple_base::type_obj() -{ - return &PyTuple_Type; -} - -bool tuple_base::accepts(ref p) -{ - return PyTuple_Check(p.get()); -} - -std::size_t tuple_base::size() const -{ - return PyTuple_Size(get()); -} - -ref tuple_base::operator[](std::size_t pos) const -{ - return ref(PyTuple_GetItem(get(), static_cast(pos)), - ref::increment_count); -} - -void tuple_base::set_item(std::size_t pos, const ref& rhs) -{ - int failed = PyTuple_SetItem( - get(), static_cast(pos), ref(rhs).release()); // A reference is stolen here. - (void)failed; - assert(failed == 0); -} - -tuple tuple_base::slice(int low, int high) const -{ - return tuple(ref(PyTuple_GetSlice(get(), low, high))); -} - -BOOST_PYTHON_DECL tuple& operator+=(tuple& self, const tuple& rhs) -{ - return self = self + rhs; -} - - -// Construct from an owned PyObject*. -// Precondition: p must point to a python string. -string::string(ref p) - : object(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw_error_already_set(); - } -} - -string::string(const char* s) - : object(ref(PyString_FromString(s))) {} - -string::string(const char* s, std::size_t length) - : object(ref(PyString_FromStringAndSize(s, length))) {} - -string::string(const char* s, interned_t) - : object(ref(PyString_InternFromString(s))) {} - -#if 0 -string::string(const char* s, std::size_t length, interned_t) - : object(ref(PyString_InternFromStringAndSize(s, length))) {} -#endif - -string::string(const string& rhs) - : object(rhs.reference()) {} - -// Get the type object for Strings -PyTypeObject* string::type_obj() -{ return &PyString_Type; } - -// Return true if the given object is a python string -bool string::accepts(ref o) -{ return PyString_Check(o.get()); } - -// Return the length of the string. -std::size_t string::size() const -{ - int size = PyString_GET_SIZE(get()); - assert(size >= 0); - return static_cast(size); -} - -// Returns a null-terminated representation of the contents of string. -// The pointer refers to the internal buffer of string, not a copy. -// The data must not be modified in any way. It must not be de-allocated. -const char* string::c_str() const -{ return PyString_AS_STRING(get()); } - -void string::intern() -{ // UNTESTED!! - *this = string(ref(PyString_InternFromString(c_str()), ref::increment_count)); -} - -string& string::operator*=(unsigned int repeat_count) -{ - *this = string(ref(PySequence_Repeat(get(), repeat_count))); - return *this; -} - -dictionary_base::dictionary_base(ref p) - : object(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw_error_already_set(); - } -} - -dictionary_base::dictionary_base() - : object(ref(PyDict_New())) {} - -PyTypeObject* dictionary_base::type_obj() -{ return &PyDict_Type; } - -bool dictionary_base::accepts(ref p) -{ return PyDict_Check(p.get()); } - -void dictionary_base::clear() -{ PyDict_Clear(get()); } - -const ref& dictionary_proxy::operator=(const ref& rhs) -{ - if (PyDict_SetItem(m_dict.get(), m_key.get(), rhs.get()) == -1) - throw_error_already_set(); - return rhs; -} - -dictionary_proxy::operator ref() const -{ - return ref(m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get())); -} - -dictionary_proxy::dictionary_proxy(const ref& dict, const ref& key) - : m_dict(dict), m_key(key) {} - -dictionary_proxy dictionary_base::operator[](ref key) -{ return proxy(reference(), key); } - -ref dictionary_base::operator[](ref key) const { - // An odd MSVC bug causes the ".operator Ptr()" to be needed - return proxy(reference(), key).operator ref(); -} - - -ref dictionary_base::get_item(const ref& key) const -{ - return get_item(key, ref()); -} - -ref dictionary_base::get_item(const ref& key, const ref& default_) const -{ - PyObject* value_or_null = PyDict_GetItem(get(), key.get()); - if (value_or_null == 0 && !PyErr_Occurred()) - return default_; - else - return ref(value_or_null, ref::increment_count); // Will throw if there was another error -} - -void dictionary_base::set_item(const ref& key, const ref& value) -{ - if (PyDict_SetItem(get(), key.get(), value.get()) == -1) - throw_error_already_set(); -} - -void dictionary_base::erase(ref key) { - if (PyDict_DelItem(get(), key.get()) == -1) - throw_error_already_set(); -} - -list dictionary_base::items() const { return list(ref(PyDict_Items(get()))); } -list dictionary_base::keys() const { return list(ref(PyDict_Keys(get()))); } -list dictionary_base::values() const { return list(ref(PyDict_Values(get()))); } - -std::size_t dictionary_base::size() const { return static_cast(PyDict_Size(get())); } - -string operator+(string x, string y) -{ - PyObject* io_string = x.reference().release(); - PyString_Concat(&io_string, y.get()); - return string(ref(io_string)); -} - -string& string::operator+=(const string& rhs) -{ - return *this = *this + rhs; -} - -string& string::operator+=(const char* y) -{ - return *this += string(y); -} - -string operator%(const string& format, const tuple& args) -{ - return string(ref(PyString_Format(format.get(), args.reference().get()))); -} - -string operator+(string x, const char* y) -{ - return x + string(y); -} - -string operator+(const char* x, string y) -{ - return string(x) + y; -} - -tuple operator+(const tuple& x, const tuple& y) -{ - tuple result(x.size() + y.size()); - for (std::size_t xi = 0; xi < x.size(); ++xi) - result.set_item(xi, x[xi]); - for (std::size_t yi = 0; yi < y.size(); ++yi) - result.set_item(yi + x.size(), y[yi]); - return result; -} - - -list_base::list_base(ref p) - : object(p) -{ - assert(accepts(p)); - if (!accepts(p)) - { - PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name); - throw_error_already_set(); - } -} - -list_base::list_base(std::size_t sz) - : object(ref(PyList_New(sz))) -{ -} - -PyTypeObject* list_base::type_obj() -{ - return &PyList_Type; -} - -bool list_base::accepts(ref p) -{ - return PyList_Check(p.get()); -} - -std::size_t list_base::size() const -{ - return PyList_Size(get()); -} - -ref list_base::operator[](std::size_t pos) const -{ - return ref(PyList_GetItem(get(), pos), ref::increment_count); -} - -list_proxy list_base::operator[](std::size_t pos) -{ - return proxy(reference(), pos); -} - -void list_base::insert(std::size_t index, const ref& item) -{ - if (PyList_Insert(get(), index, item.get()) == -1) - throw_error_already_set(); -} - -void list_base::push_back(const ref& item) -{ - if (PyList_Append(get(), item.get()) == -1) - throw_error_already_set(); -} - -void list_base::append(const ref& item) -{ - this->push_back(item); -} - -list list_base::slice(int low, int high) const -{ - return list(ref(PyList_GetSlice(get(), low, high))); -} - -list_slice_proxy list_base::slice(int low, int high) -{ - return list_slice_proxy(reference(), low, high); -} - -void list_base::sort() -{ - if (PyList_Sort(get()) == -1) - throw_error_already_set(); -} - -void list_base::reverse() -{ - if (PyList_Reverse(get()) == -1) - throw_error_already_set(); -} - -tuple list_base::as_tuple() const -{ - return tuple(ref(PyList_AsTuple(get()))); -} - -const ref& list_proxy::operator=(const ref& rhs) -{ - m_list.set_item(m_index, rhs); - return rhs; -} - -list_proxy::operator ref() const -{ - return ref(PyList_GetItem(m_list.get(), m_index), ref::increment_count); -} - -ref list_base::get_item(std::size_t pos) const -{ - return ref(PyList_GetItem(this->get(), pos), ref::increment_count); -} - -void list_base::set_item(std::size_t pos, const ref& rhs) -{ - int result = PyList_SetItem(this->get(), pos, rhs.get()); - if (result == -1) - throw_error_already_set(); - Py_INCREF(rhs.get()); -} - -list_proxy::list_proxy(const ref& list, std::size_t index) - : m_list(list), m_index(index) -{ -} - -const list& list_slice_proxy::operator=(const list& rhs) -{ - if (PyList_SetSlice(m_list.get(), m_low, m_high, rhs.get()) == -1) - throw_error_already_set(); - return rhs; -} - -list_slice_proxy::operator ref() const -{ - return ref(PyList_GetSlice(m_list.get(), m_low, m_high)); -} - -list_slice_proxy::operator list() const -{ - return list(this->operator ref()); -} - -std::size_t list_slice_proxy::size() const -{ - return this->operator list().size(); -} - -ref list_slice_proxy::operator[](std::size_t pos) const -{ - return this->operator list()[pos].operator ref(); -} - -list_slice_proxy::list_slice_proxy(const ref& list, int low, int high) - : m_list(list), m_low(low), m_high(high) -{ -} - -}} // namespace boost::python diff --git a/src/py_interface.cpp b/src/py_interface.cpp deleted file mode 100644 index e34bf6f9..00000000 --- a/src/py_interface.cpp +++ /dev/null @@ -1,1103 +0,0 @@ -// Automatically generated from py_api_gen.py - -#include - -namespace boost { namespace python { namespace api { - -namespace api_detail { - -BOOST_PYTHON_DECL object get_func(const char* name) { - object __builtin__((python::detail::borrowed_reference)::PyImport_AddModule(const_cast("__builtin__"))); - return object(__builtin__.attr(name)); -} - -inline handle<> get_current_frame() -{ - return handle<>(allow_null(borrowed((PyObject*)(PyThreadState_Get()->frame)))); -} - -inline object get_global_dict(call_dict_usage cdu, handle<> const& frame) -{ - if(frame.get()) - return object(object(frame).attr("f_globals")); - else - return api::globals(); -} - -object get_local_dict(call_dict_usage cdu, handle<> const& frame, object const& global_dict) -{ - switch(cdu) { - case use_new_dict: - return api::dict(); - case use_global_dict: - return global_dict; - default: - if(frame.get()) - return object(object(frame).attr("f_locals")); - else - return api::dict(); - } -} - -inline object call_statement(const char *stmt, object const& global_dict, object& local_dict) -{ - local_dict["_0"] = object((python::detail::borrowed_reference)Py_None); - api::run_string(stmt, Py_file_input, global_dict, local_dict); - return object(local_dict["_0"]); -} - -object call_statement(const char *stmt) -{ - handle<> frame(get_current_frame()); - if(frame.get()) { - object f(frame); - object gd(f.attr("f_globals")); - object ld(f.attr("f_locals")); - return call_statement(stmt, gd, ld); - } else { - object gd(api::globals()); - object ld(api::dict()); - return call_statement(stmt, gd, ld); - } -} - -object call_statement_du(const char *stmt, call_dict_usage cdu) -{ - handle<> frame(get_current_frame()); - object gd(get_global_dict(cdu, frame)); - return call_statement(stmt, gd, get_local_dict(cdu, frame, gd)); -} - -inline object call_statement(const char *stmt, object const& global_dict, object& local_dict, int n, va_list mk) -{ - static const char *(idx[]) = { "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8", "_9", "_10" }; - local_dict["_0"] = object((python::detail::borrowed_reference)Py_None); - for(int i = 0; i < n; ++i) - { - object const* p_arg = va_arg(mk, object const*); - object const& arg = *p_arg; - if(i < (int) (sizeof(idx) / sizeof(idx[0]))) - local_dict[idx[i]] = arg; - else { - local_dict[object("_") + object((python::detail::new_reference)PyObject_Str(object(i + 1).ptr()))] = arg; - } - } - va_end(mk); - api::run_string(stmt, Py_file_input, global_dict, local_dict); - return object(local_dict["_0"]); -} - -BOOST_PYTHON_DECL object call_statement(const char *stmt, int n, ...) -{ - va_list mk; - va_start(mk, n); - handle<> frame(get_current_frame()); - if(frame.get()) { - object f(frame); - object gd(f.attr("f_globals")); - object ld(f.attr("f_locals")); - return call_statement(stmt, gd, ld, n, mk); - } else { - object gd(api::globals()); - object ld(api::dict()); - return call_statement(stmt, gd, ld, n, mk); - } -} - -BOOST_PYTHON_DECL object call_statement_du(const char *stmt, call_dict_usage cdu, int n, ...) -{ - handle<> frame(get_current_frame()); - object gd(get_global_dict(cdu, frame)); - va_list mk; - va_start(mk, n); - return call_statement(stmt, gd, get_local_dict(cdu, frame, gd), n, mk); -} - -} - -BOOST_PYTHON_DECL object locals() -{ - handle<> frame(api_detail::get_current_frame()); - if(frame.get()) - return object(object(frame).attr("f_locals")); - else - return api::dict(); -} - - -BOOST_PYTHON_DECL object abs(object const& a0) { - return api_detail::get_func("abs")(a0); -} - -BOOST_PYTHON_DECL object abs(short a0) { - return api_detail::get_func("abs")(object(a0)); -} - -BOOST_PYTHON_DECL object abs(int a0) { - return api_detail::get_func("abs")(object(a0)); -} - -BOOST_PYTHON_DECL object abs(long a0) { - return api_detail::get_func("abs")(object(a0)); -} - -BOOST_PYTHON_DECL object abs(double const & a0) { - return api_detail::get_func("abs")(object(a0)); -} - -BOOST_PYTHON_DECL object apply(object const& a0, object const& a1) { - return object((python::detail::new_reference)::PyObject_CallObject(a0.ptr(), a1.ptr())); -} - -BOOST_PYTHON_DECL object apply(object const& a0, object const& a1, object const& a2) { - return object((python::detail::new_reference)::PyObject_Call(a0.ptr(), a1.ptr(), a2.ptr())); -} - -BOOST_PYTHON_DECL bool callable(object const& a0) { - return ::PyCallable_Check(a0.ptr()); -} - -BOOST_PYTHON_DECL object chr(object const& a0) { - return api_detail::get_func("chr")(a0); -} - -BOOST_PYTHON_DECL object chr(short a0) { - return api_detail::get_func("chr")(object(a0)); -} - -BOOST_PYTHON_DECL object chr(int a0) { - return api_detail::get_func("chr")(object(a0)); -} - -BOOST_PYTHON_DECL object chr(long a0) { - return api_detail::get_func("chr")(object(a0)); -} - -BOOST_PYTHON_DECL int cmp(object const& a0, object const& a1) { - int rslt; - int r = ::PyObject_Cmp(a0.ptr(), a1.ptr(), &rslt); - if(r == -1) - throw_error_already_set(); - return rslt; -} - -BOOST_PYTHON_DECL object coerce(object const& a0, object const& a1) { - return api_detail::get_func("coerce")(a0, a1); -} - -BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("compile")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2) { - return api_detail::get_func("compile")(object(a0), object(a1), object(a2)); -} - -BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2, object const& a3) { - return api_detail::get_func("compile")(a0, a1, a2, a3); -} - -BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2, int a3) { - return api_detail::get_func("compile")(object(a0), object(a1), object(a2), object(a3)); -} - -BOOST_PYTHON_DECL object compile(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { - return api_detail::get_func("compile")(a0, a1, a2, a3, a4); -} - -BOOST_PYTHON_DECL object compile(const char* a0, const char* a1, const char* a2, int a3, int a4) { - return api_detail::get_func("compile")(object(a0), object(a1), object(a2), object(a3), object(a4)); -} - -BOOST_PYTHON_DECL object complex(object const& a0) { - return api_detail::get_func("complex")(a0); -} - -BOOST_PYTHON_DECL object complex(double const& a0) { - return api_detail::get_func("complex")(object(a0)); -} - -BOOST_PYTHON_DECL object complex(object const& a0, object const& a1) { - return api_detail::get_func("complex")(a0, a1); -} - -BOOST_PYTHON_DECL object complex(double const& a0, double const& a1) { - return api_detail::get_func("complex")(object(a0), object(a1)); -} - -BOOST_PYTHON_DECL object dict() { - return api_detail::get_func("dict")(); -} - -BOOST_PYTHON_DECL object dict(object const& a0) { - return api_detail::get_func("dict")(a0); -} - -BOOST_PYTHON_DECL object dir() { - return object((python::detail::new_reference)::PyObject_Dir(NULL)); -} - -BOOST_PYTHON_DECL object dir(object const& a0) { - return object((python::detail::new_reference)::PyObject_Dir(a0.ptr())); -} - -BOOST_PYTHON_DECL object divmod(object const& a0, object const& a1) { - return api_detail::get_func("divmod")(a0, a1); -} - -BOOST_PYTHON_DECL object divmod(int a0, int a1) { - return api_detail::get_func("divmod")(object(a0), object(a1)); -} - -BOOST_PYTHON_DECL object divmod(long a0, long a1) { - return api_detail::get_func("divmod")(object(a0), object(a1)); -} - -BOOST_PYTHON_DECL object divmod(double const& a0, double const& a1) { - return api_detail::get_func("divmod")(object(a0), object(a1)); -} - -BOOST_PYTHON_DECL object eval(const char* a0) { - return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_eval_input, globals().ptr(), globals().ptr())); -} - -BOOST_PYTHON_DECL object eval(const char* a0, object const& a2) { - return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_eval_input, a2.ptr(), globals().ptr())); -} - -BOOST_PYTHON_DECL object eval(const char* a0, object const& a2, object const& a3) { - return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_eval_input, a2.ptr(), a3.ptr())); -} - -BOOST_PYTHON_DECL object exec(const char* a0) { - return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_file_input, globals().ptr(), globals().ptr())); -} - -BOOST_PYTHON_DECL object exec(const char* a0, object const& a2) { - return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_file_input, a2.ptr(), globals().ptr())); -} - -BOOST_PYTHON_DECL object exec(const char* a0, object const& a2, object const& a3) { - return object((python::detail::new_reference)::PyRun_String(const_cast(a0), Py_file_input, a2.ptr(), a3.ptr())); -} - -BOOST_PYTHON_DECL object execfile(object const& a0) { - return api_detail::get_func("execfile")(a0); -} - -BOOST_PYTHON_DECL object execfile(object const& a0, object const& a1) { - return api_detail::get_func("execfile")(a0, a1); -} - -BOOST_PYTHON_DECL object execfile(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("execfile")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object file(object const& a0) { - return api_detail::get_func("file")(a0); -} - -BOOST_PYTHON_DECL object file(const char* a0) { - return api_detail::get_func("file")(object(a0)); -} - -BOOST_PYTHON_DECL object file(object const& a0, object const& a1) { - return api_detail::get_func("file")(a0, a1); -} - -BOOST_PYTHON_DECL object file(const char* a0, const char* a1) { - return api_detail::get_func("file")(object(a0), object(a1)); -} - -BOOST_PYTHON_DECL object file(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("file")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object file(const char* a0, const char* a1, int a2) { - return api_detail::get_func("file")(object(a0), object(a1), object(a2)); -} - -BOOST_PYTHON_DECL object filter(object const& a0, object const& a1) { - return api_detail::get_func("filter")(a0, a1); -} - -BOOST_PYTHON_DECL object float_(object const& a0) { - return api_detail::get_func("float")(a0); -} - -BOOST_PYTHON_DECL object float_(const char* a0) { - return api_detail::get_func("float")(object(a0)); -} - -BOOST_PYTHON_DECL object float_(double const& a0) { - return api_detail::get_func("float")(object(a0)); -} - -BOOST_PYTHON_DECL object getattr(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("getattr")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object getattr(object const& a0, const char * a1, object const& a2) { - return api_detail::get_func("getattr")(a0, object(a1), a2); -} - -BOOST_PYTHON_DECL object globals() { - return object((python::detail::borrowed_reference)::PyModule_GetDict(PyImport_AddModule("__main__"))); -} - -BOOST_PYTHON_DECL bool hasattr(object const& a0, object const& a1) { - return ::PyObject_HasAttr(a0.ptr(), a1.ptr()); -} - -BOOST_PYTHON_DECL bool hasattr(object const& a0, const char* a1) { - return ::PyObject_HasAttrString(a0.ptr(), const_cast(a1)); -} - -BOOST_PYTHON_DECL long hash(object const& a0) { - long r = ::PyObject_Hash(a0.ptr()); - if(r == -1) - throw_error_already_set(); - return r; -} - -BOOST_PYTHON_DECL object hex(object const& a0) { - return api_detail::get_func("hex")(a0); -} - -BOOST_PYTHON_DECL object hex(char a0) { - return api_detail::get_func("hex")(object(a0)); -} - -BOOST_PYTHON_DECL object hex(short a0) { - return api_detail::get_func("hex")(object(a0)); -} - -BOOST_PYTHON_DECL object hex(int a0) { - return api_detail::get_func("hex")(object(a0)); -} - -BOOST_PYTHON_DECL object hex(long a0) { - return api_detail::get_func("hex")(object(a0)); -} - -BOOST_PYTHON_DECL long id(object const& a0) { - object r(api_detail::get_func("id")(a0)); - return boost::python::arg_from_python(r.ptr())(r.ptr()); -} - -BOOST_PYTHON_DECL object input() { - return api_detail::get_func("input")(); -} - -BOOST_PYTHON_DECL object input(object const& a0) { - return api_detail::get_func("input")(a0); -} - -BOOST_PYTHON_DECL object input(const char* a0) { - return api_detail::get_func("input")(object(a0)); -} - -BOOST_PYTHON_DECL object int_(object const& a0) { - return api_detail::get_func("int")(a0); -} - -BOOST_PYTHON_DECL object int_(long a0) { - return api_detail::get_func("int")(object(a0)); -} - -BOOST_PYTHON_DECL object int_(const char* a0) { - return api_detail::get_func("int")(object(a0)); -} - -BOOST_PYTHON_DECL object intern(object const& a0) { - return api_detail::get_func("intern")(a0); -} - -BOOST_PYTHON_DECL object intern(const char* a0) { - return api_detail::get_func("intern")(object(a0)); -} - -BOOST_PYTHON_DECL bool isinstance(object const& a0, object const& a1) { - return ::PyObject_IsInstance(a0.ptr(), a1.ptr()); -} - -BOOST_PYTHON_DECL bool issubclass(object const& a0, object const& a1) { - return ::PyObject_IsSubclass(a0.ptr(), a1.ptr()); -} - -BOOST_PYTHON_DECL object iter(object const& a0) { - return object((python::detail::new_reference)::PyObject_GetIter(a0.ptr())); -} - -BOOST_PYTHON_DECL object iter(object const& a0, object const& a1) { - return api_detail::get_func("iter")(a0, a1); -} - -BOOST_PYTHON_DECL long len(object const& a0) { - long r = ::PyObject_Length(a0.ptr()); - if(r == -1) - throw_error_already_set(); - return r; -} - -BOOST_PYTHON_DECL object list() { - return api_detail::get_func("list")(); -} - -BOOST_PYTHON_DECL object list(object const& a0) { - return api_detail::get_func("list")(a0); -} - -BOOST_PYTHON_DECL object long_(object const& a0) { - return api_detail::get_func("long")(a0); -} - -BOOST_PYTHON_DECL object long_(long a0) { - return api_detail::get_func("long")(object(a0)); -} - -BOOST_PYTHON_DECL object long_(const char* a0) { - return api_detail::get_func("long")(object(a0)); -} - -BOOST_PYTHON_DECL object map(object const& a0) { - return api_detail::get_func("map")(a0); -} - -BOOST_PYTHON_DECL object map(object const& a0, object const& a1) { - return api_detail::get_func("map")(a0, a1); -} - -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("map")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3) { - return api_detail::get_func("map")(a0, a1, a2, a3); -} - -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { - return api_detail::get_func("map")(a0, a1, a2, a3, a4); -} - -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { - return api_detail::get_func("map")(a0, a1, a2, a3, a4, a5); -} - -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { - return api_detail::get_func("map")(a0, a1, a2, a3, a4, a5, a6); -} - -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { - return api_detail::get_func("map")(a0, a1, a2, a3, a4, a5, a6, a7); -} - -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { - return api_detail::get_func("map")(a0, a1, a2, a3, a4, a5, a6, a7, a8); -} - -BOOST_PYTHON_DECL object map(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { - return api_detail::get_func("map")(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); -} - -BOOST_PYTHON_DECL object max(object const& a0) { - return api_detail::get_func("max")(a0); -} - -BOOST_PYTHON_DECL object max(object const& a0, object const& a1) { - return api_detail::get_func("max")(a0, a1); -} - -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("max")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3) { - return api_detail::get_func("max")(a0, a1, a2, a3); -} - -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { - return api_detail::get_func("max")(a0, a1, a2, a3, a4); -} - -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { - return api_detail::get_func("max")(a0, a1, a2, a3, a4, a5); -} - -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { - return api_detail::get_func("max")(a0, a1, a2, a3, a4, a5, a6); -} - -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { - return api_detail::get_func("max")(a0, a1, a2, a3, a4, a5, a6, a7); -} - -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { - return api_detail::get_func("max")(a0, a1, a2, a3, a4, a5, a6, a7, a8); -} - -BOOST_PYTHON_DECL object max(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { - return api_detail::get_func("max")(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); -} - -BOOST_PYTHON_DECL object min(object const& a0) { - return api_detail::get_func("min")(a0); -} - -BOOST_PYTHON_DECL object min(object const& a0, object const& a1) { - return api_detail::get_func("min")(a0, a1); -} - -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("min")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3) { - return api_detail::get_func("min")(a0, a1, a2, a3); -} - -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { - return api_detail::get_func("min")(a0, a1, a2, a3, a4); -} - -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { - return api_detail::get_func("min")(a0, a1, a2, a3, a4, a5); -} - -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { - return api_detail::get_func("min")(a0, a1, a2, a3, a4, a5, a6); -} - -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { - return api_detail::get_func("min")(a0, a1, a2, a3, a4, a5, a6, a7); -} - -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { - return api_detail::get_func("min")(a0, a1, a2, a3, a4, a5, a6, a7, a8); -} - -BOOST_PYTHON_DECL object min(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { - return api_detail::get_func("min")(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); -} - -BOOST_PYTHON_DECL object oct(object const& a0) { - return api_detail::get_func("oct")(a0); -} - -BOOST_PYTHON_DECL object oct(char a0) { - return api_detail::get_func("oct")(object(a0)); -} - -BOOST_PYTHON_DECL object oct(short a0) { - return api_detail::get_func("oct")(object(a0)); -} - -BOOST_PYTHON_DECL object oct(int a0) { - return api_detail::get_func("oct")(object(a0)); -} - -BOOST_PYTHON_DECL object oct(long a0) { - return api_detail::get_func("oct")(object(a0)); -} - -BOOST_PYTHON_DECL object open(object const& a0) { - return api_detail::get_func("open")(a0); -} - -BOOST_PYTHON_DECL object open(const char* a0) { - return api_detail::get_func("open")(object(a0)); -} - -BOOST_PYTHON_DECL object open(object const& a0, object const& a1) { - return api_detail::get_func("open")(a0, a1); -} - -BOOST_PYTHON_DECL object open(const char* a0, const char* a1) { - return api_detail::get_func("open")(object(a0), object(a1)); -} - -BOOST_PYTHON_DECL object open(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("open")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object open(const char* a0, const char* a1, int a2) { - return api_detail::get_func("open")(object(a0), object(a1), object(a2)); -} - -BOOST_PYTHON_DECL long ord(object const& a0) { - object r(api_detail::get_func("ord")(a0)); - return boost::python::arg_from_python(r.ptr())(r.ptr()); -} - -BOOST_PYTHON_DECL long ord(const char* a0) { - object r(api_detail::get_func("ord")(object(a0))); - return boost::python::arg_from_python(r.ptr())(r.ptr()); -} - -BOOST_PYTHON_DECL object pow(object const& a0, object const& a1) { - return api_detail::get_func("pow")(a0, a1); -} - -BOOST_PYTHON_DECL object pow(double const& a0, double const& a1) { - return api_detail::get_func("pow")(object(a0), object(a1)); -} - -BOOST_PYTHON_DECL object pow(double const& a0, double const& a1, double const& a2) { - return api_detail::get_func("pow")(object(a0), object(a1), object(a2)); -} - -BOOST_PYTHON_DECL object print(object const& a0) { - return api_detail::call_statement_du("print _1", use_new_dict, 1, &a0); -} - -BOOST_PYTHON_DECL object print(object const& a0, object const& a1) { - return api_detail::call_statement_du("print _1, _2", use_new_dict, 2, &a0, &a1); -} - -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2) { - return api_detail::call_statement_du("print _1, _2, _3", use_new_dict, 3, &a0, &a1, &a2); -} - -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3) { - return api_detail::call_statement_du("print _1, _2, _3, _4", use_new_dict, 4, &a0, &a1, &a2, &a3); -} - -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { - return api_detail::call_statement_du("print _1, _2, _3, _4, _5", use_new_dict, 5, &a0, &a1, &a2, &a3, &a4); -} - -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { - return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6", use_new_dict, 6, &a0, &a1, &a2, &a3, &a4, &a5); -} - -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { - return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7", use_new_dict, 7, &a0, &a1, &a2, &a3, &a4, &a5, &a6); -} - -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { - return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8", use_new_dict, 8, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7); -} - -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { - return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8, _9", use_new_dict, 9, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8); -} - -BOOST_PYTHON_DECL object print(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { - return api_detail::call_statement_du("print _1, _2, _3, _4, _5, _6, _7, _8, _9, _10", use_new_dict, 10, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9); -} - -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1) { - return api_detail::call_statement_du("print >>_1, _2", use_new_dict, 2, &a0, &a1); -} - -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2) { - return api_detail::call_statement_du("print >>_1, _2, _3", use_new_dict, 3, &a0, &a1, &a2); -} - -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3) { - return api_detail::call_statement_du("print >>_1, _2, _3, _4", use_new_dict, 4, &a0, &a1, &a2, &a3); -} - -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5", use_new_dict, 5, &a0, &a1, &a2, &a3, &a4); -} - -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6", use_new_dict, 6, &a0, &a1, &a2, &a3, &a4, &a5); -} - -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7", use_new_dict, 7, &a0, &a1, &a2, &a3, &a4, &a5, &a6); -} - -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8", use_new_dict, 8, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7); -} - -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9", use_new_dict, 9, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8); -} - -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9, _10", use_new_dict, 10, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9); -} - -BOOST_PYTHON_DECL object print_file(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10) { - return api_detail::call_statement_du("print >>_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11", use_new_dict, 11, &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10); -} - -BOOST_PYTHON_DECL object range(object const& a0) { - return api_detail::get_func("range")(a0); -} - -BOOST_PYTHON_DECL object range(int a0) { - return api_detail::get_func("range")(object(a0)); -} - -BOOST_PYTHON_DECL object range(object const& a0, object const& a1) { - return api_detail::get_func("range")(a0, a1); -} - -BOOST_PYTHON_DECL object range(int a0, int a1) { - return api_detail::get_func("range")(object(a0), object(a1)); -} - -BOOST_PYTHON_DECL object range(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("range")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object range(int a0, int a1, int a2) { - return api_detail::get_func("range")(object(a0), object(a1), object(a2)); -} - -BOOST_PYTHON_DECL object raw_input() { - return api_detail::get_func("raw_input")(); -} - -BOOST_PYTHON_DECL object raw_input(object const& a0) { - return api_detail::get_func("raw_input")(a0); -} - -BOOST_PYTHON_DECL object raw_input(const char* a0) { - return api_detail::get_func("raw_input")(object(a0)); -} - -BOOST_PYTHON_DECL object reduce(object const& a0, object const& a1) { - return api_detail::get_func("reduce")(a0, a1); -} - -BOOST_PYTHON_DECL object reduce(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("reduce")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object reload(object const& a0) { - return object((python::detail::new_reference)::PyImport_ReloadModule(a0.ptr())); -} - -BOOST_PYTHON_DECL object repr(object const& a0) { - return object((python::detail::new_reference)::PyObject_Repr(a0.ptr())); -} - -BOOST_PYTHON_DECL object round(object const& a0) { - return api_detail::get_func("round")(a0); -} - -BOOST_PYTHON_DECL object round(double const& a0) { - return api_detail::get_func("round")(object(a0)); -} - -BOOST_PYTHON_DECL object round(object const& a0, object const& a1) { - return api_detail::get_func("round")(a0, a1); -} - -BOOST_PYTHON_DECL object round(double const& a0, double const& a1) { - return api_detail::get_func("round")(object(a0), object(a1)); -} - -BOOST_PYTHON_DECL object slice(object const& a0) { - return api_detail::get_func("slice")(a0); -} - -BOOST_PYTHON_DECL object slice(int a0) { - return api_detail::get_func("slice")(object(a0)); -} - -BOOST_PYTHON_DECL object slice(object const& a0, object const& a1) { - return api_detail::get_func("slice")(a0, a1); -} - -BOOST_PYTHON_DECL object slice(int a0, int a1) { - return api_detail::get_func("slice")(object(a0), object(a1)); -} - -BOOST_PYTHON_DECL object slice(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("slice")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object slice(int a0, int a1, int a2) { - return api_detail::get_func("slice")(object(a0), object(a1), object(a2)); -} - -BOOST_PYTHON_DECL object str(object const& a0) { - return object((python::detail::new_reference)::PyObject_Str(a0.ptr())); -} - -BOOST_PYTHON_DECL object tuple() { - return api_detail::get_func("tuple")(); -} - -BOOST_PYTHON_DECL object tuple(object const& a0) { - return api_detail::get_func("tuple")(a0); -} - -BOOST_PYTHON_DECL object type_(object const& a0) { - return object((python::detail::new_reference)::PyObject_Type(a0.ptr())); -} - -BOOST_PYTHON_DECL object unichr(object const& a0) { - return api_detail::get_func("unichr")(a0); -} - -BOOST_PYTHON_DECL object unichr(short a0) { - return api_detail::get_func("unichr")(object(a0)); -} - -BOOST_PYTHON_DECL object unichr(int a0) { - return api_detail::get_func("unichr")(object(a0)); -} - -BOOST_PYTHON_DECL object unichr(long a0) { - return api_detail::get_func("unichr")(object(a0)); -} - -BOOST_PYTHON_DECL object unicode(object const& a0) { - return object((python::detail::new_reference)::PyObject_Unicode(a0.ptr())); -} - -BOOST_PYTHON_DECL object unicode(object const& a0, object const& a1) { - return api_detail::get_func("unicode")(a0, a1); -} - -BOOST_PYTHON_DECL object unicode(object const& a0, const char* a1) { - return api_detail::get_func("unicode")(a0, object(a1)); -} - -BOOST_PYTHON_DECL object unicode(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("unicode")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object unicode(object const& a0, const char* a1, const char* a2) { - return api_detail::get_func("unicode")(a0, object(a1), object(a2)); -} - -BOOST_PYTHON_DECL object vars() { - return api_detail::get_func("vars")(); -} - -BOOST_PYTHON_DECL object vars(object const& a0) { - return api_detail::get_func("vars")(a0); -} - -BOOST_PYTHON_DECL object xrange(object const& a0) { - return api_detail::get_func("xrange")(a0); -} - -BOOST_PYTHON_DECL object xrange(int a0) { - return api_detail::get_func("xrange")(object(a0)); -} - -BOOST_PYTHON_DECL object xrange(object const& a0, object const& a1) { - return api_detail::get_func("xrange")(a0, a1); -} - -BOOST_PYTHON_DECL object xrange(int a0, int a1) { - return api_detail::get_func("xrange")(object(a0), object(a1)); -} - -BOOST_PYTHON_DECL object xrange(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("xrange")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object xrange(int a0, int a1, int a2) { - return api_detail::get_func("xrange")(object(a0), object(a1), object(a2)); -} - -BOOST_PYTHON_DECL object zip(object const& a0) { - return api_detail::get_func("zip")(a0); -} - -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1) { - return api_detail::get_func("zip")(a0, a1); -} - -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2) { - return api_detail::get_func("zip")(a0, a1, a2); -} - -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3) { - return api_detail::get_func("zip")(a0, a1, a2, a3); -} - -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4) { - return api_detail::get_func("zip")(a0, a1, a2, a3, a4); -} - -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { - return api_detail::get_func("zip")(a0, a1, a2, a3, a4, a5); -} - -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { - return api_detail::get_func("zip")(a0, a1, a2, a3, a4, a5, a6); -} - -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { - return api_detail::get_func("zip")(a0, a1, a2, a3, a4, a5, a6, a7); -} - -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { - return api_detail::get_func("zip")(a0, a1, a2, a3, a4, a5, a6, a7, a8); -} - -BOOST_PYTHON_DECL object zip(object const& a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { - return api_detail::get_func("zip")(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); -} - -BOOST_PYTHON_DECL object compile_string(const char* a0, const char* a1, int a2) { - return object((python::detail::new_reference)::Py_CompileString(const_cast(a0), const_cast(a1), a2)); -} - -BOOST_PYTHON_DECL int import_append_inittab(const char* a0, void(*a1)(void)) { - int r = ::PyImport_AppendInittab(const_cast(a0), a1); - if(r == -1) - throw_error_already_set(); - return r; -} - -BOOST_PYTHON_DECL object import_add_module(const char* a0) { - return object((python::detail::borrowed_reference)::PyImport_AddModule(const_cast(a0))); -} - -BOOST_PYTHON_DECL object import_get_module_dict() { - return object((python::detail::borrowed_reference)::PyImport_GetModuleDict()); -} - -BOOST_PYTHON_DECL object import_import(object const& a0) { - return object((python::detail::new_reference)::PyImport_Import(a0.ptr())); -} - -BOOST_PYTHON_DECL object import_import(const char* a0) { - return object((python::detail::new_reference)::PyImport_Import(object(a0).ptr())); -} - -BOOST_PYTHON_DECL object import_import_module(const char* a0) { - return object((python::detail::new_reference)::PyImport_ImportModule(const_cast(a0))); -} - -BOOST_PYTHON_DECL object import_import_module_ex(const char* a0, object const& a1, object const& a2, object const& a3) { - return object((python::detail::new_reference)::PyImport_ImportModuleEx(const_cast(a0), a1.ptr(), a2.ptr(), a3.ptr())); -} - -BOOST_PYTHON_DECL object module_get_dict(object const& a0) { - return object((python::detail::borrowed_reference)::PyModule_GetDict(a0.ptr())); -} - -BOOST_PYTHON_DECL int object_print(object const& a0, FILE* a1, int a2) { - int r = ::PyObject_Print(a0.ptr(), a1, a2); - if(r == -1) - throw_error_already_set(); - return r; -} - -BOOST_PYTHON_DECL object run_file(FILE* a0, const char* a1, int a2, object const& a3, object const& a4) { - return object((python::detail::new_reference)::PyRun_File(a0, const_cast(a1), a2, a3.ptr(), a4.ptr())); -} - -BOOST_PYTHON_DECL int run_simple_file(FILE* a0, const char* a1) { - int r = ::PyRun_SimpleFile(a0, const_cast(a1)); - if(r == -1) - throw_error_already_set(); - return r; -} - -BOOST_PYTHON_DECL int run_simple_string(const char* a0) { - int r = ::PyRun_SimpleString(const_cast(a0)); - if(r == -1) - throw_error_already_set(); - return r; -} - -BOOST_PYTHON_DECL object run_string(const char* a0, int a1, object const& a2, object const& a3) { - return object((python::detail::new_reference)::PyRun_String(const_cast(a0), a1, a2.ptr(), a3.ptr())); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0) { - return api_detail::call_statement(a0); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1) { - return api_detail::call_statement_du(a0, a1); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1) { - return api_detail::call_statement(a0, 1, &a1); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2) { - return api_detail::call_statement(a0, 2, &a1, &a2); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3) { - return api_detail::call_statement(a0, 3, &a1, &a2, &a3); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4) { - return api_detail::call_statement(a0, 4, &a1, &a2, &a3, &a4); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5) { - return api_detail::call_statement(a0, 5, &a1, &a2, &a3, &a4, &a5); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { - return api_detail::call_statement(a0, 6, &a1, &a2, &a3, &a4, &a5, &a6); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { - return api_detail::call_statement(a0, 7, &a1, &a2, &a3, &a4, &a5, &a6, &a7); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { - return api_detail::call_statement(a0, 8, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { - return api_detail::call_statement(a0, 9, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, object const& a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10) { - return api_detail::call_statement(a0, 10, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2) { - return api_detail::call_statement_du(a0, a1, 1, &a2); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3) { - return api_detail::call_statement_du(a0, a1, 2, &a2, &a3); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4) { - return api_detail::call_statement_du(a0, a1, 3, &a2, &a3, &a4); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5) { - return api_detail::call_statement_du(a0, a1, 4, &a2, &a3, &a4, &a5); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6) { - return api_detail::call_statement_du(a0, a1, 5, &a2, &a3, &a4, &a5, &a6); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7) { - return api_detail::call_statement_du(a0, a1, 6, &a2, &a3, &a4, &a5, &a6, &a7); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8) { - return api_detail::call_statement_du(a0, a1, 7, &a2, &a3, &a4, &a5, &a6, &a7, &a8); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9) { - return api_detail::call_statement_du(a0, a1, 8, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10) { - return api_detail::call_statement_du(a0, a1, 9, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10); -} - -BOOST_PYTHON_DECL object call_statement(const char* a0, call_dict_usage a1, object const& a2, object const& a3, object const& a4, object const& a5, object const& a6, object const& a7, object const& a8, object const& a9, object const& a10, object const& a11) { - return api_detail::call_statement_du(a0, a1, 10, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11); -} - - -}}} - diff --git a/src/types.cpp b/src/types.cpp deleted file mode 100644 index eae9adff..00000000 --- a/src/types.cpp +++ /dev/null @@ -1,1272 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#define BOOST_PYTHON_SOURCE - -#include -#include -#include // for handle_exception() -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace python { - -namespace -{ - using detail::type_object_base; - using detail::call_object; - - - // Define a family of forwarding functions that can be called from a - // PyTypeObject's slots. These functions dispatch through a (virtual) member - // function pointer in the type_object_base, and handle exceptions in a - // uniform way, preventing us from having to rewrite the dispatching code over - // and over. - - // Given a function object f with signature - // - // PyObject* f(PyTypeObject*,PyObject*) - // - // calls f inside of handle_exception, and returns the result. If an exception - // is thrown by f, returns 0. - template - PyObject* obj_call(PyObject* obj, F f) - { - PyObject* result; - return call_object(result, obj, f) ? 0 : result; - } - - // Call the given integer-returning function object inside of - // handle_exception, returning a value_holder. F is a function - // object with "signature" - // - // R F(PyTypeObject*, PyObject*) - // - // where R is an integer type. - template - R int_call(PyObject* obj, F f, R* = 0) - { - R result; - return call_object(result, obj, f) ? -1 : result; - } - - // Implemented in terms of obj_call, above - PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*) const) - { - return obj_call(obj, bind(f, _1, _2)); - } - - // Implemented in terms of int_call, above - int call(PyObject* obj, int (type_object_base::*f)(PyObject*) const) - { - return int_call(obj, bind(f, _1, _2)); - } - - template - PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*, A1) const, A1 a1) - { - return obj_call(obj, bind(f, _1, _2, a1)); - } - - template - int call(PyObject* obj, int (type_object_base::*f)(PyObject*, A1) const, A1 a1) - { - return int_call(obj, bind(f, _1, _2, a1)); - } - - template - PyObject* call(PyObject* obj, PyObject* (type_object_base::*f)(PyObject*, A1, A2) const, A1 a1, A2 a2) - { - return obj_call(obj, bind(f, _1, _2, a1, a2)); - } - - template - int call(PyObject* obj, int (type_object_base::*f)(PyObject*, A1, A2) const, A1 a1, A2 a2) - { - return int_call(obj, bind(f, _1, _2, a1, a2)); - } - - template - int call(PyObject* obj, int (type_object_base::*f)(PyObject*, A1, A2, A3) const, A1 a1, A2 a2, A3 a3) - { - return int_call(obj, bind(f, _1, _2, a1, a2, a3)); - } - - int call_length_function(PyObject* obj, int (type_object_base::*f)(PyObject*) const) - { - int result; - if (call_object(result, obj, bind(f, _1, _2))) - return -1; - - if (result >= 0) - return result; - - PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0"); - return -1; - } -} // anonymous namespace - -extern "C" { - -// -// These functions actually go into the type object's slots, and dispatch to the -// "call" wrappers defined above. -// -static PyObject* do_instance_repr(PyObject* obj) -{ - return call(obj, &type_object_base::instance_repr); -} - -static PyObject* do_instance_richcompare(PyObject* obj, PyObject* other, int d) -{ -#if PYTHON_API_VERSION >= 1010 - switch(d) - { - case Py_LT: - return call(obj, &type_object_base::instance_lt, other); - case Py_LE: - return call(obj, &type_object_base::instance_le, other); - case Py_EQ: - return call(obj, &type_object_base::instance_eq, other); - case Py_NE: - return call(obj, &type_object_base::instance_ne, other); - case Py_GT: - return call(obj, &type_object_base::instance_gt, other); - case Py_GE: - return call(obj, &type_object_base::instance_ge, other); - } -#endif - return 0; -} - -static int do_instance_compare(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_compare, other); -} - -static PyObject* do_instance_str(PyObject* obj) -{ - return call(obj, &type_object_base::instance_str); -} - -static long do_instance_hash(PyObject* obj) -{ - return int_call(obj, bind(&type_object_base::instance_hash, _1, _2)); -} - -static PyObject* do_instance_call(PyObject* obj, PyObject* args, PyObject* keywords) -{ - return call(obj, &type_object_base::instance_call, args, keywords); -} - -static void do_instance_dealloc(PyObject* obj) -{ - if (handle_exception( - bind(&type_object_base::instance_dealloc - , static_cast(obj->ob_type) - , obj)) - ) - { - assert(!"exception during destruction!"); - } -} - -static PyObject* do_instance_getattr(PyObject* obj, char* name) -{ - const char* name_ = name; - return call(obj, &type_object_base::instance_getattr, name_); -} - -static int do_instance_setattr(PyObject* obj, char* name, PyObject* value) -{ - const char* name_ = name; - return call(obj, &type_object_base::instance_setattr, name_, value); -} - -static int do_instance_mp_length(PyObject* obj) -{ - return call_length_function(obj, &type_object_base::instance_mapping_length); -} - -static int do_instance_sq_length(PyObject* obj) -{ - return call_length_function(obj, &type_object_base::instance_sequence_length); -} - -static PyObject* do_instance_mp_subscript(PyObject* obj, PyObject* index) -{ - return call(obj, &type_object_base::instance_mapping_subscript, index); -} - -static PyObject* do_instance_sq_item(PyObject* obj, int index) -{ - // This is an extension to standard class behavior. If sequence_length - // is implemented and n >= sequence_length(), raise an IndexError. That - // keeps users from having to worry about raising it themselves - const PyTypeObject* const type = obj->ob_type; - if (type->tp_as_sequence != 0 && type->tp_as_sequence->sq_length != 0 - && index >= type->tp_as_sequence->sq_length(obj)) - { - PyErr_SetString(PyExc_IndexError, type->tp_name); - return 0; - } - - return obj_call( - obj - , bind(&type_object_base::instance_sequence_item, _1, _2, index)); -} - -static int do_instance_mp_ass_subscript(PyObject* obj, PyObject* index, PyObject* value) -{ - return call(obj, &type_object_base::instance_mapping_ass_subscript, index, value); -} - -static int do_instance_sq_ass_item(PyObject* obj, int index, PyObject* value) -{ - return call(obj, &type_object_base::instance_sequence_ass_item, index, value); -} - -static PyObject* do_instance_sq_concat(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_sequence_concat, other); -} - -static PyObject* do_instance_sq_repeat(PyObject* obj, int n) -{ - return call(obj, &type_object_base::instance_sequence_repeat, n); -} - -static PyObject* do_instance_sq_slice( - PyObject* obj, int start, int finish) -{ - return call(obj, &type_object_base::instance_sequence_slice, start, finish); -} - -static int do_instance_sq_ass_slice( - PyObject* obj, int start, int finish, PyObject* value) -{ - return call(obj, &type_object_base::instance_sequence_ass_slice, start, finish, value); -} - -static PyObject* do_instance_nb_add(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_add, other); -} - -static PyObject* do_instance_nb_subtract(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_subtract, other); -} - -static PyObject* do_instance_nb_multiply(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_multiply, other); -} - -static PyObject* do_instance_nb_divide(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_divide, other); -} - -static PyObject* do_instance_nb_remainder(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_remainder, other); -} - -static PyObject* do_instance_nb_divmod(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_divmod, other); -} - -static PyObject* do_instance_nb_power(PyObject* obj, PyObject* exponent, PyObject* modulus) -{ - return call(obj, &type_object_base::instance_number_power, exponent, modulus); -} - -static PyObject* do_instance_nb_negative(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_negative); -} - -static PyObject* do_instance_nb_positive(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_positive); -} - -static PyObject* do_instance_nb_absolute(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_absolute); -} - -static int do_instance_nb_nonzero(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_nonzero); -} - -static PyObject* do_instance_nb_invert(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_invert); -} - - -static PyObject* do_instance_nb_lshift(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_lshift, other); -} - -static PyObject* do_instance_nb_rshift(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_rshift, other); -} - -static PyObject* do_instance_nb_and(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_and, other); -} - -static PyObject* do_instance_nb_xor(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_xor, other); -} - -static PyObject* do_instance_nb_or(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_or, other); -} - -static int do_instance_nb_coerce(PyObject**obj, PyObject**other) -{ - // no call() overload for this oddball function, so we'll do it manually - return int_call( - *obj, bind( - &type_object_base::instance_number_coerce, _1, _2, obj, other)); -} -static PyObject* do_instance_nb_int(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_int); -} - -static PyObject* do_instance_nb_long(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_long); -} - -static PyObject* do_instance_nb_float(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_float); -} - -static PyObject* do_instance_nb_oct(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_oct); -} - -static PyObject* do_instance_nb_hex(PyObject* obj) -{ - return call(obj, &type_object_base::instance_number_hex); -} - -static PyObject* do_instance_nb_inplace_add(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_add, other); -} - -static PyObject* do_instance_nb_inplace_subtract(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_subtract, other); -} - -static PyObject* do_instance_nb_inplace_multiply(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_multiply, other); -} - -static PyObject* do_instance_nb_inplace_divide(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_divide, other); -} - -static PyObject* do_instance_nb_inplace_remainder(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_remainder, other); -} - -static PyObject* do_instance_nb_inplace_power(PyObject* obj, PyObject* exponent, PyObject* modulus) -{ - return call(obj, &type_object_base::instance_number_inplace_power, exponent, modulus); -} - -static PyObject* do_instance_nb_inplace_lshift(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_lshift, other); -} - -static PyObject* do_instance_nb_inplace_rshift(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_rshift, other); -} - -static PyObject* do_instance_nb_inplace_and(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_and, other); -} - -static PyObject* do_instance_nb_inplace_or(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_or, other); -} - -static PyObject* do_instance_nb_inplace_xor(PyObject* obj, PyObject* other) -{ - return call(obj, &type_object_base::instance_number_inplace_xor, other); -} - -} // extern "C" - -namespace -{ - -#define ENABLE_GENERAL_CAPABILITY(field) \ - case type_object_base::field: \ - dest->tp_##field = &do_instance_##field; \ - return true - -bool add_capability_general(type_object_base::capability capability, PyTypeObject* dest) -{ - assert(dest != 0); - - switch(capability) - { - ENABLE_GENERAL_CAPABILITY(hash); - ENABLE_GENERAL_CAPABILITY(call); - ENABLE_GENERAL_CAPABILITY(str); - ENABLE_GENERAL_CAPABILITY(getattr); - ENABLE_GENERAL_CAPABILITY(setattr); - ENABLE_GENERAL_CAPABILITY(compare); - ENABLE_GENERAL_CAPABILITY(repr); - default: - return false; - } -} - - -template -void create_method_table_if_null(T*& table) -{ - if(table == 0) - { - detail::shared_pod_manager::create(table); - } - else - { - detail::shared_pod_manager::make_unique_copy(table); - } -} - -bool add_capability_richcompare(type_object_base::capability capability, PyTypeObject* dest) -{ - assert(dest != 0); - if (capability == type_object_base::richcompare) { -#if PYTHON_API_VERSION >= 1010 - dest->tp_richcompare = &do_instance_richcompare; - dest->tp_flags |= Py_TPFLAGS_HAVE_RICHCOMPARE; -#endif - return true; - } - - return false; -} - -#define ENABLE_INPLACE_CAPABILITY(field) \ - case type_object_base::number_##field: \ - create_method_table_if_null(dest->tp_as_number); \ - dest->tp_as_number->nb_##field = &do_instance_nb_##field; \ - detail::shared_pod_manager::replace_if_equal(dest->tp_as_number); \ - dest->tp_flags |= Py_TPFLAGS_HAVE_INPLACEOPS; \ - return true - -bool add_capability_inplace(type_object_base::capability capability, PyTypeObject* dest) -{ - assert(dest != 0); - switch (capability) - { -#if PYTHON_API_VERSION >= 1010 - ENABLE_INPLACE_CAPABILITY (inplace_add); - ENABLE_INPLACE_CAPABILITY (inplace_subtract); - ENABLE_INPLACE_CAPABILITY (inplace_multiply); - ENABLE_INPLACE_CAPABILITY (inplace_divide); - ENABLE_INPLACE_CAPABILITY (inplace_remainder); - ENABLE_INPLACE_CAPABILITY (inplace_power); - ENABLE_INPLACE_CAPABILITY (inplace_lshift); - ENABLE_INPLACE_CAPABILITY (inplace_rshift); - ENABLE_INPLACE_CAPABILITY (inplace_and); - ENABLE_INPLACE_CAPABILITY (inplace_or); - ENABLE_INPLACE_CAPABILITY (inplace_xor); -#endif - default: - return false; - } -} - -#define ENABLE_MAPPING_CAPABILITY(field) \ - case type_object_base::mapping_##field: \ - create_method_table_if_null(dest); \ - dest->mp_##field = &do_instance_mp_##field; \ - detail::shared_pod_manager::replace_if_equal(dest); \ - return true - -bool add_capability_mapping(type_object_base::capability capability, PyMappingMethods*& dest) -{ - switch(capability) - { - ENABLE_MAPPING_CAPABILITY(length); - ENABLE_MAPPING_CAPABILITY(subscript); - ENABLE_MAPPING_CAPABILITY(ass_subscript); - default: - return false; - } -} - -#define ENABLE_SEQUENCE_CAPABILITY(field) \ - case type_object_base::sequence_##field: \ - create_method_table_if_null(dest); \ - dest->sq_##field = &do_instance_sq_##field; \ - detail::shared_pod_manager::replace_if_equal(dest); \ - return true - -bool add_capability_sequence(type_object_base::capability capability, PySequenceMethods*& dest) -{ - switch(capability) - { - ENABLE_SEQUENCE_CAPABILITY(length); - ENABLE_SEQUENCE_CAPABILITY(item); - ENABLE_SEQUENCE_CAPABILITY(ass_item); - ENABLE_SEQUENCE_CAPABILITY(concat); - ENABLE_SEQUENCE_CAPABILITY(repeat); - ENABLE_SEQUENCE_CAPABILITY(slice); - ENABLE_SEQUENCE_CAPABILITY(ass_slice); - default: - return false; - } -} - -#define ENABLE_NUMBER_CAPABILITY(field) \ - case type_object_base::number_##field: \ - create_method_table_if_null(dest); \ - dest->nb_##field = &do_instance_nb_##field; \ - detail::shared_pod_manager::replace_if_equal(dest); \ - return true - -bool add_capability_number(type_object_base::capability capability, PyNumberMethods*& dest) -{ - switch(capability) - { - ENABLE_NUMBER_CAPABILITY(add); - ENABLE_NUMBER_CAPABILITY(subtract); - ENABLE_NUMBER_CAPABILITY(multiply); - ENABLE_NUMBER_CAPABILITY(divide); - ENABLE_NUMBER_CAPABILITY(remainder); - ENABLE_NUMBER_CAPABILITY(divmod); - ENABLE_NUMBER_CAPABILITY(power); - ENABLE_NUMBER_CAPABILITY(negative); - ENABLE_NUMBER_CAPABILITY(positive); - ENABLE_NUMBER_CAPABILITY(absolute); - ENABLE_NUMBER_CAPABILITY(nonzero); - ENABLE_NUMBER_CAPABILITY(invert); - ENABLE_NUMBER_CAPABILITY(lshift); - ENABLE_NUMBER_CAPABILITY(rshift); - ENABLE_NUMBER_CAPABILITY(and); - ENABLE_NUMBER_CAPABILITY(xor); - ENABLE_NUMBER_CAPABILITY(or); - ENABLE_NUMBER_CAPABILITY(coerce); - ENABLE_NUMBER_CAPABILITY(int); - ENABLE_NUMBER_CAPABILITY(long); - ENABLE_NUMBER_CAPABILITY(float); - ENABLE_NUMBER_CAPABILITY(oct); - ENABLE_NUMBER_CAPABILITY(hex); - default: - return false; - } -} - -#define ENABLE_BUFFER_CAPABILITY(field) \ - case type_object_base::buffer_##field: \ - create_method_table_if_null(dest); \ - dest->bf_##field = &do_instance_bf_##field; \ - detail::shared_pod_manager::replace_if_equal(dest); \ - return true - -bool add_capability_buffer(type_object_base::capability capability, PyBufferProcs*& dest) -{ - (void)dest; // suppress unused argument warning - (void)capability; // likwise -#if 0 - switch(capability) - { - // nothing defined yet - default: - return false; - } -#endif - return false; -} - -} // anonymous namespace - -namespace detail { - - void add_capability( - type_object_base::capability capability, - PyTypeObject* dest_) - { - if(add_capability_general(capability, dest_)) - return; - if(add_capability_richcompare(capability, dest_)) - return; - if(add_capability_inplace(capability, dest_)) - return; - if(add_capability_mapping(capability, dest_->tp_as_mapping)) - return; - if(add_capability_sequence(capability, dest_->tp_as_sequence)) - return; - if(add_capability_number(capability, dest_->tp_as_number)) - return; - if(add_capability_buffer(capability, dest_->tp_as_buffer)) - return; - - // no one recognized the capability - throw std::runtime_error("py::detail::add_capability(): unknown capability"); - } -} // namespace detail - -type_object_base::~type_object_base() -{ - detail::shared_pod_manager::dispose(tp_as_mapping); - detail::shared_pod_manager::dispose(tp_as_sequence); - detail::shared_pod_manager::dispose(tp_as_number); - detail::shared_pod_manager::dispose(tp_as_buffer); -} - -void type_object_base::enable(type_object_base::capability capability) -{ - detail::add_capability(capability, this); -} - -type_object_base::type_object_base(PyTypeObject* t) - : python_type(t) -{ - this->tp_dealloc = do_instance_dealloc; -} - -namespace -{ - typedef long pod_refcount; - - inline pod_refcount pod_refcount_offset(std::size_t size) - { - const std::size_t alignment = boost::alignment_of::value; - return (size + alignment - 1) / alignment * alignment; - } - - inline pod_refcount* counted_pod_refcount(char* pod, std::size_t size) - { - if(pod == 0) - return 0; - - return reinterpret_cast(pod + pod_refcount_offset(size)); - } - - #ifdef TYPE_OBJECT_BASE_STANDALONE_TEST - int pod_instance_counter = 0; - #endif - - inline pod_refcount counted_pod_getref(char* pod, std::size_t size) - { - pod_refcount* ref_count = counted_pod_refcount(pod, size); - return ref_count == 0 ? -1 : *ref_count; - } - - inline pod_refcount counted_pod_decref(char* pod, std::size_t size) - { - pod_refcount* const ref_count = counted_pod_refcount(pod, size); - if (ref_count == 0) - return -1; - --(*ref_count); - if (*ref_count <= 0) - { - #ifdef TYPE_OBJECT_BASE_STANDALONE_TEST - --pod_instance_counter; - #endif - ::operator delete(pod); - return 0; - } - return *ref_count; - } - - pod_refcount counted_pod_incref(char* pod, std::size_t size) - { - pod_refcount* ref_count = counted_pod_refcount(pod, size); - return ref_count == 0 ? -1 : ++(*ref_count); - } - -} // anonymous namespace - -namespace detail -{ - struct shared_pod_manager::compare - { - bool operator()(const std::pair& x1, - const std::pair& x2) const - { - const std::size_t n1 = x1.second; - const std::size_t n2 = x2.second; - return n1 < n2 || n1 == n2 && BOOST_CSTD_::memcmp(x1.first, x2.first, n1) < 0; - } - }; - - struct shared_pod_manager::identical - { - identical(char* p) : pod(p) {} - - bool operator()(const std::pair& x) const - { - return pod == x.first; - } - - char* pod; - }; - - shared_pod_manager& shared_pod_manager::obj() - { - static shared_pod_manager spm; - return spm; - } - - shared_pod_manager::~shared_pod_manager() - { - } - - void* shared_pod_manager::replace_if_equal(void* pod, std::size_t size) - { - if(pod == 0) - return 0; - - const holder element(static_cast(pod), size); - - const storage::iterator found - = std::lower_bound(m_storage.begin(), m_storage.end(), element, compare()); - - if (found != m_storage.end() && pod == found->first) - { - // pod already in list => do nothing - return pod; - } - else if (found != m_storage.end() && !compare()(element, *found)) - { - // equal element in list => replace - void* replacement = found->first; - counted_pod_incref(found->first, size); - dec_ref(element.first, size); // invalidates iterator 'found' - return replacement; - } - else - { - // new element => insert - m_storage.insert(found, element); - return pod; - } - } - - void* shared_pod_manager::make_unique_copy(void* pod, std::size_t size) - { - if(pod == 0) - return 0; - if(counted_pod_getref(static_cast(pod), size) == 1) - { - erase_from_list(pod); - return pod; - } - else - { - void* copy = create(size); - memmove(copy, pod, size); - dec_ref(pod, size); - return copy; - } - } - - void* shared_pod_manager::create(std::size_t size) - { - std::size_t total_size = pod_refcount_offset(size) + sizeof(pod_refcount); - char* pod = static_cast(::operator new(total_size)); - #ifdef TYPE_OBJECT_BASE_STANDALONE_TEST - ++pod_instance_counter; - #endif - memset(pod, 0, total_size); - - *counted_pod_refcount(pod, size) = 1; - - return pod; - } - - void shared_pod_manager::dec_ref(void* pod, std::size_t size) - { - if(pod == 0) - return; - - int ref_count = counted_pod_decref(static_cast(pod), size); - - if(ref_count <= 0) - erase_from_list(pod); - } - - void shared_pod_manager::erase_from_list(void* pod) - { - if(pod == 0) - return; - - const storage::iterator found = - std::find_if(m_storage.begin(), m_storage.end(), - identical(static_cast(pod))); - - if(found != m_storage.end()) - { - m_storage.erase(found); - } - } -} // namespace detail - -namespace { - struct error_type { - operator PyObject*() const { return 0; } - operator int() const { return -1; } - }; - - error_type unimplemented(const char* name) - { - assert(!"Control should never reach here"); - string s("Unimplemented "); - s += string(name); - PyErr_SetObject(PyExc_RuntimeError, s.get()); - return error_type(); - } -} - -PyObject* type_object_base::instance_repr(PyObject*) const -{ - return unimplemented("instance_repr"); -} - -int type_object_base::instance_compare(PyObject*, PyObject*) const -{ - return unimplemented("instance_compare"); -} - -PyObject* type_object_base::instance_str(PyObject*) const -{ - return unimplemented("instance_str"); -} - -long type_object_base::instance_hash(PyObject* /* obj */) const -{ - return unimplemented("instance_hash"); -} - -PyObject* type_object_base::instance_call(PyObject* /*obj*/, PyObject* /*args*/, PyObject* /*kw*/) const -{ - return unimplemented("instance_call"); -} - -PyObject* type_object_base::instance_getattr(PyObject* /*obj*/, const char* /*name*/) const -{ - return unimplemented("instance_getattr"); -} - -int type_object_base::instance_setattr(PyObject* /*obj*/, const char* /*name*/, PyObject* /*value*/) const -{ - return unimplemented("instance_setattr"); -} - -int type_object_base::instance_mapping_length(PyObject*) const -{ - return unimplemented("instance_mapping_length"); -} - -int type_object_base::instance_sequence_length(PyObject*) const -{ - return unimplemented("instance_sequence_length"); -} - -PyObject* type_object_base::instance_mapping_subscript(PyObject*, PyObject*) const -{ - return unimplemented("instance_mapping_subscript"); -} - -PyObject* type_object_base::instance_sequence_item(PyObject*, int) const -{ - return unimplemented("instance_sequence_item"); -} - -int type_object_base::instance_mapping_ass_subscript(PyObject*, PyObject*, PyObject*) const -{ - return unimplemented("instance_mapping_ass_subscript"); -} - -int type_object_base::instance_sequence_ass_item(PyObject*, int, PyObject*) const -{ - return unimplemented("instance_sequence_ass_item"); -} - -PyObject* type_object_base::instance_sequence_concat(PyObject*, PyObject*) const -{ - return unimplemented("instance_sequence_concat"); -} - -PyObject* type_object_base::instance_sequence_repeat(PyObject*, int) const -{ - return unimplemented("instance_sequence_repeat"); -} - -PyObject* type_object_base::instance_sequence_slice(PyObject*, int, int) const -{ - return unimplemented("instance_sequence_slice"); -} - -int type_object_base::instance_sequence_ass_slice(PyObject*, int, int, PyObject*) const -{ - return unimplemented("instance_sequence_ass_slice"); -} - -PyObject* type_object_base::instance_number_add(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_add"); -} - -PyObject* type_object_base::instance_number_subtract(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_subtract"); -} - -PyObject* type_object_base::instance_number_multiply(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_multiply"); -} - -PyObject* type_object_base::instance_number_divide(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_divide"); -} - -PyObject* type_object_base::instance_number_remainder(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_remainder"); -} - -PyObject* type_object_base::instance_number_divmod(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_divmod"); -} - -PyObject* type_object_base::instance_number_power(PyObject*, PyObject*, PyObject*) const -{ - return unimplemented("instance_number_power"); -} - -PyObject* type_object_base::instance_number_negative(PyObject*) const -{ - return unimplemented("instance_number_negative"); -} - -PyObject* type_object_base::instance_number_positive(PyObject*) const -{ - return unimplemented("instance_number_positive"); -} - -PyObject* type_object_base::instance_number_absolute(PyObject*) const -{ - return unimplemented("instance_number_absolute"); -} - -int type_object_base::instance_number_nonzero(PyObject*) const -{ - return unimplemented("instance_number_nonzero"); -} - -PyObject* type_object_base::instance_number_invert(PyObject*) const -{ - return unimplemented("instance_number_invert"); -} - -PyObject* type_object_base::instance_number_lshift(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_lshift"); -} - -PyObject* type_object_base::instance_number_rshift(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_rshift"); -} - -PyObject* type_object_base::instance_number_and(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_and"); -} - -PyObject* type_object_base::instance_number_xor(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_xor"); -} - -PyObject* type_object_base::instance_number_or(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_or"); -} - -int type_object_base::instance_number_coerce(PyObject*, PyObject**, PyObject**) const -{ - return unimplemented("instance_number_coerce"); -} - -PyObject* type_object_base::instance_number_int(PyObject*) const -{ - return unimplemented("instance_number_int"); -} - -PyObject* type_object_base::instance_number_long(PyObject*) const -{ - return unimplemented("instance_number_long"); -} - -PyObject* type_object_base::instance_number_float(PyObject*) const -{ - return unimplemented("instance_number_float"); -} - -PyObject* type_object_base::instance_number_oct(PyObject*) const -{ - return unimplemented("instance_number_oct"); -} - -PyObject* type_object_base::instance_number_hex(PyObject*) const -{ - return unimplemented("instance_number_hex"); -} - -PyObject* type_object_base::instance_number_inplace_add(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_add"); -} - -PyObject* type_object_base::instance_number_inplace_subtract(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_subtract"); -} - -PyObject* type_object_base::instance_number_inplace_multiply(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_multiply"); -} - -PyObject* type_object_base::instance_number_inplace_divide(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_divide"); -} - -PyObject* type_object_base::instance_number_inplace_remainder(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_remainder"); -} - -PyObject* type_object_base::instance_number_inplace_power(PyObject*, PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_power"); -} - -PyObject* type_object_base::instance_number_inplace_lshift(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_lshift"); -} - -PyObject* type_object_base::instance_number_inplace_rshift(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_rshift"); -} - -PyObject* type_object_base::instance_number_inplace_and(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_and"); -} - -PyObject* type_object_base::instance_number_inplace_or(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_or"); -} - -PyObject* type_object_base::instance_number_inplace_xor(PyObject*, PyObject*) const -{ - return unimplemented("instance_number_inplace_xor"); -} - -PyObject* type_object_base::instance_lt(PyObject*, PyObject*) const -{ - return unimplemented("instance_lt"); -} - -PyObject* type_object_base::instance_le(PyObject*, PyObject*) const -{ - return unimplemented("instance_le"); -} - -PyObject* type_object_base::instance_eq(PyObject*, PyObject*) const -{ - return unimplemented("instance_eq"); -} - -PyObject* type_object_base::instance_ne(PyObject*, PyObject*) const -{ - return unimplemented("instance_ne"); -} - -PyObject* type_object_base::instance_gt(PyObject*, PyObject*) const -{ - return unimplemented("instance_gt"); -} - -PyObject* type_object_base::instance_ge(PyObject*, PyObject*) const -{ - return unimplemented("instance_ge"); -} - -}} // namespace boost::python - -#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST - -struct TestTypeObject : boost::python::type_object_base -{ - TestTypeObject() - : boost::python::type_object_base(Py_None->ob_type->ob_type) - {} - - void instance_dealloc(PyObject*) const {} -}; - -struct POD1 -{ - unsigned char data; -}; - -int main() -{ - boost::python::type_object_base *o1, *o2, *o3; - -// POD1 * pod1; -// boost::python::detail::shared_pod_manager::create(pod1); - - o1 = new TestTypeObject; - o2 = new TestTypeObject; - o3 = new TestTypeObject; - - assert(boost::python::pod_instance_counter == 0); - - o1->enable(boost::python::type_object_base::number_add); - o1->enable(boost::python::type_object_base::compare); - - o2->enable(boost::python::type_object_base::number_add); - o2->enable(boost::python::type_object_base::mapping_length); - - o3->enable(boost::python::type_object_base::number_add); - o3->enable(boost::python::type_object_base::sequence_length); - - assert(boost::python::pod_instance_counter == 3); - assert(o1->tp_as_number && !o1->tp_as_mapping && !o1->tp_as_sequence); - assert(o2->tp_as_number && o2->tp_as_mapping && !o2->tp_as_sequence); - assert(o3->tp_as_number && !o3->tp_as_mapping && o3->tp_as_sequence); - assert(o1->tp_as_number == o2->tp_as_number); - assert(o1->tp_as_number == o3->tp_as_number); - assert((void*)o2->tp_as_number != o2->tp_as_mapping); - assert((void*)o2->tp_as_mapping != o3->tp_as_sequence); - - o1->enable(boost::python::type_object_base::number_subtract); - - assert(boost::python::pod_instance_counter == 4); - assert(o1->tp_as_number != o2->tp_as_number); - assert(o2->tp_as_number == o3->tp_as_number); - - o3->enable(boost::python::type_object_base::mapping_subscript); - - assert(boost::python::pod_instance_counter == 5); - assert(o3->tp_as_number && o3->tp_as_mapping && o3->tp_as_sequence); - assert(o2->tp_as_mapping != o3->tp_as_mapping); - - o2->enable(boost::python::type_object_base::mapping_subscript); - o3->enable(boost::python::type_object_base::mapping_length); - - assert(boost::python::pod_instance_counter == 4); - assert(o2->tp_as_number && o2->tp_as_mapping && !o2->tp_as_sequence); - assert(o3->tp_as_number && o3->tp_as_mapping && o3->tp_as_sequence); - assert(o2->tp_as_mapping == o3->tp_as_mapping); - - boost::python::type_object_base *o4 = new TestTypeObject; - - assert(boost::python::pod_instance_counter == 4); - - o4->enable(boost::python::type_object_base::number_add); - - assert(boost::python::pod_instance_counter == 4); - assert(o4->tp_as_number && !o4->tp_as_mapping && !o4->tp_as_sequence); - assert(o4->tp_as_number == o3->tp_as_number); - - delete o3; - - assert(boost::python::pod_instance_counter == 3); - assert(o1->tp_as_number && !o1->tp_as_mapping && !o1->tp_as_sequence); - assert(o2->tp_as_number && o2->tp_as_mapping && !o2->tp_as_sequence); - assert(o4->tp_as_number && !o4->tp_as_mapping && !o4->tp_as_sequence); - assert(o4->tp_as_number == o2->tp_as_number); - - o3 = new TestTypeObject; - - assert(boost::python::pod_instance_counter == 3); - - o3->enable(boost::python::type_object_base::number_add); - o3->enable(boost::python::type_object_base::sequence_length); - - assert(boost::python::pod_instance_counter == 4); - assert(o3->tp_as_number && !o3->tp_as_mapping && o3->tp_as_sequence); - assert(o1->tp_as_number != o3->tp_as_number); - assert(o2->tp_as_number == o3->tp_as_number); - - delete o1; - - assert(boost::python::pod_instance_counter == 3); - - delete o4; - - assert(boost::python::pod_instance_counter == 3); - - delete o3; - - assert(boost::python::pod_instance_counter == 2); - - delete o2; - - assert(boost::python::pod_instance_counter == 0); - - assert(boost::python::detail::shared_pod_manager::obj().m_storage.size() == 0); -} - -#endif diff --git a/test/Jamfile b/test/Jamfile index 6e305b42..de63e575 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -1,3 +1,7 @@ +# +# To run all tests quietly: jam test +# To run all tests with verbose output: jam -sPYTHON_TEST_ARGS=-v test +# subproject libs/python/test ; # bring in the rules for python @@ -7,9 +11,6 @@ include python.jam ; SEARCH on testing.jam = $(BOOST_BUILD_PATH) ; include testing.jam ; -local PYTHON_V1_PROPERTIES = $(PYTHON_PROPERTIES) ; -local PYTHON_PROPERTIES = $(BOOST_PYTHON_V2_PROPERTIES) ; - # Convenience rule makes declaring tests faster rule bpl-test ( name ? : files * : requirements * ) { @@ -46,7 +47,7 @@ rule bpl-test ( name ? : files * : requirements * ) m = $(m)_ext ; } } - extension $(m) : $(f) ../bpl : $(requirements) ; + extension $(m) : $(f) ../build/boost_python : $(requirements) ; modules += $(m) ; } } From 33f139e5163013cf9723f2ed3b516228900e4eab Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 5 Oct 2002 16:45:37 +0000 Subject: [PATCH 0825/1042] Patches for CWPro8.3 [SVN r15735] --- include/boost/python/object_core.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/object_core.hpp b/include/boost/python/object_core.hpp index 2ee532a8..4727edba 100755 --- a/include/boost/python/object_core.hpp +++ b/include/boost/python/object_core.hpp @@ -180,7 +180,7 @@ namespace api // there is a confirmed CWPro8 codegen bug here. We prevent the // early destruction of a temporary by binding a named object // instead. -# if __MWERKS__ < 0x3000 || __MWERKS__ > 0x3002 +# if __MWERKS__ < 0x3000 || __MWERKS__ > 0x3003 typedef object const& object_cref2; # else typedef object const object_cref2; From 86489dd5a7751440756172c67389b338df9c57cd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 5 Oct 2002 17:29:32 +0000 Subject: [PATCH 0826/1042] Make AIX work again [SVN r15737] --- build/Jamfile | 5 ++++- src/aix_init_module.cpp | 16 +++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index 97d8222e..eb092146 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -20,7 +20,10 @@ if [ check-python-config ] if $(UNIX) && ( $(OS) = AIX ) { - bpl-linkflags = "-e initlibbpl" ; + bpl-linkflags = "-e initlibboost_python" + "-e initlibboost_python_debug + "-e initlibboost_python_pydebug" + ; } dll boost_python diff --git a/src/aix_init_module.cpp b/src/aix_init_module.cpp index 2345aa4f..93c710ec 100644 --- a/src/aix_init_module.cpp +++ b/src/aix_init_module.cpp @@ -23,10 +23,20 @@ namespace boost { namespace python { namespace detail { namespace { - extern "C" void initlibbpl() + static PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; + extern "C" void initlibboost_python() { - static PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; - Py_InitModule("libbpl", initial_methods); + Py_InitModule("libbboost_python", initial_methods); + } + + extern "C" void initlibboost_python_debug() + { + Py_InitModule("libbboost_python_debug", initial_methods); + } + + extern "C" void initlibboost_python_pydebug() + { + Py_InitModule("libbboost_python_pydebug", initial_methods); } struct find_and_open_file From 6f76db9c6c0e8fd9c631d7ce10c10427e1804bdb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 5 Oct 2002 17:42:34 +0000 Subject: [PATCH 0827/1042] quick bug fix [SVN r15738] --- build/Jamfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Jamfile b/build/Jamfile index eb092146..b7f197b6 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -21,7 +21,7 @@ if [ check-python-config ] if $(UNIX) && ( $(OS) = AIX ) { bpl-linkflags = "-e initlibboost_python" - "-e initlibboost_python_debug + "-e initlibboost_python_debug" "-e initlibboost_python_pydebug" ; } From 7e840acd19600dca0efb7e424769bc057503b02d Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 5 Oct 2002 19:31:43 +0000 Subject: [PATCH 0828/1042] Repair AIX build [SVN r15740] --- build/Jamfile | 5 +---- src/aix_init_module.cpp | 18 ++++-------------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index b7f197b6..b5f45314 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -20,10 +20,7 @@ if [ check-python-config ] if $(UNIX) && ( $(OS) = AIX ) { - bpl-linkflags = "-e initlibboost_python" - "-e initlibboost_python_debug" - "-e initlibboost_python_pydebug" - ; + bpl-linkflags = "-e initlibboost_python" ; } dll boost_python diff --git a/src/aix_init_module.cpp b/src/aix_init_module.cpp index 93c710ec..3eb9f097 100644 --- a/src/aix_init_module.cpp +++ b/src/aix_init_module.cpp @@ -26,17 +26,7 @@ namespace static PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; extern "C" void initlibboost_python() { - Py_InitModule("libbboost_python", initial_methods); - } - - extern "C" void initlibboost_python_debug() - { - Py_InitModule("libbboost_python_debug", initial_methods); - } - - extern "C" void initlibboost_python_pydebug() - { - Py_InitModule("libbboost_python_pydebug", initial_methods); + Py_InitModule("libboost_python", initial_methods); } struct find_and_open_file @@ -115,7 +105,7 @@ void aix_init_module( static bool initialized; if (!initialized) { - char const* const name = "libbpl.so"; + char const* const name = "libboost_python.so"; find_and_open_file dynlib("LIBPATH", name); if (dynlib.fp == 0) { @@ -123,8 +113,8 @@ void aix_init_module( return; } - std::string::size_type pos = pos = dynlib.filename.find_first_of(".so",0); - if (pos == std::string::npos) + std::string::size_type pos = pos = dynlib.filename.rfind(".so"); + if (pos != dynlib.filename.size() - 3) { fprintf(stderr, "dynamic library %s must end with .so\n", dynlib.filename.c_str()); return; From e9757c46e3b90a21a3b7f383abf9028f595aa9b3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 5 Oct 2002 19:46:26 +0000 Subject: [PATCH 0829/1042] *** empty log message *** [SVN r15741] --- include/boost/python/init.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 9991268e..882ce756 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -1,10 +1,10 @@ /////////////////////////////////////////////////////////////////////////////// // -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. +// Copyright David Abrahams 2002, Joel de Guzman, 2002. Permission to copy, +// use, modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided "as is" +// without express or implied warranty, and with no claim as to its +// suitability for any purpose. // /////////////////////////////////////////////////////////////////////////////// #ifndef INIT_JDG20020820_HPP From ca6c28ed934bbf96ae6713671b7d6d8e19227540 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 7 Oct 2002 13:42:55 +0000 Subject: [PATCH 0830/1042] merge Joel's copyrights [SVN r15772] --- include/boost/python/detail/defaults_def.hpp | 10 +++++----- include/boost/python/detail/defaults_gen.hpp | 10 +++++----- include/boost/python/signature.hpp | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index 7062283e..db807a08 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -1,10 +1,10 @@ /////////////////////////////////////////////////////////////////////////////// // -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. +// Copyright David Abrahams 2002, Joel de Guzman, 2002. Permission to copy, +// use, modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided "as is" +// without express or implied warranty, and with no claim as to its +// suitability for any purpose. // /////////////////////////////////////////////////////////////////////////////// #if !defined(BOOST_PP_IS_ITERATING) diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index be41c716..4c4bf217 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -1,10 +1,10 @@ /////////////////////////////////////////////////////////////////////////////// // -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. +// Copyright David Abrahams 2002, Joel de Guzman, 2002. Permission to copy, +// use, modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided "as is" +// without express or implied warranty, and with no claim as to its +// suitability for any purpose. // /////////////////////////////////////////////////////////////////////////////// #ifndef DEFAULTS_GEN_JDG20020807_HPP diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index be93ea4a..e4545ea8 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -1,10 +1,10 @@ /////////////////////////////////////////////////////////////////////////////// // -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. +// Copyright David Abrahams 2002, Joel de Guzman, 2002. Permission to copy, +// use, modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided "as is" +// without express or implied warranty, and with no claim as to its +// suitability for any purpose. // /////////////////////////////////////////////////////////////////////////////// #if !defined(BOOST_PP_IS_ITERATING) From 920125794ad1bc0c4e4ea2e98661049e296799a0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 7 Oct 2002 19:23:08 +0000 Subject: [PATCH 0831/1042] Workaround GCC 3.x problem [SVN r15790] --- include/boost/python/init.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 882ce756..94d2dd31 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -270,13 +270,13 @@ class init : public init_base > typedef typename mpl::fold< required_args , mpl::list0<> - , mpl::push_front<> + , mpl::push_front >::type reversed_required; typedef typename mpl::fold< optional_args , reversed_required - , mpl::push_front<> + , mpl::push_front >::type reversed_args; // Count the maximum number of arguments @@ -310,7 +310,7 @@ namespace detail typedef typename mpl::fold< ReversedArgs , mpl::list0<> - , mpl::push_front<> + , mpl::push_front >::type args; typedef typename ClassT::holder_selector holder_selector_t; From 4fd20185e986bcb6c2b4bd7c0e85852b6ca36364 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 9 Oct 2002 02:52:47 +0000 Subject: [PATCH 0832/1042] Clean up Boost.Python v1 flotsam, update documentation [SVN r15815] --- doc/building.html | 434 ++++--- doc/comparisons.html | 231 ---- doc/cross_module.html | 336 ----- doc/data_structures.txt | 192 --- doc/enums.html | 120 -- doc/example1.html | 75 -- doc/exporting_classes.html | 143 --- doc/extending.html | 73 -- doc/index.html | 233 +--- doc/inheritance.html | 166 --- doc/overloading.html | 155 --- doc/overriding.html | 208 --- doc/pickle.html | 272 ---- doc/pointers.html | 148 --- doc/richcmp.html | 106 -- doc/special.html | 973 -------------- doc/under-the-hood.html | 61 - doc/v2/acknowledgments.html | 111 +- doc/v2/callbacks.html | 385 +++--- doc/v2/def.html | 1 + doc/v2/faq.html | 4 +- doc/v2/index.html | 56 +- doc/v2/python.html | 108 ++ doc/v2/reference.html | 94 +- doc/v2/scope.html | 13 +- example/Attic/project.zip | Bin 0 -> 1469 bytes example/project.zip | Bin 0 -> 1469 bytes include/boost/python.hpp | 62 + include/boost/python/detail/module_init.hpp | 53 - include/boost/python/errors.hpp | 2 - include/boost/python/init.hpp | 6 +- include/boost/python/operators.hpp | 851 +++++------- include/boost/python/operators2.hpp | 340 ----- src/converter/registry.cpp | 2 +- src/errors.cpp | 8 +- test/Jamfile | 3 +- test/comprehensive.cpp | 1265 ------------------ test/comprehensive.hpp | 235 ---- test/comprehensive.py | 1281 ------------------- 39 files changed, 1180 insertions(+), 7626 deletions(-) delete mode 100644 doc/comparisons.html delete mode 100644 doc/cross_module.html delete mode 100644 doc/data_structures.txt delete mode 100644 doc/enums.html delete mode 100644 doc/example1.html delete mode 100644 doc/exporting_classes.html delete mode 100644 doc/extending.html delete mode 100644 doc/inheritance.html delete mode 100644 doc/overloading.html delete mode 100644 doc/overriding.html delete mode 100644 doc/pickle.html delete mode 100644 doc/pointers.html delete mode 100644 doc/richcmp.html delete mode 100644 doc/special.html delete mode 100644 doc/under-the-hood.html create mode 100644 doc/v2/python.html create mode 100644 example/Attic/project.zip create mode 100644 example/project.zip create mode 100644 include/boost/python.hpp delete mode 100644 include/boost/python/detail/module_init.hpp delete mode 100755 include/boost/python/operators2.hpp delete mode 100644 test/comprehensive.cpp delete mode 100644 test/comprehensive.hpp delete mode 100644 test/comprehensive.py diff --git a/doc/building.html b/doc/building.html index cdca6b97..d76a708c 100644 --- a/doc/building.html +++ b/doc/building.html @@ -1,222 +1,294 @@ - + + + + + - Building an Extension Module + Boost.Python - Building and Testing + -
      -

      c++boost.gif (8819 bytes)Building an - Extension Module

      + + + + -

      Building Boost.Python

      + + +
      +

      +

      +
      +

      Boost.Python

      -

      Every Boost.Python extension module must be linked with the - boost_python shared library. To build - boost_python, use Boost.Build in the - usual way from the libs/python/build subdirectory - of your boost installation (if you have already built boost from - the top level this may have no effect, since the work is already - done). +

      Building and Testing

      +
      +
      -

      Configuration

      - You may need to configure the following variables to point Boost.Build at your Python installation: +

      Contents

      + +
      +
      Requirements
      + +
      Building Boost.Python
      + +
      +
      +
      Configuration
      + +
      Results
      + +
      Testing
      +
      +
      + +
      Building your Extension Module
      + +
      Build Variants
      +
      +
      + +

      Requirements

      + Boost.Python requires Python 2.2 or + later. + +

      Building Boost.Python

      + +

      Every Boost.Python extension module must be linked with the + boost_python shared library. To build + boost_python, use Boost.Build in the usual way from + the libs/python/build subdirectory of your boost + installation (if you have already built boost from the top level this may + have no effect, since the work is already done).

      + +

      Configuration

      + You may need to configure the following variables to point Boost.Build at + your Python installation: + + + + + + + + + + + + + + + + -
      Variable NameSemanticsDefaultNotes
      PYTHON_ROOTThe root directory of your Python installation
      - - + + + + + + + + + + - - + - - + - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - + - - + -
      Variable Name Semantics Default Notes -
      PYTHON_ROOT - The root directory of your Python installation Windows: c:/tools/python - Unix: /usr/local - On Unix, this is the --with-prefix= directory - used to configure Python + Unix: /usr/localOn Unix, this is the --with-prefix= directory used + to configure Python
      PYTHON_VERSIONThe The 2-part python Major.Minor version number2.2
      PYTHON_VERSION - The The 2-part python Major.Minor version number - Windows: 2.1 - Unix: 1.5 Be sure not to include a third number, e.g. not - "2.2.1", even if that's the version you - have. + "2.2.1", even if that's the version you have.
      PYTHON_INCLUDES - path to Python #include directories - Autoconfigured from PYTHON_ROOT +
      PYTHON_INCLUDES
      PYTHON_LIB_PATH - path to Python library object. - Autoconfigured from PYTHON_ROOT + path to Python #include directories
      PYTHON_STDLIB_PATH - path to Python standard library modules - Autoconfigured from PYTHON_ROOT + Autoconfigured from PYTHON_ROOT
      PYTHON_LIB_PATHpath to Python library object.Autoconfigured from PYTHON_ROOT
      PYTHON_STDLIB_PATHpath to Python standard library modulesAutoconfigured from PYTHON_ROOT
      CYGWIN_ROOTpath to the user's Cygwin installation
      CYGWIN_ROOT - path to the user's Cygwin installation - Cygwin only. This and the following two settings are - useful when building with multiple toolsets on Windows, since - Cygwin requires a different build of Python. +
      GCC_PYTHON_ROOT - path to the user's Cygwin Python installation - $(CYGWIN_ROOT)/usr/local - Cygwin only + Cygwin only. This and the + following two settings are useful when building with multiple + toolsets on Windows, since Cygwin requires a different build of + Python.
      GCC_DEBUG_PYTHON_ROOT - path to the user's Cygwin pydebug build - $(CYGWIN_ROOT)/usr/local/pydebug - Cygwin only +
      GCC_PYTHON_ROOT
      + path to the user's Cygwin Python installation -

      Results

      -

      The build process will create a - libs/python/build/bin-stage subdirectory of the - boost root (or of $(ALL_LOCATE_TARGET), - if you have set that variable), containing the built - libraries. The libraries are actually built to unique - directories for each toolset and variant elsewhere in the - filesystem, and copied to the - bin-stage directory as a convenience, so if you - build with multiple toolsets at once, the product of later - toolsets will overwrite that of earlier toolsets in - bin-stage. + $(CYGWIN_ROOT)/usr/local -

      Testing

      -

      To build and test Boost.Python from within the - libs/python/build directory, invoke -

      + Cygwin only + + + + GCC_DEBUG_PYTHON_ROOT + + path to the user's Cygwin pydebug build + + $(CYGWIN_ROOT)/usr/local/pydebug + + Cygwin only + + + +

      Results

      + +

      The build process will create a + libs/python/build/bin-stage subdirectory of the boost root + (or of $(ALL_LOCATE_TARGET), if you have set that variable), + containing the built libraries. The libraries are actually built to + unique directories for each toolset and variant elsewhere in the + filesystem, and copied to the bin-stage directory as a + convenience, so if you build with multiple toolsets at once, the product + of later toolsets will overwrite that of earlier toolsets in + bin-stage.

      + +

      Testing

      + +

      To build and test Boost.Python, start from the + libs/python/test directory and invoke

      + +
      -bjam -sTOOLS=toolset test
      +bjam -sTOOLS=toolset test
       
      -
      -This will -update all of the Boost.Python v1 test and example targets. The tests -are relatively quiet by default. To get more-verbose output, you might try -
      +
      + This will update all of the Boost.Python v1 test and example targets. The + tests are relatively quiet by default. To get more-verbose output, you + might try + +
      -bjam -sTOOLS=toolset -sPYTHON_TEST_ARGS=-v test
      +bjam -sTOOLS=toolset -sPYTHON_TEST_ARGS=-v test
       
      -
      -which will print each test's Python code with the expected output as -it passes. +
      + which will print each test's Python code with the expected output as it + passes. -

      Building your Extension Module

      +

      Building your Extension Module

      + Though there are other approaches, the easiest way to build an extension + module using Boost.Python is with Boost.Build. Until Boost.Build v2 is + released, cross-project build dependencies are not supported, so it works + most smoothly if you add a new subproject to your boost installation. The + libs/python/example subdirectory of your boost installation + contains a minimal example (along with many extra sources). To copy the + example subproject: - Though there are other approaches, the easiest way to build an - extension module using Boost.Python is with Boost.Build. Until - Boost.Build v2 is released, cross-project build dependencies are - not supported, so it works most smoothly if you add a new - subproject to your boost installation. The - libs/python/example subdirectory of your boost - installation contains a minimal example (along with many extra - sources). To copy the example subproject: - -
        +
        1. Create a new subdirectory in, libs/python, say - libs/python/my_project. + libs/python/my_project.
        2. -
        3. Copy libs/python/example/Jamfile - to your new directory. +
        4. Copy libs/python/example/Jamfile to your new + directory.
        5. -
        6. Edit the Jamfile as appropriate for your project. You'll - want to change the "subproject" rule - invocation at the top, and the names of some of the source files - and/or targets. +
        7. Edit the Jamfile as appropriate for your project. You'll want to + change the "subproject" rule invocation at the top, and + the names of some of the source files and/or targets.
        8. +
        + If you can't modify or copy your boost installation, the alternative is + to create your own Boost.Build project. A similar example you can use as + a starting point is available in this archive. You'll need to edit the + Jamfile and Jamrules files, depending on the relative location of your + Boost installation and the new project. Note that automatic testing of + extension modules is not available in this configuration. -
      +

      Build Variants

      + Three variant + configurations of all python-related targets are supported, and can be + selected by setting the BUILD + variable: - If you can't modify or copy your boost installation, the - alternative is to create your own Boost.Build project. A similar - example you can use as a starting point is available in this archive. You'll - need to edit the Jamfile and Jamrules files, depending on the - relative location of your Boost installation and the new - project. Note that automatic testing of extension modules is not - available in this configuration. +
        +
      • release (optimization, -DNDEBUG)
      • -

        Build Variants

        +
      • debug (no optimization -D_DEBUG)
      • - Three variant - configurations of all python-related targets are supported, and - can be selected by setting the BUILD - variable: +
      • debug-python (no optimization, -D_DEBUG + -DBOOST_DEBUG_PYTHON)
      • +
      -
        -
      • release (optimization, -DNDEBUG) +

        The first two variants of the boost_python library are + built by default, and are compatible with the default Python + distribution. The debug-python variant corresponds to a + specially-built debugging version of Python. On Unix platforms, this + python is built by adding --with-pydebug when configuring + the Python build. On Windows, the debugging version of Python is + generated by the "Win32 Debug" target of the PCBuild.dsw + Visual C++ 6.0 project in the PCBuild subdirectory of your + Python distribution. Extension modules built with Python debugging + enabled are not link-compatible with a non-debug build of Python. + Since few people actually have a debug build of Python (it doesn't come + with the standard distribution), the normal debug variant + builds modules which are compatible with ordinary Python.

        -
      • debug (no optimization -D_DEBUG) +

        On many windows compilers, when extension modules are built with + -D_DEBUG, Python defaults to force linking with a special + debugging version of the Python DLL. Since this debug DLL isn't supplied + with the default Python installation for Windows, Boost.Python uses + boost/python/detail/wrap_python.hpp + to temporarily undefine _DEBUG when Python.h is + #included - unless BOOST_DEBUG_PYTHON is + defined.

        -
      • debug-python (no optimization, -D_DEBUG - -DBOOST_DEBUG_PYTHON) -
      +

      If you want the extra runtime checks available with the debugging + version of the library, #define BOOST_DEBUG_PYTHON to re-enable + python debuggin, and link with the debug-python variant of + boost_python.

      -

      The first two variants of the boost_python - library are built by default, and are compatible with the - default Python distribution. The debug-python - variant corresponds to a specially-built debugging version of - Python. On Unix platforms, this python is built by adding - --with-pydebug when configuring the Python - build. On Windows, the debugging version of Python is generated - by the "Win32 Debug" target of the - PCBuild.dsw Visual C++ 6.0 project in the - PCBuild subdirectory of your Python distribution. +

      If you do not #define BOOST_DEBUG_PYTHON, be sure that any + source files in your extension module #include <boost/python/detail/wrap_python.hpp> + instead of the usual Python.h, or you will have link + incompatibilities.
      +

      +
      - Extension modules built with Python debugging enabled are not - link-compatible with a non-debug build of Python. Since few - people actually have a debug build of Python (it doesn't come - with the standard distribution), the normal - debug variant builds modules which are compatible - with ordinary Python. +

      © Copyright David Abrahams 2002. Permission to copy, use, modify, + sell and distribute this document is granted provided this copyright + notice appears in all copies. This document is provided ``as is'' without + express or implied warranty, and with no claim as to its suitability for + any purpose.

      +

      Updated: O8 October, 2002 (David Abrahams)

      + + -

      On many windows compilers, when extension modules are built - with - -D_DEBUG, Python defaults to force linking with a - special debugging version of the Python DLL. Since this debug DLL - isn't supplied with the default Python installation for Windows, - Boost.Python uses boost/python/detail/wrap_python.hpp - to temporarily undefine _DEBUG when Python.h is - #included - unless BOOST_DEBUG_PYTHON is defined. - -

      If you want the extra runtime checks available with the - debugging version of the library, #define - BOOST_DEBUG_PYTHON to re-enable python debuggin, and link - with the debug-python variant of - boost_python. - -

      If you do not #define BOOST_DEBUG_PYTHON, be sure that - any source files in your extension module #include <boost/python/detail/wrap_python.hpp> - instead of the usual Python.h, or you will have link - incompatibilities.
      - -


      - Next: Wrapping Enums Previous: A Peek Under the Hood Up: Top - -
      -

      © Copyright David Abrahams 2002. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as is'' without - express or implied warranty, and with no claim as to its suitability for - any purpose. - -

      Updated: May 15, 2002 (David Abrahams) -

      diff --git a/doc/comparisons.html b/doc/comparisons.html deleted file mode 100644 index 57cec744..00000000 --- a/doc/comparisons.html +++ /dev/null @@ -1,231 +0,0 @@ - - - Comparisons with Other Systems - -
      -

      - c++boost.gif (8819 bytes)
      - Comparisons with - Other Systems -

      - -

      CXX

      -

      - Like Boost.Python, CXX attempts to - provide a C++-oriented interface to Python. In most cases, as with the - boost library, it relieves the user from worrying about - reference-counts. Both libraries automatically convert thrown C++ - exceptions into Python exceptions. As far as I can tell, CXX has no - support for subclassing C++ extension types in Python. An even - more significant difference is that a user's C++ code is still basically - ``dealing with Python objects'', though they are wrapped in - C++ classes. This means such jobs as argument parsing and conversion are - still left to be done explicitly by the user. - -

      - CXX claims to interoperate well with the C++ Standard Library - (a.k.a. STL) by providing iterators into Python Lists and Dictionaries, - but the claim is unfortunately unsupportable. The problem is that in - general, access to Python sequence and mapping elements through - iterators requires the use of proxy objects as the return value of - iterator dereference operations. This usage conflicts with the basic - ForwardIterator requirements in - section 24.1.3 of the standard (dereferencing must produce a - reference). Although you may be able to use these iterators with some - operations in some standard library implementations, it is neither - guaranteed to work nor portable. - -

      - As far as I can tell, CXX enables one to write what is essentially - idiomatic Python code in C++, manipulating Python objects through the - same fully-generic interfaces we use in Python. While you're hardly - programming directly to the ``bare metal'' with CXX, it basically - presents a ``C++-ized'' version of the Python 'C' API. Some fraction of - that capability is available in Boost.Python through boost/python/objects.hpp, - which provides C++ objects corresponding to Python lists, tuples, - strings, and dictionaries, and through boost/python/callback.hpp, - which allows you to call back into python with C++ arguments. - -

      - Paul F. Dubois, the original - author of CXX, has told me that what I've described is only half of the - picture with CXX, but I never understood his explanation well-enough to - fill in the other half. Here is his response to the commentary above: - -

      -``My intention with CXX was not to do what you are doing. It was to enable a -person to write an extension directly in C++ rather than C. I figured others had -the wrapping business covered. I thought maybe CXX would provide an easier -target language for those making wrappers, but I never explored -that.''
      -Paul Dubois -
      - -

      SWIG

      -

      - SWIG is an impressively mature tool - for exporting an existing ANSI 'C' interface into various scripting - languages. Swig relies on a parser to read your source code and produce - additional source code files which can be compiled into a Python (or - Perl or Tcl) extension module. It has been successfully used to create - many Python extension modules. Like Boost.Python, SWIG is trying to allow an - existing interface to be wrapped with little or no change to the - existing code. The documentation says ``SWIG parses a form of ANSI C - syntax that has been extended with a number of special directives. As a - result, interfaces are usually built by grabbing a header file and - tweaking it a little bit.'' For C++ interfaces, the tweaking has often - proven to amount to more than just a little bit. One user - writes: - -

      ``The problem with swig (when I used it) is that it - couldnt handle templates, didnt do func overloading properly etc. For - ANSI C libraries this was fine. But for usual C++ code this was a - problem. Simple things work. But for anything very complicated (or - realistic), one had to write code by hand. I believe Boost.Python doesn't have - this problem[sic]... IMHO overloaded functions are very important to - wrap correctly.''
      -Prabhu Ramachandran -
      - -

      - By contrast, Boost.Python doesn't attempt to parse C++ - the problem is simply - too complex to do correctly. Technically, one does - write code by hand to use Boost.Python. The goal, however, has been to make - that code nearly as simple as listing the names of the classes and - member functions you want to expose in Python. - -

      SIP

      -

      - SIP - is a system similar to SWIG, though seemingly more - C++-oriented. The author says that like Boost.Python, SIP supports overriding - extension class member functions in Python subclasses. It appears to - have been designed specifically to directly support some features of - PyQt/PyKDE, which is its primary client. Documentation is almost - entirely missing at the time of this writing, so a detailed comparison - is difficult. - -

      ILU

      -

      - ILU - is a very ambitious project which tries to describe a module's interface - (types and functions) in terms of an Interface - Specification Language (ISL) so that it can be uniformly interfaced - to a wide range of computer languages, including Common Lisp, C++, C, - Modula-3, and Python. ILU can parse the ISL to generate a C++ language - header file describing the interface, of which the user is expected to - provide an implementation. Unlike Boost.Python, this means that the system - imposes implementation details on your C++ code at the deepest level. It - is worth noting that some of the C++ names generated by ILU are supposed - to be reserved to the C++ implementation. It is unclear from the - documentation whether ILU supports overriding C++ virtual functions in Python. - -

      GRAD

      -

      - GRAD - is another very ambitious project aimed at generating Python wrappers for - interfaces written in ``legacy languages'', among which C++ is the first one - implemented. Like SWIG, it aims to parse source code and automatically - generate wrappers, though it appears to take a more sophisticated approach - to parsing in general and C++ in particular, so it should do a much better - job with C++. It appears to support function overloading. The - documentation is missing a lot of information I'd like to see, so it is - difficult to give an accurate and fair assessment. I am left with the - following questions: -

        -
      • Does it support overriding of virtual functions? -
      • What about overriding private or protected virtual functions (the documentation indicates -that only public interfaces are supported)? -
      • Which C++ language constructs are supportd? -
      • Does it support implicit conversions between wrapped C++ classes that have -an inheritance relationship? -
      • Does it support smart pointers? -
      -

      - Anyone in the possession of the answers to these questions will earn my - gratitude for a write-up ;-) - -

      Zope ExtensionClasses

      -

      - - ExtensionClasses in Zope use the same underlying mechanism as Boost.Python - to support subclassing of extension types in Python, including - multiple-inheritance. Both systems support pickling/unpickling of - extension class instances in very similar ways. Both systems rely on the - same ``Don - Beaudry Hack'' that also inspired Don's MESS System. -

      - The major differences are: -

        -
      • Zope is entirely 'C' language-based. It doesn't require a C++ - compiler, so it's much more portable than Boost.Python, which stresses - the limits of even some modern C++ implementations. - -
      • - Boost.Python lifts the burden on the user to parse and convert function - argument types. Zope provides no such facility. -
      • - Boost.Python lifts the burden on the user to maintain Python - reference-counts. -
      • - Boost.Python supports function overloading; Zope does not. -
      • - Boost.Python supplies a simple mechanism for exposing read-only and - read/write access to data members of the wrapped C++ type as Python - attributes. -
      • - Writing a Zope ExtensionClass is significantly more complex than - exposing a C++ class to python using Boost.Python (mostly a summary of the - previous 4 items). A - Zope Example illustrates the differences. -
      • - Zope's ExtensionClasses are specifically motivated by ``the need for a - C-based persistence mechanism''. Boost.Python's are motivated by the desire - to simply reflect a C++ API into Python with as little modification as - possible. -
      • - The following Zope restriction does not apply to Boost.Python: ``At most one - base extension direct or indirect super class may define C data - members. If an extension subclass inherits from multiple base - extension classes, then all but one must be mix-in classes that - provide extension methods but no data.'' -
      • - Zope requires use of the somewhat funky inheritedAttribute (search for - ``inheritedAttribute'' on this page) - method to access base class methods. In Boost.Python, base class methods can - be accessed in the usual way by writing - ``BaseClass.method''. -
      • - Zope supplies some creative but esoteric idioms such as - Acquisition. No specific support for this is built into Boost.Python. -
      • - Zope's ComputedAttribute support is designed to be used from Python. - The analogous feature of - Boost.Python can be used from C++ or Python. The feature is arguably - easier to use in Boost.Python. -
      -

      - Next: A Simple Example Using Boost.Python - Previous: A Brief Introduction to writing Python Extension Modules - Up: Top -

      - © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as is'' without - express or implied warranty, and with no claim as to its suitability - for any purpose. -

      - Updated: Mar 6, 2001 -

      - diff --git a/doc/cross_module.html b/doc/cross_module.html deleted file mode 100644 index 08c39bfe..00000000 --- a/doc/cross_module.html +++ /dev/null @@ -1,336 +0,0 @@ - - -Cross-extension-module dependencies - -
      - -c++boost.gif (8819 bytes) - -
      -

      Cross-extension-module dependencies

      - -It is good programming practice to organize large projects as modules -that interact with each other via well defined interfaces. With -Boost.Python it is possible to reflect this organization at the C++ -level at the Python level. This is, each logical C++ module can be -organized as a separate Python extension module. - -

      -At first sight this might seem natural and straightforward. However, it -is a fairly complex problem to establish cross-extension-module -dependencies while maintaining the same ease of use Boost.Python -provides for classes that are wrapped in the same extension module. To -a large extent this complexity can be hidden from the author of a -Boost.Python extension module, but not entirely. - -


      -

      The recipe

      - -Suppose there is an extension module that exposes certain instances of -the C++ std::vector template library such that it can be used -from Python in the following manner: - -
      -import std_vector
      -v = std_vector.double([1, 2, 3, 4])
      -v.push_back(5)
      -v.size()
      -
      - -Suppose the std_vector module is done well and reflects all -C++ functions that are useful at the Python level, for all C++ built-in -data types (std_vector.int, std_vector.long, etc.). - -

      -Suppose further that there is statistic module with a C++ class that -has constructors or member functions that use or return a -std::vector. For example: - -

      -class xy {
      -  public:
      -    xy(const std::vector<double>& x, const std::vector<double>& y) : m_x(x), m_y(y) {}
      -    const std::vector<double>& x() const { return m_x; }
      -    const std::vector<double>& y() const { return m_y; }
      -    double correlation();
      -  private:
      -    std::vector<double> m_x;
      -    std::vector<double> m_y;
      -}
      -
      - -What is more natural than reusing the std_vector extension -module to expose these constructors or functions to Python? - -

      -Unfortunately, what seems natural needs a little work in both the -std_vector and the statistics module. - -

      -In the std_vector extension module, -std::vector<double> is exposed to Python in the usual -way with the class_builder<> template. To also enable the -automatic conversion of std::vector<double> function -arguments or return values in other Boost.Python C++ modules, the -converters that convert a std::vector<double> C++ object -to a Python object and vice versa (i.e. the to_python() and -from_python() template functions) have to be exported. For -example: - -

      -  #include <boost/python/cross_module.hpp>
      -  //...
      -  class_builder<std::vector<double> > v_double(std_vector_module, "double");
      -  export_converters(v_double);
      -
      - -In the extension module that wraps class xy we can now import -these converters with the import_converters<> template. -For example: - -
      -  #include <boost/python/cross_module.hpp>
      -  //...
      -  import_converters<std::vector<double> > v_double_converters("std_vector", "double");
      -
      - -That is all. All the attributes that are defined for -std_vector.double in the std_vector Boost.Python -module will be available for the returned objects of xy.x() -and xy.y(). Similarly, the constructor for xy will -accept objects that were created by the std_vectormodule. - -
      -

      Placement of import_converters<> template instantiations

      - -import_converts<> can be viewed as a drop-in replacement -for class_wrapper<>, and the recommendations for the -placement of class_wrapper<> template instantiations -also apply to to import_converts<>. In particular, it is -important that an instantiation of class_wrapper<> is -visible to any code which wraps a C++ function with a T, -T*, const T&, etc. parameter or return value. -Therefore you may want to group all class_wrapper<> and -import_converts<> instantiations at the top of your -module's init function, then def() the member functions later -to avoid problems with inter-class dependencies. - -
      -

      Non-copyable types

      - -export_converters() instantiates C++ template functions that -invoke the copy constructor of the wrapped type. For a type that is -non-copyable this will result in compile-time error messages. In such a -case, export_converters_noncopyable() can be used to export -the converters that do not involve the copy constructor of the wrapped -type. For example: - -
      -class_builder<store> py_store(your_module, "store");
      -export_converters_noncopyable(py_store);
      -
      - -The corresponding import_converters<> statement does not -need any special attention: - -
      -import_converters<store> py_store("noncopyable_export", "store");
      -
      - -
      -

      Python module search path

      - -The std_vector and statistics modules can now be used -in the following way: - -
      -import std_vector
      -import statistics
      -x = std_vector.double([1, 2, 3, 4])
      -y = std_vector.double([2, 4, 6, 8])
      -xy = statistics.xy(x, y)
      -xy.correlation()
      -
      - -In this example it is clear that Python has to be able to find both the -std_vector and the statistics extension module. In -other words, both extension modules need to be in the Python module -search path (sys.path). - -

      -The situation is not always this obvious. Suppose the -statistics module has a random() function that -returns a vector of random numbers with a given length: - -

      -import statistics
      -x = statistics.random(5)
      -y = statistics.random(5)
      -xy = statistics.xy(x, y)
      -xy.correlation()
      -
      - -A naive user will not easily anticipate that the std_vector -module is used to pass the x and y vectors around. If -the std_vector module is in the Python module search path, -this form of ignorance is of no harm. On the contrary, we are glad -that we do not have to bother the user with details like this. - -

      -If the std_vector module is not in the Python module search -path, a Python exception will be raised: - -

      -Traceback (innermost last):
      -  File "foo.py", line 2, in ?
      -    x = statistics.random(5)
      -ImportError: No module named std_vector
      -
      - -As is the case with any system of a non-trivial complexity, it is -important that the setup is consistent and complete. - -
      -

      Two-way module dependencies

      - -Boost.Python supports two-way module dependencies. This is best -illustrated by a simple example. - -

      -Suppose there is a module ivect that implements vectors of -integers, and a similar module dvect that implements vectors -of doubles. We want to be able do convert an integer vector to a double -vector and vice versa. For example: - -

      -import ivect
      -iv = ivect.ivect((1,2,3,4,5))
      -dv = iv.as_dvect()
      -
      - -The last expression will implicitly import the dvect module in -order to enable the conversion of the C++ representation of -dvect to a Python object. The analogous is possible for a -dvect: - -
      -import dvect
      -dv = dvect.dvect((1,2,3,4,5))
      -iv = dv.as_ivect()
      -
      - -Now the ivect module is imported implicitly. - -

      -Note that the two-way dependencies are possible because the -dependencies are resolved only when needed. This is, the initialization -of the ivect module does not rely on the dvect -module, and vice versa. Only if as_dvect() or -as_ivect() is actually invoked will the corresponding module -be implicitly imported. This also means that, for example, the -dvect module does not have to be available at all if -as_dvect() is never used. - -


      -

      Clarification of compile-time and link-time dependencies

      - -Boost.Python's support for resolving cross-module dependencies at -runtime does not imply that compile-time dependencies are eliminated. -For example, the statistics extension module in the example above will -need to #include <vector>. This is immediately obvious -from the definition of class xy. - -

      -If a library is wrapped that consists of both header files and compiled -components (e.g. libdvect.a, dvect.lib, etc.), both -the Boost.Python extension module with the -export_converters() statement and the module with the -import_converters<> statement need to be linked against -the object library. Ideally one would build a shared library (e.g. -libdvect.so, dvect.dll, etc.). However, this -introduces the issue of having to configure the search path for the -dynamic loading correctly. For small libraries it is therefore often -more convenient to ignore the fact that the object files are loaded -into memory more than once. - -


      -

      Summary of motivation for cross-module support

      - -The main purpose of Boost.Python's cross-module support is to allow for -a modular system layout. With this support it is straightforward to -reflect C++ code organization at the Python level. Without the -cross-module support, a multi-purpose module like std_vector -would be impractical because the entire wrapper code would somehow have -to be duplicated in all extension modules that use it, making them -harder to maintain and harder to build. - -

      -Another motivation for the cross-module support is that two extension -modules that wrap the same class cannot both be imported into Python. -For example, if there are two modules A and B that -both wrap a given class X, this will work: - -

      -import A
      -x = A.X()
      -
      - -This will also work: - -
      -import B
      -x = B.X()
      -
      - -However, this will fail: - -
      -import A
      -import B
      -python: /net/cci/rwgk/boost/boost/python/detail/extension_class.hpp:866:
      -static void boost::python::detail::class_registry<X>::register_class(boost::python::detail::extension_class_base *):
      -Assertion `static_class_object == 0' failed.
      -Abort
      -
      - -A good solution is to wrap class X only once. Depending on the -situation, this could be done by module A or B, or an -additional small extension module that only wraps and exports -class X. - -

      -Finally, there can be important psychological or political reasons for -using the cross-module support. If a group of classes is lumped -together with many others in a huge module, the authors will have -difficulties in being identified with their work. The situation is -much more transparent if the work is represented by a module with a -recognizable name. This is not just a question of strong egos, but also -of getting credit and funding. - -


      -

      Why not use export_converters() universally?

      - -There is some overhead associated with the Boost.Python cross-module -support. Depending on the platform, the size of the code generated by -export_converters() is roughly 10%-20% of that generated -by class_builder<>. For a large extension module with -many wrapped classes, this could mean a significant difference. -Therefore the general recommendation is to use -export_converters() only for classes that are likely to -be used as function arguments or return values in other modules. - -
      -© Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, -use, modify, sell and distribute this document is granted provided this -copyright notice appears in all copies. This document is provided "as -is" without express or implied warranty, and with no claim as to its -suitability for any purpose. - -

      -Updated: April 2001 - -

      diff --git a/doc/data_structures.txt b/doc/data_structures.txt deleted file mode 100644 index 90e41b91..00000000 --- a/doc/data_structures.txt +++ /dev/null @@ -1,192 +0,0 @@ -Given a real Python class 'A', a wrapped C++ class 'B', and this definition: - - class C(A, B): - def __init__(self): - B.__init__(self) - self.x = 1 - ... - - c = C() - -this diagram describes the internal structure of an instance of 'C', including -its inheritance relationships. Note that ExtensionClass is derived from -Class, and is in fact identical for all intents and purposes. - - MetaClass - +---------+ +---------+ -types.ClassType: | | | | - | | | | - | | | | - +---------+ +---------+ - ^ ^ ^ - PyClassObject | ExtensionClass | | - A: +------------+ | B: +------------+ | | - | ob_type -+-+ | ob_type -+-----+ | - | | ()<--+- __bases__ | | - | | | __dict__ -+->{...} | - | | 'B'<-+- __name__ | | - +------------+ +------------+ | - ^ ^ | - | | | - +-----+ +-------------+ | - | | | - | | Class | - | | C: +------------+ | - | | | ob_type -+------------+ - tuple:(*, *)<--+- __bases__ | - | __dict__ -+->{__module__, } - 'C' <-+- __name__ | - +------------+ - ^ (in case of inheritance from more than one - | extension class, this vector would contain - +---------------+ a pointer to an instance holder for the data - | of each corresponding C++ class) - | ExtensionInstance - | c: +---------------------+ std::vector - +----+- __class__ | +---+-- - | m_wrapped_objects -+->| * | ... - {'x': 1}<-+- __dict__ | +-|-+-- - +---------------------+ | InstanceValueHolder - | +--------------------------------+ - +-->| (contains a C++ instance of B) | - +--------------------------------+ - - - - - - -In our inheritance test cases in extclass_demo.cpp/test_extclass.py, we have the -following C++ inheritance hierarchy: - - +-----+ +----+ - | A1 | | A2 | - +-----+ +----+ - ^ ^ ^ ^ ^ - | | | | | - +-----+ | +---------+-----+ - | | | | - | +---+----------+ - .......!...... | | - : A_callback : +-+--+ +-+--+ - :............: | B1 | | B2 | - +----+ +----+ - ^ - | - +-------+---------+ - | | - +-+-+ ......!....... - | C | : B_callback : - +---+ :............: - - -A_callback and B_callback are used as part of the wrapping mechanism but not -represented in Python. C is also not represented in Python but is delivered -there polymorphically through a smart pointer. - -This is the data structure in Python. - - ExtensionClass - A1: +------------+ - ()<--+- __bases__ | - | __dict__ -+->{...} - +------------+ - ^ - | ExtensionInstance - | a1: +---------------------+ vec InstanceValueHolder - +---------+- __class__ | +---+ +---------------------+ - | | m_wrapped_objects -+->| *-+-->| contains A_callback | - | +---------------------+ +---+ +---------------------+ - | - | ExtensionInstance - | pa1_a1: +---------------------+ vec InstancePtrHolder,A1> - +---------+- __class__ | +---+ +---+ - | | m_wrapped_objects -+->| *-+-->| *-+-+ A1 - | +---------------------+ +---+ +---+ | +---+ - | +->| | - | ExtensionInstance +---+ - | pb1_a1: +---------------------+ vec InstancePtrHolder,A1> - +---------+- __class__ | +---+ +---+ - | | m_wrapped_objects -+->| *-+-->| *-+-+ B1 - | +---------------------+ +---+ +---+ | +---+ - | +->| | - | ExtensionInstance +---+ - | pb2_a1: +---------------------+ vec InstancePtrHolder,A1> - +---------+- __class__ | +---+ +---+ - | | m_wrapped_objects -+->| *-+-->| *-+-+ B2 - | +---------------------+ +---+ +---+ | +---+ - | +->| | - | +---+ - | ExtensionClass - | A2: +------------+ - | ()<--+- __bases__ | - | | __dict__ -+->{...} - | +------------+ - | ^ - | | ExtensionInstance - | a2: | +---------------------+ vec InstanceValueHolder - | +-+- __class__ | +---+ +-------------+ - | | | m_wrapped_objects -+->| *-+-->| contains A2 | - | | +---------------------+ +---+ +-------------+ - | | - | | ExtensionInstance - | pa2_a2: | +---------------------+ vec InstancePtrHolder,A2> - | +-+- __class__ | +---+ +---+ - | | | m_wrapped_objects -+->| *-+-->| *-+-+ A2 - | | +---------------------+ +---+ +---+ | +---+ - | | +->| | - | | ExtensionInstance +---+ - | pb1_a2: | +---------------------+ vec InstancePtrHolder,A2> - | +-+- __class__ | +---+ +---+ - | | | m_wrapped_objects -+->| *-+-->| *-+-+ B1 - | | +---------------------+ +---+ +---+ | +---+ - | | +->| | - | | +---+ - | | - | +---------------+------------------------------+ - | | | - +------+-------------------------+-|----------------------------+ | - | | | | | - | Class | | ExtensionClass | | ExtensionClass - | DA1: +------------+ | | B1: +------------+ | | B2: +------------+ -(*,)<---+- __bases__ | (*,*)<---+- __bases__ | (*,*)<---+- __bases__ | - | __dict__ -+->{...} | __dict__ -+->{...} | __dict__ -+->{...} - +------------+ +------------+ +------------+ - ^ ^ ^ - | ExtensionInstance | | - | da1: +---------------------+ | vec InstanceValueHolder - +-------+- __class__ | | +---+ +---------------------+ | - | m_wrapped_objects -+--|-->| *-+-->| contains A_callback | | - +---------------------+ | +---+ +---------------------+ | - +--------------------------------------+ | - | ExtensionInstance | - b1: | +---------------------+ vec InstanceValueHolder | - +-+- __class__ | +---+ +---------------------+ | - | | m_wrapped_objects -+->| *-+-->| contains B_callback | | - | +---------------------+ +---+ +---------------------+ | - | | - | ExtensionInstance | -pb1_b1: | +---------------------+ vec InstancePtrHolder,B1> | - +-+- __class__ | +---+ +---+ | - | | m_wrapped_objects -+->| *-+-->| *-+-+ B1 | - | +---------------------+ +---+ +---+ | +---+ | - | +->| | | - | ExtensionInstance +---+ | - pc_b1: | +---------------------+ vec InstancePtrHolder,B1> | - +-+- __class__ | +---+ +---+ | - | | m_wrapped_objects -+->| *-+-->| *-+-+ C | - | +---------------------+ +---+ +---+ | +---+ | - | +->| | | - | +---+ | - | | - | Class +---------------------------------------+ - | DB1: +------------+ | ExtensionInstance - (*,)<---+- __bases__ | a2: | +---------------------+ vec InstanceValueHolder - | __dict__ -+->{...} +-+- __class__ | +---+ +-------------+ - +------------+ | m_wrapped_objects -+->| *-+-->| contains A2 | - ^ +---------------------+ +---+ +-------------+ - | ExtensionInstance - db1: | +---------------------+ vec InstanceValueHolder - +-+- __class__ | +---+ +----------------------+ - | m_wrapped_objects -+-->| *-+-->| contains B1_callback | - +---------------------+ +---+ +----------------------+ diff --git a/doc/enums.html b/doc/enums.html deleted file mode 100644 index c58ca34d..00000000 --- a/doc/enums.html +++ /dev/null @@ -1,120 +0,0 @@ - - - Wrapping enums - -
      -

      - c++boost.gif (8819 bytes)
      - Wrapping enums -

      - -

      Because there is in general no way to deduce that a value of arbitrary type T -is an enumeration constant, the Boost Python Library cannot automatically -convert enum values to and from Python. To handle this case, you need to decide -how you want the enum to show up in Python (since Python doesn't have -enums). Once you have done that, you can write some simple -from_python() and to_python() functions. - -

      If you are satisfied with a Python int as a way to represent your enum -values, we provide a shorthand for these functions. You just need to cause -boost::python::enum_as_int_converters<EnumType> to be -instantiated, where -EnumType is your enumerated type. There are two convenient ways to do this: - -

        -
      1. Explicit instantiation: - -
        -  template class boost::python::enum_as_int_converters<my_enum>;
        -
        - -Some buggy C++ implementations require a class to be instantiated in the same -namespace in which it is defined. In that case, the simple incantation above becomes: - -
        -
        -   ...
        -} // close my_namespace
        -
        -// drop into namespace python and explicitly instantiate
        -namespace boost { namespace python {
        -  template class enum_as_int_converters<my_enum_type>;
        -}} // namespace boost::python
        -
        -namespace my_namespace { // re-open my_namespace
        -   ...
        -
        -
        - - -
      2. If you have such an implementation, you may find this technique more convenient -
        -// instantiate as base class in any namespace
        -struct EnumTypeConverters
        -    : boost::python::enum_as_int_converters<EnumType>
        -{
        -};
        -
        -
      - -

      Either of the above is equivalent to the following declarations: -

      -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
      -
      -  MyEnumType from_python(PyObject* x, boost::python::type<MyEnumType>)
      -  {
      -      return static_cast<MyEnum>(
      -        from_python(x, boost::python::type<long>()));
      -  }
      -
      -  MyEnumType from_python(PyObject* x, boost::python::type<const MyEnumType&>)
      -  {
      -      return static_cast<MyEnum>(
      -        from_python(x, boost::python::type<long>()));
      -  }
      -
      -  PyObject* to_python(MyEnumType x)
      -  {
      -      return to_python(static_cast<long>(x));
      -  }
      -BOOST_PYTHON_END_CONVERSION_NAMESPACE
      -
      - -

      This technique defines the conversions of -MyEnumType in terms of the conversions for the built-in - long type. - -You may also want to add a bunch of lines like this to your module -initialization. These bind the corresponding enum values to the appropriate -names so they can be used from Python: - -

      -mymodule.add(boost::python::make_ref(enum_value_1), "enum_value_1");
      -mymodule.add(boost::python::make_ref(enum_value_2), "enum_value_2");
      -...
      -
      - -You can also add these to an extension class definition, if your enum happens to -be local to a class and you want the analogous interface in Python: - -
      -my_class_builder.add(boost::python::to_python(enum_value_1), "enum_value_1");
      -my_class_builder.add(boost::python::to_python(enum_value_2), "enum_value_2");
      -...
      -
      -

      - Next: Pointers and Smart Pointers - Previous: Building an Extension Module - Up: Top -

      - © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as - is'' without express or implied warranty, and with no claim as to - its suitability for any purpose. -

      - Updated: Mar 6, 2001 -

      - diff --git a/doc/example1.html b/doc/example1.html deleted file mode 100644 index ee01e72c..00000000 --- a/doc/example1.html +++ /dev/null @@ -1,75 +0,0 @@ - - - A Simple Example - -
      -

      - - -

      -

      - A Simple Example -

      -

      - Suppose we have the following C++ API which we want to expose in - Python: -

      -
      -#include <string>
      -
      -namespace { // Avoid cluttering the global namespace.
      -
      -  // A couple of simple C++ functions that we want to expose to Python.
      -  std::string greet() { return "hello, world"; }
      -  int square(int number) { return number * number; }
      -}
      -
      -
      -
      -

      - Here is the C++ code for a python module called getting_started1 - which exposes the API. -

      -
      -#include <boost/python/class_builder.hpp>
      -namespace python = boost::python;
      -
      -BOOST_PYTHON_MODULE_INIT(getting_started1)
      -{
      -    // Create an object representing this extension module.
      -    python::module_builder this_module("getting_started1");
      -
      -    // Add regular functions to the module.
      -    this_module.def(greet, "greet");
      -    this_module.def(square, "square");
      -}
      -
      -
      -

      - That's it! If we build this shared library and put it on our - PYTHONPATH we can now access our C++ functions from - Python. -

      -
      ->>> import getting_started1
      ->>> print getting_started1.greet()
      -hello, world
      ->>> number = 11
      ->>> print number, '*', number, '=', getting_started1.square(number)
      -11 * 11 = 121
      -
      -

      - Next: Exporting Classes - Previous: Comparisons with other systems Up: - Top -

      - © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability - for any purpose. -

      - Updated: Mar 6, 2000 -

      - diff --git a/doc/exporting_classes.html b/doc/exporting_classes.html deleted file mode 100644 index cbeb8a9e..00000000 --- a/doc/exporting_classes.html +++ /dev/null @@ -1,143 +0,0 @@ - - - Exporting Classes - -
      -

      - - -

      -

      - Exporting Classes -

      -

      - Now let's expose a C++ class to Python: - -

      -#include <iostream>
      -#include <string>
      -
      -namespace { // Avoid cluttering the global namespace.
      -
      -  // A friendly class.
      -  class hello
      -  {
      -    public:
      -      hello(const std::string& country) { this->country = country; }
      -      std::string greet() const { return "Hello from " + country; }
      -    private:
      -      std::string country;
      -  };
      -
      -  // A function taking a hello object as an argument.
      -  std::string invite(const hello& w) {
      -    return w.greet() + "! Please come soon!";
      -  }
      -}
      -
      -

      - To expose the class, we use a class_builder in addition to the - module_builder from the previous example. Class member functions - are exposed by using the def() member function on the - class_builder: -

      -#include <boost/python/class_builder.hpp>
      -namespace python = boost::python;
      -
      -BOOST_PYTHON_MODULE_INIT(getting_started2)
      -{
      -    // Create an object representing this extension module.
      -    python::module_builder this_module("getting_started2");
      -
      -    // Create the Python type object for our extension class.
      -    python::class_builder<hello> hello_class(this_module, "hello");
      -
      -    // Add the __init__ function.
      -    hello_class.def(python::constructor<std::string>());
      -    // Add a regular member function.
      -    hello_class.def(&hello::greet, "greet");
      -
      -    // Add invite() as a regular function to the module.
      -    this_module.def(invite, "invite");
      -
      -    // Even better, invite() can also be made a member of hello_class!!!
      -    hello_class.def(invite, "invite");
      -}
      -
      -

      -Now we can use the class normally from Python: - -

      ->>> from getting_started2 import *
      ->>> hi = hello('California')
      ->>> hi.greet()
      -'Hello from California'
      ->>> invite(hi)
      -'Hello from California! Please come soon!'
      ->>> hi.invite()
      -'Hello from California! Please come soon!'
      -
      - -Notes:
        -
      • We expose the class' constructor by calling def() on the - class_builder with an argument whose type is - constructor<params>, where params - matches the list of constructor argument types: - - -
      • Regular member functions are defined by calling def() with a - member function pointer and its Python name: - -
      • Any function added to a class whose initial argument matches the class (or -any base) will act like a member function in Python. - -
      • To define a nested class, just pass the enclosing -class_builder (instead of a module_builder) as the -first argument to the nested class_builder's constructor. - - -
      -

      - We can even make a subclass of hello.world: - -

      ->>> class wordy(hello):
      -...     def greet(self):
      -...         return hello.greet(self) + ', where the weather is fine'
      -...
      ->>> hi2 = wordy('Florida')
      ->>> hi2.greet()
      -'Hello from Florida, where the weather is fine'
      ->>> invite(hi2)
      -'Hello from Florida! Please come soon!'
      -
      -

      - Pretty cool! You can't do that with an ordinary Python extension type! - - Of course, you may now have a slightly empty feeling in the pit of - your little pythonic stomach. Perhaps you wanted to see the following - wordy invitation: - -

      -'Hello from Florida, where the weather is fine! Please come soon!'
      -
      - - After all, invite calls hello::greet(), and you - reimplemented that in your Python subclass, wordy. If so, read on... - -

      - Next: Overridable virtual functions - Previous: A Simple Example Up: - Top -

      - © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability - for any purpose. -

      - Updated: Mar 6, 2001 -

      - diff --git a/doc/extending.html b/doc/extending.html deleted file mode 100644 index 8839ab43..00000000 --- a/doc/extending.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - A Brief Introduction to writing Python extension modules - -

      - c++boost.gif (8819 bytes) -

      -

      - A Brief Introduction to writing Python extension modules -

      -

      - Interfacing any language to Python involves building a module which can - be loaded by the Python interpreter, but which isn't written in Python. - This is known as an extension module. Many of the built-in Python - libraries are constructed in 'C' this way; Python even supplies its - fundamental - types using the same mechanism. An extension module can be statically - linked with the Python interpreter, but it more commonly resides in a - shared library or DLL. -

      - As you can see from The Python Extending - and Embedding Tutorial, writing an extension module normally means - worrying about -

      - This last item typically occupies a great deal of code in an extension - module. Remember that Python is a completely dynamic language. A callable - object receives its arguments in a tuple; it is up to that object to extract - those arguments from the tuple, check their types, and raise appropriate - exceptions. There are numerous other tedious details that need to be - managed; too many to mention here. The Boost Python Library is designed to - lift most of that burden.
      -
      - -

      - Another obstacle that most people run into eventually when extending - Python is that there's no way to make a true Python class in an extension - module. The typical solution is to create a new Python type in the - extension module, and then write an additional module in 100% Python. The - Python module defines a Python class which dispatches to an instance of - the extension type, which it contains. This allows users to write - subclasses of the class in the Python module, almost as though they were - sublcassing the extension type. Aside from being tedious, it's not really - the same as having a true class, because there's no way for the user to - override a method of the extension type which is called from the - extension module. Boost.Python solves this problem by taking advantage of Python's metaclass - feature to provide objects which look, walk, and hiss almost exactly - like regular Python classes. Boost.Python classes are actually cleaner than - Python classes in some subtle ways; a more detailed discussion will - follow (someday).

      -

      Next: Comparisons with Other Systems Up: Top

      -

      - © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability for - any purpose.

      - diff --git a/doc/index.html b/doc/index.html index fffe13e9..f9bcc646 100644 --- a/doc/index.html +++ b/doc/index.html @@ -1,205 +1,64 @@ - - - The Boost Python Library (Boost.Python) - -

      - c++boost.gif (8819 bytes)
      The Boost Python Library (Boost.Python) -

      + -

      Synopsis

      -

      - Use the Boost Python Library to quickly and easily export a C++ library to Python such that the Python interface is - very similar to the C++ interface. It is designed to be minimally - intrusive on your C++ design. In most cases, you should not have to alter - your C++ classes in any way in order to use them with Boost.Python. The system - should simply ``reflect'' your C++ classes and functions into - Python. + + + + + -

      + Boost.Python + - -
      Note: this is the last official release of -Boost.Python v1. Development of this version of the library has -stopped; it will be retired soon in favor of the redesigned and -improved version 2. A summary of the development goals is available on -the Python C++-sig -page, which also serves as a mailing list for users of both versions -of the library. A preview of the v2 documentation is available here, -and instructions for getting started with a prerelease are available -upon request. -
      + + + + -

      Supported Platforms

      -

      Boost.Python is known to have been tested -against Python 2.2.1 using -the following compilers: +

      + +
      +

      +

      +
      +

      Boost.Python

      -
      +


      -
    • MSVC++6sp5 - with STLPort-4.5.3. A compiler bug interferes with - libs/python/example/simple_vector.cpp. All - other tests pass. +

      Contents

      -

      -

    • MSVC++7 (Visual - Studio .NET). All tests pass. +
      +
      Tutorial Introduction
      -

      -

    • Metrowerks - CodeWarrior Pro7.2 and Pro7.0 for Windows. All tests pass. +
      Building and Testing
      -

      -

    • GCC 3.0.4 under Cygwin and - RedHat Linux 7.1. - All tests pass. +
      Reference
      -

      -

    • Compaq C++ V6.2-024 for Digital UNIX (an EDG-based compiler). - All tests pass.
      - Note that the Boost.Compatibility - library must be included (see e.g. tru64_cxx.mak in the build - directory). +
      Configuration Information
      -

      -

    • Silicon Graphics MIPSpro Version 7.3.1.2m (an EDG-based compiler). - All tests pass.
      - Note that the Boost.Compatibility - library must be included (see e.g. irix_CC.mak in the build - directory). +
      Rationale
      -

      -

    • GCC 2.95.2 under MinGW and RedHat Linux 7.1. - Compilation succeeds, but some tests fail at runtime due to - exception handling bugs. It is therefore highly recommended - to use GCC 3.0.4 instead. +
      Definitions
      -

      -

    • Intel - C++ 6.0 beta: Comprehensive test fails to link due to a - linker bug. Other tests seem to work. +
      Frequently Asked Questions (FAQs)
      -

      -

    • Intel - C++ 5.0 Comprehensive test fails at runtime due to an - exception-handling bug. Other tests seem to work. +
      Progress Reports
      - +
      Acknowledgments
      +
    • +
      -

      -Note that pickling doesn't work with Python 2.2 -due to a core language bug. This is fixed in -2.2.1. +

      Revised + + 08 October, 2002 + +

      -

      -Boost.Python has also been used with other versions of Python back to -Python 1.5.2. It is expected that the older Python releases still work, -but we are not regularly testing for backward compatibility. - -

      Credits

      -
        -
      • David Abrahams originated - and wrote most of the library, and continues to coordinate development. - -
      • Ullrich Koethe - had independently developed a similar system. When he discovered Boost.Python, - he generously contributed countless hours of coding and much insight into - improving it. He is responsible for an early version of the support for function overloading and wrote the support for - reflecting C++ inheritance - relationships. He has helped to improve error-reporting from both - Python and C++, and has designed an extremely easy-to-use way of - exposing numeric operators, including - a way to avoid explicit coercion by means of overloading. - -
      • Ralf W. - Grosse-Kunstleve contributed pickle support - and numerous other small improvements. He's working on a way to allow - types exported by multiple modules to interact. - -
      • The members of the boost mailing list and the Python community - supplied invaluable early feedback. In particular, Ron Clarke, Mark Evans, - Anton Gluck, Chuck Ingold, Prabhu Ramachandran, and Barry Scott took the - brave step of trying to use Boost.Python while it was still in early - stages of development. - -
      • The development of Boost.Python wouldn't have been possible without - the generous support of Dragon - Systems/Lernout and Hauspie, Inc who supported its development as an - open-source project. -
      - -

      Table of Contents

      - -
        -
      1. A Brief Introduction to writing Python - extension modules - -
      2. Comparisons between Boost.Python and other - systems for extending Python - -
      3. A Simple Example - -
      4. Exporting Classes - -
      5. Overridable Virtual Functions - -
      6. Function Overloading - -
      7. Inheritance - -
      8. Special Method and Operator Support - -
      9. A Peek Under the Hood - -
      10. Building an Extension Module - -
      11. Pickle Support - -
      12. Cross-Extension-Module Dependencies - -
      13. Wrapping Enums - -
      14. Pointers and Smart Pointers - -
      15. Internal Data Structures - -
      - -

      - Documentation is a major ongoing project; assistance is greatly - appreciated! In the meantime, useful examples of every Boost.Python feature should - be evident in the regression test files test/comprehensive.[py/hpp/cpp] - -

      - Questions should be directed to the Python C++ SIG. - -

      - © Copyright David Abrahams 2001. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as is'' without - express or implied warranty, and with no claim as to its suitability for - any purpose. -

      - Updated: Apr 2002 +

      © Copyright Dave + Abrahams 2002. All Rights Reserved.

      + + diff --git a/doc/inheritance.html b/doc/inheritance.html deleted file mode 100644 index 56e96872..00000000 --- a/doc/inheritance.html +++ /dev/null @@ -1,166 +0,0 @@ - - - Inheritance - -
      -

      - c++boost.gif (8819 bytes)Inheritance -

      - -

      Inheritance in Python

      - -

      - Boost.Python extension classes support single and multiple-inheritance in - Python, just like regular Python classes. You can arbitrarily mix - built-in Python classes with extension classes in a derived class' - tuple of bases. Whenever a Boost.Python extension class is among the bases for a - new class in Python, the result is an extension class: -

      -
      ->>> class MyPythonClass:
      -...     def f(): return 'MyPythonClass.f()'
      -...
      ->>> import my_extension_module
      ->>> class Derived(my_extension_module.MyExtensionClass, MyPythonClass):
      -...     '''This is an extension class'''
      -...     pass
      -...
      ->>> x = Derived()
      ->>> x.f()
      -'MyPythonClass.f()'
      ->>> x.g()
      -'MyExtensionClass.g()'
      -
      -
      - -

      Reflecting C++ Inheritance Relationships

      -

      - Boost.Python also allows us to represent C++ inheritance relationships so that - wrapped derived classes may be passed where values, pointers, or - references to a base class are expected as arguments. The - declare_base member function of - class_builder<> is used to establish the relationship - between base and derived classes: - -

      -
      -#include <memory> // for std::auto_ptr<>
      -
      -struct Base {
      -    virtual ~Base() {}
      -    virtual const char* name() const { return "Base"; }
      -};
      -
      -struct Derived : Base {
      -    Derived() : x(-1) {}
      -    virtual const char* name() const { return "Derived"; }
      -    int x;
      -};
      -
      -std::auto_ptr<Base> derived_as_base() {
      -    return std::auto_ptr<Base>(new Derived);
      -}
      -
      -const char* get_name(const Base& b) {
      -    return b.name();
      -}
      -
      -int get_derived_x(const Derived& d) {
      -    return d.x;
      -}
      -    
      -#include <boost/python/class_builder.hpp> - -// namespace alias for code brevity -namespace python = boost::python; - -BOOST_PYTHON_MODULE_INIT(my_module) -{ -    python::module_builder my_module("my_module"); - -    python::class_builder<Base> base_class(my_module, "Base"); -    base_class.def(python::constructor<>()); - -    python::class_builder<Derived> derived_class(my_module, "Derived"); -    derived_class.def(python::constructor<>()); - // Establish the inheritance relationship between Base and Derived - derived_class.declare_base(base_class); - - my_module.def(derived_as_base, "derived_as_base"); - my_module.def(get_name, "get_name"); - my_module.def(get_derived_x, "get_derived_x"); -} -
      -
      - -

      - Then, in Python: -

      -
      ->>> from my_module import *
      ->>> base = Base()
      ->>> derived = Derived()
      ->>> get_name(base)
      -'Base'
      -
      -
      -objects of wrapped class Derived may be passed where Base is expected -
      -
      ->>> get_name(derived) 
      -'Derived'
      -
      -
      -objects of wrapped class Derived can be passed where Derived is -expected but where type information has been lost. -
      -
      ->>> get_derived_x(derived_as_base()) 
      --1
      -
      -
      - -

      Inheritance Without Virtual Functions

      - -

      - If for some reason your base class has no virtual functions but you still want - to represent the inheritance relationship between base and derived classes, - pass the special symbol boost::python::without_downcast as the 2nd parameter - to declare_base: - -

      -
      -struct Base2 {};
      -struct Derived2 { int f(); };
      -
      - ... -   python::class_builder<Base> base2_class(my_module, "Base2"); -   base2_class.def(python::constructor<>()); - -   python::class_builder<Derived2> derived2_class(my_module, "Derived2"); -   derived2_class.def(python::constructor<>()); - derived_class.declare_base(base_class, python::without_downcast); -
      -
      - -

      This approach will allow Derived2 objects to be passed where - Base2 is expected, but does not attempt to implicitly convert (downcast) - smart-pointers to Base2 into Derived2 pointers, - references, or values. - -

      - Next: Special Method and Operator Support - Previous: Function Overloading - Up: Top -

      - © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability - for any purpose. -

      - Updated: Nov 26, 2000 -

      - diff --git a/doc/overloading.html b/doc/overloading.html deleted file mode 100644 index 242e023f..00000000 --- a/doc/overloading.html +++ /dev/null @@ -1,155 +0,0 @@ - - - Function Overloading - -
      -

      - c++boost.gif (8819 bytes)Function Overloading -

      - -

      An Example

      -

      - To expose overloaded functions in Python, simply def() each - one with the same Python name: -

      -
      -inline int f1() { return 3; }
      -inline int f2(int x) { return x + 1; }
      -
      -class X {
      -public:
      -    X() : m_value(0) {}
      -    X(int n) : m_value(n) {}
      -    int value() const { return m_value; }
      -    void value(int v) { m_value = v; }
      -private:
      -    int m_value;
      -};
      -  ...
      -
      -BOOST_PYTHON_MODULE_INIT(overload_demo)
      -{
      -    try
      -    {
      -        boost::python::module_builder overload_demo("overload_demo");
      -        // Overloaded functions at module scope
      -        overload_demo.def(f1, "f");
      -        overload_demo.def(f2, "f");
      -
      -        boost::python::class_builder<X> x_class(overload_demo, "X");
      -        // Overloaded constructors
      -        x_class.def(boost::python::constructor<>());
      -        x_class.def(boost::python::constructor<int>());
      -
      -        // Overloaded member functions
      -        x_class.def((int (X::*)() const)&X::value, "value");
      -        x_class.def((void (X::*)(int))&X::value, "value");
      -  ...
      -
      -
      - -

      - Now in Python: -

      -
      ->>> from overload_demo import *
      ->>> x0 = X()
      ->>> x1 = X(1)
      ->>> x0.value()
      -0
      ->>> x1.value()
      -1
      ->>> x0.value(3)
      ->>> x0.value()
      -3
      ->>> X('hello')
      -TypeError: No overloaded functions match (X, string). Candidates are:
      -void (*)()
      -void (*)(int)
      ->>> f()
      -3
      ->>> f(4)
      -5
      -
      -
      - -

      Discussion

      -

      - Notice that overloading in the Python module was produced three ways:

        -
      1. by combining the non-overloaded C++ functions int f1() - and int f2(int) and exposing them as f in Python. -
      2. by exposing the overloaded constructors of class X -
      3. by exposing the overloaded member functions X::value. -
      -

      - Techniques 1. and 3. above are really alternatives. In case 3, you need - to form a pointer to each of the overloaded functions. The casting - syntax shown above is one way to do that in C++. Case 1 does not require - complicated-looking casts, but may not be viable if you can't change - your C++ interface. N.B. There's really nothing unsafe about casting an - overloaded (member) function address this way: the compiler won't let - you write it at all unless you get it right. - -

      An Alternative to Casting

      -

      - This approach is not neccessarily better, but may be preferable for some - people who have trouble writing out the types of (member) function - pointers or simply prefer to avoid all casts as a matter of principle: -

      -
      -// Forwarding functions for X::value
      -inline void set_x_value(X& self, int v) { self.value(v); }
      -inline int get_x_value(X& self) { return self.value(); }
      -   ...
      -        // Overloaded member functions
      -        x_class.def(set_x_value, "value");
      -        x_class.def(get_x_value, "value");
      -
      -
      -

      Here we are taking advantage of the ability to expose C++ functions at -namespace scope as Python member functions. - -

      Overload Resolution

      -

      - The function overload resolution mechanism works as follows: - -

        - -
      • Attribute lookup for extension classes proceeds in the - usual Python way using a depth-first, left-to-right search. When a - class is found which has a matching attribute, only functions overloaded - in the context of that class are candidates for overload resolution. In - this sense, overload resolution mirrors the C++ mechanism, where a name - in a derived class ``hides'' all functions with the same name from a base - class. -

        - -

      • Within a name-space context (extension class or module), overloaded - functions are tried in the same order they were - def()ed. The first function whose signature can be made to - match each argument passed is the one which is ultimately called. - This means in particular that you cannot overload the same function on - both ``int'' and ``float'' because Python - automatically converts either of the two types into the other one. - If the ``float'' overload is found first, it is used - also used for arguments of type ``int'' as well, and the - ``int'' version of the function is never invoked. -
      - -

      - Next: Inheritance - Previous: Overridable Virtual Functions - Up: Top -

      - © Copyright David Abrahams 2001. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided ``as - is'' without express or implied warranty, and with no claim as to - its suitability for any purpose. -

      - Updated: Mar 6, 2001 -

      - diff --git a/doc/overriding.html b/doc/overriding.html deleted file mode 100644 index 085d5a7f..00000000 --- a/doc/overriding.html +++ /dev/null @@ -1,208 +0,0 @@ - - - - Overridable Virtual Functions - - c++boost.gif (8819 bytes) - -

      Overridable Virtual Functions

      - -

      - In the previous example we exposed a simple - C++ class in Python and showed that we could write a subclass. We even - redefined one of the functions in our derived class. Now we will learn - how to make the function behave virtually when called from C++. - - -

      Example

      - -

      In this example, it is assumed that hello::greet() is a virtual -member function: - -

      -class hello
      -{
      - public:
      -    hello(const std::string& country) { this->country = country; }
      -    virtual std::string greet() const { return "Hello from " + country; }
      -    virtual ~hello(); // Good practice 
      -    ...
      -};
      -
      - -

      - We'll need a derived class* to help us - dispatch the call to Python. In our derived class, we need the following - elements: - -

        - -
      1. A PyObject* data member (usually - called self) that holds a pointer to the Python object corresponding - to our C++ hello instance. - -
      2. For each exposed constructor of the - base class T, a constructor which takes the same parameters preceded by an initial - PyObject* argument. The initial argument should be stored in the self data - member described above. - -
      3. If the class being wrapped is ever returned by - value from a wrapped function, be sure you do the same for the - T's copy constructor: you'll need a constructor taking arguments - (PyObject*, const T&). - -
      4. An implementation of each virtual function you may - wish to override in Python which uses - callback<return-type>::call_method(self, "name", args...) to call - the Python override. - -
      5. For each non-pure virtual function meant to be - overridable from Python, a static member function (or a free function) taking - a reference or pointer to the T as the first parameter and which - forwards any additional parameters neccessary to the default - implementation of the virtual function. See also this - note if the base class virtual function is private. - -
      - -
      -struct hello_callback : hello
      -{
      -    // hello constructor storing initial self_ parameter
      -    hello_callback(PyObject* self_, const std::string& x) // 2
      -        : hello(x), self(self_) {}
      -
      -    // In case hello is returned by-value from a wrapped function
      -    hello_callback(PyObject* self_, const hello& x) // 3
      -        : hello(x), self(self_) {}
      -
      -    // Override greet to call back into Python
      -    std::string greet() const // 4
      -        { return boost::python::callback<std::string>::call_method(self, "greet"); }
      -
      -    // Supplies the default implementation of greet
      -    static std::string default_greet(const hello& self_) const // 5
      -        { return self_.hello::greet(); }
      - private:
      -    PyObject* self; // 1
      -};
      -
      - -

      - Finally, we add hello_callback to the - class_builder<> declaration in our module initialization - function, and when we define the function, we must tell Boost.Python about the default - implementation: - -

      -// Create the Python type object for our extension class
      -boost::python::class_builder<hello,hello_callback> hello_class(hello, "hello");
      -// Add a virtual member function
      -hello_class.def(&hello::greet, "greet", &hello_callback::default_greet);
      -
      - -

      - Now our Python subclass of hello behaves as expected: - -

      ->>> class wordy(hello):
      -...     def greet(self):
      -...         return hello.greet(self) + ', where the weather is fine'
      -...
      ->>> hi2 = wordy('Florida')
      ->>> hi2.greet()
      -'Hello from Florida, where the weather is fine'
      ->>> invite(hi2)
      -'Hello from Florida, where the weather is fine! Please come soon!'
      -
      -

      - *You may ask, "Why do we need this derived - class? This could have been designed so that everything gets done right - inside of hello." One of the goals of Boost.Python is to be - minimally intrusive on an existing C++ design. In principle, it should be - possible to expose the interface for a 3rd party library without changing - it. To unintrusively hook into the virtual functions so that a Python - override may be called, we must use a derived class. - -

      Pure Virtual Functions

      - -

      - A pure virtual function with no implementation is actually a lot easier to - deal with than a virtual function with a default implementation. First of - all, you obviously don't need to supply - a default implementation. Secondly, you don't need to call - def() on the extension_class<> instance - for the virtual function. In fact, you wouldn't want to: if the - corresponding attribute on the Python class stays undefined, you'll get an - AttributeError in Python when you try to call the function, - indicating that it should have been implemented. For example: -

      -
      -struct baz {
      -    virtual int pure(int) = 0;
      -    int calls_pure(int x) { return pure(x) + 1000; }
      -};
      -
      -struct baz_callback {
      -    int pure(int x) { boost::python::callback<int>::call_method(m_self, "pure", x); }
      -};
      -
      -BOOST_PYTHON_MODULE_INIT(foobar)
      -{
      -     boost::python::module_builder foobar("foobar");                          
      -     boost::python::class_builder<baz,baz_callback> baz_class("baz");   
      -     baz_class.def(&baz::calls_pure, "calls_pure"); 
      -}
      -
      -
      -

      - Now in Python: -

      -
      ->>> from foobar import baz
      ->>> x = baz()
      ->>> x.pure(1)
      -Traceback (innermost last):
      -  File "<stdin>", line 1, in ?
      -AttributeError: pure
      ->>> x.calls_pure(1)
      -Traceback (innermost last):
      -  File "<stdin>", line 1, in ?
      -AttributeError: pure
      ->>> class mumble(baz):
      -...    def pure(self, x): return x + 1
      -...
      ->>> y = mumble()
      ->>> y.pure(99)
      -100
      ->>> y.calls_pure(99)
      -1100
      -
      - -

      Private Non-Pure Virtual Functions

      - -

      This is one area where some minor intrusiveness on the wrapped library is -required. Once it has been overridden, the only way to call the base class -implementation of a private virtual function is to make the derived class a -friend of the base class. You didn't hear it from me, but most C++ -implementations will allow you to change the declaration of the base class in -this limited way without breaking binary compatibility (though it will certainly -break the ODR). - -


      -

      - Next: Function Overloading - Previous: Exporting Classes - Up: Top -

      - © Copyright David Abrahams 2001. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability for - any purpose. -

      - Updated: Mar 21, 2001 - diff --git a/doc/pickle.html b/doc/pickle.html deleted file mode 100644 index 994a78ab..00000000 --- a/doc/pickle.html +++ /dev/null @@ -1,272 +0,0 @@ - - -Boost.Python Pickle Support - -

      - -c++boost.gif (8819 bytes) - -
      -

      Boost.Python Pickle Support

      - -Pickle is a Python module for object serialization, also known -as persistence, marshalling, or flattening. - -

      -It is often necessary to save and restore the contents of an object to -a file. One approach to this problem is to write a pair of functions -that read and write data from a file in a special format. A powerful -alternative approach is to use Python's pickle module. Exploiting -Python's ability for introspection, the pickle module recursively -converts nearly arbitrary Python objects into a stream of bytes that -can be written to a file. - -

      -The Boost Python Library supports the pickle module by emulating the -interface implemented by Jim Fulton's ExtensionClass module that is -included in the -ZOPE -distribution. -This interface is similar to that for regular Python classes as -described in detail in the -Python Library Reference for pickle. - -


      -

      The Boost.Python Pickle Interface

      - -At the user level, the Boost.Python pickle interface involves three special -methods: - -
      -
      -__getinitargs__ -
      - When an instance of a Boost.Python extension class is pickled, the - pickler tests if the instance has a __getinitargs__ method. - This method must return a Python tuple (it is most convenient to use - a boost::python::tuple). When the instance is restored by the - unpickler, the contents of this tuple are used as the arguments for - the class constructor. - -

      - If __getinitargs__ is not defined, the class constructor - will be called without arguments. - -

      -

      -__getstate__ - -
      - When an instance of a Boost.Python extension class is pickled, the - pickler tests if the instance has a __getstate__ method. - This method should return a Python object representing the state of - the instance. - -

      - If __getstate__ is not defined, the instance's - __dict__ is pickled (if it is not empty). - -

      -

      -__setstate__ - -
      - When an instance of a Boost.Python extension class is restored by the - unpickler, it is first constructed using the result of - __getinitargs__ as arguments (see above). Subsequently the - unpickler tests if the new instance has a __setstate__ - method. If so, this method is called with the result of - __getstate__ (a Python object) as the argument. - -

      - If __setstate__ is not defined, the result of - __getstate__ must be a Python dictionary. The items of this - dictionary are added to the instance's __dict__. - -

      - -If both __getstate__ and __setstate__ are defined, -the Python object returned by __getstate__ need not be a -dictionary. The __getstate__ and __setstate__ methods -can do what they want. - -
      -

      Pitfalls and Safety Guards

      - -In Boost.Python extension modules with many extension classes, -providing complete pickle support for all classes would be a -significant overhead. In general complete pickle support should only be -implemented for extension classes that will eventually be pickled. -However, the author of a Boost.Python extension module might not -anticipate correctly which classes need support for pickle. -Unfortunately, the pickle protocol described above has two important -pitfalls that the end user of a Boost.Python extension module might not -be aware of: - -
      -
      -Pitfall 1: -Both __getinitargs__ and __getstate__ are not defined. - -
      - In this situation the unpickler calls the class constructor without - arguments and then adds the __dict__ that was pickled by - default to that of the new instance. - -

      - However, most C++ classes wrapped with Boost.Python will have member - data that are not restored correctly by this procedure. To alert the - user to this problem, a safety guard is provided. If both - __getinitargs__ and __getstate__ are not defined, - Boost.Python tests if the class has an attribute - __dict_defines_state__. An exception is raised if this - attribute is not defined: - -

      -    RuntimeError: Incomplete pickle support (__dict_defines_state__ not set)
      -
      - - In the rare cases where this is not the desired behavior, the safety - guard can deliberately be disabled. The corresponding C++ code for - this is, e.g.: - -
      -    class_builder<your_class> py_your_class(your_module, "your_class");
      -    py_your_class.dict_defines_state();
      -
      - - It is also possible to override the safety guard at the Python level. - E.g.: - -
      -    import your_bpl_module
      -    class your_class(your_bpl_module.your_class):
      -      __dict_defines_state__ = 1
      -
      - -

      -

      -Pitfall 2: -__getstate__ is defined and the instance's __dict__ is not empty. - -
      - The author of a Boost.Python extension class might provide a - __getstate__ method without considering the possibilities - that: - -

      -

        -
      • - his class is used in Python as a base class. Most likely the - __dict__ of instances of the derived class needs to be - pickled in order to restore the instances correctly. - -

        -

      • - the user adds items to the instance's __dict__ directly. - Again, the __dict__ of the instance then needs to be - pickled. - -
      -

      - - To alert the user to this highly unobvious problem, a safety guard is - provided. If __getstate__ is defined and the instance's - __dict__ is not empty, Boost.Python tests if the class has - an attribute __getstate_manages_dict__. An exception is - raised if this attribute is not defined: - -

      -    RuntimeError: Incomplete pickle support (__getstate_manages_dict__ not set)
      -
      - - To resolve this problem, it should first be established that the - __getstate__ and __setstate__ methods manage the - instances's __dict__ correctly. Note that this can be done - both at the C++ and the Python level. Finally, the safety guard - should intentionally be overridden. E.g. in C++: - -
      -    class_builder<your_class> py_your_class(your_module, "your_class");
      -    py_your_class.getstate_manages_dict();
      -
      - - In Python: - -
      -    import your_bpl_module
      -    class your_class(your_bpl_module.your_class):
      -      __getstate_manages_dict__ = 1
      -      def __getstate__(self):
      -        # your code here
      -      def __setstate__(self, state):
      -        # your code here
      -
      -
      - -
      -

      Practical Advice

      - -
        -
      • - Avoid using __getstate__ if the instance can also be - reconstructed by way of __getinitargs__. This automatically - avoids Pitfall 2. - -

        -

      • - If __getstate__ is required, include the instance's - __dict__ in the Python object that is returned. - -
      - -
      -

      Examples

      - -There are three files in boost/libs/python/example that -show how so provide pickle support. - -

      pickle1.cpp

      - - The C++ class in this example can be fully restored by passing the - appropriate argument to the constructor. Therefore it is sufficient - to define the pickle interface method __getinitargs__. - -

      pickle2.cpp

      - - The C++ class in this example contains member data that cannot be - restored by any of the constructors. Therefore it is necessary to - provide the __getstate__/__setstate__ pair of - pickle interface methods. - -

      - For simplicity, the __dict__ is not included in the result - of __getstate__. This is not generally recommended, but a - valid approach if it is anticipated that the object's - __dict__ will always be empty. Note that the safety guards - will catch the cases where this assumption is violated. - -

      pickle3.cpp

      - - This example is similar to pickle2.cpp. However, the - object's __dict__ is included in the result of - __getstate__. This requires more code but is unavoidable - if the object's __dict__ is not always empty. - -
      -© Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy, -use, modify, sell and distribute this document is granted provided this -copyright notice appears in all copies. This document is provided "as -is" without express or implied warranty, and with no claim as to its -suitability for any purpose. - -

      -Updated: March 21, 2001 -

      diff --git a/doc/pointers.html b/doc/pointers.html deleted file mode 100644 index 11cfd8d9..00000000 --- a/doc/pointers.html +++ /dev/null @@ -1,148 +0,0 @@ - - - Pointers - -
      -

      - c++boost.gif (8819 bytes)Pointers -

      - -

      The Problem With Pointers

      - -

      -In general, raw pointers passed to or returned from functions are problematic -for Boost.Python because pointers have too many potential meanings. Is it an iterator? -A pointer to a single element? An array? When used as a return value, is the -caller expected to manage (delete) the pointed-to object or is the pointer -really just a reference? If the latter, what happens to Python references to the -referent when some C++ code deletes it? -

      -There are a few cases in which pointers are converted automatically: -

        - -
      • Both const- and non-const pointers to wrapped class instances can be passed -to C++ functions. - -
      • Values of type const char* are interpreted as -null-terminated 'C' strings and when passed to or returned from C++ functions are -converted from/to Python strings. - -
      - -

      Can you avoid the problem?

      - -

      My first piece of advice to anyone with a case not covered above is -``find a way to avoid the problem.'' For example, if you have just one -or two functions that return a pointer to an individual const -T, and T is a wrapped class, you may be able to write a ``thin -converting wrapper'' over those two functions as follows: - -

      -const Foo* f(); // original function
      -const Foo& f_wrapper() { return *f(); }
      -  ...
      -my_module.def(f_wrapper, "f");
      -
      -

      -Foo must have a public copy constructor for this technique to work, since Boost.Python -converts const T& values to_python by copying the T -value into a new extension instance. - -

      Dealing with the problem

      - -

      The first step in handling the remaining cases is to figure out what the pointer -means. Several potential solutions are provided in the examples that follow: - -

      Returning a pointer to a wrapped type

      - -

      Returning a const pointer

      - -

      If you have lots of functions returning a const T* for some -wrapped T, you may want to provide an automatic -to_python conversion function so you don't have to write lots of -thin wrappers. You can do this simply as follows: - -

      -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
      -  PyObject* to_python(const Foo* p) {
      -     return to_python(*p); // convert const Foo* in terms of const Foo&
      -  }
      -BOOST_PYTHON_END_CONVERSION_NAMESPACE
      -
      - -

      If you can't (afford to) copy the referent, or the pointer is non-const

      - -

      If the wrapped type doesn't have a public copy constructor, if copying is -extremely costly (remember, we're dealing with Python here), or if the -pointer is non-const and you really need to be able to modify the referent from -Python, you can use the following dangerous trick. Why dangerous? Because python -can not control the lifetime of the referent, so it may be destroyed by your C++ -code before the last Python reference to it disappears: - -

      -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
      -  PyObject* to_python(Foo* p)
      -  {
      -      return boost::python::python_extension_class_converters<Foo>::smart_ptr_to_python(p);
      -  }
      -
      -  PyObject* to_python(const Foo* p)
      -  {
      -      return to_python(const_cast<Foo*>(p));
      -  }
      -BOOST_PYTHON_END_CONVERSION_NAMESPACE
      -
      - -This will cause the Foo* to be treated as though it were an owning smart -pointer, even though it's not. Be sure you don't use the reference for anything -from Python once the pointer becomes invalid, though. Don't worry too much about -the const_cast<> above: Const-correctness is completely lost -to Python anyway! - -

      [In/]Out Parameters and Immutable Types

      - -

      If you have an interface that uses non-const pointers (or references) as -in/out parameters to types which in Python are immutable (e.g. int, string), -there simply is no way to get the same interface in Python. You must -resort to transforming your interface with simple thin wrappers as shown below: -

      -const void f(int* in_out_x); // original function
      -const int f_wrapper(int in_x) { f(in_x); return in_x; }
      -  ...
      -my_module.def(f_wrapper, "f");
      -
      - -

      Of course, [in/]out parameters commonly occur only when there is already a -return value. You can handle this case by returning a Python tuple: -

      -typedef unsigned ErrorCode;
      -const char* f(int* in_out_x); // original function
      - ...
      -#include <boost/python/objects.hpp>
      -const boost::python::tuple f_wrapper(int in_x) { 
      -  const char* s = f(in_x); 
      -  return boost::python::tuple(s, in_x);
      -}
      -  ...
      -my_module.def(f_wrapper, "f");
      -
      -

      Now, in Python: -

      ->>> str,out_x = f(3)
      -
      - -

      - Previous: Enums - Up: Top -

      - © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability - for any purpose. -

      - Updated: Nov 26, 2000 -

      - diff --git a/doc/richcmp.html b/doc/richcmp.html deleted file mode 100644 index d9ab7044..00000000 --- a/doc/richcmp.html +++ /dev/null @@ -1,106 +0,0 @@ - - -Rich Comparisons - -
      - -c++boost.gif (8819 bytes) - -
      -

      Rich Comparisons

      - -
      -In Python versions up to and including Python 2.0, support for -implementing comparisons on user-defined classes and extension types -was quite simple. Classes could implement a __cmp__ method -that was given two instances of a class as arguments, and could only -return 0 if they were equal or +1 or -1 if -they were not. The method could not raise an exception or return -anything other than an integer value. -In Python 2.1, Rich Comparisons were added (see -PEP 207). -Python classes can now individually overload each of the <, <=, ->, >=, ==, and != operations. - -

      -For more detailed information, search for "rich comparison" -here. - -

      -Boost.Python supports both automatic overloading and manual overloading -of the Rich Comparison operators. The compile-time support is -independent of the Python version that is used when compiling -Boost.Python extension modules. That is, op_lt for example can -always be used, and the C++ operator< will always be bound -to the Python method __lt__. However, the run-time -behavior will depend on the Python version. - -

      -With Python versions before 2.1, the Rich Comparison operators will not -be called by Python when any of the six comparison operators -(<, <=, ==, !=, ->, >=) is used in an expression. The only way -to access the corresponding methods is to call them explicitly, e.g. -a.__lt__(b). Only with Python versions 2.1 or higher will -expressions like a < b work as expected. - -

      -To support Rich Comparisions, the Python C API was modified between -Python versions 2.0 and 2.1. A new slot was introduced in the -PyTypeObject structure: tp_richcompare. For backwards -compatibility, a flag (Py_TPFLAGS_HAVE_RICHCOMPARE) has to be -set to signal to the Python interpreter that Rich Comparisions are -supported by a particular type. -There is only one flag for all the six comparison operators. -When any of the six operators is wrapped automatically or -manually, Boost.Python will set this flag. Attempts to use comparison -operators at the Python level that are not defined at the C++ level -will then lead to an AttributeError when the Python 2.1 -(or higher) interpreter tries, e.g., a.__lt__(b). That -is, in general all six operators should be supplied. Automatically -wrapped operators and manually wrapped operators can be mixed. For -example:

      -    boost::python::class_builder<code> py_code(this_module, "code");
      -
      -    py_code.def(boost::python::constructor<>());
      -    py_code.def(boost::python::constructor<int>());
      -    py_code.def(boost::python::operators<(  boost::python::op_eq
      -                                          | boost::python::op_ne)>());
      -    py_code.def(NotImplemented, "__lt__");
      -    py_code.def(NotImplemented, "__le__");
      -    py_code.def(NotImplemented, "__gt__");
      -    py_code.def(NotImplemented, "__ge__");
      -
      - -NotImplemented is a simple free function that (currently) has -to be provided by the user. For example:
      -  boost::python::ref
      -  NotImplemented(const code&, const code&) {
      -    return
      -    boost::python::ref(Py_NotImplemented, boost::python::ref::increment_count);
      -  }
      -
      - -See also: - - -
      -© Copyright Nicholas K. Sauter & Ralf W. Grosse-Kunstleve 2001. -Permission to copy, use, modify, sell and distribute this document is -granted provided this copyright notice appears in all copies. This -document is provided "as is" without express or implied warranty, and -with no claim as to its suitability for any purpose. - -

      -Updated: July 2001 - -

      diff --git a/doc/special.html b/doc/special.html deleted file mode 100644 index d53ec712..00000000 --- a/doc/special.html +++ /dev/null @@ -1,973 +0,0 @@ - - - Special Method and Operator Support - -
      -

      - c++boost.gif (8819 bytes)Special Method and - Operator Support -

      -

      - Overview -

      -

      - Boost.Python supports all of the standard - special method names supported by real Python class instances - except __complex__ (more on the reasons below). In addition, it can quickly and easily expose - suitable C++ functions and operators as Python operators. The following - categories of special method names are supported: -

      - -

      Basic Customization

      - - -

      - Python provides a number of special operators for basic customization of a - class. Only a brief description is provided below; more complete - documentation can be found here. - -

      -
      - __init__(self) -
      - Initialize the class instance. For extension classes not subclassed in - Python, __init__ is defined by - -
          my_class.def(boost::python::constructor<...>())
      - - (see section "A Simple Example Using Boost.Python").

      -

      - __del__(self) -
      - Called when the extension instance is about to be destroyed. For extension classes - not subclassed in Python, __del__ is always defined automatically by - means of the class' destructor. -
      - __repr__(self) -
      - Create a string representation from which the object can be - reconstructed. -
      - __str__(self) -
      - Create a string representation which is suitable for printing. -
      - __lt__(self, other) -
      - __le__(self, other) -
      - __eq__(self, other) -
      - __ne__(self, other) -
      - __gt__(self, other) -
      - __ge__(self, other) -
      - Rich Comparison methods. - New in Python 2.1. - See Rich Comparisons. -
      - __cmp__(self, other) -
      - Three-way compare function. - See Rich Comparisons. -
      - __hash__(self) -
      - Called for the key object for dictionary operations, and by the - built-in function hash(). Should return a 32-bit integer usable as a - hash value for dictionary operations (only allowed if __cmp__ is also - defined) -
      - __nonzero__(self) -
      - called if the object is used as a truth value (e.g. in an if - statement) -
      - __call__ (self[, args...]) -
      -Called when the instance is ``called'' as a function; if this method -is defined, x(arg1, arg2, ...) is a shorthand for -x.__call__(arg1, arg2, ...). -
      - - If we have a suitable C++ function that supports any of these features, - we can export it like any other function, using its Python special name. - For example, suppose that class Foo provides a string - conversion function: -
      -std::string to_string(Foo const& f)
      -{
      -    std::ostringstream s;
      -    s << f;
      -    return s.str();
      -}
      -
      - This function would be wrapped like this: -
      -boost::python::class_builder<Foo> foo_class(my_module, "Foo");
      -foo_class.def(&to_string, "__str__");
      -
      - Note that Boost.Python also supports automatic wrapping of - __str__ and __cmp__. This is explained in the next section and the Table of - Automatically Wrapped Methods. - -

      Numeric Operators

      - -

      - Numeric operators can be exposed manually, by defing C++ - [member] functions that support the standard Python numeric - protocols. This is the same basic technique used to expose - to_string() as __str__() above, and is covered in detail below. Boost.Python also supports - automatic wrapping of numeric operators whenever they have already - been defined in C++. - -

      Exposing C++ Operators Automatically

      - -

      -Supose we wanted to expose a C++ class - BigNum which supports addition. That is, in C++ we can write: -

      -BigNum a, b, c;
      -...
      -c = a + b;
      -
      -

      - To enable the same functionality in Python, we first wrap the - BigNum class as usual: -

      -boost::python::class_builder<BigNum> bignum_class(my_module, "BigNum");
      -bignum_class.def(boost::python::constructor<>());
      -...
      -
      - Then we export the addition operator like this: - -
      -bignum_class.def(boost::python::operators<boost::python::op_add>());
      -
      - - Since BigNum also supports subtraction, multiplication, and division, we - want to export those also. This can be done in a single command by - ``or''ing the operator identifiers together (a complete list of these - identifiers and the corresponding operators can be found in the Table of Automatically Wrapped Methods): -
      -bignum_class.def(boost::python::operators<(boost::python::op_sub | boost::python::op_mul | boost::python::op_div)>());
      -
      - [Note that the or-expression must be enclosed in parentheses.] - -

      This form of operator definition can be used to wrap unary and - homogeneous binary operators (a homogeneous operator has left and - right operands of the same type). Now suppose that our C++ library also - supports addition of BigNums and plain integers: - -

      -BigNum a, b;
      -int i;
      -...
      -a = b + i;
      -a = i + b;
      -
      - To wrap these heterogeneous operators, we need to specify a different type for - one of the operands. This is done using the right_operand - and left_operand templates: -
      -bignum_class.def(boost::python::operators<boost::python::op_add>(), boost::python::right_operand<int>());
      -bignum_class.def(boost::python::operators<boost::python::op_add>(), boost::python::left_operand<int>());
      -
      - Boost.Python uses overloading to register several variants of the same - operation (more on this in the context of - coercion). Again, several operators can be exported at once: -
      -bignum_class.def(boost::python::operators<(boost::python::op_sub | boost::python::op_mul | boost::python::op_div)>(),
      -                 boost::python::right_operand<int>());
      -bignum_class.def(boost::python::operators<(boost::python::op_sub | boost::python::op_mul | boost::python::op_div)>(), 
      -                 boost::python::left_operand<int>());
      -
      - The type of the operand not mentioned is taken from the class being wrapped. In - our example, the class object is bignum_class, and thus the - other operand's type is ``BigNum const&''. You can override - this default by explicitly specifying a type in the - operators template: -
      -bignum_class.def(boost::python::operators<boost::python::op_add, BigNum>(), boost::python::right_operand<int>());
      -
      -

      - Note that automatic wrapping uses the expression - ``left + right'' and can be used uniformly - regardless of whether the C++ operators are supplied as free functions - -

      -BigNum operator+(BigNum, BigNum)
      -
      - - or as member functions - -
      -BigNum::operator+(BigNum).
      -
      - -

      - For the Python built-in functions pow() and - abs(), there is no corresponding C++ operator. Instead, - automatic wrapping attempts to wrap C++ functions of the same name. This - only works if those functions are known in namespace - python. On some compilers (e.g. MSVC) it might be - necessary to add a using declaration prior to wrapping: - -

      -namespace boost { namespace python { 
      -  using my_namespace::pow;
      -  using my_namespace::abs;
      -}
      -
      - -

      Wrapping Numeric Operators Manually

      -

      - In some cases, automatic wrapping of operators may be impossible or - undesirable. Suppose, for example, that the modulo operation for BigNums - is defined by a set of functions called mod(): - -

      -BigNum mod(BigNum const& left, BigNum const& right);
      -BigNum mod(BigNum const& left, int right);
      -BigNum mod(int left, BigNum const& right);
      -
      - -

      - For automatic wrapping of the modulo function, operator%() would be needed. - Therefore, the mod()-functions must be wrapped manually. That is, we have - to export them explicitly with the Python special name "__mod__": - -

      -bignum_class.def((BigNum (*)(BigNum const&, BigNum const&))&mod, "__mod__");
      -bignum_class.def((BigNum (*)(BigNum const&, int))&mod, "__mod__");
      -
      - -

      - The third form of mod() (with int as left operand) cannot - be wrapped directly. We must first create a function rmod() with the - operands reversed: - -

      -BigNum rmod(BigNum const& right, int left)
      -{
      -    return mod(left, right);
      -}
      -
      - - This function must be wrapped under the name "__rmod__" (standing for "reverse mod"): - -
      -bignum_class.def(&rmod,  "__rmod__");
      -
      - - Many of the possible operator names can be found in the Table of Automatically Wrapped Methods. Special treatment is - necessary to export the ternary pow operator. - -

      - Automatic and manual wrapping can be mixed arbitrarily. Note that you - cannot overload the same operator for a given extension class on both - ``int'' and ``float'', because Python implicitly - converts these types into each other. Thus, the overloaded variant - found first (be it ``int`` or ``float'') will be - used for either of the two types. - -

      Inplace Operators

      -

      - Boost.Python can also be used to expose inplace numeric operations - (i.e., += and so forth). These operators must be wrapped - manually, as described in the previous section. For example, suppose - the class BigNum has an operator+=: - -

      -BigNum& operator+= (BigNum const& right);
      -
      - - This can be exposed by first writing a wrapper function: - -
      -BigNum& iadd (BigNum& self, const BigNum& right)
      -{
      -  return self += right;
      -}
      -
      - - and then exposing the wrapper with - -
      -bignum_class.def(&iadd, "__iadd__");
      -
      - - - - -

      Coercion

      - - - Plain Python can only execute operators with identical types on the left - and right hand side. If it encounters an expression where the types of - the left and right operand differ, it tries to coerce these types to a - common type before invoking the actual operator. Implementing good - coercion functions can be difficult if many type combinations must be - supported. -

      - Boost.Python solves this problem the same way that C++ does: with overloading. This technique drastically - simplifies the code neccessary to support operators: you just register - operators for all desired type combinations, and Boost.Python automatically - ensures that the correct function is called in each case; there is no - need for user-defined coercion functions. To enable operator - overloading, Boost.Python provides a standard coercion which is implicitly - registered whenever automatic operator wrapping is used. -

      - If you wrap all operator functions manually, but still want to use - operator overloading, you have to register the standard coercion - function explicitly: - -

      -// this is not necessary if automatic operator wrapping is used
      -bignum_class.def_standard_coerce();
      -
      - - If you encounter a situation where you absolutely need a customized - coercion, you can still define the "__coerce__" operator manually. The signature - of a coercion function should look like one of the following (the first is - the safest): - -
      -boost::python::tuple custom_coerce(boost::python::reference left, boost::python::reference right);
      -boost::python::tuple custom_coerce(PyObject* left, PyObject* right);
      -PyObject* custom_coerce(PyObject* left, PyObject* right);
      -
      - - The resulting tuple must contain two elements which - represent the values of left and right - converted to the same type. Such a function is wrapped as usual: - -
      -// this must be called before any use of automatic operator  
      -// wrapping or a call to some_class.def_standard_coerce()
      -some_class.def(&custom_coerce, "__coerce__");
      -
      - - Note that the standard coercion (defined by use of automatic - operator wrapping on a class_builder or a call to - class_builder::def_standard_coerce()) will never be applied if - a custom coercion function has been registered. Therefore, in - your coercion function you should call - -
      -boost::python::standard_coerce(left, right);
      -
      - - for all cases that you don't want to handle yourself. - -

      The Ternary pow() Operator

      - -

      - In addition to the usual binary pow(x, y) operator (meaning - xy), Python also provides a ternary variant that implements - xy mod z, presumably using a more efficient algorithm than - concatenation of power and modulo operators. Automatic operator wrapping - can only be used with the binary variant. Ternary pow() must - always be wrapped manually. For a homgeneous ternary pow(), - this is done as usual: - -

      -BigNum power(BigNum const& first, BigNum const& second, BigNum const& modulus);
      -typedef BigNum (ternary_function1)(const BigNum&, const BigNum&, const BigNum&);
      -...
      -bignum_class.def((ternary_function1)&power,  "__pow__");
      -
      - - If you want to support this function with non-uniform argument - types, wrapping is a little more involved. Suppose you have to wrap: - -
      -BigNum power(BigNum const& first, int second, int modulus);
      -BigNum power(int first, BigNum const& second, int modulus);
      -BigNum power(int first, int second, BigNum const& modulus);
      -
      - - The first variant can be wrapped as usual: - -
      -typedef BigNum (ternary_function2)(const BigNum&, int, int);
      -bignum_class.def((ternary_function2)&power,  "__pow__");
      -
      - - In the second variant, however, BigNum appears only as second - argument, and in the last one it's the third argument. These functions - must be presented to Boost.Python such that that the BigNum - argument appears in first position: - -
      -BigNum rpower(BigNum const& second, int first, int modulus)
      -{
      -    return power(first, second, modulus);
      -}
      -
      -BigNum rrpower(BigNum const& modulus, int first, int second)
      -{
      -    return power(first, second, modulus);
      -}
      -
      - -

      These functions must be wrapped under the names "__rpow__" and "__rrpow__" - respectively: - -

      -bignum_class.def((ternary_function2)&rpower,  "__rpow__");
      -bignum_class.def((ternary_function2)&rrpower,  "__rrpow__");
      -
      - -Note that "__rrpow__" is an extension not present in plain Python. - -

      Table of Automatically Wrapped Methods

      -

      - Boost.Python can automatically wrap the following - special methods: - -

      - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Python Operator Name - - Python Expression - - C++ Operator Id - - C++ Expression Used For Automatic Wrapping
      - with cpp_left = from_python(left, - type<Left>()),
      - cpp_right = from_python(right, - type<Right>()),
      - and cpp_oper = from_python(oper, type<Oper>()) -
      - __add__, __radd__ - - left + right - - op_add - - cpp_left + cpp_right -
      - __sub__, __rsub__ - - left - right - - op_sub - - cpp_left - cpp_right -
      - __mul__, __rmul__ - - left * right - - op_mul - - cpp_left * cpp_right -
      - __div__, __rdiv__ - - left / right - - op_div - - cpp_left / cpp_right -
      - __mod__, __rmod__ - - left % right - - op_mod - - cpp_left % cpp_right -
      - __divmod__, __rdivmod__ - - (quotient, remainder)
      - = divmod(left, right)
      -
      - op_divmod - - cpp_left / cpp_right -
      cpp_left % cpp_right -
      - __pow__, __rpow__ - - pow(left, right)
      - (binary power) -
      - op_pow - - pow(cpp_left, cpp_right) -
      - __rrpow__ - - pow(left, right, modulo)
      - (ternary power modulo) -
      - no automatic wrapping, special treatment - required -
      - __lshift__, __rlshift__ - - left << right - - op_lshift - - cpp_left << cpp_right -
      - __rshift__, __rrshift__ - - left >> right - - op_rshift - - cpp_left >> cpp_right -
      - __and__, __rand__ - - left & right - - op_and - - cpp_left & cpp_right -
      - __xor__, __rxor__ - - left ^ right - - op_xor - - cpp_left ^ cpp_right -
      - __or__, __ror__ - - left | right - - op_or - - cpp_left | cpp_right - -
      - __cmp__, __rcmp__ - - cmp(left, right)
      -
      See Rich Comparisons. -
      - op_cmp - - cpp_left < cpp_right  -
      cpp_right < cpp_left -
      - __lt__ -
      __le__ -
      __eq__ -
      __ne__ -
      __gt__ -
      __ge__ -
      - left < right -
      left <= right -
      left == right -
      left != right -
      left > right -
      left >= right -
      See Rich Comparisons -
      - op_lt -
      op_le -
      op_eq -
      op_ne -
      op_gt -
      op_ge -
      - cpp_left < cpp_right  -
      cpp_left <= cpp_right  -
      cpp_left == cpp_right  -
      cpp_left != cpp_right  -
      cpp_left > cpp_right  -
      cpp_left >= cpp_right  - -
      - __neg__ - - -oper  (unary negation) - - op_neg - - -cpp_oper -
      - __pos__ - - +oper  (identity) - - op_pos - - +cpp_oper -
      - __abs__ - - abs(oper)  (absolute value) - - op_abs - - abs(cpp_oper) -
      - __invert__ - - ~oper  (bitwise inversion) - - op_invert - - ~cpp_oper -
      - __int__ - - int(oper)  (integer conversion) - - op_int - - long(cpp_oper) -
      - __long__ - - long(oper) 
      - (infinite precision integer conversion) -
      - op_long - - PyLong_FromLong(cpp_oper) -
      - __float__ - - float(oper)  (float conversion) - - op_float - - double(cpp_oper) -
      - __str__ - - str(oper)  (string conversion) - - op_str - - std::ostringstream s; s << oper; -
      - __coerce__ - - coerce(left, right) - - usually defined automatically, otherwise - special treatment required -
      - -

      Sequence and Mapping Operators

      - -

      - Sequence and mapping operators let wrapped objects behave in accordance - to Python's iteration and access protocols. These protocols differ - considerably from the ones found in C++. For example, Python's typical - iteration idiom looks like - -

      -for i in S:
      -
      - - while in C++ one writes - -
      -for (iterator i = S.begin(), end = S.end(); i != end; ++i)
      -
      - -

      One could try to wrap C++ iterators in order to carry the C++ idiom into - Python. However, this does not work very well because - -

        -
      1. It leads to - non-uniform Python code (wrapped sequences support a usage different from - Python built-in sequences) and - -
      2. Iterators (e.g. std::vector::iterator) are often implemented as plain C++ - pointers which are problematic for any automatic - wrapping system. -
      - -

      - It is a better idea to support the standard Python - sequence and mapping protocols for your wrapped containers. These - operators have to be wrapped manually because there are no corresponding - C++ operators that could be used for automatic wrapping. The Python - documentation lists the relevant - container operators. In particular, expose __getitem__, __setitem__ - and remember to raise the appropriate Python exceptions - (PyExc_IndexError for sequences, - PyExc_KeyError for mappings) when the requested item is not - present. - -

      - In the following example, we expose std::map<std::size_t,std::string>: -

      -
      -typedef std::map<std::size_t, std::string> StringMap;
      -
      -// A helper function for dealing with errors. Throw a Python exception
      -// if p == m.end().
      -void throw_key_error_if_end(
      -        const StringMap& m, 
      -        StringMap::const_iterator p, 
      -        std::size_t key)
      -{
      -    if (p == m.end())
      -    {
      -        PyErr_SetObject(PyExc_KeyError, boost::python::converters::to_python(key));
      -        boost::python::throw_error_already_set();
      -    }
      -}
      -
      -// Define some simple wrapper functions which match the Python  protocol
      -// for __getitem__, __setitem__, and __delitem__.  Just as in Python, a
      -// free function with a ``self'' first parameter makes a fine class method.
      -
      -const std::string& get_item(const StringMap& self, std::size_t key)
      -{
      -    const StringMap::const_iterator p = self.find(key);
      -    throw_key_error_if_end(self, p, key);
      -    return p->second;
      -}
      -
      -// Sets the item corresponding to key in the map.
      -void StringMapPythonClass::set_item(StringMap& self, std::size_t key, const std::string& value)
      -{
      -    self[key] = value;
      -}
      -
      -// Deletes the item corresponding to key from the map.
      -void StringMapPythonClass::del_item(StringMap& self, std::size_t key)
      -{
      -    const StringMap::iterator p = self.find(key);
      -    throw_key_error_if_end(self, p, key);
      -    self.erase(p);
      -}
      -
      -class_builder<StringMap> string_map(my_module, "StringMap");
      -string_map.def(boost::python::constructor<>());
      -string_map.def(&StringMap::size, "__len__");
      -string_map.def(get_item, "__getitem__");
      -string_map.def(set_item, "__setitem__");
      -string_map.def(del_item, "__delitem__");
      -
      -
      -

      - Then in Python: -

      -
      ->>> m = StringMap()
      ->>> m[1]
      -Traceback (innermost last):
      -  File "<stdin>", line 1, in ?
      -KeyError: 1
      ->>> m[1] = 'hello'
      ->>> m[1]
      -'hello'
      ->>> del m[1]
      ->>> m[1]            # prove that it's gone
      -Traceback (innermost last):
      -  File "<stdin>", line 1, in ?
      -KeyError: 1
      ->>> del m[2]
      -Traceback (innermost last):
      -  File "<stdin>", line 1, in ?
      -KeyError: 2
      ->>> len(m)
      -0
      ->>> m[0] = 'zero'
      ->>> m[1] = 'one'
      ->>> m[2] = 'two'
      ->>> m[3] = 'three'
      ->>> len(m)
      -4
      -
      -
      - -

      Customized Attribute Access

      - -

      - Just like built-in Python classes, Boost.Python extension classes support special - the usual attribute access methods __getattr__, - __setattr__, and __delattr__. - Because writing these functions can - be tedious in the common case where the attributes being accessed are - known statically, Boost.Python checks the special names - -

        -
      • - __getattr__<name>__ -
      • - __setattr__<name>__ -
      • - __delattr__<name>__ -
      - - to provide functional access to the attribute <name>. This - facility can be used from C++ or entirely from Python. For example, the - following shows how we can implement a ``computed attribute'' in Python: -
      -
      ->>> class Range(AnyBoost.PythonExtensionClass):
      -...    def __init__(self, start, end):
      -...        self.start = start
      -...        self.end = end
      -...    def __getattr__length__(self):
      -...        return self.end - self.start
      -...
      ->>> x = Range(3, 9)
      ->>> x.length
      -6
      -
      -
      -

      - Direct Access to Data Members -

      -

      - Boost.Python uses the special - __xxxattr__<name>__ functionality described above - to allow direct access to data members through the following special - functions on class_builder<> and - extension_class<>: -

        -
      • - def_getter(pointer-to-member, name) // - read access to the member via attribute name -
      • - def_setter(pointer-to-member, name) // - write access to the member via attribute name -
      • - def_readonly(pointer-to-member, name) - // read-only access to the member via attribute name -
      • - def_read_write(pointer-to-member, - name) // read/write access to the member via attribute - name -
      -

      - Note that the first two functions, used alone, may produce surprising - behavior. For example, when def_getter() is used, the - default functionality for setattr() and - delattr() remains in effect, operating on items in the extension - instance's name-space (i.e., its __dict__). For that - reason, you'll usually want to stick with def_readonly and - def_read_write. -

      - For example, to expose a std::pair<int,long> we - might write: -

      -
      -typedef std::pair<int,long> Pil;
      -int first(const Pil& x) { return x.first; }
      -long second(const Pil& x) { return x.second; }
      -   ...
      -my_module.def(first, "first");
      -my_module.def(second, "second");
      -
      -class_builder<Pil> pair_int_long(my_module, "Pair");
      -pair_int_long.def(boost::python::constructor<>());
      -pair_int_long.def(boost::python::constructor<int,long>());
      -pair_int_long.def_read_write(&Pil::first, "first");
      -pair_int_long.def_read_write(&Pil::second, "second");
      -
      -
      -

      - Now your Python class has attributes first and - second which, when accessed, actually modify or reflect the - values of corresponding data members of the underlying C++ object. Now - in Python: -

      -
      ->>> x = Pair(3,5)
      ->>> x.first
      -3
      ->>> x.second
      -5
      ->>> x.second = 8
      ->>> x.second
      -8
      ->>> second(x) # Prove that we're not just changing the instance __dict__
      -8
      -
      -
      -

      - And what about __complex__? -

      -

      - That, dear reader, is one problem we don't know how to solve. The - Python source contains the following fragment, indicating the - special-case code really is hardwired: -

      -
      -/* XXX Hack to support classes with __complex__ method */
      -if (PyInstance_Check(r)) { ...
      -
      -
      -

      -Next: A Peek Under the Hood -Previous: Inheritance -Up: Top -

      - © Copyright David Abrahams and Ullrich Köthe 2000. - Permission to copy, use, modify, sell and distribute this document is - granted provided this copyright notice appears in all copies. This - document is provided ``as is'' without express or implied - warranty, and with no claim as to its suitability for any purpose. -

      - Updated: Nov 26, 2000 -

      - diff --git a/doc/under-the-hood.html b/doc/under-the-hood.html deleted file mode 100644 index ee0ecdfb..00000000 --- a/doc/under-the-hood.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - A Peek Under the Hood - -

      - c++boost.gif (8819 bytes) -

      -

      - A Peek Under the Hood -

      -

      - Declaring a class_builder<T> causes the instantiation - of an extension_class<T> to which it forwards all - member function calls and which is doing most of the real work. - extension_class<T> is a subclass of - PyTypeObject, the struct which Python's 'C' API uses - to describe a type. An instance of the - extension_class<> becomes the Python type object - corresponding to hello::world. When we add it to the module it goes into the - module's dictionary to be looked up under the name "world". -

      - Boost.Python uses C++'s template argument deduction mechanism to determine the - types of arguments to functions (except constructors, for which we must - provide an argument list - because they can't be named in C++). Then, it calls the appropriate - overloaded functions PyObject* - to_python(S) and - S'from_python(PyObject*, - type<S>) which convert between any C++ - type S and a PyObject*, the type which represents a - reference to any Python object in its 'C' API. The extension_class<T> - template defines a whole raft of these conversions (for T, T*, - T&, std::auto_ptr<T>, etc.), using the same inline - friend function technique employed by the boost operators - library. -

      - Because the to_python and from_python functions - for a user-defined class are defined by - extension_class<T>, it is important that an instantiation of - extension_class<T> is visible to any code which wraps - a C++ function with a T, T*, const T&, etc. parameter or - return value. In particular, you may want to create all of the classes at - the top of your module's init function, then def the member - functions later to avoid problems with inter-class dependencies. -

      - Next: Building a Module with Boost.Python - Previous: Special Method and Operator Support - Up: Top -

      - © Copyright David Abrahams 2000. Permission to copy, use, modify, - sell and distribute this document is granted provided this copyright - notice appears in all copies. This document is provided "as is" without - express or implied warranty, and with no claim as to its suitability for - any purpose. -

      - Updated: Nov 26, 2000 - diff --git a/doc/v2/acknowledgments.html b/doc/v2/acknowledgments.html index 071919e3..b2591e6d 100644 --- a/doc/v2/acknowledgments.html +++ b/doc/v2/acknowledgments.html @@ -1,32 +1,85 @@ + + - - - -Boost.Python - Acknowledgments - - - + + + + + Boost.Python - Acknowledgments + + + +
      - - - - -
      -

      -

      -
      -

      Boost.Python

      -

      Acknowledgments

      -
      -


      -{{text}} -
      -

      Revised - - 05 November, 2002 - -

      -

      © Copyright Dave Abrahams - 2002. All Rights Reserved.

      - + + +

      C++ Boost

      + + + +

      Boost.Python

      + +

      Acknowledgments

      + + + +
      + +

      Dave Abrahams is + the architect, designer, and implementor of Boost.Python.

      + +

      Joel de Guzman implemented the default + argument support and wrote the excellent tutorial documentation.

      + +

      Ralf W. + Grosse-Kunstleve implemented the pickle + support, and has enthusiastically supported the library since its + birth, contributing to design decisions and providing invaluable + real-world insight into user requirements. Ralf has written some + extensions for converting C++ containers that I hope will be incorporated + into the library soon. He also implemented the cross-module support in + the first version of Boost.Python. More importantly, Ralf makes sure + nobody forgets the near-perfect synergy of C++ and Python for solving the + problems of large-scale software construction.

      + +

      Achim Domma contributed some + of the Object Wrappers and + HTML templates for this documentation. Dave Hawkes contributed + inspiration for the use of the scope class to simplify module + definition syntax. Pearu Pearson wrote some of the test cases that are in + the current test suite.

      + +

      Martin Casado solved some sticky problems which allow us to build the + Boost.Python shared library for AIX's crazy dynamic linking model.

      + +

      The development of this version of Boost.Python was funded in part by + the Lawrence Livermore National + Laboratories and by the Computational + Crystallography Initiative at Lawrence Berkeley National + Laboratories.

      + +

      Ullrich + Koethe provided the implementation of inheritance and special + method/operator support in the first version of Boost.Python.

      + +

      The first version of Boost.Python would not have been possible without + the support of Dragon Systems, which supported its development and + release as a Boost library.

      +
      + +

      Revised + + 08 October, 2002 + +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + diff --git a/doc/v2/callbacks.html b/doc/v2/callbacks.html index f001984d..8c563336 100644 --- a/doc/v2/callbacks.html +++ b/doc/v2/callbacks.html @@ -1,62 +1,85 @@ + + - - - -Boost.Python - Calling Python Functions and Methods - - - + + + + + Boost.Python - Calling Python Functions and Methods + + + +
      - - - - -
      -

      -

      -
      -

      Boost.Python

      -

      Calling Python Functions and Methods

      -
      -
      -

      Contents

      -
      -
      Introduction
      -
      Argument Handling
      -
      Result Handling
      -
      Rationale
      -
      -
      + + +

      C++ Boost

      + -

      Introduction

      -

      -Boost.Python provides two families of function templates, -call and call_method, for -invoking Python functions and methods respectively. The interface for -calling a Python function object (or any Python callable object) looks -like: + +

      Boost.Python

      +

      Calling Python Functions and Methods

      + + + +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Argument Handling
      + +
      Result Handling
      + +
      Rationale
      +
      +
      + +

      Introduction

      + The simplest way to call a Python function from C++, given an object instance f + holding the function, is simply to invoke its function call operator. +
      +f("tea", 4, 2) // In Python: f('tea', 4, 2)
      +
      + And of course, a method of an object instance x can + be invoked by using the function-call operator of the corresponding + attribute: +
      +x.attr("tea")(4, 2); // In Python: x.tea(4, 2)
      +
      + +

      If you don't have an object instance, Boost.Python + provides two families of function templates, call and call_method, for invoking + Python functions and methods respectively on PyObject*s. The + interface for calling a Python function object (or any Python callable + object) looks like:

       call<ResultType>(callable_object, a1, a2... aN);
       
      - -Calling a method of a Python object is similarly easy: - + Calling a method of a Python object is similarly easy:
      -call_method<ResultType>(self_object, "method-name", a1, a2... aN);
      +call_method<ResultType>(self_object, "method-name", a1, a2... aN);
       
      + This comparitively low-level interface is the one you'll use when + implementing C++ virtual functions that can be overridden in Python. +

      Argument Handling

      -

      Argument Handling

      -

      - -Arguments are converted to Python according to their type. By default, -the arguments a1...aN are copied into -new Python objects, but this behavior can be overridden by the use of -ptr() and ref(): - +

      Arguments are converted to Python according to their type. By default, + the arguments a1...aN are copied into + new Python objects, but this behavior can be overridden by the use of + ptr() and ref():

       class X : boost::noncopyable
       {
      @@ -69,178 +92,160 @@ void apply(PyObject* callable, X& x)
          boost::python::call<void>(callable, boost::ref(x));
       }
       
      - -In the table below, x denotes the actual argument -object and cv denotes an optional -cv-qualification: "const", -"volatile", or "const -volatile". + In the table below, x denotes the actual argument + object and cv denotes an optional + cv-qualification: "const", "volatile", + or "const volatile". - - + - + - - + - - + - + +
      Argument Type + Argument TypeBehavior + Behavior
      T cv&
      - T cv + T cv
      The Python argument is created by the same means used - for the return value of a wrapped C++ function returning - T. When - T is a class type, that normally means - *x is copy-constructed into the new Python - object. + The Python argument is created by the same means used for the + return value of a wrapped C++ function returning T. When + T is a class type, that normally means *x + is copy-constructed into the new Python object.
      T* + T*If x == 0, the Python argument will - be None. Otherwise, - the Python argument is created by the same means used for the - return value of a wrapped C++ function returning - T. When - T is a class type, that normally means - *x is copy-constructed into the new Python - object. + If x == 0, the Python argument will be + None. + Otherwise, the Python argument is created by the same means used for + the return value of a wrapped C++ function returning T. + When T is a class type, that normally means + *x is copy-constructed into the new Python object.
      boost::reference_wrapper<T> + boost::reference_wrapper<T>The Python argument contains a pointer to, rather than a - copy of, x.get(). Note: failure to ensure that no - Python code holds a reference to the resulting object beyond - the lifetime of *x.get() may result in a - crash! + The Python argument contains a pointer to, rather than a copy of, + x.get(). Note: failure to ensure that no Python code + holds a reference to the resulting object beyond the lifetime of + *x.get() may result in a crash!
      pointer_wrapper<T> - - If x.get() == 0, the Python - argument will be None. - Otherwise, the Python argument contains a pointer to, rather - than a copy of, *x.get(). Note: failure to ensure - that no Python code holds a reference to the resulting object - beyond the lifetime of *x.get() may result in - a crash! + pointer_wrapper<T>If x.get() == 0, the Python argument will + be None. + Otherwise, the Python argument contains a pointer to, rather than a + copy of, *x.get(). Note: failure to ensure that no + Python code holds a reference to the resulting object beyond the + lifetime of *x.get() may result in a crash!
      -

      Result Handling

      +

      Result Handling

      + In general, call<ResultType>() and + call_method<ResultType>() return + ResultType by exploiting all lvalue and rvalue + from_python converters registered for ResultType and + returning a copy of the result. However, when ResultType is + a pointer or reference type, Boost.Python searches only for lvalue + converters. To prevent dangling pointers and references, an exception + will be thrown if the Python result object has only a single reference + count. -In general, call<ResultType>() and -call_method<ResultType>() return -ResultType by exploiting all lvalue and rvalue -from_python converters registered for ResultType and -returning a copy of the result. However, when -ResultType is a pointer or reference type, Boost.Python -searches only for lvalue converters. To prevent dangling pointers and -references, an exception will be thrown if the Python result object -has only a single reference count. +

      Rationale

      + In general, to get Python arguments corresponding to + a1...aN, a new Python object must be + created for each one; should the C++ object be copied into that Python + object, or should the Python object simply hold a reference/pointer to + the C++ object? In general, the latter approach is unsafe, since the + called function may store a reference to the Python object somewhere. If + the Python object is used after the C++ object is destroyed, we'll crash + Python. -

      Rationale

      +

      In keeping with the philosophy that users on the Python side shouldn't + have to worry about crashing the interpreter, the default behavior is to + copy the C++ object, and to allow a non-copying behavior only if the user + writes boost::ref(a1) + instead of a1 directly. At least this way, the user doesn't get dangerous + behavior "by accident". It's also worth noting that the non-copying + ("by-reference") behavior is in general only available for class types, + and will fail at runtime with a Python exception if used otherwise[1].

      -In general, to get Python arguments corresponding to -a1...aN, a new Python object must be -created for each one; should the C++ object be copied into that Python -object, or should the Python object simply hold a reference/pointer to -the C++ object? In general, the latter approach is unsafe, since the -called function may store a reference to the Python object -somewhere. If the Python object is used after the C++ object is -destroyed, we'll crash Python. +

      However, pointer types present a problem: one approach is to refuse to + compile if any aN has pointer type: after all, a user can always pass + *aN to pass "by-value" or ref(*aN) to indicate + a pass-by-reference behavior. However, this creates a problem for the + expected null pointer to None conversion: it's illegal to + dereference a null pointer value.

      -

      In keeping with the philosophy that users on the Python side -shouldn't have to worry about crashing the interpreter, the default -behavior is to copy the C++ object, and to allow a non-copying -behavior only if the user writes boost::ref(a1) instead of a1 -directly. At least this way, the user doesn't get dangerous behavior -"by accident". It's also worth noting that the non-copying -("by-reference") behavior is in general only available for -class types, and will fail at runtime with a Python exception if used -otherwise[1]. +

      The compromise I've settled on is this:

      -

      -However, pointer types present a problem: one approach is to refuse -to compile if any aN has pointer type: after all, a user can always pass -*aN to pass "by-value" or ref(*aN) -to indicate a pass-by-reference behavior. However, this creates a -problem for the expected null pointer to -None conversion: it's illegal to dereference a null -pointer value. +

        +
      1. The default behavior is pass-by-value. If you pass a non-null + pointer, the pointee is copied into a new Python object; otherwise the + corresponding Python argument will be None.
      2. -

        +

      3. if you want by-reference behavior, use ptr(aN) if + aN is a pointer and ref(aN) otherwise. If a + null pointer is passed to ptr(aN), the corresponding + Python argument will be None.
      4. +
      -The compromise I've settled on is this: +

      As for results, we have a similar problem: if ResultType + is allowed to be a pointer or reference type, the lifetime of the object + it refers to is probably being managed by a Python object. When that + Python object is destroyed, our pointer dangles. The problem is + particularly bad when the ResultType is char const* - the + corresponding Python String object is typically uniquely-referenced, + meaning that the pointer dangles as soon as call<char + const*>(...) returns.

      -
        -
      1. The default behavior is pass-by-value. If you pass a non-null - pointer, the pointee is copied into a new Python object; otherwise - the corresponding Python argument will be None. +

        The old Boost.Python v1 deals with this issue by refusing to compile + any uses of call<char const*>(), but this goes both + too far and not far enough. It goes too far because there are cases where + the owning Python string object survives beyond the call (just for + instance, when it's the name of a Python class), and it goes not far + enough because we might just as well have the same problem with a + returned pointer or reference of any other type.

        -
      2. if you want by-reference behavior, use ptr(aN) if - aN is a pointer and ref(aN) otherwise. If - a null pointer is passed to ptr(aN), the corresponding - Python argument will be None. -
      +

      In Boost.Python v2 this is dealt with by:

      -

      -As for results, we have a similar problem: if ResultType -is allowed to be a pointer or reference type, the lifetime of the -object it refers to is probably being managed by a Python object. When -that Python object is destroyed, our pointer dangles. The problem is -particularly bad when the ResultType is char const* - the -corresponding Python String object is typically uniquely-referenced, -meaning that the pointer dangles as soon as call<char -const*>(...) returns. +

        +
      1. lifting the compile-time restriction on const char* callback + returns
      2. -

        -The old Boost.Python v1 deals with this issue by refusing to compile -any uses of call<char const*>(), but this goes both -too far and not far enough. It goes too far because there are cases -where the owning Python string object survives beyond the call (just -for instance, when it's the name of a Python class), and it goes not -far enough because we might just as well have the same problem with a -returned pointer or reference of any other type. +

      3. detecting the case when the reference count on the result Python + object is 1 and throwing an exception inside of + call<U>(...) when U is a pointer or + reference type.
      4. +
      + This should be acceptably safe because users have to explicitly specify a + pointer/reference for U in call<U>, and + they will be protected against dangles at runtime, at least long enough + to get out of the call<U>(...) invocation. +
      + [1] It would be possible to make it fail at compile-time + for non-class types such as int and char, but I'm not sure it's a good + idea to impose this restriction yet. -

      +

      Revised + + 17 April, 2002 +

      -In Boost.Python v2 this is dealt with by: - -
        -
      1. lifting the compile-time restriction on const - char* callback returns - - -
      2. detecting the case when the reference count on the result - Python object is 1 and throwing an exception inside of - call<U>(...) when U is a pointer - or reference type. -
      - -This should be acceptably safe because users have to explicitly -specify a pointer/reference for U in -call<U>, and they will be protected against dangles -at runtime, at least long enough to get out of the -call<U>(...) invocation. - -
      - -[1] It would be possible to make it fail at compile-time for non-class -types such as int and char, but I'm not sure it's a good idea to impose -this restriction yet. - -

      Revised - - 17 April, 2002 - -

      -

      © Copyright Dave Abrahams - 2002. All Rights Reserved.

      - +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + diff --git a/doc/v2/def.html b/doc/v2/def.html index 25a78bf8..d0447930 100644 --- a/doc/v2/def.html +++ b/doc/v2/def.html @@ -52,6 +52,7 @@ in the current scope.

      Functions

      + def
       template <class F>
       void def(char const* name, F f);
      diff --git a/doc/v2/faq.html b/doc/v2/faq.html
      index 7a2811af..d15f536a 100644
      --- a/doc/v2/faq.html
      +++ b/doc/v2/faq.html
      @@ -32,8 +32,8 @@
             
      Is return_internal reference efficient?
      -
      How can I which take C++ containers as - arguments?
      +
      How can I wrap containers which take C++ + containers as arguments?

      Is return_internal reference efficient?

      diff --git a/doc/v2/index.html b/doc/v2/index.html index d1c1c0c0..6f5150fb 100644 --- a/doc/v2/index.html +++ b/doc/v2/index.html @@ -1,43 +1,17 @@ + + - - - -Boost.Python - - - - - - - -
      -

      -

      -
      -

      Boost.Python

      -

      Index

      -
      -
      -

      Contents

      -
      -
      Overview
      -
      Reference
      -
      Configuration Information
      -
      Rationale
      -
      Definitions
      -
      Frequently Asked Questions (FAQs)
      -
      Progress Reports
      -
      Bibliography
      -
      Acknowledgments
      -
      -
      -

      Revised - - 05 November, 2002 - -

      -

      © Copyright Dave Abrahams - 2002. All Rights Reserved.

      - + + + + + + + + + Automatic redirection failed, please go to ../index.html. + + diff --git a/doc/v2/python.html b/doc/v2/python.html new file mode 100644 index 00000000..78706681 --- /dev/null +++ b/doc/v2/python.html @@ -0,0 +1,108 @@ + + + + + + + + + Boost.Python - <boost/python.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      +
      +
      + +

      Introduction

      + +

      This is a convenience header which #includes all of the public + interface headers that are part of the Boost.Python library

      +
      +# include <args.hpp>
      +# include <args_fwd.hpp>
      +# include <back_reference.hpp>
      +# include <bases.hpp>
      +# include <borrowed.hpp>
      +# include <call.hpp>
      +# include <call_method.hpp>
      +# include <class.hpp>
      +# include <copy_const_reference.hpp>
      +# include <copy_non_const_reference.hpp>
      +# include <data_members.hpp>
      +# include <def.hpp>
      +# include <default_call_policies.hpp>
      +# include <dict.hpp>
      +# include <enum.hpp>
      +# include <errors.hpp>
      +# include <exception_translator.hpp>
      +# include <extract.hpp>
      +# include <handle.hpp>
      +# include <has_back_reference.hpp>
      +# include <implicit.hpp>
      +# include <init.hpp>
      +# include <instance_holder.hpp>
      +# include <iterator.hpp>
      +# include <list.hpp>
      +# include <long.hpp>
      +# include <lvalue_from_pytype.hpp>
      +# include <make_function.hpp>
      +# include <manage_new_object.hpp>
      +# include <module.hpp>
      +# include <numeric.hpp>
      +# include <object.hpp>
      +# include <object_protocol.hpp>
      +# include <object_protocol_core.hpp>
      +# include <operators.hpp>
      +# include <other.hpp>
      +# include <overloads.hpp>
      +# include <pointee.hpp>
      +# include <ptr.hpp>
      +# include <reference_existing_object.hpp>
      +# include <return_internal_reference.hpp>
      +# include <return_value_policy.hpp>
      +# include <scope.hpp>
      +# include <self.hpp>
      +# include <slice_nil.hpp>
      +# include <str.hpp>
      +# include <to_python_converter.hpp>
      +# include <to_python_indirect.hpp>
      +# include <to_python_value.hpp>
      +# include <tuple.hpp>
      +# include <type_id.hpp>
      +# include <with_custodian_and_ward.hpp>
      +
      + +

      Revised + + 08 October, 2002 + +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 0923a434..fed0e92a 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -13,7 +13,7 @@ p.c3 {font-style: italic} h2.c2 {text-align: center} h1.c1 {text-align: center} - + @@ -61,6 +61,8 @@
      To/From Python Type Conversion
      Utility and Infrastructure
      + +
      Topics

      @@ -111,6 +113,34 @@ +
      def.hpp
      + +
      +
      +
      Functions
      + +
      +
      +
      def
      +
      +
      +
      +
      + +
      enum.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      enum_
      +
      +
      +
      +
      +
      errors.hpp
      @@ -136,7 +166,6 @@
      throw_error_already_set
      - @@ -207,7 +236,8 @@
      -
      BOOST_PYTHON_MODULE
      +
      BOOST_PYTHON_MODULE
      @@ -238,6 +268,20 @@ + +
      scope.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      scope
      +
      +
      +
      +

      Object Wrappers

      @@ -326,6 +370,28 @@ + +
      tuple.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      tuple
      +
      +
      + +
      Functions
      + +
      +
      +
      make_tuple
      +
      +
      +
      +

      Function Invocation and Creation

      @@ -771,6 +837,8 @@ +
      <boost/python.hpp>
      +
      handle.hpp
      @@ -779,18 +847,17 @@
      -
      handle
      +
      handle
      +
      Functions
      -
      borrowed
      -
      allow_null
      +
      borrowed
      + +
      allow_null
      @@ -818,6 +885,15 @@ + +

      Topics

      + +
      +
      Calling Python Functions and + Methods
      + +
      Pickle Support
      +

      Revised diff --git a/doc/v2/scope.html b/doc/v2/scope.html index 17450645..5a6c4be2 100644 --- a/doc/v2/scope.html +++ b/doc/v2/scope.html @@ -121,15 +121,22 @@ struct X { void f(); - struct Y { int g() { return 0; } }; + struct Y { int g() { return 42; } }; }; BOOST_PYTHON_MODULE(nested) { + // add some constants to the current (module) scope + scope().attr("yes") = 1; + scope().attr("no") = 0; + + // Change the current scope scope outer = class_<X>("X") .def("f", &X::f) ; + + // Define a class Y in the current scope, X class_<Y>("Y") .def("g", &Y::g) ; @@ -138,9 +145,11 @@ BOOST_PYTHON_MODULE(nested) Interactive Python:

       >>> import nested
      +>>> nested.yes
      +1
       >>> y = nested.X.Y()
       >>> y.g()
      -0
      +42
       

      Revised 03 October, 2002

      diff --git a/example/Attic/project.zip b/example/Attic/project.zip new file mode 100644 index 0000000000000000000000000000000000000000..d863defdb784ca6864f83a6ca22443b65259bda6 GIT binary patch literal 1469 zcmWIWW@Zs#U|`^2aL-z=bNJRCn;-@ThExUy25|-khJvE}tkmQZ{iOW-;u77Y(#)I` zy{yFC;4lt758rb>t3xzAbWR3noDA1E=@II2>b$;QpoiAkGoFDO>vZ%y&pv%x^yxc4 zUnl>k@BD!qLN8pt%&yFu9jCV;DYheN#*RAAx;np&b}kpB7!c0*nYCVr<@xLNO-u|7 zuB;3U{7BC5O3Y2m%t>txiS@tjAW+jk<^Kk+Ul+V?bbRY|TC!w8Q-~ekh-xlMm~)Kl=XCCX%Bmwa zJ??+)J&)AN_8(iU8IzDV_4v92v(_w~TPV$OD&OGBa;Aste>_*2dg_PFg{y5cQ!%Rh;e%O!zHU z=F3kDH@6Qzefsy)th(=i|JmH!B-`b*$vxC-=A2VOmUAN>{}8zTWaDk!$KUtun%1&q|%IrgyH9vOj*qP|t9e>?k zFKqkgr&rZ)=3f@CZ~a^S+L2c_Zrg(XKX1?Vxa&_iygRr-^U9SUF(ID>E`5=h9~v2H z^Y8j1ZnYwte|bH}C*99faoZGAP~-2sW!0nU(Uph0k3XLozOVP?ksFmeq_%bC&wZlx z#<*WBw0E;HU#Oa(=H{Lbd1rAq{wp&~XO}0e=BVKH+tvNuB6N59$@3-acLx1=R(1St z&C%39I}|HonO-?@wsdOR1YDk~87f`weBlK5xqm--J!ejv{Cw-PmbIaqT=qWNSE$sR zZZk>ZT47qup$oiRUE+`U5y^FB)_R@1rIH!yj0_A985tM^P?Kv>X-;afYk+U|VFRAM z;=knOQZ{_O@MYg!w%t5#$7cO55ZZdNU`dkp%U|!))is&pb@uA-W!f6|AXBNo+`Q#t z@SVJEvzgqLW~}OOPfNKk8)5ZJw_4i9PwGOZHJ{3}p3qa)M+Hh1J``L`@Z(8e-}`w+ zOu}`Q+z*`BF7xi4?IFi|j=ktEFYiPJwZ>=D7$fs~L>5fipHV6?r=xoH_8i&c}HD)t{a<}NprJAG4!c6I;i(?P6q^Ws*&im0y- z4c#04)?z_I=HDBFdgp!#ah9!HeV(ObbNh~xzpu*oTdv+ZYgSUC<@wb<$24CU{Etw} zeeUqWA|P8Th<%qr^S>o0Ydo?ng}-Mn|NryDoT4?JW$l|{4{>p_9a#Q*{V+3R&c zGz@bf1!{mdBa;XN?jj4Mhmk>nVOt}Jg`)sNHUwLN1JVjHq#em>Xz_!r8C&!tG@CIa ticqh_TySE5=*I0&kZw>i`tR7yg3uk{&B_LnVPRll_{PA%u#pAC0|1J>SqlIF literal 0 HcmV?d00001 diff --git a/example/project.zip b/example/project.zip new file mode 100644 index 0000000000000000000000000000000000000000..d863defdb784ca6864f83a6ca22443b65259bda6 GIT binary patch literal 1469 zcmWIWW@Zs#U|`^2aL-z=bNJRCn;-@ThExUy25|-khJvE}tkmQZ{iOW-;u77Y(#)I` zy{yFC;4lt758rb>t3xzAbWR3noDA1E=@II2>b$;QpoiAkGoFDO>vZ%y&pv%x^yxc4 zUnl>k@BD!qLN8pt%&yFu9jCV;DYheN#*RAAx;np&b}kpB7!c0*nYCVr<@xLNO-u|7 zuB;3U{7BC5O3Y2m%t>txiS@tjAW+jk<^Kk+Ul+V?bbRY|TC!w8Q-~ekh-xlMm~)Kl=XCCX%Bmwa zJ??+)J&)AN_8(iU8IzDV_4v92v(_w~TPV$OD&OGBa;Aste>_*2dg_PFg{y5cQ!%Rh;e%O!zHU z=F3kDH@6Qzefsy)th(=i|JmH!B-`b*$vxC-=A2VOmUAN>{}8zTWaDk!$KUtun%1&q|%IrgyH9vOj*qP|t9e>?k zFKqkgr&rZ)=3f@CZ~a^S+L2c_Zrg(XKX1?Vxa&_iygRr-^U9SUF(ID>E`5=h9~v2H z^Y8j1ZnYwte|bH}C*99faoZGAP~-2sW!0nU(Uph0k3XLozOVP?ksFmeq_%bC&wZlx z#<*WBw0E;HU#Oa(=H{Lbd1rAq{wp&~XO}0e=BVKH+tvNuB6N59$@3-acLx1=R(1St z&C%39I}|HonO-?@wsdOR1YDk~87f`weBlK5xqm--J!ejv{Cw-PmbIaqT=qWNSE$sR zZZk>ZT47qup$oiRUE+`U5y^FB)_R@1rIH!yj0_A985tM^P?Kv>X-;afYk+U|VFRAM z;=knOQZ{_O@MYg!w%t5#$7cO55ZZdNU`dkp%U|!))is&pb@uA-W!f6|AXBNo+`Q#t z@SVJEvzgqLW~}OOPfNKk8)5ZJw_4i9PwGOZHJ{3}p3qa)M+Hh1J``L`@Z(8e-}`w+ zOu}`Q+z*`BF7xi4?IFi|j=ktEFYiPJwZ>=D7$fs~L>5fipHV6?r=xoH_8i&c}HD)t{a<}NprJAG4!c6I;i(?P6q^Ws*&im0y- z4c#04)?z_I=HDBFdgp!#ah9!HeV(ObbNh~xzpu*oTdv+ZYgSUC<@wb<$24CU{Etw} zeeUqWA|P8Th<%qr^S>o0Ydo?ng}-Mn|NryDoT4?JW$l|{4{>p_9a#Q*{V+3R&c zGz@bf1!{mdBa;XN?jj4Mhmk>nVOt}Jg`)sNHUwLN1JVjHq#em>Xz_!r8C&!tG@CIa ticqh_TySE5=*I0&kZw>i`tR7yg3uk{&B_LnVPRll_{PA%u#pAC0|1J>SqlIF literal 0 HcmV?d00001 diff --git a/include/boost/python.hpp b/include/boost/python.hpp new file mode 100644 index 00000000..dd87d2bc --- /dev/null +++ b/include/boost/python.hpp @@ -0,0 +1,62 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef PYTHON_DWA2002810_HPP +# define PYTHON_DWA2002810_HPP + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +#endif PYTHON_DWA2002810_HPP diff --git a/include/boost/python/detail/module_init.hpp b/include/boost/python/detail/module_init.hpp deleted file mode 100644 index 5b2366f6..00000000 --- a/include/boost/python/detail/module_init.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifdef BOOST_PYTHON_V2 -# error obsolete -#endif -#ifndef MODULE_INIT_DWA2002529_HPP -# define MODULE_INIT_DWA2002529_HPP - -# ifndef BOOST_PYTHON_MODULE_INIT - -# if defined(_WIN32) || defined(__CYGWIN__) - -# define BOOST_PYTHON_MODULE_INIT(name) \ -void init_module_##name(); \ -extern "C" __declspec(dllexport) void init##name() \ -{ \ - boost::python::handle_exception(&init_module_##name); \ -} \ -void init_module_##name() - -# elif defined(_AIX) - -# include -# define BOOST_PYTHON_MODULE_INIT(name) \ -void init_module_##name(); \ -extern "C" \ -{ \ - extern PyObject* _PyImport_LoadDynamicModule(char*, char*, FILE *); \ - void init##name() \ - { \ - boost::python::detail::aix_init_module(_PyImport_LoadDynamicModule, &init_module_##name); \ - } \ -} \ -void init_module_##name() - -# else - -# define BOOST_PYTHON_MODULE_INIT(name) \ -void init_module_##name(); \ -extern "C" void init##name() \ -{ \ - boost::python::handle_exception(&init_module_##name); \ -} \ -void init_module_##name() - -# endif - -# endif - -#endif // MODULE_INIT_DWA2002529_HPP diff --git a/include/boost/python/errors.hpp b/include/boost/python/errors.hpp index 4c47aca8..cd0b3586 100644 --- a/include/boost/python/errors.hpp +++ b/include/boost/python/errors.hpp @@ -46,11 +46,9 @@ inline T* expect_non_null(T* x) return x; } -# ifdef BOOST_PYTHON_V2 // Return source if it is an instance of pytype; throw an appropriate // exception otherwise. BOOST_PYTHON_DECL PyObject* pytype_check(PyTypeObject* pytype, PyObject* source); -# endif }} // namespace boost::python diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 94d2dd31..882ce756 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -270,13 +270,13 @@ class init : public init_base > typedef typename mpl::fold< required_args , mpl::list0<> - , mpl::push_front + , mpl::push_front<> >::type reversed_required; typedef typename mpl::fold< optional_args , reversed_required - , mpl::push_front + , mpl::push_front<> >::type reversed_args; // Count the maximum number of arguments @@ -310,7 +310,7 @@ namespace detail typedef typename mpl::fold< ReversedArgs , mpl::list0<> - , mpl::push_front + , mpl::push_front<> >::type args; typedef typename ClassT::holder_selector holder_selector_t; diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp index df401f85..7087f83a 100644 --- a/include/boost/python/operators.hpp +++ b/include/boost/python/operators.hpp @@ -1,555 +1,332 @@ -// (C) Copyright Ullrich Koethe and David Abrahams 2000-2001. Permission to -// copy, use, modify, sell and distribute this software is granted provided -// this copyright notice appears in all copies. This software is provided "as -// is" without express or implied warranty, and with no claim as to its -// suitability for any purpose. -// -// The authors gratefully acknowlege the support of Dragon Systems, Inc., in -// producing this work. -// -// Revision History: -// 23 Jan 2001 - Another stupid typo fix by Ralf W. Grosse-Kunstleve (David Abrahams) -// 20 Jan 2001 - Added a fix from Ralf W. Grosse-Kunstleve (David Abrahams) -#ifndef OPERATORS_UK112000_H_ -# define OPERATORS_UK112000_H_ -# ifdef BOOST_PYTHON_V2 +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef OPERATORS_DWA2002530_HPP +# define OPERATORS_DWA2002530_HPP -# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include -# else - -# include -# include - -// When STLport is used with native streams, _STL::ostringstream().str() is not -// _STL::string, but std::string. This confuses to_python(), so we'll use -// strstream instead. Also, GCC 2.95.2 doesn't have sstream. -# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2) -# define BOOST_PYTHON_USE_SSTREAM -# endif - -# if defined(BOOST_PYTHON_USE_SSTREAM) -# include -# else -# include -# endif - -namespace boost { namespace python { - -BOOST_PYTHON_DECL tuple standard_coerce(ref l, ref r); - -namespace detail { - - // helper class for automatic operand type detection - // during operator wrapping. - struct auto_operand {}; -} - -// Define operator ids that can be or'ed together -// (boost::python::op_add | boost::python::op_sub | boost::python::op_mul). -// This allows to wrap several operators in one line. -enum operator_id -{ - op_add = 0x1, - op_sub = 0x2, - op_mul = 0x4, - op_div = 0x8, - op_mod = 0x10, - op_divmod =0x20, - op_pow = 0x40, - op_lshift = 0x80, - op_rshift = 0x100, - op_and = 0x200, - op_xor = 0x400, - op_or = 0x800, - op_neg = 0x1000, - op_pos = 0x2000, - op_abs = 0x4000, - op_invert = 0x8000, - op_int = 0x10000, - op_long = 0x20000, - op_float = 0x40000, - op_str = 0x80000, - op_cmp = 0x100000, - op_gt = 0x200000, - op_ge = 0x400000, - op_lt = 0x800000, - op_le = 0x1000000, - op_eq = 0x2000000, - op_ne = 0x4000000 -}; - -// Wrap the operators given by "which". Usage: -// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>()); -template -struct operators {}; - -// Wrap heterogeneous operators with given left operand type. Usage: -// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), -// boost::python::left_operand()); -template -struct left_operand {}; - -// Wrap heterogeneous operators with given right operand type. Usage: -// foo_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub)>(), -// boost::python::right_operand()); -template -struct right_operand {}; +namespace boost { namespace python { namespace detail { - template - struct operand_select + // This is essentially the old v1 to_python(). It will be eliminated + // once the public interface for to_python is settled on. + template + PyObject* convert_result(T const& x) { - template - struct wrapped - { - typedef Specified type; - }; - }; - - template <> - struct operand_select - { - template - struct wrapped - { - typedef const wrapped_type& type; - }; - }; - - template struct define_operator; - - // Base class which grants access to extension_class_base::add_method() to its derived classes - struct add_operator_base - { - protected: - static inline void add_method(extension_class_base* target, function* method, const char* name) - { target->add_method(method, name); } - }; - -// -// choose_op, choose_unary_op, and choose_rop -// -// These templates use "poor man's partial specialization" to generate the -// appropriate add_method() call (if any) for a given operator and argument set. -// -// Usage: -// choose_op<(which & op_add)>::template args::add(ext_class); -// -// (see extension_class<>::def_operators() for more examples). -// - template - struct choose_op - { - template - struct args : add_operator_base - { - static inline void add(extension_class_base* target) - { - typedef define_operator def_op; - add_method(target, - new typename def_op::template operator_function(), - def_op::name()); - } - - }; - }; - - // specialization for 0 has no effect - template <> - struct choose_op<0> - { - template - struct args - { - static inline void add(extension_class_base*) - { - } - - }; - }; - - template - struct choose_unary_op - { - template - struct args : add_operator_base - { - static inline void add(extension_class_base* target) - { - typedef define_operator def_op; - add_method(target, - new typename def_op::template operator_function(), - def_op::name()); - } - - }; - }; - - // specialization for 0 has no effect - template <> - struct choose_unary_op<0> - { - template - struct args - { - static inline void add(extension_class_base*) - { - } - - }; - }; - - template - struct choose_rop - { - template - struct args : add_operator_base - { - static inline void add(extension_class_base* target) - { - typedef define_operator def_op; - add_method(target, - new typename def_op::template roperator_function(), - def_op::rname()); - } - - }; - }; - - // specialization for 0 has no effect - template <> - struct choose_rop<0> - { - template - struct args - { - static inline void add(extension_class_base*) - { - } - - }; - }; - - -// Fully specialize define_operator for all operators defined in operator_id above. -// Every specialization defines one function object for normal operator calls and one -// for operator calls with operands reversed ("__r*__" function variants). -// Specializations for most operators follow a standard pattern: execute the expression -// that uses the operator in question. This standard pattern is realized by the following -// macros so that the actual specialization can be done by just calling a macro. -# define PY_DEFINE_BINARY_OPERATORS(id, oper) \ - template <> \ - struct define_operator \ - { \ - template \ - struct operator_function : function \ - { \ - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ - { \ - tuple args(ref(arguments, ref::increment_count)); \ - \ - return BOOST_PYTHON_CONVERSION::to_python( \ - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) oper \ - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type())); \ - } \ - \ - const char* description() const \ - { return "__" #id "__"; } \ - }; \ - \ - template \ - struct roperator_function : function \ - { \ - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ - { \ - tuple args(ref(arguments, ref::increment_count)); \ - \ - return BOOST_PYTHON_CONVERSION::to_python( \ - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()) oper \ - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type())); \ - } \ - \ - const char* description() const \ - { return "__r" #id "__"; } \ - \ - }; \ - \ - static const char * name() { return "__" #id "__"; } \ - static const char * rname() { return "__r" #id "__"; } \ + return converter::arg_to_python(x).release(); } -# define PY_DEFINE_UNARY_OPERATORS(id, oper) \ - template <> \ - struct define_operator \ - { \ - template \ - struct operator_function : function \ - { \ - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \ - { \ - tuple args(ref(arguments, ref::increment_count)); \ - \ - return BOOST_PYTHON_CONVERSION::to_python( \ - oper(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()))); \ - } \ - \ - const char* description() const \ - { return "__" #id "__"; } \ - }; \ - \ - static const char * name() { return "__" #id "__"; } \ - } - - PY_DEFINE_BINARY_OPERATORS(add, +); - PY_DEFINE_BINARY_OPERATORS(sub, -); - PY_DEFINE_BINARY_OPERATORS(mul, *); - PY_DEFINE_BINARY_OPERATORS(div, /); - PY_DEFINE_BINARY_OPERATORS(mod, %); - PY_DEFINE_BINARY_OPERATORS(lshift, <<); - PY_DEFINE_BINARY_OPERATORS(rshift, >>); - PY_DEFINE_BINARY_OPERATORS(and, &); - PY_DEFINE_BINARY_OPERATORS(xor, ^); - PY_DEFINE_BINARY_OPERATORS(or, |); - PY_DEFINE_BINARY_OPERATORS(gt, >); - PY_DEFINE_BINARY_OPERATORS(ge, >=); - PY_DEFINE_BINARY_OPERATORS(lt, <); - PY_DEFINE_BINARY_OPERATORS(le, <=); - PY_DEFINE_BINARY_OPERATORS(eq, ==); - PY_DEFINE_BINARY_OPERATORS(ne, !=); - - PY_DEFINE_UNARY_OPERATORS(neg, -); - PY_DEFINE_UNARY_OPERATORS(pos, +); - PY_DEFINE_UNARY_OPERATORS(abs, abs); - PY_DEFINE_UNARY_OPERATORS(invert, ~); - PY_DEFINE_UNARY_OPERATORS(int, long); - PY_DEFINE_UNARY_OPERATORS(long, PyLong_FromLong); - PY_DEFINE_UNARY_OPERATORS(float, double); - -# undef PY_DEFINE_BINARY_OPERATORS -# undef PY_DEFINE_UNARY_OPERATORS - -// Some operators need special treatment, e.g. because there is no corresponding -// expression in C++. These are specialized manually. - -// pow(): Manual specialization needed because an error message is required if this -// function is called with three arguments. The "power modulo" operator is not -// supported by define_operator, but can be wrapped manually (see special.html). - template <> - struct define_operator + // Operator implementation template declarations. The nested apply + // declaration here keeps MSVC6 happy. + template struct operator_l { - template - struct operator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - - if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type) - { - PyErr_SetString(PyExc_TypeError, "expected 2 arguments, got 3"); - throw_argument_error(); - } - - return BOOST_PYTHON_CONVERSION::to_python( - pow(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()), - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()))); - } - - const char* description() const - { return "__pow__"; } - - }; - - template - struct roperator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - - if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type) - { - PyErr_SetString(PyExc_TypeError, "bad operand type(s) for pow()"); - throw_argument_error(); - } - - return BOOST_PYTHON_CONVERSION::to_python( - pow(BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()), - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()))); - } - - const char* description() const - { return "__rpow__"; } - - }; - - static const char * name() { return "__pow__"; } - static const char * rname() { return "__rpow__"; } + template struct apply; }; - -// divmod(): Manual specialization needed because we must actually call two operators and -// return a tuple containing both results - template <> - struct define_operator - { - template - struct operator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - PyObject * res = PyTuple_New(2); - - PyTuple_SET_ITEM(res, 0, - BOOST_PYTHON_CONVERSION::to_python( - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) / - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()))); - PyTuple_SET_ITEM(res, 1, - BOOST_PYTHON_CONVERSION::to_python( - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) % - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()))); - - return res; - } - - const char* description() const - { return "__divmod__"; } - - }; - - template - struct roperator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - PyObject * res = PyTuple_New(2); - - PyTuple_SET_ITEM(res, 0, - BOOST_PYTHON_CONVERSION::to_python( - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()) / - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()))); - PyTuple_SET_ITEM(res, 1, - BOOST_PYTHON_CONVERSION::to_python( - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()) % - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()))); - - return res; - } - - const char* description() const - { return "__rdivmod__"; } - - }; - - static const char * name() { return "__divmod__"; } - static const char * rname() { return "__rdivmod__"; } - }; - -// cmp(): Manual specialization needed because there is no three-way compare in C++. -// It is implemented by two one-way comparisons with operators reversed in the second. - template <> - struct define_operator - { - template - struct operator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - - return BOOST_PYTHON_CONVERSION::to_python( - (BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) < - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type())) ? - - 1 : - (BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()) < - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type())) ? - 1 : - 0) ; - } - - const char* description() const - { return "__cmp__"; } - - }; - - template - struct roperator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const - { - tuple args(ref(arguments, ref::increment_count)); - - return BOOST_PYTHON_CONVERSION::to_python( - (BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()) < - BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type())) ? - - 1 : - (BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) < - BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type())) ? - 1 : - 0) ; - } - - const char* description() const - { return "__rcmp__"; } - - }; - - static const char * name() { return "__cmp__"; } - static const char * rname() { return "__rcmp__"; } - }; - -# ifndef BOOST_PYTHON_USE_SSTREAM - class unfreezer { - public: - unfreezer(std::ostrstream& s) : m_stream(s) {} - ~unfreezer() { m_stream.freeze(false); } - private: - std::ostrstream& m_stream; - }; -# endif -// str(): Manual specialization needed because the string conversion does not follow -// the standard pattern relized by the macros. - template <> - struct define_operator + template struct operator_r { - template - struct operator_function : function - { - PyObject* do_call(PyObject* arguments, PyObject*) const - { - tuple args(ref(arguments, ref::increment_count)); - -// When STLport is used with native streams, _STL::ostringstream().str() is not -// _STL::string, but std::string. -# ifdef BOOST_PYTHON_USE_SSTREAM - std::ostringstream s; - s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()); - return BOOST_PYTHON_CONVERSION::to_python(s.str()); -# else - std::ostrstream s; - s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()) << char(); - auto unfreezer unfreeze(s); - return BOOST_PYTHON_CONVERSION::to_python(const_cast(s.str())); -# endif - } - - const char* description() const - { return "__str__"; } - - }; - - static const char * name() { return "__str__"; } + template struct apply; }; + template struct operator_1 + { + template struct apply; + }; -} // namespace detail + // MSVC6 doesn't want us to do this sort of inheritance on a nested + // class template, so we use this layer of indirection to avoid + // ::template<...> on the nested apply functions below + template + struct operator_l_inner + : operator_l::template apply + {}; + + template + struct operator_r_inner + : operator_r::template apply + {}; + + template + struct operator_1_inner + : operator_1::template apply + {}; + + // Define three different binary_op templates which take care of + // these cases: + // self op self + // self op R + // L op self + // + // The inner apply metafunction is used to adjust the operator to + // the class type being defined. Inheritance of the outer class is + // simply used to provide convenient access to the operation's + // name(). + + // self op self + template + struct binary_op : operator_l + { + template + struct apply : operator_l_inner + { + }; + }; + + // self op R + template + struct binary_op_l : operator_l + { + template + struct apply : operator_l_inner + { + }; + }; + + // L op self + template + struct binary_op_r : operator_r + { + template + struct apply : operator_r_inner + { + }; + }; + + template + struct unary_op : operator_1 + { + template + struct apply : operator_1_inner + { + }; + }; + + // This type is what actually gets returned from operators used on + // self_t + template + struct operator_ + : mpl::if_< + is_same + , typename mpl::if_< + is_same + , binary_op + , binary_op_l::type> + >::type + , typename mpl::if_< + is_same + , unary_op + , binary_op_r::type> + >::type + >::type + { + }; +} + +# define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \ +namespace detail \ +{ \ + template <> \ + struct operator_l \ + { \ + template \ + struct apply \ + { \ + static inline PyObject* execute(L const& l, R const& r) \ + { \ + return detail::convert_result(expr); \ + } \ + }; \ + static char const* name() { return "__" #id "__"; } \ + }; \ + \ + template <> \ + struct operator_r \ + { \ + template \ + struct apply \ + { \ + static inline PyObject* execute(R const& r, L const& l) \ + { \ + return detail::convert_result(expr); \ + } \ + }; \ + static char const* name() { return "__" #rid "__"; } \ + }; \ +} + +# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \ +BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \ +namespace self_ns \ +{ \ + template \ + inline detail::operator_ \ + operator##op(L const&, R const&) \ + { \ + return detail::operator_(); \ + } \ +} + +BOOST_PYTHON_BINARY_OPERATOR(add, radd, +) +BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -) +BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *) +BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /) +BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %) +BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<) +BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>) +BOOST_PYTHON_BINARY_OPERATOR(and, rand, &) +BOOST_PYTHON_BINARY_OPERATOR(xor, rxor, ^) +BOOST_PYTHON_BINARY_OPERATOR(or, ror, |) +BOOST_PYTHON_BINARY_OPERATOR(gt, lt, >) +BOOST_PYTHON_BINARY_OPERATOR(ge, le, >=) +BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <) +BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=) +BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==) +BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=) +# undef BOOST_PYTHON_BINARY_OPERATOR + +// pow isn't an operator in C++; handle it specially. +BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r)) +# undef BOOST_PYTHON_BINARY_OPERATION + +namespace self_ns +{ +# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + template + inline detail::operator_ + pow(L const&, R const&) + { + return detail::operator_(); + } +# else + // When there's no argument-dependent lookup, we need these + // overloads to handle the case when everything is imported into the + // global namespace. Note that the plain overload below does /not/ + // take const& arguments. This is needed by MSVC6 at least, or it + // complains of ambiguities, since there's no partial ordering. + inline detail::operator_ + pow(self_t, self_t) + { + return detail::operator_(); + } + template + inline detail::operator_ + pow(self_t const&, R const&) + { + return detail::operator_(); + } + template + inline detail::operator_ + pow(L const&, self_t const&) + { + return detail::operator_(); + } +# endif +} + + +# define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \ +namespace detail \ +{ \ + template <> \ + struct operator_l \ + { \ + template \ + struct apply \ + { \ + static inline PyObject* \ + execute(back_reference l, R const& r) \ + { \ + l.get() op r; \ + return python::incref(l.source().ptr()); \ + } \ + }; \ + static char const* name() { return "__" #id "__"; } \ + }; \ +} \ +namespace self_ns \ +{ \ + template \ + inline detail::operator_ \ + operator##op(self_t const&, R const&) \ + { \ + return detail::operator_(); \ + } \ +} + +BOOST_PYTHON_INPLACE_OPERATOR(iadd,+=) +BOOST_PYTHON_INPLACE_OPERATOR(isub,-=) +BOOST_PYTHON_INPLACE_OPERATOR(imul,*=) +BOOST_PYTHON_INPLACE_OPERATOR(idiv,/=) +BOOST_PYTHON_INPLACE_OPERATOR(imod,%=) +BOOST_PYTHON_INPLACE_OPERATOR(ilshift,<<=) +BOOST_PYTHON_INPLACE_OPERATOR(irshift,>>=) +BOOST_PYTHON_INPLACE_OPERATOR(iand,&=) +BOOST_PYTHON_INPLACE_OPERATOR(ixor,^=) +BOOST_PYTHON_INPLACE_OPERATOR(ior,|=) + +# define BOOST_PYTHON_UNARY_OPERATOR(id, op, func_name) \ +namespace detail \ +{ \ + template <> \ + struct operator_1 \ + { \ + template \ + struct apply \ + { \ + static PyObject* execute(T const& x) \ + { \ + return detail::convert_result(op(x)); \ + } \ + }; \ + static char const* name() { return "__" #id "__"; } \ + }; \ +} \ +namespace self_ns \ +{ \ + inline detail::operator_ \ + func_name(self_t const&) \ + { \ + return detail::operator_(); \ + } \ +} +# undef BOOST_PYTHON_INPLACE_OPERATOR + +BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-) +BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+) +BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs) +BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~) +BOOST_PYTHON_UNARY_OPERATOR(int, long, int_) +BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_) +BOOST_PYTHON_UNARY_OPERATOR(float, double, float_) +BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex, complex_) +BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast, str) +# undef BOOST_PYTHON_UNARY_OPERATOR }} // namespace boost::python -# undef BOOST_PYTHON_USE_SSTREAM -# endif -#endif /* OPERATORS_UK112000_H_ */ +# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +using boost::python::self_ns::abs; +using boost::python::self_ns::int_; +using boost::python::self_ns::long_; +using boost::python::self_ns::float_; +using boost::python::self_ns::complex_; +using boost::python::self_ns::str; +using boost::python::self_ns::pow; +# endif + +#endif // OPERATORS_DWA2002530_HPP diff --git a/include/boost/python/operators2.hpp b/include/boost/python/operators2.hpp deleted file mode 100755 index 3f06eb46..00000000 --- a/include/boost/python/operators2.hpp +++ /dev/null @@ -1,340 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef OPERATORS2_DWA2002530_HPP -# define OPERATORS2_DWA2002530_HPP - -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - // This is essentially the old v1 to_python(). It will be eliminated - // once the public interface for to_python is settled on. - template - PyObject* convert_result(T const& x) - { - return converter::arg_to_python(x).release(); - } - - // Operator implementation template declarations. The nested apply - // declaration here keeps MSVC6 happy. - template struct operator_l - { - template struct apply; - }; - - template struct operator_r - { - template struct apply; - }; - - template struct operator_1 - { - template struct apply; - }; - - // MSVC6 doesn't want us to do this sort of inheritance on a nested - // class template, so we use this layer of indirection to avoid - // ::template<...> on the nested apply functions below - template - struct operator_l_inner - : operator_l::template apply - {}; - - template - struct operator_r_inner - : operator_r::template apply - {}; - - template - struct operator_1_inner - : operator_1::template apply - {}; - - // Define three different binary_op templates which take care of - // these cases: - // self op self - // self op R - // L op self - // - // The inner apply metafunction is used to adjust the operator to - // the class type being defined. Inheritance of the outer class is - // simply used to provide convenient access to the operation's - // name(). - - // self op self - template - struct binary_op : operator_l - { - template - struct apply : operator_l_inner - { - }; - }; - - // self op R - template - struct binary_op_l : operator_l - { - template - struct apply : operator_l_inner - { - }; - }; - - // L op self - template - struct binary_op_r : operator_r - { - template - struct apply : operator_r_inner - { - }; - }; - - template - struct unary_op : operator_1 - { - template - struct apply : operator_1_inner - { - }; - }; - - // This type is what actually gets returned from operators used on - // self_t - template - struct operator_ - : mpl::if_< - is_same - , typename mpl::if_< - is_same - , binary_op - , binary_op_l::type> - >::type - , typename mpl::if_< - is_same - , unary_op - , binary_op_r::type> - >::type - >::type - { - }; -} - -# define BOOST_PYTHON_BINARY_OPERATION(id, rid, expr) \ -namespace detail \ -{ \ - template <> \ - struct operator_l \ - { \ - template \ - struct apply \ - { \ - static inline PyObject* execute(L const& l, R const& r) \ - { \ - return detail::convert_result(expr); \ - } \ - }; \ - static char const* name() { return "__" #id "__"; } \ - }; \ - \ - template <> \ - struct operator_r \ - { \ - template \ - struct apply \ - { \ - static inline PyObject* execute(R const& r, L const& l) \ - { \ - return detail::convert_result(expr); \ - } \ - }; \ - static char const* name() { return "__" #rid "__"; } \ - }; \ -} - -# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \ -BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \ -namespace self_ns \ -{ \ - template \ - inline detail::operator_ \ - operator##op(L const&, R const&) \ - { \ - return detail::operator_(); \ - } \ -} - -BOOST_PYTHON_BINARY_OPERATOR(add, radd, +) -BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -) -BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *) -BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /) -BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %) -BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<) -BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>) -BOOST_PYTHON_BINARY_OPERATOR(and, rand, &) -BOOST_PYTHON_BINARY_OPERATOR(xor, rxor, ^) -BOOST_PYTHON_BINARY_OPERATOR(or, ror, |) -BOOST_PYTHON_BINARY_OPERATOR(gt, lt, >) -BOOST_PYTHON_BINARY_OPERATOR(ge, le, >=) -BOOST_PYTHON_BINARY_OPERATOR(lt, gt, <) -BOOST_PYTHON_BINARY_OPERATOR(le, ge, <=) -BOOST_PYTHON_BINARY_OPERATOR(eq, eq, ==) -BOOST_PYTHON_BINARY_OPERATOR(ne, ne, !=) -# undef BOOST_PYTHON_BINARY_OPERATOR - -// pow isn't an operator in C++; handle it specially. -BOOST_PYTHON_BINARY_OPERATION(pow, rpow, pow(l,r)) -# undef BOOST_PYTHON_BINARY_OPERATION - -namespace self_ns -{ -# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP - template - inline detail::operator_ - pow(L const&, R const&) - { - return detail::operator_(); - } -# else - // When there's no argument-dependent lookup, we need these - // overloads to handle the case when everything is imported into the - // global namespace. Note that the plain overload below does /not/ - // take const& arguments. This is needed by MSVC6 at least, or it - // complains of ambiguities, since there's no partial ordering. - inline detail::operator_ - pow(self_t, self_t) - { - return detail::operator_(); - } - template - inline detail::operator_ - pow(self_t const&, R const&) - { - return detail::operator_(); - } - template - inline detail::operator_ - pow(L const&, self_t const&) - { - return detail::operator_(); - } -# endif -} - - -# define BOOST_PYTHON_INPLACE_OPERATOR(id, op) \ -namespace detail \ -{ \ - template <> \ - struct operator_l \ - { \ - template \ - struct apply \ - { \ - static inline PyObject* \ - execute(back_reference l, R const& r) \ - { \ - l.get() op r; \ - return python::incref(l.source().ptr()); \ - } \ - }; \ - static char const* name() { return "__" #id "__"; } \ - }; \ -} \ -namespace self_ns \ -{ \ - template \ - inline detail::operator_ \ - operator##op(self_t const&, R const&) \ - { \ - return detail::operator_(); \ - } \ -} - -BOOST_PYTHON_INPLACE_OPERATOR(iadd,+=) -BOOST_PYTHON_INPLACE_OPERATOR(isub,-=) -BOOST_PYTHON_INPLACE_OPERATOR(imul,*=) -BOOST_PYTHON_INPLACE_OPERATOR(idiv,/=) -BOOST_PYTHON_INPLACE_OPERATOR(imod,%=) -BOOST_PYTHON_INPLACE_OPERATOR(ilshift,<<=) -BOOST_PYTHON_INPLACE_OPERATOR(irshift,>>=) -BOOST_PYTHON_INPLACE_OPERATOR(iand,&=) -BOOST_PYTHON_INPLACE_OPERATOR(ixor,^=) -BOOST_PYTHON_INPLACE_OPERATOR(ior,|=) - -# define BOOST_PYTHON_UNARY_OPERATOR(id, op, func_name) \ -namespace detail \ -{ \ - template <> \ - struct operator_1 \ - { \ - template \ - struct apply \ - { \ - static PyObject* execute(T const& x) \ - { \ - return detail::convert_result(op(x)); \ - } \ - }; \ - static char const* name() { return "__" #id "__"; } \ - }; \ -} \ -namespace self_ns \ -{ \ - inline detail::operator_ \ - func_name(self_t const&) \ - { \ - return detail::operator_(); \ - } \ -} -# undef BOOST_PYTHON_INPLACE_OPERATOR - -BOOST_PYTHON_UNARY_OPERATOR(neg, -, operator-) -BOOST_PYTHON_UNARY_OPERATOR(pos, +, operator+) -BOOST_PYTHON_UNARY_OPERATOR(abs, abs, abs) -BOOST_PYTHON_UNARY_OPERATOR(invert, ~, operator~) -BOOST_PYTHON_UNARY_OPERATOR(int, long, int_) -BOOST_PYTHON_UNARY_OPERATOR(long, PyLong_FromLong, long_) -BOOST_PYTHON_UNARY_OPERATOR(float, double, float_) -BOOST_PYTHON_UNARY_OPERATOR(complex, std::complex, complex_) -BOOST_PYTHON_UNARY_OPERATOR(str, lexical_cast, str) -# undef BOOST_PYTHON_UNARY_OPERATOR - -}} // namespace boost::python - -# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -using boost::python::self_ns::abs; -using boost::python::self_ns::int_; -using boost::python::self_ns::long_; -using boost::python::self_ns::float_; -using boost::python::self_ns::complex_; -using boost::python::self_ns::str; -using boost::python::self_ns::pow; -# endif - -#endif // OPERATORS2_DWA2002530_HPP - - - - - - - - diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index 60db3bb8..8c495106 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -25,7 +25,7 @@ namespace // { static registry_t registry; -# ifdef BOOST_PYTHON_DYNAMIC_LIB // this conditional should go away eventually. +# ifndef BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION static bool builtin_converters_initialized = false; if (!builtin_converters_initialized) { diff --git a/src/errors.cpp b/src/errors.cpp index 05e40658..8cda9f0e 100644 --- a/src/errors.cpp +++ b/src/errors.cpp @@ -10,9 +10,7 @@ #include #include -#ifdef BOOST_PYTHON_V2 -# include -#endif +#include namespace boost { namespace python { @@ -21,10 +19,8 @@ BOOST_PYTHON_DECL bool handle_exception_impl(function0 f) { try { -#ifdef BOOST_PYTHON_V2 if (detail::exception_handler::chain) return detail::exception_handler::chain->handle(f); -#endif f(); return false; } @@ -75,7 +71,6 @@ namespace detail { // needed by void_adaptor (see void_adaptor.hpp) BOOST_PYTHON_DECL PyObject arbitrary_object = { 0 }; -#ifdef BOOST_PYTHON_V2 bool exception_handler::operator()(function0 const& f) const { if (m_next) @@ -110,7 +105,6 @@ BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f) // interpreter exits). new exception_handler(f); } -#endif } // namespace boost::python::detail diff --git a/test/Jamfile b/test/Jamfile index de63e575..7a888842 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -120,8 +120,7 @@ if $(TEST_BIENSTMAN_NON_BUGS) # --- unit tests of library components --- -local UNIT_TEST_PROPERTIES = - [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] BOOST_PYTHON_STATIC_LIB ; +local UNIT_TEST_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION ; run indirect_traits_test.cpp ; run destroy_test.cpp ; diff --git a/test/comprehensive.cpp b/test/comprehensive.cpp deleted file mode 100644 index e3a756b9..00000000 --- a/test/comprehensive.cpp +++ /dev/null @@ -1,1265 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -// Revision History: -// 04 Mar 01 Changed name of extension module so it would work with DebugPython, -// eliminated useless test that aggravated MSVC (David Abrahams) -#include "comprehensive.hpp" -#include -#include // used for portability on broken compilers -#include // for pow() -#include - -#if defined(__sgi) \ - && ( (defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730) \ - && !defined(__GNUC__)) -inline double pow(int x, int y) { return pow(static_cast(x), y); } -#endif - -namespace bpl_test { - -FooCallback::FooCallback(PyObject* self, int x) - : Foo(x), m_self(self) -{ -} - -int FooCallback::add_len(const char* x) const -{ - // Try to call the "add_len" method on the corresponding Python object. - return boost::python::callback::call_method(m_self, "add_len", x); -} - -// A function which Python can call in case bar is not overridden from -// Python. In true Python style, we use a free function taking an initial self -// parameter. This function anywhere needn't be a static member of the callback -// class. The only reason to do it this way is that Foo::add_len is private, and -// FooCallback is already a friend of Foo. -int FooCallback::default_add_len(const Foo* self, const char* x) -{ - // Don't forget the Foo:: qualification, or you'll get an infinite - // recursion! - return self->Foo::add_len(x); -} - -// Since Foo::pure() is pure virtual, we don't need a corresponding -// default_pure(). A failure to override it in Python will result in an -// exception at runtime when pure() is called. -std::string FooCallback::pure() const -{ - return boost::python::callback::call_method(m_self, "pure"); -} - -Foo::PythonClass::PythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "Foo") -{ - def(boost::python::constructor()); - def(&Foo::mumble, "mumble"); - def(&Foo::set, "set"); - def(&Foo::call_pure, "call_pure"); - def(&Foo::call_add_len, "call_add_len"); - - // This is the way we add a virtual function that has a default implementation. - def(&Foo::add_len, "add_len", &FooCallback::default_add_len); - - // Since pure() is pure virtual, we are leaving it undefined. - - // And the nested classes. - boost::python::class_builder foo_a(*this, "Foo_A"); - foo_a.def(boost::python::constructor<>()); - foo_a.def(&Foo::Foo_A::mumble, "mumble"); - - boost::python::class_builder foo_b(get_extension_class(), - "Foo_B"); - foo_b.def(boost::python::constructor<>()); - foo_b.def(&Foo::Foo_B::mumble, "mumble"); -} - -BarPythonClass::BarPythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "Bar") -{ - def(boost::python::constructor()); - def(&Bar::first, "first"); - def(&Bar::second, "second"); - def(&Bar::pass_baz, "pass_baz"); -} - -BazPythonClass::BazPythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "Baz") // optional -{ - def(boost::python::constructor<>()); - def(&Baz::pass_bar, "pass_bar"); - def(&Baz::clone, "clone"); - def(&Baz::create_foo, "create_foo"); - def(&Baz::get_foo_value, "get_foo_value"); - def(&Baz::eat_baz, "eat_baz"); -} - -StringMapPythonClass::StringMapPythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "StringMap") -{ - def(boost::python::constructor<>()); - // Some compilers make the target of this function - // pointer the same type as the class in which it is defined (some - // standard library class), instead of StringMap. - def((std::size_t (StringMap::*)()const)&StringMap::size, "__len__"); - - def(&get_item, "__getitem__"); - def(&set_item, "__setitem__"); - def(&del_item, "__delitem__"); -} - -int get_first(const IntPair& p) -{ - return p.first; -} - -void set_first(IntPair& p, int value) -{ - p.first = -value; -} - -void del_first(const IntPair&) -{ - PyErr_SetString(PyExc_AttributeError, "first can't be deleted!"); - boost::python::throw_error_already_set(); -} - -IntPairPythonClass::IntPairPythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "IntPair") -{ - def(boost::python::constructor()); - def(&getattr, "__getattr__"); - def(&setattr, "__setattr__"); - def(&delattr, "__delattr__"); - def(&get_first, "__getattr__first__"); - def(&set_first, "__setattr__first__"); - def(&del_first, "__delattr__first__"); -} - -void IntPairPythonClass::setattr(IntPair& x, const std::string& name, int value) -{ - if (name == "second") - { - x.second = value; - } - else - { - PyErr_SetString(PyExc_AttributeError, name.c_str()); - boost::python::throw_error_already_set(); - } -} - -void IntPairPythonClass::delattr(IntPair&, const char*) -{ - PyErr_SetString(PyExc_AttributeError, "Attributes can't be deleted!"); - boost::python::throw_error_already_set(); -} - -int IntPairPythonClass::getattr(const IntPair& p, const std::string& s) -{ - if (s == "second") - { - return p.second; - } - else - { - PyErr_SetString(PyExc_AttributeError, s.c_str()); - boost::python::throw_error_already_set(); - } - return 0; -} - -namespace { namespace file_local { -void throw_key_error_if_end(const StringMap& m, StringMap::const_iterator p, std::size_t key) -{ - if (p == m.end()) - { - PyErr_SetObject(PyExc_KeyError, BOOST_PYTHON_CONVERSION::to_python(key)); - boost::python::throw_error_already_set(); - } -} -}} // namespace ::file_local - -const std::string& StringMapPythonClass::get_item(const StringMap& m, std::size_t key) -{ - const StringMap::const_iterator p = m.find(key); - file_local::throw_key_error_if_end(m, p, key); - return p->second; -} - -void StringMapPythonClass::set_item(StringMap& m, std::size_t key, const std::string& value) -{ - m[key] = value; -} - -void StringMapPythonClass::del_item(StringMap& m, std::size_t key) -{ - const StringMap::iterator p = m.find(key); - file_local::throw_key_error_if_end(m, p, key); - m.erase(p); -} - -// -// Show that polymorphism can work. a DerivedFromFoo object will be passed to -// Python in a smart pointer object. -// -class DerivedFromFoo : public Foo -{ -public: - DerivedFromFoo(int x) : Foo(x) {} - -private: - std::string pure() const - { return "this was never pure!"; } - - int add_len(const char*) const - { return 1000; } -}; - -// -// function implementations -// - -IntPair make_pair(int x, int y) -{ - return std::make_pair(x, y); -} - -const char* Foo::mumble() -{ - return "mumble"; -} - -const char* Foo::Foo_A::mumble() -{ - return "mumble a"; -} - -const char* Foo::Foo_B::mumble() -{ - return "mumble b"; -} - -void Foo::set(long x) -{ - m_x = x; -} - -std::string Foo::call_pure() -{ - return this->pure(); -} - -int Foo::call_add_len(const char* s) const -{ - return this->add_len(s); -} - -int Foo::add_len(const char* s) const // sum the held value and the length of s -{ - return BOOST_CSTD_::strlen(s) + static_cast(m_x); -} - -boost::shared_ptr Baz::create_foo() -{ - return boost::shared_ptr(new DerivedFromFoo(0)); -} - -// Used to check conversion to None -boost::shared_ptr foo_factory(bool create) -{ - return boost::shared_ptr(create ? new DerivedFromFoo(0) : 0); -} - -// Used to check conversion from None -bool foo_ptr_is_null(Foo* p) -{ - return p == 0; -} - -bool foo_shared_ptr_is_null(boost::shared_ptr p) -{ - return p.get() == 0; -} - -// We can accept smart pointer parameters -int Baz::get_foo_value(boost::shared_ptr foo) -{ - return foo->call_add_len(""); -} - -// Show what happens in python when we take ownership from an auto_ptr -void Baz::eat_baz(std::auto_ptr baz) -{ - baz->clone(); // just do something to show that it is valid. -} - -Baz Bar::pass_baz(Baz b) -{ - return b; -} - -std::string stringpair_repr(const StringPair& sp) -{ - return "('" + sp.first + "', '" + sp.second + "')"; -} - -int stringpair_compare(const StringPair& sp1, const StringPair& sp2) -{ - return sp1 < sp2 ? -1 : sp2 < sp1 ? 1 : 0; -} - -boost::python::string range_str(const Range& r) -{ - char buf[200]; - sprintf(buf, "(%d, %d)", r.m_start, r.m_finish); - return boost::python::string(buf); -} - -int range_compare(const Range& r1, const Range& r2) -{ - int d = r1.m_start - r2.m_start; - if (d == 0) - d = r1.m_finish - r2.m_finish; - return d; -} - -long range_hash(const Range& r) -{ - return r.m_start * 123 + r.m_finish; -} - -/************************************************************/ -/* */ -/* some functions to test overloading */ -/* */ -/************************************************************/ - -static std::string testVoid() -{ - return std::string("Hello world!"); -} - -static int testInt(int i) -{ - return i; -} - -static std::string testString(std::string i) -{ - return i; -} - -static int test2(int i1, int i2) -{ - return i1+i2; -} - -static int test3(int i1, int i2, int i3) -{ - return i1+i2+i3; -} - -static int test4(int i1, int i2, int i3, int i4) -{ - return i1+i2+i3+i4; -} - -static int test5(int i1, int i2, int i3, int i4, int i5) -{ - return i1+i2+i3+i4+i5; -} - -/************************************************************/ -/* */ -/* a class to test overloading */ -/* */ -/************************************************************/ - -struct OverloadTest -{ - OverloadTest(): x_(1000) {} - OverloadTest(int x): x_(x) {} - OverloadTest(int x,int y): x_(x+y) { } - OverloadTest(int x,int y,int z): x_(x+y+z) {} - OverloadTest(int x,int y,int z, int a): x_(x+y+z+a) {} - OverloadTest(int x,int y,int z, int a, int b): x_(x+y+z+a+b) {} - - int x() const { return x_; } - void setX(int x) { x_ = x; } - - int p1(int x) { return x; } - int p2(int x, int y) { return x + y; } - int p3(int x, int y, int z) { return x + y + z; } - int p4(int x, int y, int z, int a) { return x + y + z + a; } - int p5(int x, int y, int z, int a, int b) { return x + y + z + a + b; } - private: - int x_; -}; - -static int getX(OverloadTest* u) -{ - return u->x(); -} - - -/************************************************************/ -/* */ -/* classes to test base declarations and conversions */ -/* */ -/************************************************************/ - -struct Dummy -{ - virtual ~Dummy() {} - int dummy_; -}; - -struct Base -{ - virtual int x() const { return 999; }; - virtual ~Base() {} -}; - -// inherit Dummy so that the Base part of Concrete starts at an offset -// otherwise, typecast tests wouldn't be very meaningful -struct Derived1 : public Dummy, public Base -{ - Derived1(int x): x_(x) {} - virtual int x() const { return x_; } - - private: - int x_; -}; - -struct Derived2 : public Dummy, public Base -{ - Derived2(int x): x_(x) {} - virtual int x() const { return x_; } - - private: - int x_; -}; - -static int testUpcast(Base* b) -{ - return b->x(); -} - -static std::auto_ptr derived1Factory(int i) -{ - return std::auto_ptr(i < 0 ? 0 : new Derived1(i)); -} - -static std::auto_ptr derived2Factory(int i) -{ - return std::auto_ptr(new Derived2(i)); -} - -static int testDowncast1(Derived1* d) -{ - return d->x(); -} - -static int testDowncast2(Derived2* d) -{ - return d->x(); -} - -/************************************************************/ -/* */ -/* test classes for interaction of overloading, */ -/* base declarations, and callbacks */ -/* */ -/************************************************************/ - -struct CallbackTestBase -{ - virtual int testCallback(int i) { return callback(i); } - virtual int callback(int i) = 0; - virtual ~CallbackTestBase() {} -}; - -struct CallbackTest : public CallbackTestBase -{ - virtual int callback(int i) { return i + 1; } - virtual std::string callbackString(std::string const & i) { return i + " 1"; } -}; - -struct CallbackTestCallback : public CallbackTest -{ - CallbackTestCallback(PyObject* self) - : m_self(self) - {} - - int callback(int x) - { - return boost::python::callback::call_method(m_self, "callback", x); - } - std::string callbackString(std::string const & x) - { - return boost::python::callback::call_method(m_self, "callback", x); - } - - static int default_callback(CallbackTest* self, int x) - { - return self->CallbackTest::callback(x); - } - static std::string default_callbackString(CallbackTest* self, std::string x) - { - return self->CallbackTest::callbackString(x); - } - - PyObject* m_self; -}; - -int testCallback(CallbackTestBase* b, int i) -{ - return b->testCallback(i); -} - -/************************************************************/ -/* */ -/* test classes for interaction of method lookup */ -/* in the context of inheritance */ -/* */ -/************************************************************/ - -struct A1 { - virtual ~A1() {} - virtual std::string overrideA1() const { return "A1::overrideA1"; } - virtual std::string inheritA1() const { return "A1::inheritA1"; } -}; - -struct A2 { - virtual ~A2() {} - virtual std::string inheritA2() const { return "A2::inheritA2"; } -}; - -struct B1 : A1, A2 { - std::string overrideA1() const { return "B1::overrideA1"; } - virtual std::string overrideB1() const { return "B1::overrideB1"; } -}; - -struct B2 : A1, A2 { - std::string overrideA1() const { return "B2::overrideA1"; } - virtual std::string inheritB2() const { return "B2::inheritB2"; } -}; - -struct C : B1 { - std::string overrideB1() const { return "C::overrideB1"; } -}; - -std::string call_overrideA1(const A1& a) { return a.overrideA1(); } -std::string call_overrideB1(const B1& b) { return b.overrideB1(); } -std::string call_inheritA1(const A1& a) { return a.inheritA1(); } - -std::auto_ptr factoryA1asA1() { return std::auto_ptr(new A1); } -std::auto_ptr factoryB1asA1() { return std::auto_ptr(new B1); } -std::auto_ptr factoryB2asA1() { return std::auto_ptr(new B2); } -std::auto_ptr factoryCasA1() { return std::auto_ptr(new C); } -std::auto_ptr factoryA2asA2() { return std::auto_ptr(new A2); } -std::auto_ptr factoryB1asA2() { return std::auto_ptr(new B1); } -std::auto_ptr factoryB1asB1() { return std::auto_ptr(new B1); } -std::auto_ptr factoryCasB1() { return std::auto_ptr(new C); } - -struct B_callback : B1 { - B_callback(PyObject* self) : m_self(self) {} - - std::string overrideA1() const { return boost::python::callback::call_method(m_self, "overrideA1"); } - std::string overrideB1() const { return boost::python::callback::call_method(m_self, "overrideB1"); } - - static std::string default_overrideA1(B1& x) { return x.B1::overrideA1(); } - static std::string default_overrideB1(B1& x) { return x.B1::overrideB1(); } - - PyObject* m_self; -}; - -struct A_callback : A1 { - A_callback(PyObject* self) : m_self(self) {} - - std::string overrideA1() const { return boost::python::callback::call_method(m_self, "overrideA1"); } - std::string inheritA1() const { return boost::python::callback::call_method(m_self, "inheritA1"); } - - static std::string default_overrideA1(A1& x) { return x.A1::overrideA1(); } - static std::string default_inheritA1(A1& x) { return x.A1::inheritA1(); } - - PyObject* m_self; -}; - -/************************************************************/ -/* */ -/* RawTest */ -/* (test passing of raw arguments to C++) */ -/* */ -/************************************************************/ - -struct RawTest -{ - RawTest(int i) : i_(i) {} - - int i_; -}; - -PyObject* raw(boost::python::tuple const & args, boost::python::dictionary const & keywords); - -int raw1(PyObject* args, PyObject* keywords) -{ - return PyTuple_Size(args) + PyDict_Size(keywords); -} - -int raw2(boost::python::ref args, boost::python::ref keywords) -{ - return PyTuple_Size(args.get()) + PyDict_Size(keywords.get()); -} - - - -/************************************************************/ -/* */ -/* Ratio */ -/* */ -/************************************************************/ - -typedef boost::rational Ratio; - -boost::python::string ratio_str(const Ratio& r) -{ - char buf[200]; - - if (r.denominator() == 1) - sprintf(buf, "%d", r.numerator()); - else - sprintf(buf, "%d/%d", r.numerator(), r.denominator()); - - return boost::python::string(buf); -} - -boost::python::string ratio_repr(const Ratio& r) -{ - char buf[200]; - sprintf(buf, "Rational(%d, %d)", r.numerator(), r.denominator()); - return boost::python::string(buf); -} - -boost::python::tuple ratio_coerce(const Ratio& r1, int r2) -{ - return boost::python::tuple(r1, Ratio(r2)); -} - -// The most reliable way, across compilers, to grab the particular abs function -// we're interested in. -Ratio ratio_abs(const Ratio& r) -{ - return boost::abs(r); -} - -// An experiment, to be integrated into the py_cpp library at some point. -template -struct StandardOps -{ - static T add(const T& x, const T& y) { return x + y; } - static T sub(const T& x, const T& y) { return x - y; } - static T mul(const T& x, const T& y) { return x * y; } - static T div(const T& x, const T& y) { return x / y; } - static T cmp(const T& x, const T& y) { return std::less()(x, y) ? -1 : std::less()(y, x) ? 1 : 0; } -}; - -// This helps us prove that we can now pass non-const reference parameters to constructors -struct Fubar { - Fubar(Foo&) {} - Fubar(int) {} -}; - -/************************************************************/ -/* */ -/* Int */ -/* this class tests operator export */ -/* */ -/************************************************************/ - -#ifndef NDEBUG -int total_Ints = 0; -#endif - -struct Int -{ - explicit Int(int i) : i_(i), j_(0) { -#ifndef NDEBUG - ++total_Ints; -#endif - } - -#ifndef NDEBUG - ~Int() { --total_Ints; } - Int(const Int& rhs) : i_(rhs.i_), j_(rhs.j_) { ++total_Ints; } -#endif - - int i() const { return i_; } - int j() const { return j_; } - - int i_; - int j_; - - Int& operator +=(Int const& r) { ++j_; i_ += r.i_; return *this; } - Int& operator -=(Int const& r) { ++j_; i_ -= r.i_; return *this; } - Int& operator *=(Int const& r) { ++j_; i_ *= r.i_; return *this; } - Int& operator /=(Int const& r) { ++j_; i_ /= r.i_; return *this; } - Int& operator %=(Int const& r) { ++j_; i_ %= r.i_; return *this; } - Int& ipow (Int const& r) { ++j_; - int o=i_; - for (int k=1; k>=(Int const& r) { ++j_; i_ >>= r.i_; return *this; } - Int& operator &=(Int const& r) { ++j_; i_ &= r.i_; return *this; } - Int& operator |=(Int const& r) { ++j_; i_ |= r.i_; return *this; } - Int& operator ^=(Int const& r) { ++j_; i_ ^= r.i_; return *this; } -}; - -Int operator+(Int const & l, Int const & r) { return Int(l.i_ + r.i_); } -Int operator+(Int const & l, int const & r) { return Int(l.i_ + r); } -Int operator+(int const & l, Int const & r) { return Int(l + r.i_); } - -Int operator-(Int const & l, Int const & r) { return Int(l.i_ - r.i_); } -Int operator-(Int const & l, int const & r) { return Int(l.i_ - r); } -Int operator-(int const & l, Int const & r) { return Int(l - r.i_); } -Int operator-(Int const & r) { return Int(- r.i_); } - -Int mul(Int const & l, Int const & r) { return Int(l.i_ * r.i_); } -Int imul(Int const & l, int const & r) { return Int(l.i_ * r); } -Int rmul(Int const & r, int const & l) { return Int(l * r.i_); } - -Int operator/(Int const & l, Int const & r) { return Int(l.i_ / r.i_); } - -Int operator%(Int const & l, Int const & r) { return Int(l.i_ % r.i_); } - -bool operator<(Int const & l, Int const & r) { return l.i_ < r.i_; } -bool operator<(Int const & l, int const & r) { return l.i_ < r; } -bool operator<(int const & l, Int const & r) { return l < r.i_; } - -Int pow(Int const & l, Int const & r) { return Int(static_cast(::pow(l.i_, r.i_))); } -Int powmod(Int const & l, Int const & r, Int const & m) { return Int((int)::pow(l.i_, r.i_) % m.i_); } -Int pow(Int const & l, int const & r) { return Int(static_cast(::pow(l.i_, r))); } - -std::ostream & operator<<(std::ostream & o, Int const & r) { return (o << r.i_); } - -/************************************************************/ -/* */ -/* double tests from Mark Evans() */ -/* */ -/************************************************************/ -double sizelist(boost::python::list list) { return list.size(); } -void vd_push_back(std::vector& vd, const double& x) -{ - vd.push_back(x); -} - -/************************************************************/ -/* */ -/* What if I want to return a pointer? */ -/* */ -/************************************************************/ - -// -// This example exposes the pointer by copying its referent -// -struct Record { - Record(int x) : value(x){} - int value; -}; - -const Record* get_record() -{ - static Record v(1234); - return &v; -} - -} // namespace bpl_test - -namespace boost { namespace python { - template class class_builder; // explicitly instantiate -}} // namespace boost::python - -BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE -inline PyObject* to_python(const bpl_test::Record* p) -{ - return to_python(*p); -} -BOOST_PYTHON_END_CONVERSION_NAMESPACE - -/************************************************************/ -/* */ -/* Enums and non-method class attributes */ -/* */ -/************************************************************/ - -namespace bpl_test { - -struct EnumOwner -{ - public: - enum enum_type { one = 1, two = 2, three = 3 }; - - EnumOwner(enum_type a1, const enum_type& a2) - : m_first(a1), m_second(a2) {} - - void set_first(const enum_type& x) { m_first = x; } - void set_second(const enum_type& x) { m_second = x; } - - enum_type first() { return m_first; } - enum_type second() { return m_second; } - private: - enum_type m_first, m_second; -}; - -} - -namespace boost { namespace python { - template class enum_as_int_converters; - using bpl_test::pow; -}} // namespace boost::python - -// This is just a way of getting the converters instantiated -//struct EnumOwner_enum_type_Converters -// : boost::python::py_enum_as_int_converters -//{ -//}; - -namespace bpl_test { - -/************************************************************/ -/* */ -/* pickling support */ -/* */ -/************************************************************/ - class world - { - private: - std::string country; - int secret_number; - public: - world(const std::string& country) : secret_number(0) { - this->country = country; - } - std::string greet() const { return "Hello from " + country + "!"; } - std::string get_country() const { return country; } - void set_secret_number(int number) { secret_number = number; } - int get_secret_number() const { return secret_number; } - }; - - // Support for pickle. - boost::python::tuple world_getinitargs(const world& w) - { - boost::python::tuple result(1); - result.set_item(0, w.get_country()); - return result; - } - - boost::python::tuple world_getstate(const world& w) - { - boost::python::tuple result(1); - result.set_item(0, w.get_secret_number()); - return result; - } - - void world_setstate(world& w, boost::python::tuple state) - { - if (state.size() != 1) { - PyErr_SetString(PyExc_ValueError, - "Unexpected argument in call to __setstate__."); - boost::python::throw_error_already_set(); - } - - const int number = BOOST_PYTHON_CONVERSION::from_python(state[0].get(), boost::python::type()); - if (number != 42) - w.set_secret_number(number); - } - - // Test plain char converters. - char get_plain_char() { return 'x'; } - std::string use_plain_char(char c) { return std::string(3, c); } - - // This doesn't test anything but the compiler, since it has the same signature as the above. - // Since MSVC is broken and gets the signature wrong, we'll skip it. - std::string use_const_plain_char( -#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - const -#endif - char c) { return std::string(5, c); } - - // Test std::complex converters. - std::complex dpolar(double rho, double theta) { - return std::polar(rho, theta); - } - double dreal(const std::complex& c) { return c.real(); } - double dimag(std::complex c) { return c.imag(); } - - // Test std::complex converters. - std::complex fpolar(float rho, float theta) { - return std::polar(rho, theta); - } - double freal(const std::complex& c) { return c.real(); } - double fimag(std::complex c) { return c.imag(); } - - // Wrappers for inplace operators. - Int& int_iadd(Int& self, const Int& r) { self += r; return self; } - Int& int_isub(Int& self, const Int& r) { self -= r; return self; } - Int& int_imul(Int& self, const Int& r) { self *= r; return self; } - Int& int_idiv(Int& self, const Int& r) { self /= r; return self; } - Int& int_imod(Int& self, const Int& r) { self %= r; return self; } - Int& int_ipow(Int& self, const Int& r) { self.ipow (r); return self; } - Int& int_ilshift(Int& self, const Int& r) { self <<= r; return self; } - Int& int_irshift(Int& self, const Int& r) { self >>= r; return self; } - Int& int_iand(Int& self, const Int& r) { self &= r; return self; } - Int& int_ior(Int& self, const Int& r) { self |= r; return self; } - Int& int_ixor(Int& self, const Int& r) { self ^= r; return self; } - -/************************************************************/ -/* */ -/* init the module */ -/* */ -/************************************************************/ - -void init_module(boost::python::module_builder& m) -{ - m.def(get_record, "get_record"); - boost::python::class_builder record_class(m, "Record"); - record_class.def_readonly(&Record::value, "value"); - - m.def(sizelist, "sizelist"); - - boost::python::class_builder > vector_double(m, "vector_double"); - vector_double.def(boost::python::constructor<>()); - vector_double.def(vd_push_back, "push_back"); - - boost::python::class_builder fubar(m, "Fubar"); - fubar.def(boost::python::constructor()); - fubar.def(boost::python::constructor()); - - Foo::PythonClass foo(m); - BarPythonClass bar(m); - BazPythonClass baz(m); - StringMapPythonClass string_map(m); - IntPairPythonClass int_pair(m); - m.def(make_pair, "make_pair"); - CompareIntPairPythonClass compare_int_pair(m); - - boost::python::class_builder string_pair(m, "StringPair"); - string_pair.def(boost::python::constructor()); - string_pair.def_readonly(&StringPair::first, "first"); - string_pair.def_read_write(&StringPair::second, "second"); - string_pair.def(&stringpair_repr, "__repr__"); - string_pair.def(&stringpair_compare, "__cmp__"); - m.def(first_string, "first_string"); - m.def(second_string, "second_string"); - - // This shows the wrapping of a 3rd-party numeric type. - boost::python::class_builder > rational(m, "Rational"); - rational.def(boost::python::constructor()); - rational.def(boost::python::constructor()); - rational.def(boost::python::constructor<>()); - rational.def(StandardOps::add, "__add__"); - rational.def(StandardOps::sub, "__sub__"); - rational.def(StandardOps::mul, "__mul__"); - rational.def(StandardOps::div, "__div__"); - rational.def(StandardOps::cmp, "__cmp__"); - rational.def(ratio_coerce, "__coerce__"); - rational.def(ratio_str, "__str__"); - rational.def(ratio_repr, "__repr__"); - rational.def(ratio_abs, "__abs__"); - - boost::python::class_builder range(m, "Range"); - range.def(boost::python::constructor()); - range.def(boost::python::constructor()); - range.def((std::size_t (Range::*)() const)&Range::length, "__len__"); - range.def((void (Range::*)(std::size_t))&Range::length, "__len__"); - range.def(&Range::operator[], "__getitem__"); - range.def(&Range::slice, "__getslice__"); - range.def(&range_str, "__str__"); - range.def(&range_compare, "__cmp__"); - range.def(&range_hash, "__hash__"); - range.def_readonly(&Range::m_start, "start"); - range.def_readonly(&Range::m_finish, "finish"); - - m.def(&testVoid, "overloaded"); - m.def(&testInt, "overloaded"); - m.def(&testString, "overloaded"); - m.def(&test2, "overloaded"); - m.def(&test3, "overloaded"); - m.def(&test4, "overloaded"); - m.def(&test5, "overloaded"); - - boost::python::class_builder over(m, "OverloadTest"); - over.def(boost::python::constructor<>()); - over.def(boost::python::constructor()); - over.def(boost::python::constructor()); - over.def(boost::python::constructor()); - over.def(boost::python::constructor()); - over.def(boost::python::constructor()); - over.def(boost::python::constructor()); - over.def(&getX, "getX"); - over.def(&OverloadTest::setX, "setX"); - over.def(&OverloadTest::x, "overloaded"); - over.def(&OverloadTest::p1, "overloaded"); - over.def(&OverloadTest::p2, "overloaded"); - over.def(&OverloadTest::p3, "overloaded"); - over.def(&OverloadTest::p4, "overloaded"); - over.def(&OverloadTest::p5, "overloaded"); - - boost::python::class_builder base(m, "Base"); - base.def(&Base::x, "x"); - - boost::python::class_builder derived1(m, "Derived1"); - // this enables conversions between Base and Derived1 - // and makes wrapped methods of Base available - derived1.declare_base(base); - derived1.def(boost::python::constructor()); - - boost::python::class_builder derived2(m, "Derived2"); - // don't enable downcast from Base to Derived2 - derived2.declare_base(base, boost::python::without_downcast); - derived2.def(boost::python::constructor()); - - m.def(&testUpcast, "testUpcast"); - m.def(&derived1Factory, "derived1Factory"); - m.def(&derived2Factory, "derived2Factory"); - m.def(&testDowncast1, "testDowncast1"); - m.def(&testDowncast2, "testDowncast2"); - - boost::python::class_builder callbackTestBase(m, "CallbackTestBase"); - callbackTestBase.def(&CallbackTestBase::testCallback, "testCallback"); - m.def(&testCallback, "testCallback"); - - boost::python::class_builder callbackTest(m, "CallbackTest"); - callbackTest.def(boost::python::constructor<>()); - callbackTest.def(&CallbackTest::callback, "callback", - &CallbackTestCallback::default_callback); - callbackTest.def(&CallbackTest::callbackString, "callback", - &CallbackTestCallback::default_callbackString); - - callbackTest.declare_base(callbackTestBase); - - boost::python::class_builder a1_class(m, "A1"); - a1_class.def(boost::python::constructor<>()); - a1_class.def(&A1::overrideA1, "overrideA1", &A_callback::default_overrideA1); - a1_class.def(&A1::inheritA1, "inheritA1", &A_callback::default_inheritA1); - - boost::python::class_builder a2_class(m, "A2"); - a2_class.def(boost::python::constructor<>()); - a2_class.def(&A2::inheritA2, "inheritA2"); - - boost::python::class_builder b1_class(m, "B1"); - b1_class.declare_base(a1_class); - b1_class.declare_base(a2_class); - - b1_class.def(boost::python::constructor<>()); - b1_class.def(&B1::overrideA1, "overrideA1", &B_callback::default_overrideA1); - b1_class.def(&B1::overrideB1, "overrideB1", &B_callback::default_overrideB1); - - boost::python::class_builder b2_class(m, "B2"); - b2_class.declare_base(a1_class); - b2_class.declare_base(a2_class); - - b2_class.def(boost::python::constructor<>()); - b2_class.def(&B2::overrideA1, "overrideA1"); - b2_class.def(&B2::inheritB2, "inheritB2"); - - m.def(call_overrideA1, "call_overrideA1"); - m.def(call_overrideB1, "call_overrideB1"); - m.def(call_inheritA1, "call_inheritA1"); - - m.def(factoryA1asA1, "factoryA1asA1"); - m.def(factoryB1asA1, "factoryB1asA1"); - m.def(factoryB2asA1, "factoryB2asA1"); - m.def(factoryCasA1, "factoryCasA1"); - m.def(factoryA2asA2, "factoryA2asA2"); - m.def(factoryB1asA2, "factoryB1asA2"); - m.def(factoryB1asB1, "factoryB1asB1"); - m.def(factoryCasB1, "factoryCasB1"); - - boost::python::class_builder rawtest_class(m, "RawTest"); - rawtest_class.def(boost::python::constructor()); - rawtest_class.def_raw(&raw, "raw"); - - m.def_raw(&raw, "raw"); - m.def_raw(&raw1, "raw1"); - m.def_raw(&raw2, "raw2"); - - boost::python::class_builder int_class(m, "Int"); - int_class.def(boost::python::constructor()); - int_class.def(&Int::i, "i"); - int_class.def(&Int::j, "j"); - - // wrap homogeneous operators - int_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub | boost::python::op_neg | - boost::python::op_cmp | boost::python::op_str | boost::python::op_divmod | boost::python::op_pow )>()); - // export non-operator functions as homogeneous operators - int_class.def(&mul, "__mul__"); - int_class.def(&powmod, "__pow__"); - - // wrap heterogeneous operators (lhs: Int const &, rhs: int const &) - int_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub | boost::python::op_cmp | boost::python::op_pow)>(), - boost::python::right_operand()); - // export non-operator function as heterogeneous operator - int_class.def(&imul, "__mul__"); - - // wrap heterogeneous operators (lhs: int const &, rhs: Int const &) - int_class.def(boost::python::operators<(boost::python::op_add | boost::python::op_sub | boost::python::op_cmp)>(), - boost::python::left_operand()); - // export non-operator function as heterogeneous reverse-argument operator - int_class.def(&rmul, "__rmul__"); - -#if PYTHON_API_VERSION >= 1010 - // inplace operators. - int_class.def(&int_iadd, "__iadd__"); - int_class.def(&int_isub, "__isub__"); - int_class.def(&int_imul, "__imul__"); - int_class.def(&int_idiv, "__idiv__"); - int_class.def(&int_imod, "__imod__"); - int_class.def(&int_ipow, "__ipow__"); - int_class.def(&int_ilshift, "__ilshift__"); - int_class.def(&int_irshift, "__irshift__"); - int_class.def(&int_iand, "__iand__"); - int_class.def(&int_ior, "__ior__"); - int_class.def(&int_ixor, "__ixor__"); -#endif - - - boost::python::class_builder enum_owner(m, "EnumOwner"); - enum_owner.def(boost::python::constructor()); - enum_owner.def(&EnumOwner::set_first, "__setattr__first__"); - enum_owner.def(&EnumOwner::set_second, "__setattr__second__"); - enum_owner.def(&EnumOwner::first, "__getattr__first__"); - enum_owner.def(&EnumOwner::second, "__getattr__second__"); - enum_owner.add(PyInt_FromLong(EnumOwner::one), "one"); - enum_owner.add(PyInt_FromLong(EnumOwner::two), "two"); - enum_owner.add(PyInt_FromLong(EnumOwner::three), "three"); - - // pickling support - - // Create the Python type object for our extension class. - boost::python::class_builder world_class(m, "world"); - - // Add the __init__ function. - world_class.def(boost::python::constructor()); - // Add a regular member function. - world_class.def(&world::greet, "greet"); - world_class.def(&world::get_secret_number, "get_secret_number"); - world_class.def(&world::set_secret_number, "set_secret_number"); - - // Support for pickle. - world_class.def(world_getinitargs, "__getinitargs__"); - world_class.def(world_getstate, "__getstate__"); - world_class.def(world_setstate, "__setstate__"); - - // Test plain char converters. - m.def(get_plain_char, "get_plain_char"); - m.def(use_plain_char, "use_plain_char"); - m.def(use_const_plain_char, "use_const_plain_char"); - - // Test std::complex converters. - m.def(dpolar, "dpolar"); - m.def(dreal, "dreal"); - m.def(dimag, "dimag"); - - // Test std::complex converters. - m.def(fpolar, "fpolar"); - m.def(freal, "freal"); - m.def(fimag, "fimag"); - - // Test new null-pointer<->None conversions - m.def(foo_factory, "foo_factory"); - m.def(foo_ptr_is_null, "foo_ptr_is_null"); - m.def(foo_shared_ptr_is_null, "foo_shared_ptr_is_null"); -} - -PyObject* raw(const boost::python::tuple& args, const boost::python::dictionary& keywords) -{ - if(args.size() != 2 || keywords.size() != 2) - { - PyErr_SetString(PyExc_TypeError, "wrong number of arguments"); - boost::python::throw_argument_error(); - } - - RawTest* first = BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type()); - int second = BOOST_PYTHON_CONVERSION::from_python(args[1].get(), boost::python::type()); - - int third = BOOST_PYTHON_CONVERSION::from_python(keywords[boost::python::string("third")].get(), boost::python::type()); - int fourth = BOOST_PYTHON_CONVERSION::from_python(keywords[boost::python::string("fourth")].get(), boost::python::type()); - - return BOOST_PYTHON_CONVERSION::to_python(first->i_ + second + third + fourth); -} - -BOOST_PYTHON_MODULE(boost_python_test) -{ - boost::python::module_builder boost_python_test("boost_python_test"); - init_module(boost_python_test); - - // Just for giggles, add a raw metaclass. - boost_python_test.add(new boost::python::meta_class); -} - -CompareIntPairPythonClass::CompareIntPairPythonClass(boost::python::module_builder& m) - : boost::python::class_builder(m, "CompareIntPair") -{ - def(boost::python::constructor<>()); - def(&CompareIntPair::operator(), "__call__"); -} - -} // namespace bpl_test - - -#if defined(_WIN32) -# ifdef __MWERKS__ -# pragma ANSI_strict off -# endif -# include -# ifdef __MWERKS__ -# pragma ANSI_strict reset -# endif -extern "C" BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved ); - -# ifdef BOOST_MSVC -extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*) -# if BOOST_MSVC > 1200 - throw(...) -# endif -{ - throw; -} -# endif - -#ifndef NDEBUG -namespace boost { namespace python { namespace detail { - extern int total_Dispatchers; -}}} // namespace boost::python::detail -#endif - -BOOL WINAPI DllMain( - HINSTANCE, //hDllInst - DWORD fdwReason, - LPVOID // lpvReserved - ) -{ -# ifdef BOOST_MSVC - _set_se_translator(structured_exception_translator); -#endif - (void)fdwReason; // warning suppression. - -#ifndef NDEBUG - switch(fdwReason) - { - case DLL_PROCESS_DETACH: - assert(bpl_test::total_Ints == 0); - } -#endif - - return 1; -} -#endif // _WIN32 diff --git a/test/comprehensive.hpp b/test/comprehensive.hpp deleted file mode 100644 index 370f7d04..00000000 --- a/test/comprehensive.hpp +++ /dev/null @@ -1,235 +0,0 @@ -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -#ifndef BPL_TEST_DWA052200_H_ -# define BPL_TEST_DWA052200_H_ -// -// Example code demonstrating extension class usage -// - -# include -# include -# include -# include -# include -# include -# include -# include - -namespace bpl_test { - -// -// example: Foo, Bar, and Baz are C++ classes we want to wrap. -// - -class Foo // prohibit copying, proving that it doesn't choke - : private boost::noncopyable // our generation of to_python(). -{ - public: // constructor/destructor - Foo(int x) : m_x(x) {} - virtual ~Foo() {} - - public: // non-virtual functions - const char* mumble(); // mumble something - void set(long x); // change the held value - - // These two call virtual functions - std::string call_pure(); // call a pure virtual fuction - int call_add_len(const char* s) const; // virtual function with a default implementation - - // A couple nested classs. - struct Foo_A { const char* mumble(); }; - struct Foo_B { const char* mumble(); }; - - private: - // by default, sum the held value and the length of s - virtual int add_len(const char* s) const; - - // Derived classes can do whatever they want here, but they must do something! - virtual std::string pure() const = 0; - - public: // friend declarations - // If you have private virtual functions such as add_len which you want to - // override in Python and have default implementations, they must be - // accessible by the thing making the def() call on the extension_class (in - // this case, the nested PythonClass itself), and by the C++ derived class - // which is used to cause the Python callbacks (in this case, - // FooCallback). See the definition of FooCallback::add_len() - struct PythonClass; - friend struct PythonClass; - friend class FooCallback; - - private: - int m_x; // the held value -}; - -// -// Bar and Baz have mutually-recursive type conversion dependencies (see -// pass_xxx functions). I've done this to prove that it doesn't cause a -// problem for Python class definitions, which happen later. -// -// Bar and Baz functions are only virtual to increase the likelihood of a crash -// if I inadvertently use a pointer to garbage memory (a likely thing to test -// for considering the amount of type casting needed to translate to and from -// Python). -struct Baz; -struct Bar -{ - Bar(int x, int y) : m_first(x), m_second(y) {} - virtual int first() const { return m_first; } - virtual int second() const { return m_second; } - virtual Baz pass_baz(Baz x); - - int m_first, m_second; -}; - -struct Baz -{ - virtual Bar pass_bar(const Bar& x) { return x; } - - // We can return smart pointers - virtual std::auto_ptr clone() { return std::auto_ptr(new Baz(*this)); } - - // This illustrates creating a polymorphic derived class of Foo - virtual boost::shared_ptr create_foo(); - - // We can accept smart pointer parameters - virtual int get_foo_value(boost::shared_ptr); - - // Show what happens in python when we take ownership from an auto_ptr - virtual void eat_baz(std::auto_ptr); -}; - -typedef std::map StringMap; -typedef std::pair IntPair; - -IntPair make_pair(int, int); - -typedef std::less CompareIntPair; -typedef std::pair StringPair; - -inline std::string first_string(const StringPair& x) -{ - return x.first; -} - -inline std::string second_string(const StringPair& x) -{ - return x.second; -} - -struct Range -{ - Range(int x) - : m_start(x), m_finish(x) {} - - Range(int start, int finish) - : m_start(start), m_finish(finish) {} - - std::size_t length() const - { return m_finish < m_start ? 0 : m_finish - m_start; } - - void length(std::size_t new_length) - { m_finish = m_start + new_length; } - - int operator[](std::size_t n) - { return m_start + n; } - - Range slice(std::size_t start, std::size_t end) - { - if (start > length()) - start = length(); - if (end > length()) - end = length(); - return Range(m_start + start, m_start + end); - } - - int m_start, m_finish; -}; - -//////////////////////////////////////////////////////////////////////// -// // -// Begin wrapping code. Usually this would live in a separate header. // -// // -//////////////////////////////////////////////////////////////////////// - -// Since Foo has virtual functions which we want overriden in Python, we must -// derive FooCallback. -class FooCallback : public Foo -{ - public: - // Note the additional constructor parameter "self", which is needed to - // allow function overriding from Python. - FooCallback(PyObject* self, int x); - - friend struct PythonClass; // give it access to the functions below - - private: // implementations of Foo virtual functions that are overridable in python. - int add_len(const char* x) const; - - // A function which Python can call in case bar is not overridden from - // Python. In true Python style, we use a free function taking an initial - // self parameter. You can put this function anywhere; it needn't be a - // static member of the wrapping class. - static int default_add_len(const Foo* self, const char* x); - - // Since Foo::pure() is pure virtual, we don't need a corresponding - // default_pure(). A failure to override it in Python will result in an - // exception at runtime when pure() is called. - std::string pure() const; - - private: // Required boilerplate if functions will be overridden - PyObject* m_self; // No, we don't want a boost::python::ref here, or we'd get an ownership cycle. -}; - -// Define the Python base class -struct Foo::PythonClass : boost::python::class_builder { PythonClass(boost::python::module_builder&); }; - -// No virtual functions on Bar or Baz which are actually supposed to behave -// virtually from C++, so we'll rely on the library to define a wrapper for -// us. Even so, Python class_t types for each type we're wrapping should be -// _defined_ here in a header where they can be seen by other extension class -// definitions, since it is the definition of the boost::python::class_builder<> that -// causes to_python/from_python conversion functions to be generated. -struct BarPythonClass : boost::python::class_builder { BarPythonClass(boost::python::module_builder&); }; -struct BazPythonClass : boost::python::class_builder { BazPythonClass(boost::python::module_builder&); }; - -struct StringMapPythonClass - : boost::python::class_builder -{ - StringMapPythonClass(boost::python::module_builder&); - - // These static functions implement the right argument protocols for - // implementing the Python "special member functions" for mapping on - // StringMap. Could just as easily be global functions. - static const std::string& get_item(const StringMap& m, std::size_t key); - static void set_item(StringMap& m, std::size_t key, const std::string& value); - static void del_item(StringMap& m, std::size_t key); -}; - -struct IntPairPythonClass - : boost::python::class_builder -{ - IntPairPythonClass(boost::python::module_builder&); - - // The following could just as well be a free function; it implements the - // getattr functionality for IntPair. - static int getattr(const IntPair&, const std::string& s); - static void setattr(IntPair&, const std::string& name, int value); - static void delattr(IntPair&, const char* name); -}; - -struct CompareIntPairPythonClass - : boost::python::class_builder -{ - CompareIntPairPythonClass(boost::python::module_builder&); -}; - -} // namespace bpl_test - -#endif // BPL_TEST_DWA052200_H_ diff --git a/test/comprehensive.py b/test/comprehensive.py deleted file mode 100644 index f64ed661..00000000 --- a/test/comprehensive.py +++ /dev/null @@ -1,1281 +0,0 @@ -r''' -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. - -// Revision History: -// 2001 Nov 01 Python 2.2 pickle problems fixed (rwgk) -// 04 Mar 01 Changed name of extension module so it would work with DebugPython, -// fixed exception message checking to work with Python 2.0 -// (Dave Abrahams) - -Automatic checking of the number and type of arguments. Foo's constructor takes -a single long parameter. - - >>> try: - ... ext = Foo() - ... except TypeError, err: - ... assert re.match(r'function .* exactly 1 argument;? \(?0 given\)?', - ... str(err)) - ... else: - ... print 'no exception' - - >>> try: ext = Foo('foo') - ... except TypeError, err: - ... assert_integer_expected(err) - ... else: - ... print 'no exception' - - >>> ext = Foo(1) - -Call a virtual function. This call takes a trip into C++ where -FooCallback::add_len() looks up the Python "add_len" attribute and finds the -wrapper for FooCallback::default_add_len(), which in turn calls Foo::add_len(). - - >>> ext.add_len('hello') - 6 - >>> ext.set(3) - >>> ext.add_len('hello') - 8 - -Call a pure virtual function which should have been overridden, but was not. - - >>> ext.call_pure() - Traceback (innermost last): - File "", line 1, in ? - AttributeError: pure - -We can subclass Foo. - - >>> class Subclass(Foo): - ... def __init__(self, seq): - ... Foo.__init__(self, len(seq)) - ... - ... def pure(self): - ... return 'not pure anymore!' - ... - ... def get(self): - ... return Foo.add_len(self, '') - ... - ... def add_len(self, s): - ... print 'called add_len()' - ... return self.get() + len(s) - ... - >>> b = Subclass('yippee') - >>> b.get() - 6 - >>> b.mumble() - 'mumble' - >>> b.call_pure() - 'not pure anymore!' - -None corresponds to a NULL pointer or smart pointer - >>> f = foo_factory(1) - >>> f.add_len('xxx') - 1000 - >>> foo_factory(0) is None - 1 - >>> foo_ptr_is_null(None) - 1 - >>> foo_ptr_is_null(f) - 0 - >>> foo_shared_ptr_is_null(None) - 1 - >>> foo_shared_ptr_is_null(f) - 0 - -If no __init__ function is defined, the one from the base class takes effect, just -like in a Python class. - - >>> class DemonstrateInitPassthru(Foo): pass - ... - >>> q = DemonstrateInitPassthru(1) - >>> q.add_len("x") - 2 - -If we don't initialize the base class, we'll get a RuntimeError when we try to -use its methods. The test illustrates the kind of error to expect. - - >>> class BadSubclass(Foo): - ... def __init__(self): pass - ... - >>> barf = BadSubclass() - >>> barf.set(4) - Traceback (innermost last): - ... - RuntimeError: __init__ function for extension class 'Foo' was never called. - -Here we are tesing that the simple definition procedure used in the C++ demo -file for classes without any virtual functions actually worked. - - >>> bar = Bar(3, 4) - >>> bar.first() - 3 - >>> bar.second() - 4 - >>> baz = Baz() - -We can actually return the wrapped classes by value - - >>> baz.pass_bar(bar).first() - 3 - >>> bar.pass_baz(baz) is baz # A copy of the return value is made. - 0 - >>> type(bar.pass_baz(baz)) is type(baz) - 1 - -And, yes, we can multiply inherit from these classes. - - >>> class MISubclass(Subclass, Bar): - ... def __init__(self, s): - ... Subclass.__init__(self, s) - ... Bar.__init__(self, 0, len(s)) - ... - >>> mi = MISubclass('xx') - >>> mi.first() - 0 - >>> mi.second() - 2 - >>> mi.mumble() - 'mumble' - -We can even mulitply inherit from built-in Python classes, even if they are -first in the list of bases - - >>> class RealPythonClass: - ... def real_python_method(self): - ... print 'RealPythonClass.real_python_method()' - ... def other_first(self, other): - ... return other.first() - - >>> class MISubclass2(RealPythonClass, Bar): - ... def new_method(self): - ... print 'MISubclass2.new_method()' - ... bound_function = RealPythonClass().other_first - ... - >>> mi2 = MISubclass2(7, 8) - >>> mi2.first() # we can call inherited member functions from Bar - 7 - >>> mi2.real_python_method() # we can call inherited member functions from RealPythonClass - RealPythonClass.real_python_method() - - >>> mi2.new_method() # we can call methods on the common derived class - MISubclass2.new_method() - - We can call unbound methods from the base class accessed through the derived class - >>> MISubclass2.real_python_method(mi2) - RealPythonClass.real_python_method() - - We have not interfered with ordinary python bound methods - >>> MISubclass2.bound_function(mi2) - 7 - >>> mi2.bound_function() - 7 - -Any object whose class is derived from Bar can be passed to a function expecting -a Bar parameter: - - >>> baz.pass_bar(mi).first() - 0 - -But objects not derived from Bar cannot: - - >>> baz.pass_bar(baz) - Traceback (innermost last): - ... - TypeError: extension class 'Baz' is not convertible into 'Bar'. - -The clone function on Baz returns a smart pointer; we wrap it into an -extension_instance and make it look just like any other Baz obj. - - >>> baz_clone = baz.clone() - >>> baz_clone.pass_bar(mi).first() - 0 - -Functions expecting an std::auto_ptr parameter will not accept a raw Baz - - >>> try: baz.eat_baz(Baz()) - ... except RuntimeError, err: - ... assert re.match("Object of extension class 'Baz' does not wrap <.*>.", - ... str(err)) - ... else: - ... print 'no exception' - -We can pass std::auto_ptr where it is expected - - >>> baz.eat_baz(baz_clone) - -And if the auto_ptr has given up ownership? - - # MSVC6 ships with an outdated auto_ptr that doesn't get zeroed out when it - # gives up ownership. If you are using MSVC6 without the new Dinkumware - # library, SGI STL or the STLport, expect this test to crash unless you put - # --broken-auto-ptr on the command line. - >>> if not '--broken-auto-ptr' in sys.argv: - ... try: baz_clone.clone() - ... except RuntimeError, err: - ... assert re.match('Converting from python, pointer or smart pointer to <.*> is NULL.', str(err)) - ... else: - ... print 'no exeption' - -Polymorphism also works: - - >>> polymorphic_foo = baz.create_foo() - >>> polymorphic_foo.call_pure() - 'this was never pure!' - >>> baz.get_foo_value(polymorphic_foo) - 1000 - -Simple nested class test: - >>> foo_a = Foo.Foo_A() - >>> foo_a.mumble() - 'mumble a' - >>> foo_b = Foo.Foo_B() - >>> foo_b.mumble() - 'mumble b' - -Pickling tests: - - >>> world.__module__ - 'boost_python_test' - >>> world.__safe_for_unpickling__ - 1 - >>> world.__reduce__() - 'world' - >>> reduced = world('Hello').__reduce__() - >>> reduced[0] == world - 1 - >>> reduced[1:] - (('Hello',), (0,)) - >>> import StringIO - >>> import cPickle - >>> pickle = cPickle - >>> for number in (24, 42): - ... wd = world('California') - ... wd.set_secret_number(number) - ... # Dump it out and read it back in. - ... f = StringIO.StringIO() - ... pickle.dump(wd, f) - ... f = StringIO.StringIO(f.getvalue()) - ... wl = pickle.load(f) - ... # - ... print wd.greet(), wd.get_secret_number() - ... print wl.greet(), wl.get_secret_number() - ... - Hello from California! 24 - Hello from California! 24 - Hello from California! 42 - Hello from California! 0 - -Pickle safety measures: - >>> r=Rational(3, 4) - >>> r - Rational(3, 4) - >>> try: s=pickle.dumps(r) - ... except RuntimeError, err: print err[0] - ... - Incomplete pickle support (__dict_defines_state__ not set) - >>> r=myrational(3, 4) - >>> r - Rational(3, 4) - >>> s=pickle.dumps(r) - >>> u=pickle.loads(s) - - >>> w = myworld() - >>> w.greet() - 'Hello from anywhere!' - >>> w.__dict__ - {'x': 1} - >>> try: s=pickle.dumps(w) - ... except RuntimeError, err: print err[0] - ... - Incomplete pickle support (__getstate_manages_dict__ not set) - - >>> w = myunsafeworld() - >>> w.greet() - 'Hello from anywhere!' - >>> w.__dict__ - {'x': 1} - >>> s=pickle.dumps(w) - -Special member attributes. Tests courtesy of Barry Scott - - >>> class DerivedFromFoo(Foo): - ... def __init__(self): - ... Foo.__init__( self, 1 ) - ... def fred(self): - ... 'Docs for DerivedFromFoo.fred' - ... print 'Barry.fred' - ... def __del__(self): - ... print 'Deleting DerivedFromFoo' - - >>> class Base: - ... i_am_base = 'yes' - ... def fred(self): - ... 'Docs for Base.fred' - ... pass - - - >>> class DerivedFromBase(Base): - ... i_am_derived_from_base = 'yes' - ... def fred(self): - ... 'Docs for DerivedFromBase.fred' - ... pass - - >>> dir(DerivedFromFoo) - ['__del__', '__doc__', '__init__', '__module__', 'fred'] - - >>> df = DerivedFromFoo() - >>> df.__dict__ - {} - >>> df.fred.__doc__ - 'Docs for DerivedFromFoo.fred' - - >>> db = DerivedFromBase() - >>> db.__dict__ - {} - >>> db.fred.__doc__ - 'Docs for DerivedFromBase.fred' - - >>> import sys - >>> if not sys.__dict__.has_key('version_info') or \ - ... sys.version_info[0] < 2 or ( sys.version_info[0] == 2 and - ... sys.version_info[1] < 2 ): - ... assert dir(df) == [] - ... assert dir(db) == [] - ... assert dir(DerivedFromBase) == [ - ... '__doc__', '__module__', 'fred', 'i_am_derived_from_base'] - ... else: - ... assert dir(df) == [ - ... 'Foo_A', 'Foo_B', '__del__', '__doc__', '__init__', '__module__', 'add_len', - ... 'call_add_len', 'call_pure', 'fred', 'mumble', 'set'] - ... assert dir(db) == ['__doc__', '__module__', 'fred' - ... , 'i_am_base', 'i_am_derived_from_base'] - ... assert dir(DerivedFromBase) == [ - ... '__doc__', '__module__', 'fred', 'i_am_base', 'i_am_derived_from_base'] - -Special member functions in action - >>> del df - Deleting DerivedFromFoo - - # force method table sharing - >>> class DerivedFromStringMap(StringMap): pass - ... - - >>> m = StringMap() - -__getitem__() - >>> m[1] - Traceback (innermost last): - File "", line 1, in ? - KeyError: 1 - -__setitem__() - - >>> m[1] = 'hello' - -__getitem__() - >>> m[1] - 'hello' - -__delitem__() - >>> del m[1] - >>> m[1] # prove that it's gone - Traceback (innermost last): - File "", line 1, in ? - KeyError: 1 - -__delitem__() - >>> del m[2] - Traceback (innermost last): - File "", line 1, in ? - KeyError: 2 - -__length__() - >>> len(m) - 0 - >>> m[3] = 'farther' - >>> len(m) - 1 - -Check for sequence/mapping confusion: - >>> for x in m: - ... print x - ... - Traceback (innermost last): - File "", line 1, in ? - KeyError: 0 - -Check for the ability to pass a non-const reference as a constructor parameter - >>> x = Fubar(Foo(1)) - -Some simple overloading tests: - >>> r = Range(3) - >>> print str(r) - (3, 3) - >>> r.start - 3 - >>> r.finish - 3 - >>> r.__len__() - 0 - >>> r.__len__(4) - >>> r.finish - 7 - >>> try: r = Range('yikes') - ... except TypeError, e: - ... assert re.match( - ... 'No overloaded functions match [(]Range, str[a-z]*[)]\. Candidates are:\n.*\n.*', - ... str(e)) - ... else: print 'no exception' - -Sequence tests: - >>> len(Range(3, 10)) - 7 - - >>> map(lambda x:x, Range(3, 10)) - [3, 4, 5, 6, 7, 8, 9] - - >>> map(lambda x:x, Range(3, 10)[-2:]) - [8, 9] - - >>> map(lambda x:x, Range(3, 10)[:-4]) - [3, 4, 5] - - >>> map(lambda x:x, Range(3, 10)[4:]) - [7, 8, 9] - - >>> map(lambda x:x, Range(3, 10)[4:100]) - [7, 8, 9] - - >>> map(lambda x:x, Range(3, 10)[20:]) - [] - - >>> map(lambda x:x, Range(3, 10)[0:4]) - [3, 4, 5, 6] - -Numeric tests: - >>> x = Rational(2,3) - >>> y = Rational(1,4) - >>> print x + y - 11/12 - >>> print x - y - 5/12 - >>> print x * y - 1/6 - >>> print x / y - 8/3 - >>> print x + 1 # testing coercion - 5/3 - >>> print 1 + x # coercion the other way - 5/3 - -delete non-existent attribute: - del m.foobar - Traceback (innermost last): - File "", line 1, in ? - AttributeError: delete non-existing obj attribute - -Testing __getattr__ and __getattr__: - - >>> n = IntPair(1, 2) - >>> n.first - 1 - >>> n.second - 2 - >>> n.third - Traceback (innermost last): - File "", line 1, in ? - AttributeError: third - -Testing __setattr__ and __setattr__: - >>> n.first = 33 # N.B __setattr__first sets first to - >>> n.first # the negative of its argument. - -33 - >>> n.second = 66 - >>> n.second - 66 - -Testing __delattr__ and __delattr__: - >>> del n.first - Traceback (innermost last): - File "", line 1, in ? - AttributeError: first can't be deleted! - >>> del n.second - Traceback (innermost last): - File "", line 1, in ? - AttributeError: Attributes can't be deleted! - >>> del n.third - Traceback (innermost last): - File "", line 1, in ? - AttributeError: Attributes can't be deleted! - - # Now show that we can override it. - - >>> class IntTriple(IntPair): - ... def __getattr__(self, s): - ... if s in ['first', 'second']: - ... return IntPair.__getattr__(self, s) - ... elif s == 'third': - ... return 3 - ... else: - ... raise AttributeError(s) - ... - ... # Also show that __setattr__ is supported - ... def __setattr__(self, name, value): - ... raise AttributeError('no writable attributes') - ... - >>> p = IntTriple(0, 1) - >>> p.first - 0 - >>> p.second - 1 - >>> p.third - 3 - >>> p.bax - Traceback (innermost last): - File "", line 1, in ? - AttributeError: bax - >>> p.third = 'yes' - Traceback (innermost last): - File "", line 1, in ? - AttributeError: no writable attributes - >>> del p.third - Traceback (innermost last): - File "", line 1, in ? - AttributeError: Attributes can't be deleted! - -demonstrate def_readonly, def_read_write: - >>> sp = StringPair("hello", "world") - >>> sp.first # first is read-only - 'hello' - >>> first_string(sp) # prove that we're not just looking in sp's __dict__ - 'hello' - >>> sp.first = 'hi' # we're not allowed to change it - Traceback (innermost last): - File "", line 1, in ? - AttributeError: 'first' attribute is read-only - >>> first_string(sp) # prove that it hasn't changed - 'hello' - - >>> sp.second # second is read/write - 'world' - >>> second_string(sp) - 'world' - >>> sp.second = 'universe' # set the second attribute - >>> sp.second - 'universe' - >>> second_string(sp) # this proves we didn't just set it in sp's __dict__ - 'universe' - -some __str__ and __repr__ tests: - >>> sp - ('hello', 'universe') - >>> repr(sp) - "('hello', 'universe')" - >>> str(sp) - "('hello', 'universe')" - - Range has a __str__ function but not a __repr__ function - >>> range = Range(5, 20) - >>> str(range) - '(5, 20)' - >>> assert re.match('', repr(range)) - -__hash__ and __cmp__ tests: - # Range has both __hash__ and __cmp__, thus is hashable - >>> colors = { Range(3,4): 'blue', Range(7,9): 'red' } - >>> colors[Range(3,4)] - 'blue' - - # StringPair has only __cmp__ - >>> { StringPair('yo', 'eddy'): 1 } - Traceback (innermost last): - File "", line 1, in ? - TypeError: unhashable type - - # But it can be sorted - >>> stringpairs = [ StringPair('yo', 'eddy'), StringPair('yo', 'betty'), sp ] - >>> stringpairs.sort() - >>> stringpairs - [('hello', 'universe'), ('yo', 'betty'), ('yo', 'eddy')] - -make_pair is a global function in the module. - - >>> couple = make_pair(3,12) - >>> couple.first - 3 - >>> couple.second - 12 - -Testing __call__: - >>> couple2 = make_pair(3, 7) - >>> comparator = CompareIntPair() - >>> comparator(couple, couple) - 0 - >>> comparator(couple, couple2) - 0 - >>> comparator(couple2, couple) - 1 - -Testing overloaded free functions - >>> overloaded() - 'Hello world!' - >>> overloaded(1) - 1 - >>> overloaded('foo') - 'foo' - >>> overloaded(1,2) - 3 - >>> overloaded(1,2,3) - 6 - >>> overloaded(1,2,3,4) - 10 - >>> overloaded(1,2,3,4,5) - 15 - >>> try: overloaded(1, 'foo') - ... except TypeError, err: - ... assert re.match("No overloaded functions match \(int, str[a-z]*\)\. Candidates are:", - ... str(err)) - ... else: - ... print 'no exception' - -Testing overloaded constructors - - >>> over = OverloadTest() - >>> over.getX() - 1000 - >>> over = OverloadTest(1) - >>> over.getX() - 1 - >>> over = OverloadTest(1,1) - >>> over.getX() - 2 - >>> over = OverloadTest(1,1,1) - >>> over.getX() - 3 - >>> over = OverloadTest(1,1,1,1) - >>> over.getX() - 4 - >>> over = OverloadTest(1,1,1,1,1) - >>> over.getX() - 5 - >>> over = OverloadTest(over) - >>> over.getX() - 5 - >>> try: over = OverloadTest(1, 'foo') - ... except TypeError, err: - ... assert re.match("No overloaded functions match \(OverloadTest, int, str[a-z]*\)\. Candidates are:", - ... str(err)) - ... else: - ... print 'no exception' - -Testing overloaded methods - - >>> over.setX(3) - >>> over.overloaded() - 3 - >>> over.overloaded(1) - 1 - >>> over.overloaded(1,1) - 2 - >>> over.overloaded(1,1,1) - 3 - >>> over.overloaded(1,1,1,1) - 4 - >>> over.overloaded(1,1,1,1,1) - 5 - >>> try: over.overloaded(1,'foo') - ... except TypeError, err: - ... assert re.match("No overloaded functions match \(OverloadTest, int, str[a-z]*\)\. Candidates are:", - ... str(err)) - ... else: - ... print 'no exception' - -Testing base class conversions - - >>> testUpcast(over) - Traceback (innermost last): - TypeError: extension class 'OverloadTest' is not convertible into 'Base'. - >>> der1 = Derived1(333) - >>> der1.x() - 333 - >>> testUpcast(der1) - 333 - >>> der1 = derived1Factory(1000) - >>> testDowncast1(der1) - 1000 - >>> testDowncast2(der1) - Traceback (innermost last): - TypeError: extension class 'Base' is not convertible into 'Derived2'. - >>> der2 = Derived2(444) - >>> der2.x() - 444 - >>> testUpcast(der2) - 444 - >>> der2 = derived2Factory(1111) - >>> testDowncast2(der2) - Traceback (innermost last): - TypeError: extension class 'Base' is not convertible into 'Derived2'. - -Testing interaction between callbacks, base declarations, and overloading -- testCallback() calls callback() (within C++) -- callback() is overloaded (in the wrapped class CallbackTest) -- callback() is redefined in RedefineCallback (overloading is simulated by type casing) -- testCallback() should use the redefined callback() - - >>> c = CallbackTest() - >>> c.testCallback(1) - 2 - - >>> try: c.testCallback('foo') - ... except TypeError, err: assert_integer_expected(err) - ... else: print 'no exception' - - >>> c.callback(1) - 2 - >>> c.callback('foo') - 'foo 1' - - >>> import types - >>> class RedefineCallback(CallbackTest): - ... def callback(self, x): - ... if type(x) is types.IntType: - ... return x - 2 - ... else: - ... return CallbackTest.callback(self,x) - ... - >>> r = RedefineCallback() - >>> r.callback(1) - -1 - >>> r.callback('foo') - 'foo 1' - - >>> try: r.testCallback('foo') - ... except TypeError, err: assert_integer_expected(err) - ... else: print 'no exception' - - >>> r.testCallback(1) - -1 - >>> testCallback(r, 1) - -1 - -Regression test for a reference-counting bug thanks to Mark Evans -() - >>> sizelist([]) - 0.0 - >>> sizelist([1, 2, 4]) - 3.0 - -And another for doubles - >>> vector_double().push_back(3.0) - -Tests for method lookup in the context of inheritance -Set up the tests - - >>> a1 = A1() - >>> a2 = A2() - >>> b1 = B1() - >>> b2 = B2() - >>> pa1_a1 = factoryA1asA1() - >>> pb1_a1 = factoryB1asA1() - >>> pb2_a1 = factoryB2asA1() - >>> pc_a1 = factoryCasA1() - >>> pa2_a2 = factoryA2asA2() - >>> pb1_a2 = factoryB1asA2() - >>> pb1_b1 = factoryB1asB1() - >>> pc_b1 = factoryCasB1() - >>> class DA1(A1): - ... def overrideA1(self): - ... return 'DA1.overrideA1' - ... - >>> da1 = DA1() - >>> class DB1(B1): - ... def overrideA1(self): - ... return 'DB1.overrideA1' - ... def overrideB1(self): - ... return 'DB1.overrideB1' - ... - >>> db1 = DB1() - >>> class DB2(B2): pass - ... - >>> db2 = DB2() - -test overrideA1 - - >>> a1.overrideA1() - 'A1::overrideA1' - >>> b1.overrideA1() - 'B1::overrideA1' - >>> b2.overrideA1() - 'B2::overrideA1' - >>> da1.overrideA1() - 'DA1.overrideA1' - >>> db1.overrideA1() - 'DB1.overrideA1' - >>> pa1_a1.overrideA1() - 'A1::overrideA1' - >>> pb1_a1.overrideA1() - 'B1::overrideA1' - >>> pb2_a1.overrideA1() - 'B2::overrideA1' - >>> pb1_b1.overrideA1() - 'B1::overrideA1' - >>> pc_a1.overrideA1() - 'B1::overrideA1' - >>> pc_b1.overrideA1() - 'B1::overrideA1' - -test call_overrideA1 - - >>> call_overrideA1(a1) - 'A1::overrideA1' - >>> call_overrideA1(b1) - 'B1::overrideA1' - >>> call_overrideA1(b2) - 'B2::overrideA1' - >>> call_overrideA1(da1) - 'DA1.overrideA1' - >>> call_overrideA1(db1) - 'DB1.overrideA1' - >>> call_overrideA1(pa1_a1) - 'A1::overrideA1' - >>> call_overrideA1(pb1_a1) - 'B1::overrideA1' - >>> call_overrideA1(pb2_a1) - 'B2::overrideA1' - >>> call_overrideA1(pb1_b1) - 'B1::overrideA1' - >>> call_overrideA1(pc_a1) - 'B1::overrideA1' - >>> call_overrideA1(pc_b1) - 'B1::overrideA1' - -test inheritA1 - - >>> a1.inheritA1() - 'A1::inheritA1' - >>> b1.inheritA1() - 'A1::inheritA1' - >>> b2.inheritA1() - 'A1::inheritA1' - >>> da1.inheritA1() - 'A1::inheritA1' - >>> db1.inheritA1() - 'A1::inheritA1' - >>> pa1_a1.inheritA1() - 'A1::inheritA1' - >>> pb1_a1.inheritA1() - 'A1::inheritA1' - >>> pb2_a1.inheritA1() - 'A1::inheritA1' - >>> pb1_b1.inheritA1() - 'A1::inheritA1' - >>> pc_a1.inheritA1() - 'A1::inheritA1' - >>> pc_b1.inheritA1() - 'A1::inheritA1' - -test call_inheritA1 - - >>> call_inheritA1(a1) - 'A1::inheritA1' - >>> call_inheritA1(b1) - 'A1::inheritA1' - >>> call_inheritA1(b2) - 'A1::inheritA1' - >>> call_inheritA1(da1) - 'A1::inheritA1' - >>> call_inheritA1(db1) - 'A1::inheritA1' - >>> call_inheritA1(pa1_a1) - 'A1::inheritA1' - >>> call_inheritA1(pb1_a1) - 'A1::inheritA1' - >>> call_inheritA1(pb2_a1) - 'A1::inheritA1' - >>> call_inheritA1(pb1_b1) - 'A1::inheritA1' - >>> call_inheritA1(pc_a1) - 'A1::inheritA1' - >>> call_inheritA1(pc_b1) - 'A1::inheritA1' - -test inheritA2 - - >>> a2.inheritA2() - 'A2::inheritA2' - >>> b1.inheritA2() - 'A2::inheritA2' - >>> b2.inheritA2() - 'A2::inheritA2' - >>> db1.inheritA2() - 'A2::inheritA2' - >>> pa2_a2.inheritA2() - 'A2::inheritA2' - >>> pb1_a2.inheritA2() - 'A2::inheritA2' - >>> pb1_b1.inheritA2() - 'A2::inheritA2' - -test overrideB1 - - >>> b1.overrideB1() - 'B1::overrideB1' - >>> db1.overrideB1() - 'DB1.overrideB1' - >>> pb1_b1.overrideB1() - 'B1::overrideB1' - >>> pc_b1.overrideB1() - 'C::overrideB1' - -test call_overrideB1 - - >>> call_overrideB1(b1) - 'B1::overrideB1' - >>> call_overrideB1(db1) - 'DB1.overrideB1' - >>> call_overrideB1(pb1_a1) - 'B1::overrideB1' - >>> call_overrideB1(pc_a1) - 'C::overrideB1' - >>> call_overrideB1(pb1_b1) - 'B1::overrideB1' - >>> call_overrideB1(pc_b1) - 'C::overrideB1' - -test inheritB2 - - >>> b2.inheritB2() - 'B2::inheritB2' - >>> db2.inheritB2() - 'B2::inheritB2' - -========= test the new def_raw() feature ========== - - >>> r = RawTest(1) - >>> raw(r,1,third=1,fourth=1) - 4 - >>> r.raw(1,third=1,fourth=1) - 4 - >>> raw(r,1,third=1,f=1) - Traceback (innermost last): - KeyError: fourth - >>> raw(r,1,third=1) - Traceback (innermost last): - TypeError: wrong number of arguments - >>> raw(r,1) - Traceback (innermost last): - TypeError: wrong number of arguments - >>> raw() - Traceback (innermost last): - TypeError: wrong number of arguments - >>> raw1(1,second=1) - 2 - >>> raw1(1) - 1 - >>> raw1(second=1) - 1 - >>> raw1() - 0 - >>> raw2(1,second=1) - 2 - >>> raw2(1) - 1 - >>> raw2(second=1) - 1 - >>> raw2() - 0 - -========= test export of operators ========== - - >>> i = Int(2) - >>> j = i+i - >>> j.i() - 4 - >>> j = i-i - >>> j.i() - 0 - >>> j = i*i - >>> j.i() - 4 - >>> i>> cmp(i,i) - 0 - >>> k = Int(5) - >>> j = divmod(k, i) - >>> j[0].i() - 2 - >>> j[1].i() - 1 - >>> j = pow(i, k) - >>> j.i() - 32 - >>> j = pow(i, k, k) - >>> j.i() - 2 - >>> j = -i - >>> j.i() - -2 - >>> str(i) - '2' - >>> try: j = i/i - ... except TypeError, err: - ... assert re.match(r'(bad|unsupported) operand type\(s\) for /', - ... str(err)) - ... else: print 'no exception' - - >>> j = abs(i) - Traceback (innermost last): - TypeError: bad operand type for abs() - >>> j = i+1 - >>> j.i() - 3 - >>> j = i-1 - >>> j.i() - 1 - >>> j = i*1 - >>> j.i() - 2 - >>> i<1 - 0 - >>> cmp(i,1) - 1 - >>> j = pow(i, 5) - >>> j.i() - 32 - >>> j = pow(i, 5, k) - Traceback (innermost last): - TypeError: bad operand type(s) for pow() - >>> j = pow(i, 5, 5) - Traceback (innermost last): - TypeError: bad operand type(s) for pow() - >>> j = i/1 - Traceback (innermost last): - TypeError: bad operand type(s) for / - >>> j = 1+i - >>> j.i() - 3 - >>> j = 1-i - >>> j.i() - -1 - >>> j = 1*i - >>> j.i() - 2 - >>> 1>> cmp(1,i) - -1 - >>> j = 1/i - Traceback (innermost last): - TypeError: bad operand type(s) for / - >>> pow(1,i) - Traceback (innermost last): - TypeError: bad operand type(s) for pow() - -Test operator export to a subclass - - # force method table sharing - >>> class IntDerived1(Int): pass - ... - - >>> class IntDerived(Int): - ... def __init__(self, i): - ... Int.__init__(self, i) - ... def __str__(self): - ... return 'IntDerived: ' + str(self.i()) - ... - >>> f = IntDerived(3) - >>> str(f) - 'IntDerived: 3' - >>> j = f * f - >>> j.i() - 9 - >>> j = f * i - >>> j.i() - 6 - >>> j = f * 5 - >>> j.i() - 15 - >>> j = i * f - >>> j.i() - 6 - >>> j = 5 * f - >>> j.i() - 15 - - -========= Prove that the "phantom base class" issue is resolved ========== - - >>> assert pa1_a1.__class__ == A1 - >>> assert pb1_a1.__class__ == A1 - >>> assert pb2_a1.__class__ == A1 - >>> assert pc_a1.__class__ == A1 - >>> assert pa2_a2.__class__ == A2 - >>> assert pb1_a2.__class__ == A2 - >>> assert pb1_b1.__class__ == B1 - >>> assert pc_b1.__class__ == B1 - >>> assert A1 in B1.__bases__ - >>> assert A2 in B1.__bases__ - >>> assert A1 in B2.__bases__ - >>> assert A2 in B2.__bases__ - >>> assert A1 in DA1.__bases__ - >>> assert B1 in DB1.__bases__ - >>> assert B2 in DB2.__bases__ - -=============================================================== -test methodologies for wrapping functions that return a pointer - - >>> get_record().value - 1234 - - In this methodology, the referent is copied - >>> get_record() == get_record() - 0 - -======== Enums and non-method class attributes ============== - >>> eo = EnumOwner(EnumOwner.one, EnumOwner.two) - >>> eo.first - 1 - >>> eo.second - 2 - >>> eo.first = EnumOwner.three - >>> eo.second = EnumOwner.one - >>> eo.first - 3 - >>> eo.second - 1 - -======== test [plain] char converters ============== - >>> get_plain_char() - 'x' - >>> use_plain_char('a') - 'aaa' - >>> use_const_plain_char('b') - 'bbbbb' - -======== test std::complex converters ============== - >>> c = dpolar(3, 5) - >>> type(c) - - >>> '%.3g' % (dreal(c)) - '0.851' - >>> '%.3g' % (dimag(c)) - '-2.88' - >>> '%.3g' % (freal(c)) - '0.851' - >>> '%.3g' % (fimag(c)) - '-2.88' - >>> c = fpolar(7, 13) - >>> type(c) - - >>> '%.3g' % (fimag(c)) - '2.94' - >>> '%.3g' % (freal(c)) - '6.35' - >>> '%.3g' % (dimag(c)) - '2.94' - >>> '%.3g' % (dreal(c)) - '6.35' - >>> '%.3g' % (dreal(3)) - '3' - >>> '%.3g' % (dreal(3L)) - '3' - >>> '%.3g' % (dreal(3.)) - '3' - >>> '%.3g' % (freal(3)) - '3' - >>> '%.3g' % (freal(3L)) - '3' - >>> '%.3g' % (freal(3.)) - '3' - -''' -#' - -__test__ = {} -import sys - -# Inplace ops only exist in python 2.1 or later. -if sys.hexversion >= 0x02010000: - __test__['inplacetests'] = r''' - >>> ii = Int(1) - >>> ii += Int(2) - >>> ii.i() - 3 - >>> ii -= Int(1) - >>> ii.i() - 2 - >>> ii *= Int(3) - >>> ii.i() - 6 - >>> ii /= Int(2) - >>> ii.i() - 3 - >>> ii <<= Int(2) - >>> ii.i() - 12 - >>> ii >>= Int(1) - >>> ii.i() - 6 - >>> ii &= Int(5) - >>> ii.i() - 4 - >>> ii |= Int(9) - >>> ii.i() - 13 - >>> ii ^= Int(7) - >>> ii.i() - 10 - >>> ii %= Int(4) - >>> ii.i() - 2 - >>> ii **= Int(3) - >>> ii.i() - 8 - >>> ii.j() - 11 -''' - -from boost_python_test import * - -# pickle requires these derived classes to be -# at the global scope of the module - -class myrational(Rational): - __dict_defines_state__ = 1 # this is a lie but good enough for testing. - -class myworld(world): - def __init__(self): - world.__init__(self, 'anywhere') - self.x = 1 - -class myunsafeworld(myworld): - __getstate_manages_dict__ = 1 # this is a lie but good enough for testing. - - -def assert_integer_expected(err): - """Handle a common error report which appears differently in Python 1.5.x and 2.0""" - assert isinstance(err, TypeError) - message = str(err) - assert (message == "illegal argument type for built-in operation" - or message == "an integer is required") - -import string -import re -import sys - -def run(args = None): - if args is not None: - sys.argv = args - - import doctest, comprehensive - return doctest.testmod(comprehensive) - -if __name__ == '__main__': - sys.exit(run()[0]) From e49e0d2705d41b269fbc5558b2dd550604c923dc Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 9 Oct 2002 05:03:22 +0000 Subject: [PATCH 0833/1042] tutorial added [SVN r15817] --- doc/index.html | 6 +- doc/tutorial/doc/basic_interface.html | 77 ++ .../doc/building_an_extension_module.html | 186 +++ doc/tutorial/doc/building_hello_world.html | 48 + doc/tutorial/doc/call_policies.html | 169 +++ doc/tutorial/doc/class_data_members.html | 78 ++ .../class_operators_special_functions.html | 101 ++ doc/tutorial/doc/class_properties.html | 81 ++ doc/tutorial/doc/class_virtual_functions.html | 226 ++++ doc/tutorial/doc/constructors.html | 102 ++ doc/tutorial/doc/default_arguments.html | 118 ++ doc/tutorial/doc/derived_object_types.html | 114 ++ doc/tutorial/doc/exception_translation.html | 60 + doc/tutorial/doc/exposing_classes.html | 79 ++ doc/tutorial/doc/extracting_c___objects.html | 79 ++ doc/tutorial/doc/functions.html | 73 ++ doc/tutorial/doc/inheritance.html | 98 ++ doc/tutorial/doc/iterators.html | 101 ++ doc/tutorial/doc/object_interface.html | 54 + doc/tutorial/doc/quickstart.html | 79 ++ doc/tutorial/doc/quickstart.txt | 1020 +++++++++++++++++ doc/tutorial/doc/theme/alert.gif | Bin 0 -> 577 bytes doc/tutorial/doc/theme/arrow.gif | Bin 0 -> 70 bytes doc/tutorial/doc/theme/bkd.gif | Bin 0 -> 1317 bytes doc/tutorial/doc/theme/bkd2.gif | Bin 0 -> 2543 bytes doc/tutorial/doc/theme/bulb.gif | Bin 0 -> 944 bytes doc/tutorial/doc/theme/bullet.gif | Bin 0 -> 152 bytes doc/tutorial/doc/theme/c++boost.gif | Bin 0 -> 8819 bytes doc/tutorial/doc/theme/l_arr.gif | Bin 0 -> 147 bytes doc/tutorial/doc/theme/l_arr_disabled.gif | Bin 0 -> 91 bytes doc/tutorial/doc/theme/lens.gif | Bin 0 -> 897 bytes doc/tutorial/doc/theme/note.gif | Bin 0 -> 151 bytes doc/tutorial/doc/theme/python.png | Bin 0 -> 14699 bytes doc/tutorial/doc/theme/r_arr.gif | Bin 0 -> 147 bytes doc/tutorial/doc/theme/r_arr_disabled.gif | Bin 0 -> 91 bytes doc/tutorial/doc/theme/smiley.gif | Bin 0 -> 879 bytes doc/tutorial/doc/theme/style.css | 170 +++ doc/tutorial/doc/theme/u_arr.gif | Bin 0 -> 170 bytes doc/tutorial/index.html | 121 ++ 39 files changed, 3237 insertions(+), 3 deletions(-) create mode 100644 doc/tutorial/doc/basic_interface.html create mode 100644 doc/tutorial/doc/building_an_extension_module.html create mode 100644 doc/tutorial/doc/building_hello_world.html create mode 100644 doc/tutorial/doc/call_policies.html create mode 100644 doc/tutorial/doc/class_data_members.html create mode 100644 doc/tutorial/doc/class_operators_special_functions.html create mode 100644 doc/tutorial/doc/class_properties.html create mode 100644 doc/tutorial/doc/class_virtual_functions.html create mode 100644 doc/tutorial/doc/constructors.html create mode 100644 doc/tutorial/doc/default_arguments.html create mode 100644 doc/tutorial/doc/derived_object_types.html create mode 100644 doc/tutorial/doc/exception_translation.html create mode 100644 doc/tutorial/doc/exposing_classes.html create mode 100644 doc/tutorial/doc/extracting_c___objects.html create mode 100644 doc/tutorial/doc/functions.html create mode 100644 doc/tutorial/doc/inheritance.html create mode 100644 doc/tutorial/doc/iterators.html create mode 100644 doc/tutorial/doc/object_interface.html create mode 100644 doc/tutorial/doc/quickstart.html create mode 100644 doc/tutorial/doc/quickstart.txt create mode 100644 doc/tutorial/doc/theme/alert.gif create mode 100644 doc/tutorial/doc/theme/arrow.gif create mode 100644 doc/tutorial/doc/theme/bkd.gif create mode 100644 doc/tutorial/doc/theme/bkd2.gif create mode 100644 doc/tutorial/doc/theme/bulb.gif create mode 100644 doc/tutorial/doc/theme/bullet.gif create mode 100644 doc/tutorial/doc/theme/c++boost.gif create mode 100644 doc/tutorial/doc/theme/l_arr.gif create mode 100644 doc/tutorial/doc/theme/l_arr_disabled.gif create mode 100644 doc/tutorial/doc/theme/lens.gif create mode 100644 doc/tutorial/doc/theme/note.gif create mode 100644 doc/tutorial/doc/theme/python.png create mode 100644 doc/tutorial/doc/theme/r_arr.gif create mode 100644 doc/tutorial/doc/theme/r_arr_disabled.gif create mode 100644 doc/tutorial/doc/theme/smiley.gif create mode 100644 doc/tutorial/doc/theme/style.css create mode 100644 doc/tutorial/doc/theme/u_arr.gif create mode 100644 doc/tutorial/index.html diff --git a/doc/index.html b/doc/index.html index f9bcc646..c3090a64 100644 --- a/doc/index.html +++ b/doc/index.html @@ -31,7 +31,7 @@

      Contents

      -
      Tutorial Introduction
      +
      Tutorial Introduction
      Building and Testing
      @@ -51,9 +51,9 @@

      -

      Revised +

      Revised - 08 October, 2002 + 08 October, 2002

      diff --git a/doc/tutorial/doc/basic_interface.html b/doc/tutorial/doc/basic_interface.html new file mode 100644 index 00000000..cb4a28f4 --- /dev/null +++ b/doc/tutorial/doc/basic_interface.html @@ -0,0 +1,77 @@ + + + +Basic Interface + + + + + + + + + + +
      + + Basic Interface +
      +
      + + + + + + +
      +

      +Class object wraps PyObject*. All the intricacies of dealing with +PyObjects such as managing reference counting are handled by the +object class. C++ object interoperability is seamless. Boost.Python C++ +objects can in fact be explicitly constructed from any C++ object.

      +

      +To illustrate, this Python code snippet:

      +
      +    def f(x, f):
      +         if (y == 'foo'):
      +             x[3:7] = 'bar'
      +         else:
      +             x.items += f(3, x)
      +         return x
      +
      +    def getfunc():
      +       return f;
      +
      +

      +Can be rewritten in C++ using Boost.Python facilities this way:

      +
      +    object f(object x, object f) {
      +         if (f == "foo")
      +             x.slice(3,7) = "bar";
      +         else
      +             x.attr("items") += f(3, x);
      +         return x;
      +    }
      +    object getfunc() {
      +        return object(f);
      +    }
      +
      +

      +Apart from cosmetic differences due to the fact that we are writing the +code in C++, the look and feel should be immediately apparent to the Python +coder.

      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/building_an_extension_module.html b/doc/tutorial/doc/building_an_extension_module.html new file mode 100644 index 00000000..ffa176b7 --- /dev/null +++ b/doc/tutorial/doc/building_an_extension_module.html @@ -0,0 +1,186 @@ + + + +Building an Extension Module + + + + + + + + + + +
      + Building + an Extension Module
      +
      + + + + + + +
      +

      Building Boost.Python

      +

      Every Boost.Python extension module must be linked with the boost_python shared + library. To build boost_python, use Boost.Build + in the usual way from the libs/python/build subdirectory of your boost + installation (if you have already built boost from the top level this may have + no effect, since the work is already done).

      +

      Configuration

      +

      You may need to configure the following variables to point Boost.Build at your + Python installation:

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Variable NameSemanticsDefaultNotes
      PYTHON_ROOT The root directory of your Python installationWindows:
      + c:/tools/python
      + Unix: /usr/local
      On Unix, this is the --with-prefix= directory used to configure + Python
      PYTHON_VERSION The The 2-part python Major.Minor version numberWindows: 2.1 Unix: 1.5Be sure not to include a third number, e.g. not "2.2.1", even + if that's the version you have.
      PYTHON_INCLUDES path to Python #include directoriesAutoconfigured from
      + PYTHON_ROOT
       
      PYTHON_LIB_PATHpath to Python library object.Autoconfigured from
      + PYTHON_ROOT
       
      PYTHON_STDLIB_PATHpath to Python standard library modulesAutoconfigured from
      + PYTHON_ROOT
       
      CYGWIN_ROOT path to the user's Cygwin installationAutoconfigured from
      + PYTHON_ROOT
      Cygwin only. This and the following + two settings are useful when building with multiple toolsets on Windows, + since Cygwin requires a different build of Python.
      GCC_PYTHON_ROOTpath to the user's Cygwin Python installation$(CYGWIN_ROOT)
      + /usr/local
      Cygwin only
      GCC_DEBUG_PYTHON_ROOT path to the user's Cygwin pydebug + build$(CYGWIN_ROOT)
      + /usr/local/pydebug
      Cygwin only
      +

      Results

      +

      The build process will create a libs/python/build/bin-stage subdirectory + of the boost root (or of $(ALL_LOCATE_TARGET), if you have set that + variable), containing the built libraries. The libraries are actually built + to unique directories for each toolset and variant elsewhere in the filesystem, + and copied to the bin-stage directory as a convenience, so if you build with + multiple toolsets at once, the product of later toolsets will overwrite that + of earlier toolsets in bin-stage.

      +

      Testing

      +

      To build and test Boost.Python from within the libs/python/build directory, + invoke

      +
          bjam -sTOOLS=toolset test
      +

      This will update all of the Boost.Python v1 test and example targets. The tests + are relatively quiet by default. To get more-verbose output, you might try

      +
          bjam -sTOOLS=toolset -sPYTHON_TEST_ARGS=-v test
      +

      which will print each test's Python code with the expected output as it passes.

      +

      Building your Extension Module

      +

      Though there are other approaches, the easiest way to build an extension module + using Boost.Python is with Boost.Build. Until Boost.Build v2 is released, cross-project + build dependencies are not supported, so it works most smoothly if you add a + new subproject to your boost installation. The libs/python/example + subdirectory of your boost installation contains a minimal example (along with + many extra sources). To copy the example subproject:

      +
        +
      1. Create a new subdirectory in, libs/python, say libs/python/my_project.
      2. +
      3. Copy libs/python/example/Jamfile + to your new directory.
      4. +
      5. Edit the Jamfile as appropriate for your project. You'll want to change + the subproject rule invocation at the top, and the names of some + of the source files and/or targets.
      6. +
      +

      If you can't modify or copy your boost installation, the alternative is to + create your own Boost.Build project. A similar example you can use as a starting + point is available in this archive. You'll + need to edit the Jamfile and Jamrules files, depending on the relative location + of your Boost installation and the new project. Note that automatic testing + of extension modules is not available in this configuration.

      +

      Build Variants

      +

      Three variant configurations of all python-related targets are supported, and + can be selected by setting the BUILD variable:

      +

      * release (optimization, -DNDEBUG)
      + * debug (no optimization -D_DEBUG)
      + * debug-python (no optimization, -D_DEBUG -DBOOST_DEBUG_PYTHON)

      +

      The first two variants of the boost_python library are built by default, and + are compatible with the default Python distribution. The debug-python variant + corresponds to a specially-built debugging version of Python. On Unix platforms, + this python is built by adding --with-pydebug when configuring the + Python build. On Windows, the debugging version of Python is generated by the + "Win32 Debug" target of the PCBuild.dsw Visual C++ 6.0 project in + the PCBuild subdirectory of your Python distribution. Extension modules built + with Python debugging enabled are not link-compatible with a non-debug build + of Python. Since few people actually have a debug build of Python (it doesn't + come with the standard distribution), the normal debug variant builds modules + which are compatible with ordinary Python.

      +

      On many windows compilers, when extension modules are built with -D_DEBUG, + Python defaults to force linking with a special debugging version of the Python + DLL. Since this debug DLL isn't supplied with the default Python installation + for Windows, Boost.Python uses boost/python/detail/wrap_python.hpp + to temporarily undefine _DEBUG when Python.h is #included + - unless BOOST_DEBUG_PYTHON is defined.

      +

      If you want the extra runtime checks available with the debugging version of + the library, #define BOOST_DEBUG_PYTHON + to re-enable python debuggin, and link with the debug-python variant of boost_python.

      +

      If you do not #define BOOST_DEBUG_PYTHON, + be sure that any source files in your extension module #include + <boost/python/detail/wrap_python.hpp> instead of the usual Python.h, + or you will have link incompatibilities.

      + + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/building_hello_world.html b/doc/tutorial/doc/building_hello_world.html new file mode 100644 index 00000000..ce1d2257 --- /dev/null +++ b/doc/tutorial/doc/building_hello_world.html @@ -0,0 +1,48 @@ + + + +Building Hello World + + + + + + + + + + +
      + + Building Hello World +
      +
      + + + + + + +
      +

      From Start To Finish

      +Now the first thing you'd want to do is to build the Hello World module and +try it for yourself in Python. In this section, we shall outline the steps +necessary to achieve that. We shall use the build tool that comes bundled +with every boost distribution: bjam. For a complete reference to building +Boost.Python, check out: +building.html

      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/call_policies.html b/doc/tutorial/doc/call_policies.html new file mode 100644 index 00000000..f0decf84 --- /dev/null +++ b/doc/tutorial/doc/call_policies.html @@ -0,0 +1,169 @@ + + + +Call Policies + + + + + + + + + + +
      + + Call Policies +
      +
      + + + + + + +
      +

      +In C++, we often deal with arguments and return types such as pointers +and references. Such primitive types are rather, ummmm, low level and +they really don't tell us much. At the very least, we don't know the +owner of the pointer or the referenced object. No wonder languages +such as Java and Python never deal with such low level entities. In +C++, it's usually considered a good practice to use smart pointers +which exactly describe ownership semantics. Still, even good C++ +interfaces use raw references and pointers sometimes, so Boost.Python +must deal with them. To do this, it may need your help. Consider the +following C++ function:

      +
      +    X& f(Y& y, Z* z);
      +
      +

      +How should the library wrap this function? A naive approach builds a +Python X object around result reference. This strategy might or might +not work out. Here's an example where it didn't

      +
      +    >>> x = f(y, z) #x refers to some C++ X
      +    >>> del y
      +    >>> x.some_method() #CRASH!
      +
      +

      +What's the problem?

      +

      +Well, what if f() was implemented as shown below:

      +
      +    X& f(Y& y, Z* z)
      +    {
      +        y.z = z;
      +        return y.x;
      +    }
      +
      +

      +The problem is that the lifetime of result X& is tied to the lifetime +of y, because the f() returns a reference to a member of the y +object. This idiom is is not uncommon and perfectly acceptable in the +context of C++. However, Python users should not be able to crash the +system just by using our C++ interface. In this case deleting y will +invalidate the reference to X. We have a dangling reference.

      +

      +Here's what's happening:

      +
      1. f is called passing in a reference to y and a pointer to z
      2. A reference to y.x is returned
      3. y is deleted. x is a dangling reference
      4. x.some_method() is called
      5. BOOM!

      +We could copy result into a new object:

      +
      +    >>> f(y, z).set(42) #Result disappears
      +    >>> y.x.get()       #No crash, but still bad
      +    3.14
      +
      +

      +This is not really our intent of our C++ interface. We've broken our +promise that the Python interface should reflect the C++ interface as +closely as possible.

      +

      +Our problems do not end there. Suppose Y is implemented as follows:

      +
      +    struct Y
      +    {
      +        X x; Z* z;
      +        int z_value() { return z->value(); }
      +    };
      +
      +

      +Notice that the data member z is held by class Y using a raw +pointer. Now we have a potential dangling pointer problem inside Y:

      +
      +    >>> x = f(y, z) #y refers to z
      +    >>> del z       #Kill the z object
      +    >>> y.z_value() #CRASH!
      +
      +

      +For reference, here's the implementation of f again:

      +
      +    X& f(Y& y, Z* z)
      +    {
      +        y.z = z;
      +        return y.x;
      +    }
      +
      +

      +Here's what's happening:

      +
      1. f is called passing in a reference to y and a pointer to z
      2. A pointer to z is held by y
      3. A reference to y.x is returned
      4. z is deleted. y.z is a dangling pointer
      5. y.z_value() is called
      6. z->value() is called
      7. BOOM!

      Call Policies

      +Call Policies may be used in situations such as the example detailed above. +In our example, return_internal_reference and with_custodian_and_ward +are our friends:

      +
      +    def("f", f,
      +        return_internal_reference<1,
      +            with_custodian_and_ward<1, 2> >());
      +
      +

      +What are the 1 and 2 parameters, you ask?

      +
      +    return_internal_reference<1
      +
      +

      +Informs Boost.Python that the first argument, in our case Y& y, is the +owner of the returned reference: X&. The "1" simply specifies the +first argument. In short: "return an internal reference X& owned by the +1st argument Y& y".

      +
      +    with_custodian_and_ward<1, 2>
      +
      +

      +Informs Boost.Python that the lifetime of the argument indicated by ward +(i.e. the 2nd argument: Z* z) is dependent on the lifetime of the +argument indicated by custodian (i.e. the 1st argument: Z* z).

      +

      +It is also important to note that we have defined two policies above. Two +or more policies can be composed by chaining. Here's the general syntax:

      +
      +    policy1<args...,
      +        policy2<args...,
      +            policy3<args...> > >
      +
      +

      +Here is the list of predefined call policies. A complete reference detailing +these can be found +here.

      +
      • with_custodian_and_ward
        Ties lifetimes of the arguments
      • with_custodian_and_ward_postcall
        Ties lifetimes of the arguments and results
      • return_internal_reference
        Ties lifetime of one argument to that of result
      • return_value_policy<T> with T one of:
      • reference_existing_object
        naïve (dangerous) approach
      • copy_const_reference
        Boost.Python v1 approach
      • copy_non_const_reference
      • manage_new_object
        Adopt a pointer and hold the instance
      + + + +
      + Remember the Zen, Luke:

      +"Explicit is better than implicit"
      +"In the face of ambiguity, refuse the temptation to guess"
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/class_data_members.html b/doc/tutorial/doc/class_data_members.html new file mode 100644 index 00000000..4718880c --- /dev/null +++ b/doc/tutorial/doc/class_data_members.html @@ -0,0 +1,78 @@ + + + +Class Data Members + + + + + + + + + + +
      + + Class Data Members +
      +
      + + + + + + +
      +

      +Data members may also be exposed to Python so that they can be +accessed as attributes of the corresponding Python class. Each data +member that we wish to be exposed may be regarded as read-only or +read-write. Consider this class Var:

      +
      +    struct Var
      +    {
      +        Var(std::string name) : name(name), value() {}
      +        std::string const name;
      +        float value;
      +    };
      +
      +

      +Our C++ Var class and its data members can be exposed to Python:

      +
      +    class_<Var>("Var", init<std::string>())
      +        .def_readonly("name", &Var::name)
      +        .def_readwrite("value", &Var::value);
      +
      +

      +Then, in Python:

      +
      +    >>> x = Var('pi')
      +    >>> x.value = 3.14
      +    >>> print x.name, 'is around', x.value
      +    pi is around 3.14
      +
      +

      +Note that name is exposed as read-only while value is exposed +as read-write.

      +
      +    >>> x.name = 'e' #can't change name
      +    Traceback (most recent call last):
      +      File "<stdin>", line 1, in ?
      +    AttributeError: can't set attribute
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/class_operators_special_functions.html b/doc/tutorial/doc/class_operators_special_functions.html new file mode 100644 index 00000000..74a952a2 --- /dev/null +++ b/doc/tutorial/doc/class_operators_special_functions.html @@ -0,0 +1,101 @@ + + + +Class Operators/Special Functions + + + + + + + + + + +
      + + Class Operators/Special Functions +
      +
      + + + + + + +
      +

      Python Operators

      +C is well known for the abundance of oparators. C++ extends this to the +extremes by allowing operator overloading. Boost.Python takes advantage of +this and makes it easy to wrap C++ operator-powered classes.

      +

      +Consider a file position class FilePos and a set of operators that take +on FilePos instances:

      +
      +    class FilePos { /*...*/ };
      +
      +    FilePos     operator+(FilePos, int);
      +    FilePos     operator+(int, FilePos);
      +    int         operator-(FilePos, FilePos);
      +    FilePos     operator-(FilePos, int);
      +    FilePos&    operator+=(FilePos&, int);
      +    FilePos&    operator-=(FilePos&, int);
      +    bool        operator<(FilePos, FilePos);
      +
      +

      +The class and the various operators can be mapped to Python rather easily +and intuitively:

      +
      +    class_<FilePos>("FilePos")
      +        .def(self + int())          // __add__
      +        .def(int() + self)          // __radd__
      +        .def(self - self)           // __sub__
      +        .def(self - int())          // __rsub__
      +        .def(self += int())         // __iadd__
      +        .def(self -= other<int>())
      +        .def(self < self);          // __lt__
      +
      +

      +The code snippet above is very clear and needs almost no explanation at +all. It is virtually the same as the operators' signatures. Just take +note that self refers to FilePos object. Also, not every class T that +you might need to interact with in an operator expression is (cheaply) +default-constructible. You can use other<T>() in place of an actual +T instance when writing "self expressions".

      +

      Special Methods

      +Python has a few more Special Methods. Boost.Python supports all of the +standard special method names supported by real Python class instances. A +similar set of intuitive interfaces can also be used to wrap C++ functions +that correspond to these Python special functions. Example:

      +
      +    class Rational
      +    { operator double() const; };
      +
      +    Rational pow(Rational, Rational);
      +    Rational abs(Rational);
      +    ostream& operator<<(ostream&,Rational);
      +
      +    class_<Rational>()
      +        .def(float_(self))  // __float__
      +        .def(pow(self))     // __pow__
      +        .def(abs(self))     // __abs__
      +        .def(str(self))     // __str__
      +        ;
      +
      +

      +Need we say more?

      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/class_properties.html b/doc/tutorial/doc/class_properties.html new file mode 100644 index 00000000..cd2267d5 --- /dev/null +++ b/doc/tutorial/doc/class_properties.html @@ -0,0 +1,81 @@ + + + +Class Properties + + + + + + + + + + +
      + + Class Properties +
      +
      + + + + + + +
      +

      +In C++, classes with public data members are usually frowned +upon. Well designed classes that take advantage of encapsulation hide +the class' data members. The only way to access the class' data is +through access (getter/setter) functions. Access functions expose class +properties. Here's an example:

      +
      +    struct Num
      +    {
      +        Num();
      +        float get() const;
      +        void set(float value);
      +        ...
      +    };
      +
      +

      +However, in Python attribute access is fine; it doesn't neccessarily break +encapsulation to let users handle attributes directly, because the +attributes can just be a different syntax for a method call. Wrapping our +Num class using Boost.Python:

      +
      +    class_<Num>("Num")
      +        .add_property("rovalue", &Var::get)
      +        .add_property("value", &Var::get, &Var::set);
      +
      +

      +And at last, in Python:

      +
      +    >>> x = Num()
      +    >>> x.value = 3.14
      +    >>> x.value, x.rovalue
      +    (3.14, 3.14)
      +    >>> x.rovalue = 2.17 #error!
      +
      +

      +Take note that the class property rovalue is exposed as read-only +since the rovalue setter member function is not passed in:

      +
      +    .add_property("rovalue", &Var::get)
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/class_virtual_functions.html b/doc/tutorial/doc/class_virtual_functions.html new file mode 100644 index 00000000..dea828c4 --- /dev/null +++ b/doc/tutorial/doc/class_virtual_functions.html @@ -0,0 +1,226 @@ + + + +Class Virtual Functions + + + + + + + + + + +
      + + Class Virtual Functions +
      +
      + + + + + + +
      +

      +In this section, we shall learn how to make functions behave +polymorphically through virtual functions. Continuing our example, let us +add a virtual function to our Base class:

      +
      +    struct Base
      +    {
      +        virtual int f() = 0;
      +    };
      +
      +

      +Since f is a pure virtual function, Base is now an abstract +class. Given an instance of our class, the free function call_f +calls some implementation of this virtual function in a concrete +derived class:

      +
      +    int call_f(Base& b) { return b.f(); }
      +
      +

      +To allow this function to be implemented in a Python derived class, we +need to create a class wrapper:

      +
      +    struct BaseWrap : Base
      +    {
      +        BaseWrap(PyObject* self_)
      +            : self(self_) {}
      +        int f() { return call_method<int>(self, "f"); }
      +        PyObject* self;
      +    };
      +
      + + + + +
      + member function and methods

      Python, like +many object oriented languages uses the term methods. Methods +correspond roughly to C++'s member functions
      +

      +Our class wrapper BaseWrap is derived from Base. Its overridden +virtual member function f in effect calls the corresponding method +of the Python object self, which is a pointer back to the Python +Base object holding our BaseWrap instance.

      + + + + +
      + Why do we need BaseWrap?

      + +You may ask, "Why do we need the BaseWrap derived class? This could +have been designed so that everything gets done right inside of +Base."

      + +One of the goals of Boost.Python is to be minimally intrusive on an +existing C++ design. In principle, it should be possible to expose the +interface for a 3rd party library without changing it. To unintrusively +hook into the virtual functions so that a Python override may be called, we +must use a derived class.

      + +Note however that you don't need to do this to get methods overridden +in Python to behave virtually when called from Python. The only +time you need to do the BaseWrap dance is when you have a virtual +function that's going to be overridden in Python and called +polymorphically from C++.
      +

      +Wrapping Base and the free function call_f:

      +
      +    class_<Base, BaseWrap, noncopyable>("Base", no_init)
      +        ;
      +    def("call_f", call_f);
      +
      +

      +Notice that we parameterized the class_ template with BaseWrap as the +second parameter. What is noncopyable? Without it, the library will try +to instantiate a copy constructor for returning Base objects from +functions.

      +

      +In Python, let us try to instantiate our Base class:

      +
      +    >>> base = Base()
      +    AttributeError: ...
      +
      +

      +Why is it an error? Base is an abstract class. As such it is advisable +to define the Python wrapper with no_init as we have done above. Doing +so will disallow abstract base classes such as Base to be instantiated.

      +

      Deriving a Python class

      +Now, at last, we can even derive from our base class Base in Python:

      +
      +    >>> class Derived(Base):
      +    ...     def f(self):
      +    ...         return 42
      +    ...
      +
      +

      +Cool eh? A Python class deriving from a C++ class!

      +

      +Let's now make an instance of our Python class Derived:

      +
      +    >>> derived = Derived()
      +
      +

      +Calling derived.f():

      +
      +    >>> derived.f()
      +    42
      +
      +

      +Will yield the expected result. Finally, calling calling the free function +call_f with derived as argument:

      +
      +    >>> call_f(derived())
      +    42
      +
      +

      +Will also yield the expected result.

      +

      +Here's what's happening:

      +
      1. call_f(derived()) is called in Python
      2. This corresponds to def("call_f", call_f);. Boost.Python dispatches this call.
      3. int call_f(Base& b) { return b.f(); } accepts the call.
      4. The overridden virtual function f of BaseWrap is called.
      5. call_method<int>(self, "f"); dispatches the call back to Python.
      6. def f(self): return 42 is finally called.

      +Rewind back to our Base class, if its member function f was not +declared as pure virtual:

      +
      +    struct Base
      +    {
      +        virtual int f() { return 0; }
      +    };
      +
      +

      +And instead is implemented to return 0, as shown above.

      +
      +    struct BaseWrap : Base
      +    {
      +        BaseWrap(PyObject* self_)
      +            : self(self_) {}
      +        int f() { return call_method<int>(self, "f"); }
      +        static int default_f(Base* b) { return b->Base::f(); } // <<=== added
      +        PyObject* self;
      +    };
      +
      +

      +then, our Boost.Python wrapper:

      +
      +    class_<Base, BaseWrap>("Base")
      +        .def("f", &BaseWrap::default_f)
      +        ;
      +
      +

      +Note that we are allowing Base objects to be instantiated this time, +unlike before where we specifically defined the class_<Base> with +no_init.

      +

      +In Python, the results would be as expected:

      +
      +    >>> base = Base()
      +    >>> class Derived(Base):
      +    ...     def f(self):
      +    ...         return 42
      +    ...
      +    >>> derived = Derived()
      +
      +

      +Calling base.f():

      +
      +    >>> base.f()
      +    0
      +
      +

      +Calling derived.f():

      +
      +    >>> derived.f()
      +    42
      +
      +

      +Calling call_f, passing in a base object:

      +
      +    >>> call_f(base)
      +    0
      +
      +

      +Calling call_f, passing in a derived object:

      +
      +    >>> call_f(derived())
      +    42
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/constructors.html b/doc/tutorial/doc/constructors.html new file mode 100644 index 00000000..621387f5 --- /dev/null +++ b/doc/tutorial/doc/constructors.html @@ -0,0 +1,102 @@ + + + +Constructors + + + + + + + + + + +
      + + Constructors +
      +
      + + + + + + +
      +

      +Our previous example didn't have any explicit constructors. +Since World is declared as a plain struct, it has an implicit default +constructor. Boost.Python exposes the default constructor by default, +which is why we were able to write

      +
      +    >>> planet = hello.World()
      +
      +

      +We may wish to wrap a class with a non-default constructor. Let us +build on our previous example:

      +
      +    struct World
      +    {
      +        World(std::string msg): msg(msg) {} // added constructor
      +        void set(std::string msg) { this->msg = msg; }
      +        std::string greet() { return msg; }
      +        std::string msg;
      +    };
      +
      +

      +This time World has no default constructor; our previous +wrapping code would fail to compile when the library tried to expose +it. We have to tell class_<World> about the constructor we want to +expose instead.

      +
      +    #include <boost/python.hpp>
      +    using namespace boost::python;
      +
      +    BOOST_PYTHON_MODULE(hello)
      +    {
      +        class_<World>("World", init<std::string>())
      +            .def("greet", &World::greet)
      +            .def("set", &World::set)
      +        ;
      +    }
      +
      +

      +init<std::string>() exposes the constructor taking in a +std::string (in Python, constructors are spelled +"__init__(...)").

      +

      +We can expose additional constructors by passing more init<...>s to +the def() member function. Say for example we have another World +constructor taking in two doubles:

      +
      +    class_<World>("World", init<std::string>())
      +        .def(init<double, double>())
      +        .def("greet", &World::greet)
      +        .def("set", &World::set)
      +    ;
      +
      +

      +On the other hand, if we do not wish to expose any constructors at +all, we may use no_init instead:

      +
      +    class_<Abstract>("Abstract", no_init)
      +
      +

      +This actually adds an __init__ method which always raises a +Python RuntimeError exception.

      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/default_arguments.html b/doc/tutorial/doc/default_arguments.html new file mode 100644 index 00000000..bfb3ce3b --- /dev/null +++ b/doc/tutorial/doc/default_arguments.html @@ -0,0 +1,118 @@ + + + +Default Arguments + + + + + + + + + + +
      + + Default Arguments +
      +
      + + + + + + +
      +

      +Boost.Python wraps (member) function pointers. Unfortunately, C++ function +pointers carry no default argument info. Take a function f with default +arguments:

      +
      +    int f(int, double = 3.14, char const* = "hello");
      +
      +

      +But the type of a pointer to the function f has no information +about its default arguments:

      +
      +    int(*g)(int,double,char const*) = f;    // defaults lost!
      +
      +

      +When we pass this function pointer to the def function, there is no way +to retrieve the default arguments:

      +
      +    def("f", f);                            // defaults lost!
      +
      +

      +Because of this, when wrapping C++ code in earlier versions of +Boost.Python, we had to resort to writing thin wrappers:

      +
      +    // write "thin wrappers"
      +    int f1(int x) { f(x); }
      +    int f2(int x, double y) { f(x,y); }
      +
      +    /*...*/
      +
      +        // in module init
      +        def("f", f);  // all arguments
      +        def("f", f2); // two arguments
      +        def("f", f1); // one argument
      +
      +

      +When you want to wrap functions (or member functions) that either:

      +
      • have default arguments, or
      • are overloaded with a common sequence of initial arguments

      +Boost.Python now has a way to make it easier.

      +

      +For instance, given a function:

      +
      +    int foo(int a, char b = 1, unsigned c = 2, double d = 3);
      +
      +

      +The macro invocation:

      +
      +    BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4)
      +
      +

      +Will automatically create the thin wrappers for us. This macro will create +a class foo_overloads that can be passed on to def(...). The third +and fourth macro argument are the minimum arguments and maximum arguments, +respectively. In our foo function the minimum number of arguments is 1 +and the maximum number of arguments is 4. The def(...) function will +automatically add all the foo variants for us:

      +
      +    .def("foo", foo, foo_overloads());
      +
      +

      +A similar facility is provided for class constructors, again, with +default arguments or a sequence of overloads. Remember init<...>? For example, +given a class X with a constructor:

      +
      +    struct X
      +    {
      +        X(int a, char b = 'D', std::string c = "constructor", double d = 0.0);
      +        /*...*/
      +    }
      +
      +

      +You can easily add this constructor to Boost.Python in one shot:

      +
      +    .def(init<int, optional<char, std::string, double> >())
      +
      +

      +Notice the use of init<...> and optional<...> to signify the default +(optional arguments).

      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/derived_object_types.html b/doc/tutorial/doc/derived_object_types.html new file mode 100644 index 00000000..4d08db05 --- /dev/null +++ b/doc/tutorial/doc/derived_object_types.html @@ -0,0 +1,114 @@ + + + +Derived Object types + + + + + + + + + + +
      + + Derived Object types +
      +
      + + + + + + +
      +

      +Boost.Python comes with a set of derived object types corresponding to +that of Python's:

      +
      • list
      • dict
      • tuple
      • str
      • long_

      +These derived object types act like real Python types. For instance:

      +
      +    str(1) ==> "1"
      +
      +

      +Wherever appropriate, a particular derived object has corresponding +Python type's methods. For instance, dict has a keys() method:

      +
      +    d.keys()
      +
      +

      +make_tuple is provided for declaring tuple literals. Example:

      +
      +    make_tuple(123, 'D', "Hello, World", 0.0);
      +
      +

      +In C++, when Boost.Python objects are used as arguments to functions, +subtype matching is required. For example, when a function f, as +declared below, is wrapped, it will only accept instances of Python's +str type and subtypes.

      +
      +    void f(str name)
      +    {
      +        object n2 = name.attr("upper")();   // NAME = name.upper()
      +        str NAME = name.upper();            // better
      +        object msg = "%s is bigger than %s" % make_tuple(NAME,name);
      +    }
      +
      +

      +In finer detail:

      +
      +    str NAME = name.upper();
      +
      +

      +Illustrates that we provide versions of the str type's methods as C++ +member functions.

      +
      +    object msg = "%s is bigger than %s" % make_tuple(NAME,name);
      +
      +

      +Demonstrates that you can write the C++ equivalent of "format" % x,y,z +in Python, which is useful since there's no easy way to do that in std C++.

      + + + + +
      + Beware the common pitfall of +forgetting that the constructors of most of Python's mutable types +make copies, just as in Python.

      + + dict d(x.attr("__dict__")); # makes a copy of x's dict
      + d['whatever'] = 3; # modifies a copy of x.__dict__ (not the original)
      +
      +

      class_<T> as objects

      +Due to the dynamic nature of Boost.Python objects, any class_<T> may +also be one of these types! The following code snippet wraps the class +(type) object.

      +

      +We can use this to create wrapped instances. Example:

      +
      +    object vec345 = (
      +        class_<Vec2>("Vec2", init<double, double>())
      +            .def_readonly("length", &Point::length)
      +            .def_readonly("angle", &Point::angle)
      +        )(3.0, 4.0);
      +
      +    assert(vec345.attr("length") == 5.0);
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/exception_translation.html b/doc/tutorial/doc/exception_translation.html new file mode 100644 index 00000000..9ec6bc86 --- /dev/null +++ b/doc/tutorial/doc/exception_translation.html @@ -0,0 +1,60 @@ + + + +Exception Translation + + + + + + + + + +
      + + Exception Translation +
      +
      + + + + + + +
      +

      +All C++ exceptions must be caught at the boundary with Python code. This +boundary is the point where C++ meets Python. Boost.Python provides a +default exception handler that translates selected standard exceptions, +then gives up:

      +
      +    raise RuntimeError, 'unidentifiable C++ Exception'
      +
      +

      +Users may provide custom translation. Here's an example:

      +
      +    struct PodBayDoorException;
      +    void translator(PodBayDoorException& x) {
      +        PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave...");
      +    }
      +    BOOST_PYTHON_MODULE(kubrick) {
      +         register_exception_translator<
      +              PodBayDoorException>(translator);
      +         ...
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/exposing_classes.html b/doc/tutorial/doc/exposing_classes.html new file mode 100644 index 00000000..7a989346 --- /dev/null +++ b/doc/tutorial/doc/exposing_classes.html @@ -0,0 +1,79 @@ + + + +Exposing Classes + + + + + + + + + + +
      + + Exposing Classes +
      +
      + + + + + + +
      +

      +Now let's expose a C++ class to Python.

      +

      +Consider a C++ class/struct that we want to expose to Python:

      +
      +    struct World
      +    {
      +        void set(std::string msg) { this->msg = msg; }
      +        std::string greet() { return msg; }
      +        std::string msg;
      +    };
      +
      +

      +We can expose this to Python by writing a corresponding Boost.Python +C++ Wrapper:

      +
      +    #include <boost/python.hpp>
      +    using namespace boost::python;
      +
      +    BOOST_PYTHON_MODULE(hello)
      +    {
      +        class_<World>("World")
      +            .def("greet", &World::greet)
      +            .def("set", &World::set)
      +        ;
      +    }
      +
      +

      +Here, we wrote a C++ class wrapper that exposes the member functions +greet and set. Now, after building our module as a shared library, we +may use our class World in Python. Here's a sample Python session:

      +
      +    >>> import hello
      +    >>> planet = hello.World()
      +    >>> planet.set('howdy')
      +    >>> planet.greet()
      +    'howdy'
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/extracting_c___objects.html b/doc/tutorial/doc/extracting_c___objects.html new file mode 100644 index 00000000..6000821b --- /dev/null +++ b/doc/tutorial/doc/extracting_c___objects.html @@ -0,0 +1,79 @@ + + + +Extracting C++ objects + + + + + + + + + + +
      + + Extracting C++ objects +
      +
      + + + + + + +
      +

      +At some point, we will need to get C++ values out of object instances. This +can be achieved with the extract<T> function. Consider the following:

      +
      +    double x = o.attr("length"); // compile error
      +
      +

      +In the code above, we got a compiler error because Boost.Python +object can't be implicitly converted to doubles. Instead, what +we wanted to do above can be achieved by writing:

      +
      +    double l = extract<double>(o.attr("length"));
      +    Vec2& v = extract<Vec2&>(o);
      +    assert(l == v.length());
      +
      +

      +The first line attempts to extract the "length" attribute of the +Boost.Python object o. The second line attempts to extract the +Vec2 object from held by the Boost.Python object o.

      +

      +Take note that we said "attempt to" above. What if the Boost.Python +object o does not really hold a Vec2 type? This is certainly +a possibility considering the dynamic nature of Python objects. To +be on the safe side, if the C++ type can't be extracted, an +appropriate exception is thrown. To avoid an exception, we need to +test for extractibility:

      +
      +    extract<Vec2&> x(o);
      +    if (x.check()) {
      +        Vec2& v = x(); ...
      +
      +

      + The astute reader might have noticed that the extract<T> +facility in fact solves mutable copying problem:

      +
      +    dict d = extract<dict>(x.attr("__dict__"));
      +    d['whatever'] = 3;          #modifies x.__dict__ !
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/functions.html b/doc/tutorial/doc/functions.html new file mode 100644 index 00000000..036242e2 --- /dev/null +++ b/doc/tutorial/doc/functions.html @@ -0,0 +1,73 @@ + + + +Functions + + + + + + + + + + +
      + + Functions +
      +
      + + + + + + +
      +

      +In this chapter, we'll look at Boost.Python powered functions in closer +detail. We shall see some facilities to make exposing C++ functions to +Python safe from potential pifalls such as dangling pointers and +references. We shall also see facilities that will make it even easier for +us to expose C++ functions that take advantage of C++ features such as +overloading and default arguments.

      +

      Read on...

      +But before you do, you might want to fire up Python 2.2 or later and type +>>> import this.

      +
      +    >>> import this
      +    The Zen of Python, by Tim Peters
      +    Beautiful is better than ugly.
      +    Explicit is better than implicit.
      +    Simple is better than complex.
      +    Complex is better than complicated.
      +    Flat is better than nested.
      +    Sparse is better than dense.
      +    Readability counts.
      +    Special cases aren't special enough to break the rules.
      +    Although practicality beats purity.
      +    Errors should never pass silently.
      +    Unless explicitly silenced.
      +    In the face of ambiguity, refuse the temptation to guess.
      +    There should be one-- and preferably only one --obvious way to do it
      +    Although that way may not be obvious at first unless you're Dutch.
      +    Now is better than never.
      +    Although never is often better than *right* now.
      +    If the implementation is hard to explain, it's a bad idea.
      +    If the implementation is easy to explain, it may be a good idea.
      +    Namespaces are one honking great idea -- let's do more of those!
      +
      + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/inheritance.html b/doc/tutorial/doc/inheritance.html new file mode 100644 index 00000000..0f9fe33f --- /dev/null +++ b/doc/tutorial/doc/inheritance.html @@ -0,0 +1,98 @@ + + + +Inheritance + + + + + + + + + + +
      + + Inheritance +
      +
      + + + + + + +
      +

      +In the previous examples, we dealt with classes that are not polymorphic. +This is not often the case. Much of the time, we will be wrapping +polymorphic classes and class hierarchies related by inheritance. We will +often have to write Boost.Python wrappers for classes that are derived from +abstract base classes.

      +

      +Consider this trivial inheritance structure:

      +
      +    struct Base { virtual ~Base(); };
      +    struct Derived : Base {};
      +
      +

      +And a set of C++ functions operating on Base and Derived object +instances:

      +
      +    void b(Base*);
      +    void d(Derived*);
      +    Base* factory() { return new Derived; }
      +
      +

      +We've seen how we can wrap the base class Base:

      +
      +    class_<Base>("Base")
      +        /*...*/
      +        ;
      +
      +

      +Now we can inform Boost.Python of the inheritance relationship between +Derived and its base class Base. Thus:

      +
      +    class_<Derived, bases<Base> >("Derived")
      +        /*...*/
      +        ;
      +
      +

      +Doing so, we get some things for free:

      +
      1. Derived automatically inherits all of Base's Python methods (wrapped C++ member functions)
      2. If Base is polymorphic, Derived objects which have been passed to Python via a pointer or reference to Base can be passed where a pointer or reference to Derived is expected.

      +Now, we shall expose the C++ free functions b and d and factory:

      +
      +    def("b", b);
      +    def("d", d);
      +    def("factory", factory);
      +
      +

      +Note that free function factory is being used to generate new +instances of class Derived. In such cases, we use +return_value_policy<manage_new_object> to instruct Python to adopt +the pointer to Base and hold the instance in a new Python Base +object until the the Python object is destroyed. We shall see more of +Boost.Python +call policies later.

      +
      +    // Tell Python to take ownership of factory's result
      +    def("factory", factory,
      +        return_value_policy<manage_new_object>());
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/iterators.html b/doc/tutorial/doc/iterators.html new file mode 100644 index 00000000..7e4282cb --- /dev/null +++ b/doc/tutorial/doc/iterators.html @@ -0,0 +1,101 @@ + + + +Iterators + + + + + + + + + + +
      + + Iterators +
      +
      + + + + + + +
      +

      +In C++, and STL in particular, we see iterators everywhere. Python also has +iterators, but these are two very different beasts.

      +

      +C++ iterators:

      +
      • C++ has 5 type categories (random-access, bidirectional, forward, input, output)
      • There are 2 Operation categories: reposition, access
      • A pair of iterators is needed to represent a (first/last) range.

      +Python Iterators:

      +
      • 1 category (forward)
      • 1 operation category (next())
      • Raises StopIteration exception at end

      +The typical Python iteration protocol: for y in x... is as follows:

      +
      +    iter iter = x.__iter__()    #get iterator
      +    try:
      +        while 1:
      +        y = iter.next()         #get each item
      +        ...                     #process y
      +    except StopIteration: pass  #iterator exhausted
      +
      +

      +Boost.Python provides some mechanisms to make C++ iterators play along +nicely as Python iterators. What we need to do is to produce +appropriate __iter__ function from C++ iterators that is compatible +with the Python iteration protocol. For example:

      +
      +    object get_iterator = iterator<vector<int> >();
      +    object iter = get_iterator(v);
      +    object first = iter.next();
      +
      +

      +Or for use in class_<>:

      +
      +    .def("__iter__", iterator<vector<int> >())
      +
      +

      +range

      +

      +We can create a Python savvy iterator using the range function:

      +
      • range(start, finish)
      • range<Policies,Target>(start, finish)

      +Here, start/finish may be one of:

      +
      • member data pointers
      • member function pointers
      • adaptable function object (use Target parameter)

      +iterator

      +
      • iterator<T, Policies>()

      +Given a container T, iterator is a shortcut that simply calls range +with &T::begin, &T::end.

      +

      +Let's put this into action... Here's an example from some hypothetical +bogon Particle accelerator code:

      +
      +    f = Field()
      +    for x in f.pions:
      +        smash(x)
      +    for y in f.bogons:
      +        count(y)
      +
      +

      +Now, our C++ Wrapper:

      +
      +    class_<F>("Field")
      +        .property("pions", range(&F::p_begin, &F::p_end))
      +        .property("bogons", range(&F::b_begin, &F::b_end));
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/object_interface.html b/doc/tutorial/doc/object_interface.html new file mode 100644 index 00000000..2279a60c --- /dev/null +++ b/doc/tutorial/doc/object_interface.html @@ -0,0 +1,54 @@ + + + +Object Interface + + + + + + + + + + +
      + + Object Interface +
      +
      + + + + + + +
      +

      +Python is dynamically typed, unlike C++ which is statically typed. Python +variables may hold an integers, a float, list, dict, tuple, str, long etc., +among other things. In the viewpoint of Boost.Python and C++, these +Pythonic variables are just instances of class object. We shall see in +this chapter how to deal with Python objects.

      +

      +As mentioned, one of the goals of Boost.Python is to provide a +bidirectional mapping between C++ and Python while maintaining the Python +feel. Boost.Python C++ objects are as close as possible to Python. This +should minimize the learning curve significantly.

      +

      +

      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/quickstart.html b/doc/tutorial/doc/quickstart.html new file mode 100644 index 00000000..ec1a89ac --- /dev/null +++ b/doc/tutorial/doc/quickstart.html @@ -0,0 +1,79 @@ + + + +QuickStart + + + + + + + + + +
      + + QuickStart +
      +
      + + + + + + +
      +

      +The Boost Python Library is a framework for interfacing Python and +C++. It allows you to quickly and seamlessly expose C++ classes +functions and objects to Python, and vice-versa, using no special +tools -- just your C++ compiler. It is designed to wrap C++ interfaces +non-intrusively, so that you should not have to change the C++ code at +all in order to wrap it, making Boost.Python ideal for exposing +3rd-party libraries to Python. The library's use of advanced +metaprogramming techniques simplifies its syntax for users, so that +wrapping code takes on the look of a kind of declarative interface +definition language (IDL).

      +

      Hello World

      +Following C/C++ tradition, let's start with the "hello, world". A C++ +Function:

      +
      +    char const* greet()
      +    {
      +       return "hello, world";
      +    }
      +
      +

      +can be exposed to Python by writing a Boost.Python wrapper:

      +
      +    #include <boost/python.hpp>
      +    using namespace boost::python;
      +
      +    BOOST_PYTHON_MODULE(hello)
      +    {
      +        def("greet", greet);
      +    }
      +
      +

      +That's it. We're done. We can now build this as a shared library. The +resulting DLL is now visible to Python. Here's a sample Python session:

      +
      +    >>> import hello
      +    >>> print hello.greet()
      +    hello, world
      +
      +

      Next stop... Building your Hello World module from start to finish...

      + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt new file mode 100644 index 00000000..7c7ad628 --- /dev/null +++ b/doc/tutorial/doc/quickstart.txt @@ -0,0 +1,1020 @@ +[doc Boost Python Tutorial] + +[def __note__ [$theme/note.gif]] +[def __alert__ [$theme/alert.gif]] +[def __detail__ [$theme/lens.gif]] +[def __tip__ [$theme/bulb.gif]] +[def :-) [$theme/smiley.gif]] + +[page QuickStart] + +The Boost Python Library is a framework for interfacing Python and +C++. It allows you to quickly and seamlessly expose C++ classes +functions and objects to Python, and vice-versa, using no special +tools -- just your C++ compiler. It is designed to wrap C++ interfaces +non-intrusively, so that you should not have to change the C++ code at +all in order to wrap it, making Boost.Python ideal for exposing +3rd-party libraries to Python. The library's use of advanced +metaprogramming techniques simplifies its syntax for users, so that +wrapping code takes on the look of a kind of declarative interface +definition language (IDL). + +[h2 Hello World] + +Following C/C++ tradition, let's start with the "hello, world". A C++ +Function: + + char const* greet() + { + return "hello, world"; + } + +can be exposed to Python by writing a Boost.Python wrapper: + + #include + using namespace boost::python; + + BOOST_PYTHON_MODULE(hello) + { + def("greet", greet); + } + +That's it. We're done. We can now build this as a shared library. The +resulting DLL is now visible to Python. Here's a sample Python session: + + >>> import hello + >>> print hello.greet() + hello, world + +[:['[*Next stop... Building your Hello World module from start to finish...]]] + +[page Building Hello World] + +[h2 From Start To Finish] + +Now the first thing you'd want to do is to build the Hello World module and +try it for yourself in Python. In this section, we shall outline the steps +necessary to achieve that. We shall use the build tool that comes bundled +with every boost distribution: [*bjam]. For a complete reference to building +Boost.Python, check out: [@../../building.html building.html] + +[page Exposing Classes] + +Now let's expose a C++ class to Python. + +Consider a C++ class/struct that we want to expose to Python: + + struct World + { + void set(std::string msg) { this->msg = msg; } + std::string greet() { return msg; } + std::string msg; + }; + +We can expose this to Python by writing a corresponding Boost.Python +C++ Wrapper: + + #include + using namespace boost::python; + + BOOST_PYTHON_MODULE(hello) + { + class_("World") + .def("greet", &World::greet) + .def("set", &World::set) + ; + } + +Here, we wrote a C++ class wrapper that exposes the member functions +[^greet] and [^set]. Now, after building our module as a shared library, we +may use our class [^World] in Python. Here's a sample Python session: + + >>> import hello + >>> planet = hello.World() + >>> planet.set('howdy') + >>> planet.greet() + 'howdy' + +[page:1 Constructors] + +Our previous example didn't have any explicit constructors. +Since [^World] is declared as a plain struct, it has an implicit default +constructor. Boost.Python exposes the default constructor by default, +which is why we were able to write + + >>> planet = hello.World() + +We may wish to wrap a class with a non-default constructor. Let us +build on our previous example: + + struct World + { + World(std::string msg): msg(msg) {} // added constructor + void set(std::string msg) { this->msg = msg; } + std::string greet() { return msg; } + std::string msg; + }; + +This time [^World] has no default constructor; our previous +wrapping code would fail to compile when the library tried to expose +it. We have to tell [^class_] about the constructor we want to +expose instead. + + #include + using namespace boost::python; + + BOOST_PYTHON_MODULE(hello) + { + class_("World", init()) + .def("greet", &World::greet) + .def("set", &World::set) + ; + } + +[^init()] exposes the constructor taking in a +[^std::string] (in Python, constructors are spelled +"[^__init__(...)]"). + +We can expose additional constructors by passing more [^init<...>]s to +the [^def()] member function. Say for example we have another World +constructor taking in two doubles: + + class_("World", init()) + .def(init()) + .def("greet", &World::greet) + .def("set", &World::set) + ; + +On the other hand, if we do not wish to expose any constructors at +all, we may use [^no_init] instead: + + class_("Abstract", no_init) + +This actually adds an [^__init__] method which always raises a +Python RuntimeError exception. + +[page:1 Class Data Members] + +Data members may also be exposed to Python so that they can be +accessed as attributes of the corresponding Python class. Each data +member that we wish to be exposed may be regarded as [*read-only] or +[*read-write]. Consider this class [^Var]: + + struct Var + { + Var(std::string name) : name(name), value() {} + std::string const name; + float value; + }; + +Our C++ [^Var] class and its data members can be exposed to Python: + + class_("Var", init()) + .def_readonly("name", &Var::name) + .def_readwrite("value", &Var::value); + +Then, in Python: + + >>> x = Var('pi') + >>> x.value = 3.14 + >>> print x.name, 'is around', x.value + pi is around 3.14 + +Note that [^name] is exposed as [*read-only] while [^value] is exposed +as [*read-write]. + + >>> x.name = 'e' # can't change name + Traceback (most recent call last): + File "", line 1, in ? + AttributeError: can't set attribute + +[page:1 Class Properties] + +In C++, classes with public data members are usually frowned +upon. Well designed classes that take advantage of encapsulation hide +the class' data members. The only way to access the class' data is +through access (getter/setter) functions. Access functions expose class +properties. Here's an example: + + struct Num + { + Num(); + float get() const; + void set(float value); + ... + }; + +However, in Python attribute access is fine; it doesn't neccessarily break +encapsulation to let users handle attributes directly, because the +attributes can just be a different syntax for a method call. Wrapping our +[^Num] class using Boost.Python: + + class_("Num") + .add_property("rovalue", &Var::get) + .add_property("value", &Var::get, &Var::set); + +And at last, in Python: + + >>> x = Num() + >>> x.value = 3.14 + >>> x.value, x.rovalue + (3.14, 3.14) + >>> x.rovalue = 2.17 # error! + +Take note that the class property [^rovalue] is exposed as [*read-only] +since the [^rovalue] setter member function is not passed in: + + .add_property("rovalue", &Var::get) + +[page:1 Inheritance] + +In the previous examples, we dealt with classes that are not polymorphic. +This is not often the case. Much of the time, we will be wrapping +polymorphic classes and class hierarchies related by inheritance. We will +often have to write Boost.Python wrappers for classes that are derived from +abstract base classes. + +Consider this trivial inheritance structure: + + struct Base { virtual ~Base(); }; + struct Derived : Base {}; + +And a set of C++ functions operating on [^Base] and [^Derived] object +instances: + + void b(Base*); + void d(Derived*); + Base* factory() { return new Derived; } + +We've seen how we can wrap the base class [^Base]: + + class_("Base") + /*...*/ + ; + +Now we can inform Boost.Python of the inheritance relationship between +[^Derived] and its base class [^Base]. Thus: + + class_ >("Derived") + /*...*/ + ; + +Doing so, we get some things for free: + +# Derived automatically inherits all of Base's Python methods (wrapped C++ member functions) +# [*If] Base is polymorphic, [^Derived] objects which have been passed to Python via a pointer or reference to [^Base] can be passed where a pointer or reference to [^Derived] is expected. + +Now, we shall expose the C++ free functions [^b] and [^d] and [^factory]: + + def("b", b); + def("d", d); + def("factory", factory); + +Note that free function [^factory] is being used to generate new +instances of class [^Derived]. In such cases, we use +[^return_value_policy] to instruct Python to adopt +the pointer to [^Base] and hold the instance in a new Python [^Base] +object until the the Python object is destroyed. We shall see more of +Boost.Python [@call_policies.html call policies] later. + + // Tell Python to take ownership of factory's result + def("factory", factory, + return_value_policy()); + +[page:1 Class Virtual Functions] + +In this section, we shall learn how to make functions behave +polymorphically through virtual functions. Continuing our example, let us +add a virtual function to our [^Base] class: + + struct Base + { + virtual int f() = 0; + }; + +Since [^f] is a pure virtual function, [^Base] is now an abstract +class. Given an instance of our class, the free function [^call_f] +calls some implementation of this virtual function in a concrete +derived class: + + int call_f(Base& b) { return b.f(); } + +To allow this function to be implemented in a Python derived class, we +need to create a class wrapper: + + struct BaseWrap : Base + { + BaseWrap(PyObject* self_) + : self(self_) {} + int f() { return call_method(self, "f"); } + PyObject* self; + }; + +[blurb __detail__ [*member function and methods][br][br] Python, like +many object oriented languages uses the term [*methods]. Methods +correspond roughly to C++'s [*member functions]] + +Our class wrapper [^BaseWrap] is derived from [^Base]. Its overridden +virtual member function [^f] in effect calls the corresponding method +of the Python object [^self], which is a pointer back to the Python +[^Base] object holding our [^BaseWrap] instance. + +[blurb __note__ [*Why do we need BaseWrap?][br][br] + +['You may ask], "Why do we need the [^BaseWrap] derived class? This could +have been designed so that everything gets done right inside of +Base."[br][br] + +One of the goals of Boost.Python is to be minimally intrusive on an +existing C++ design. In principle, it should be possible to expose the +interface for a 3rd party library without changing it. To unintrusively +hook into the virtual functions so that a Python override may be called, we +must use a derived class.[br][br] + +Note however that you don't need to do this to get methods overridden +in Python to behave virtually when called ['from] [*Python]. The only +time you need to do the [^BaseWrap] dance is when you have a virtual +function that's going to be overridden in Python and called +polymorphically ['from] [*C++].] + +Wrapping [^Base] and the free function [^call_f]: + + class_("Base", no_init) + ; + def("call_f", call_f); + +Notice that we parameterized the [^class_] template with [^BaseWrap] as the +second parameter. What is [^noncopyable]? Without it, the library will try +to instantiate a copy constructor for returning Base objects from +functions. + +In Python, let us try to instantiate our [^Base] class: + + >>> base = Base() + AttributeError: ... + +Why is it an error? [^Base] is an abstract class. As such it is advisable +to define the Python wrapper with [^no_init] as we have done above. Doing +so will disallow abstract base classes such as [^Base] to be instantiated. + +[h2 Deriving a Python class] + +Now, at last, we can even derive from our base class [^Base] in Python: + + >>> class Derived(Base): + ... def f(self): + ... return 42 + ... + +Cool eh? A Python class deriving from a C++ class! + +Let's now make an instance of our Python class [^Derived]: + + >>> derived = Derived() + +Calling [^derived.f()]: + + >>> derived.f() + 42 + +Will yield the expected result. Finally, calling calling the free function +[^call_f] with [^derived] as argument: + + >>> call_f(derived()) + 42 + +Will also yield the expected result. + +Here's what's happening: + +# [^call_f(derived())] is called in Python +# This corresponds to [^def("call_f", call_f);]. Boost.Python dispatches this call. +# [^int call_f(Base& b) { return b.f(); }] accepts the call. +# The overridden virtual function [^f] of [^BaseWrap] is called. +# [^call_method(self, "f");] dispatches the call back to Python. +# [^def f(self): return 42] is finally called. + +Rewind back to our [^Base] class, if its member function [^f] was not +declared as pure virtual: + + struct Base + { + virtual int f() { return 0; } + }; + +And instead is implemented to return [^0], as shown above. + + struct BaseWrap : Base + { + BaseWrap(PyObject* self_) + : self(self_) {} + int f() { return call_method(self, "f"); } + static int default_f(Base* b) { return b->Base::f(); } // <<=== added + PyObject* self; + }; + +then, our Boost.Python wrapper: + + class_("Base") + .def("f", &BaseWrap::default_f) + ; + +Note that we are allowing [^Base] objects to be instantiated this time, +unlike before where we specifically defined the [^class_] with +[^no_init]. + +In Python, the results would be as expected: + + >>> base = Base() + >>> class Derived(Base): + ... def f(self): + ... return 42 + ... + >>> derived = Derived() + +Calling [^base.f()]: + + >>> base.f() + 0 + +Calling [^derived.f()]: + + >>> derived.f() + 42 + +Calling [^call_f], passing in a [^base] object: + + >>> call_f(base) + 0 + +Calling [^call_f], passing in a [^derived] object: + + >>> call_f(derived()) + 42 + +[page:1 Class Operators/Special Functions] + +[h2 Python Operators] + +C is well known for the abundance of oparators. C++ extends this to the +extremes by allowing operator overloading. Boost.Python takes advantage of +this and makes it easy to wrap C++ operator-powered classes. + +Consider a file position class [^FilePos] and a set of operators that take +on FilePos instances: + + class FilePos { /*...*/ }; + + FilePos operator+(FilePos, int); + FilePos operator+(int, FilePos); + int operator-(FilePos, FilePos); + FilePos operator-(FilePos, int); + FilePos& operator+=(FilePos&, int); + FilePos& operator-=(FilePos&, int); + bool operator<(FilePos, FilePos); + +The class and the various operators can be mapped to Python rather easily +and intuitively: + + class_("FilePos") + .def(self + int()) // __add__ + .def(int() + self) // __radd__ + .def(self - self) // __sub__ + .def(self - int()) // __rsub__ + .def(self += int()) // __iadd__ + .def(self -= other()) + .def(self < self); // __lt__ + +The code snippet above is very clear and needs almost no explanation at +all. It is virtually the same as the operators' signatures. Just take +note that [^self] refers to FilePos object. Also, not every class [^T] that +you might need to interact with in an operator expression is (cheaply) +default-constructible. You can use [^other()] in place of an actual +[^T] instance when writing "self expressions". + +[h2 Special Methods] + +Python has a few more ['Special Methods]. Boost.Python supports all of the +standard special method names supported by real Python class instances. A +similar set of intuitive interfaces can also be used to wrap C++ functions +that correspond to these Python ['special functions]. Example: + + class Rational + { operator double() const; }; + + Rational pow(Rational, Rational); + Rational abs(Rational); + ostream& operator<<(ostream&,Rational); + + class_() + .def(float_(self)) // __float__ + .def(pow(self)) // __pow__ + .def(abs(self)) // __abs__ + .def(str(self)) // __str__ + ; + +Need we say more? + +[page Functions] + +In this chapter, we'll look at Boost.Python powered functions in closer +detail. We shall see some facilities to make exposing C++ functions to +Python safe from potential pifalls such as dangling pointers and +references. We shall also see facilities that will make it even easier for +us to expose C++ functions that take advantage of C++ features such as +overloading and default arguments. + +[:['Read on...]] + +But before you do, you might want to fire up Python 2.2 or later and type +[^>>> import this]. + +[pre + >>> import this + The Zen of Python, by Tim Peters + Beautiful is better than ugly. + Explicit is better than implicit. + Simple is better than complex. + Complex is better than complicated. + Flat is better than nested. + Sparse is better than dense. + Readability counts. + Special cases aren't special enough to break the rules. + Although practicality beats purity. + Errors should never pass silently. + Unless explicitly silenced. + In the face of ambiguity, refuse the temptation to guess. + There should be one-- and preferably only one --obvious way to do it + Although that way may not be obvious at first unless you're Dutch. + Now is better than never. + Although never is often better than *right* now. + If the implementation is hard to explain, it's a bad idea. + If the implementation is easy to explain, it may be a good idea. + Namespaces are one honking great idea -- let's do more of those! +] + +[page:1 Call Policies] + +In C++, we often deal with arguments and return types such as pointers +and references. Such primitive types are rather, ummmm, low level and +they really don't tell us much. At the very least, we don't know the +owner of the pointer or the referenced object. No wonder languages +such as Java and Python never deal with such low level entities. In +C++, it's usually considered a good practice to use smart pointers +which exactly describe ownership semantics. Still, even good C++ +interfaces use raw references and pointers sometimes, so Boost.Python +must deal with them. To do this, it may need your help. Consider the +following C++ function: + + X& f(Y& y, Z* z); + +How should the library wrap this function? A naive approach builds a +Python X object around result reference. This strategy might or might +not work out. Here's an example where it didn't + + >>> x = f(y, z) # x refers to some C++ X + >>> del y + >>> x.some_method() # CRASH! + +What's the problem? + +Well, what if f() was implemented as shown below: + + X& f(Y& y, Z* z) + { + y.z = z; + return y.x; + } + +The problem is that the lifetime of result X& is tied to the lifetime +of y, because the f() returns a reference to a member of the y +object. This idiom is is not uncommon and perfectly acceptable in the +context of C++. However, Python users should not be able to crash the +system just by using our C++ interface. In this case deleting y will +invalidate the reference to X. We have a dangling reference. + +Here's what's happening: + +# [^f] is called passing in a reference to [^y] and a pointer to [^z] +# A reference to [^y.x] is returned +# [^y] is deleted. [^x] is a dangling reference +# [^x.some_method()] is called +# [*BOOM!] + +We could copy result into a new object: + + >>> f(y, z).set(42) # Result disappears + >>> y.x.get() # No crash, but still bad + 3.14 + +This is not really our intent of our C++ interface. We've broken our +promise that the Python interface should reflect the C++ interface as +closely as possible. + +Our problems do not end there. Suppose Y is implemented as follows: + + struct Y + { + X x; Z* z; + int z_value() { return z->value(); } + }; + +Notice that the data member [^z] is held by class Y using a raw +pointer. Now we have a potential dangling pointer problem inside Y: + + >>> x = f(y, z) # y refers to z + >>> del z # Kill the z object + >>> y.z_value() # CRASH! + +For reference, here's the implementation of [^f] again: + + X& f(Y& y, Z* z) + { + y.z = z; + return y.x; + } + +Here's what's happening: + +# [^f] is called passing in a reference to [^y] and a pointer to [^z] +# A pointer to [^z] is held by [^y] +# A reference to [^y.x] is returned +# [^z] is deleted. [^y.z] is a dangling pointer +# [^y.z_value()] is called +# [^z->value()] is called +# [*BOOM!] + +[h2 Call Policies] + +Call Policies may be used in situations such as the example detailed above. +In our example, [^return_internal_reference] and [^with_custodian_and_ward] +are our friends: + + def("f", f, + return_internal_reference<1, + with_custodian_and_ward<1, 2> >()); + +What are the [^1] and [^2] parameters, you ask? + + return_internal_reference<1 + +Informs Boost.Python that the first argument, in our case [^Y& y], is the +owner of the returned reference: [^X&]. The "[^1]" simply specifies the +first argument. In short: "return an internal reference [^X&] owned by the +1st argument [^Y& y]". + + with_custodian_and_ward<1, 2> + +Informs Boost.Python that the lifetime of the argument indicated by ward +(i.e. the 2nd argument: [^Z* z]) is dependent on the lifetime of the +argument indicated by custodian (i.e. the 1st argument: [^Z* z]). + +It is also important to note that we have defined two policies above. Two +or more policies can be composed by chaining. Here's the general syntax: + + policy1 > > + +Here is the list of predefined call policies. A complete reference detailing +these can be found [@../../v2/CallPolicies.html here]. + +* [*with_custodian_and_ward][br] Ties lifetimes of the arguments +* [*with_custodian_and_ward_postcall][br] Ties lifetimes of the arguments and results +* [*return_internal_reference][br] Ties lifetime of one argument to that of result +* [*return_value_policy with T one of:][br] +* [*reference_existing_object][br]naïve (dangerous) approach +* [*copy_const_reference][br]Boost.Python v1 approach +* [*copy_non_const_reference][br] +* [*manage_new_object][br] Adopt a pointer and hold the instance + +[blurb :-) [*Remember the Zen, Luke:][br][br] +"Explicit is better than implicit"[br] +"In the face of ambiguity, refuse the temptation to guess"[br]] + +[page:1 Default Arguments] + +Boost.Python wraps (member) function pointers. Unfortunately, C++ function +pointers carry no default argument info. Take a function [^f] with default +arguments: + + int f(int, double = 3.14, char const* = "hello"); + +But the type of a pointer to the function [^f] has no information +about its default arguments: + + int(*g)(int,double,char const*) = f; // defaults lost! + +When we pass this function pointer to the [^def] function, there is no way +to retrieve the default arguments: + + def("f", f); // defaults lost! + +Because of this, when wrapping C++ code in earlier versions of +Boost.Python, we had to resort to writing thin wrappers: + + // write "thin wrappers" + int f1(int x) { f(x); } + int f2(int x, double y) { f(x,y); } + + /*...*/ + + // in module init + def("f", f); // all arguments + def("f", f2); // two arguments + def("f", f1); // one argument + +When you want to wrap functions (or member functions) that either: + +* have default arguments, or +* are overloaded with a common sequence of initial arguments + +Boost.Python now has a way to make it easier. + +For instance, given a function: + + int foo(int a, char b = 1, unsigned c = 2, double d = 3); + +The macro invocation: + + BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4) + +Will automatically create the thin wrappers for us. This macro will create +a class [^foo_overloads] that can be passed on to [^def(...)]. The third +and fourth macro argument are the minimum arguments and maximum arguments, +respectively. In our [^foo] function the minimum number of arguments is 1 +and the maximum number of arguments is 4. The [^def(...)] function will +automatically add all the foo variants for us: + + .def("foo", foo, foo_overloads()); + +A similar facility is provided for class constructors, again, with +default arguments or a sequence of overloads. Remember init<...>? For example, +given a class X with a constructor: + + struct X + { + X(int a, char b = 'D', std::string c = "constructor", double d = 0.0); + /*...*/ + } + +You can easily add this constructor to Boost.Python in one shot: + + .def(init >()) + +Notice the use of [^init<...>] and [^optional<...>] to signify the default +(optional arguments). + +[page Object Interface] + +Python is dynamically typed, unlike C++ which is statically typed. Python +variables may hold an integers, a float, list, dict, tuple, str, long etc., +among other things. In the viewpoint of Boost.Python and C++, these +Pythonic variables are just instances of class [^object]. We shall see in +this chapter how to deal with Python objects. + +As mentioned, one of the goals of Boost.Python is to provide a +bidirectional mapping between C++ and Python while maintaining the Python +feel. Boost.Python C++ [^object]s are as close as possible to Python. This +should minimize the learning curve significantly. + +[$theme/python.png] + +[page:1 Basic Interface] + +Class [^object] wraps [^PyObject*]. All the intricacies of dealing with +[^PyObject]s such as managing reference counting are handled by the +[^object] class. C++ object interoperability is seamless. Boost.Python C++ +[^object]s can in fact be explicitly constructed from any C++ object. + +To illustrate, this Python code snippet: + + def f(x, f): + if (y == 'foo'): + x[3:7] = 'bar' + else: + x.items += f(3, x) + return x + + def getfunc(): + return f; + +Can be rewritten in C++ using Boost.Python facilities this way: + + object f(object x, object f) { + if (f == "foo") + x.slice(3,7) = "bar"; + else + x.attr("items") += f(3, x); + return x; + } + object getfunc() { + return object(f); + } + +Apart from cosmetic differences due to the fact that we are writing the +code in C++, the look and feel should be immediately apparent to the Python +coder. + +[page:1 Derived Object types] + +Boost.Python comes with a set of derived [^object] types corresponding to +that of Python's: + +* list +* dict +* tuple +* str +* long_ + +These derived [^object] types act like real Python types. For instance: + + str(1) ==> "1" + +Wherever appropriate, a particular derived [^object] has corresponding +Python type's methods. For instance, [^dict] has a [^keys()] method: + + d.keys() + +[^make_tuple] is provided for declaring ['tuple literals]. Example: + + make_tuple(123, 'D', "Hello, World", 0.0); + +In C++, when Boost.Python [^object]s are used as arguments to functions, +subtype matching is required. For example, when a function [^f], as +declared below, is wrapped, it will only accept instances of Python's +[^str] type and subtypes. + + void f(str name) + { + object n2 = name.attr("upper")(); // NAME = name.upper() + str NAME = name.upper(); // better + object msg = "%s is bigger than %s" % make_tuple(NAME,name); + } + +In finer detail: + + str NAME = name.upper(); + +Illustrates that we provide versions of the str type's methods as C++ +member functions. + + object msg = "%s is bigger than %s" % make_tuple(NAME,name); + +Demonstrates that you can write the C++ equivalent of [^"format" % x,y,z] +in Python, which is useful since there's no easy way to do that in std C++. + +[blurb __alert__ Beware the common pitfall of +forgetting that the constructors of most of Python's mutable types +make copies, just as in Python.[br][br] + + [^dict d(x.attr("__dict__")); # makes a copy of x's dict[br] + '''d['whatever']''' = 3; # modifies a copy of x.__dict__ (not the original)[br]] +] + +[h2 class_ as objects] + +Due to the dynamic nature of Boost.Python objects, any [^class_] may +also be one of these types! The following code snippet wraps the class +(type) object. + +We can use this to create wrapped instances. Example: + + object vec345 = ( + class_("Vec2", init()) + .def_readonly("length", &Point::length) + .def_readonly("angle", &Point::angle) + )(3.0, 4.0); + + assert(vec345.attr("length") == 5.0); + +[page:1 Extracting C++ objects] + +At some point, we will need to get C++ values out of object instances. This +can be achieved with the [^extract] function. Consider the following: + + double x = o.attr("length"); // compile error + +In the code above, we got a compiler error because Boost.Python +[^object] can't be implicitly converted to [^double]s. Instead, what +we wanted to do above can be achieved by writing: + + double l = extract(o.attr("length")); + Vec2& v = extract(o); + assert(l == v.length()); + +The first line attempts to extract the "length" attribute of the +Boost.Python [^object] [^o]. The second line attempts to ['extract] the +[^Vec2] object from held by the Boost.Python [^object] [^o]. + +Take note that we said "attempt to" above. What if the Boost.Python +[^object] [^o] does not really hold a [^Vec2] type? This is certainly +a possibility considering the dynamic nature of Python [^object]s. To +be on the safe side, if the C++ type can't be extracted, an +appropriate exception is thrown. To avoid an exception, we need to +test for extractibility: + + extract x(o); + if (x.check()) { + Vec2& v = x(); ... + +__tip__ The astute reader might have noticed that the [^extract] +facility in fact solves mutable copying problem: + + dict d = extract(x.attr("__dict__")); + d['whatever'] = 3; # modifies x.__dict__ ! + +[page Iterators] + +In C++, and STL in particular, we see iterators everywhere. Python also has +iterators, but these are two very different beasts. + +[*C++ iterators:] + +* C++ has 5 type categories (random-access, bidirectional, forward, input, output) +* There are 2 Operation categories: reposition, access +* A pair of iterators is needed to represent a (first/last) range. + +[*Python Iterators:] + +* 1 category (forward) +* 1 operation category (next()) +* Raises StopIteration exception at end + +The typical Python iteration protocol: [^[*for y in x...]] is as follows: + + iter iter = x.__iter__() # get iterator + try: + while 1: + y = iter.next() # get each item + ... # process y + except StopIteration: pass # iterator exhausted + +Boost.Python provides some mechanisms to make C++ iterators play along +nicely as Python iterators. What we need to do is to produce +appropriate __iter__ function from C++ iterators that is compatible +with the Python iteration protocol. For example: + + object get_iterator = iterator >(); + object iter = get_iterator(v); + object first = iter.next(); + +Or for use in class_<>: + + .def("__iter__", iterator >()) + +[*range] + +We can create a Python savvy iterator using the range function: + +* range(start, finish) +* range(start, finish) + +Here, start/finish may be one of: + +* member data pointers +* member function pointers +* adaptable function object (use Target parameter) + +[*iterator] + +* iterator() + +Given a container [^T], iterator is a shortcut that simply calls [^range] +with &T::begin, &T::end. + +Let's put this into action... Here's an example from some hypothetical +bogon Particle accelerator code: + + f = Field() + for x in f.pions: + smash(x) + for y in f.bogons: + count(y) + +Now, our C++ Wrapper: + + class_("Field") + .property("pions", range(&F::p_begin, &F::p_end)) + .property("bogons", range(&F::b_begin, &F::b_end)); + +[page Exception Translation] + +All C++ exceptions must be caught at the boundary with Python code. This +boundary is the point where C++ meets Python. Boost.Python provides a +default exception handler that translates selected standard exceptions, +then gives up: + + raise RuntimeError, 'unidentifiable C++ Exception' + +Users may provide custom translation. Here's an example: + + struct PodBayDoorException; + void translator(PodBayDoorException& x) { + PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave..."); + } + BOOST_PYTHON_MODULE(kubrick) { + register_exception_translator< + PodBayDoorException>(translator); + ... + diff --git a/doc/tutorial/doc/theme/alert.gif b/doc/tutorial/doc/theme/alert.gif new file mode 100644 index 0000000000000000000000000000000000000000..270764cc58716d36f8545c07ffbccb76a3dbc7f4 GIT binary patch literal 577 zcmZ?wbhEHb6krfwc*el+^5x4HFJ3%)^yuNkhj;GW`TvCB_N{CGA2IyD%W(C|x&OBr z{@-G_a_Q{m__~8F~vDYEl>qqZpDSjq@WJa>5z1Lm6Vd z86rG+L!23`^cb|27{rAb*jO1D7#RNl{|}<5jTL{gu!=AwGw6T}2E_>j`@DwarsiZ7 zvzCqy8~4s$Mnes@-VRGi5tqr$%yz7-+I%yUbrd6_%=Konm?$SD`KoeGb{17nO!DDy z>t(PKkWWZ*<cQAmnAE=fsD%$UE$ROUW+NUZ1+QQKJ-!ms2) z!wk-f=<_sLpE#kg){9r_k3+JcmI}v|3yP=3Bn5<=JQ5$B644M)RP)^A(&gG6!^Fs7 F4FJH#(p~@n literal 0 HcmV?d00001 diff --git a/doc/tutorial/doc/theme/arrow.gif b/doc/tutorial/doc/theme/arrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..e33db0fb4dd85e0fe527343d95a3f28a0ebb74f9 GIT binary patch literal 70 zcmZ?wbhEHb6lLIGn8?8J9}E~6W->4^DE?&OC-XFJFH7^5yH-udiOcdjJ0Y=g*&CzkdDw`}cS6-hKG+ zVdct|pFVy1_U+rhfB)XRdGq$|+aEuEeEj(F|NsB1R;~K`_wVY}tN;A@vu4ej6)RT! z{{8#cuU~7|u3fio-TL+GfByWrapT4f8#Zj(v}yC^&D*wZ+q!k@mMvR$@7{gjz=7@C zx9{A!bMM~0yLRo`vuDr#{rh+9*s*WlzC(u&9X)#V)TvV^Po6w- zyLay%Jb3Wz*|X1|Kfizf{+Tmpu3fwK^y$-^H*a3Qe*M|AXXnnHJAeNCg$oysA3uKe z>eWk^E+4<0lBLU*@T^?5dd(`K^&2*BTFEI`2zd3>o;z)v)s9R@BSUeM~|O8Wn_5q^405CHt*hl`1r~B%hzw;zdQW;{pasr zF9v2V8Hs|fgUuYmej5*MSa`TSY=y@hkBv&AY7)j-cRDt)dE zU9$D{^$pSTGkte&%f01a^!nae>+L=F4>WVj`|WA_`1r(RZF9M$J3l|aF#GrnzrDM@ zzP^$C;>NkXyT8BJIMglgzi&_FC%sFnlY$n!TsEid z)yw4z+N54FEt!_}YUPS$t6r^IvuM`A)fY$|rssS*xogRqPp5XWJpOdrfW7(58I$WZ zJ;oN#*L*&AD&X$RBj zw_mR(wCjGmkup8^+s%ySYroyf+5Yz1?SkXF-|v)M&;5S4;`!R|_iFabaxho}0O~&E Au>b%7 literal 0 HcmV?d00001 diff --git a/doc/tutorial/doc/theme/bkd2.gif b/doc/tutorial/doc/theme/bkd2.gif new file mode 100644 index 0000000000000000000000000000000000000000..b03d9ba97ca7a4c4de297b5413fd3d3df8e0fb49 GIT binary patch literal 2543 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 literal 0 HcmV?d00001 diff --git a/doc/tutorial/doc/theme/bulb.gif b/doc/tutorial/doc/theme/bulb.gif new file mode 100644 index 0000000000000000000000000000000000000000..74f3baac42f12ac0551040a00f78cb573360a0ad GIT binary patch literal 944 zcmZ?wbhEHbU2JX=yWO8qb`WHgo38Gifu=q@6jF_W#UGhBGsb&&*6a zGjrydnP<+-{D0;Q!i=IrIPje+GvC495Q% z(*85d1W7Xd|8LCj-`M!SaoT_5nIN^s|No~k{7*CfpO*GNZ6-)-+W-GE8UD{S{y#JA z|IC>nlV<+^e}>`z8RP$8cYq8A8~y)3Nb~>yAnE^L0P?^n9t{C$ zm!W3VRz=HX0SO5P1_s5SEQ|~c3=BFT0%V2*i>ts1&-4h1-QU}6JQPJ#9Az#qP{_IL z>m8xcQ#>ccK&B>uvC-M7@I$1?63NFG4AfGLn>kr6)<~>7uC&oZb>E%VNA7Gc3=Gx) DZ>u*X literal 0 HcmV?d00001 diff --git a/doc/tutorial/doc/theme/c++boost.gif b/doc/tutorial/doc/theme/c++boost.gif new file mode 100644 index 0000000000000000000000000000000000000000..58be431a3fafbd5adfa01e829ce8d80a03a83ed0 GIT binary patch literal 8819 zcmZ?wbhEHb6lDx!_|CwzZQFbH(K6ngWKJ ziiVnsJ(`+|nwo~1nogRU#hRMcnwmYDhC!N^Q#37?YC7%JbULQ#bxbqrnr8BQL(ODE zLoY+8V}?P;41=y2MlCgrx@H*l+%Wl?Ve)gs?C+L}mX?N=mWDx=hSipqQ!JgPSURn> z^vbpjT56g6-Lm?-WzTmf!(=DJY9}WzC#NVUr)(#u7ALR0PC?a9L35m__ikjmUwbv`^m{;;Wuj=n!J>P?zs)M|u zg1oYWg0h2x<^%<;4T`!KlsqLUd1+Ac+Mw)XLD|=WvhM|DKM$(D7F7K{sO5W5&-0+3 z??H3EM|mYj1#OK2ftIN3wNcggqSpRT4$4lBTAG}kot#{qoIE8tyC*q&PIC6vOS7xD zW>??KZaJ6Tb1u8*UUtv(>?z-~m%h(F_CNdD|Kj4M#l`1}=X@_-`@MMU_u_NktBZT8 zpp&i(JHp3~FQ z(gOl>dV03@^c?G%^1f%zxt=-KdX`@6S^B(Z>-#A^bEeFhGiA=&DRcHtS^9j+()UxA zexI`S-juEHr|f+`W$$+oI`@ChoO5&5URye6?b11Wmo7cFbm_UJOYbdRyLai)y3n&#m2hZSB_QYmePqd+hz%bMM!l`@Z(t_qETz@7;S2jPC8- z`+V=-_j~t#-+S!X-gEc%o_oLd-1lQ!uN`~-{oJ{G=gz%9ckkZ0d+*QP`+n{H_iNw3 z-@Etx-o5Y7LE!uQ=ilFd2LZ*OEQ|~c{~2^ZSpk$M7&!hh{O6SM*s$PWGl#HN%!v&P z54Q^_d(H9KxaerNgmKoL6B`#F?^kf{lJVTM)Z?TNcv$a| zX8p~bZNB0Df&T~6_*U;Ue!k)Nx4)0STN=lnoy=Uk&wHlPgHtoufA^>{GB7Z*NC+qx zEcpIN;8}uG+nxy)Z*Fk5pN`YwZ+XkW@@A=`LV`o-eI~Cj)^QWQ-oG;S@4wD($Mp*; zKP`6s{@DHBpR&r|f1Y;l*S~LH`{mvB-SzM1@2UKMVR3)O&lAhfXRyDTtWf>OAmU!t zs=u54Gam$&%`7~<@(I8EdENsIoYf18T1uH!F5G5d%-B3PRcBIqc*K(2v|IK+EpEtF zvVWTFZ*Tf*@q*YTCzbu}KZ#iM+uB`wtUT%073U>3|4u$WZ{ub)vwzYj1 zuldQd;&D~NvF-O#<}b8Nu8>@&;-9;Xcf)NZMy&}m=Ir4$;7VZmncQc2tKjgwqRO9N zm2B@69PXQ`ze#LXi_kW+n@esNs@-bIFpJ8}njN-lZftLp)yfr%lw4wFt350_kh}L| z+bR2hhkXvb%G=Y~cylrH%;s)`%pM)00cDHCB8v?zgnNb(GKA z#VV6;>)Rcd&s%@~^7x$1zd6b0?C$^iIo0ykHf4VM&pV8lZu@Lu*+1oT!|Hxpf4|Hp zebJ9zByaeB$KplThPhp@+}w7ws^{-I@aj&~7QP3E9IP%KooDK%P!P@VoTuVR?H94` zCpNd97&Ruj`*iYECj5P=JLyHiW`FayIluYr-`yzgH@o}hbD!0}CB}K?FTZT=v;Hk} z*Wb!~J9CMZ>G{tyuKeBLtiR*imCgMV{z~j#(jUWiC!yMCQ>B4B)0tJb8Fs#D?q0)q z;wM8smqL1^eT~I-iGN!rN2$G9{?}&G>8NXw2Oq>Pd~2*xz3{8?!x??n>n!ZQoBUAi z{}dgt z+CLsYPp}lKr}0kz_UE(Cjeixn=arWW*d5?Mdt3Fq+0Tf_yms$*G@rM4{ATfKgFi9M z=WOo^IQyI4zjJt>-Hn*T{Dw!KeD?kQBBq$%>gJQnz2<*jxcxrVXp+6cL-y^1<5sr{ z`AbdC%KXfjzPTZlzxu=CroTTf_WNC*B_^p;##iY5_F7rj>MP4aUq9$&K4+pK&+5n2 z!p(61TN3}pH%Ikq4zMyjF=2>~Y^(eCN8^~qA4a>{2K|ohC)^DWE#y!Acv#~4jpK$J zCh})UD9aza;A&SA$Xgq+QGWk|V|EKZcGtx$mio(a-29VaPu`tm*#{5Wr7lO9EI*qg z_x*>M{f@2fH8&SWOYE86f26Jd%#L$;3OOAdnOkRvpM0FMR_TBQhXG^Do5zBR5#60P z3bl5BIiCOT1+(6&VC{gj>ONC~C-i-q$Y1rM!|PW<>cn?T7pPrjwogoYI#uL~SMtlp zaz72i*j_HQ;AZM7j}w0CS{L;d zE~=m2vY1ct#=_Edu3C*3-sHVm(ags>fq^Mvq3pkZi{15F7V;NbD9dljIA%L#VNZ?D zV~H;}T(zDsa>iYGEV_O}yH-sgfBYUL`Bfc9ZFVf`kKOQS;hGc2^^z94q+D?pUozvk ze$T@GEC*-#>lH7}HwE_RS2WAr?r^g^wz03K#aZ@e#Bu9)AN$IGtZA#CBQ$x2iWPrW zvErQ=2W3_xMpmB(tM~#K=CTy=7u!5q-M^w)P^e6{jAyY(LaKY+pCi4wHck9VM_a$F zDG1wO*Cc%*fz5u(MV@MfWU1bpDlCu?UGugvkfU^sbp!| zxOzv6ZNkE?@*_%%jzze-_CD;3w@H>;ccIm0Rb%h%u*ci(Z)i6^RM?-tM_K;8hr-oY zM{UCTjyY-SaTHfRKD#%8%}iBUm67MdoiIZO^B$E338V5&x1MTFTCr?uCx;-H%JxUH z3mjamCnU1wGCUG~f1;7^%*8gxEy=u@8SPS66#7l>D9UDfd=vCC=+|Ac@aFuEb=*%9 zIm~Y?=AByMuBv0$e{@&!#tE^l)*+1Cl?xt;e2G};70%6*af4afD0ja3m4*E!OAgE5 z`6Sq&=A-;I!Rqqtvb-Xeq}~{nV=n90@#$AEa?1%Um{(T8W~i0E{Pl+oR>vIJbpBNZ zobUd>K=y9M@!IZReAOL?r4CPUtG%1ZS6F#C^R0us^@4AG_H!T0-2HKF{+)|`WhL+Z zZ%%Trf8MB5S+Ke~X!Z1l=NA(c6<5oCom90~-l(`LsX7Qzz_eLm>(Kl$h$PuI8) zit=SQw(GCB@s7b^!d0#lnQ}Hi99fkXH0=A|X!GNRb(OV21Bb-|^Vbg=IkYA;?BjP} zOgpjFT3{ka%=JgI3K@>(c7c@^42{wjKbowTENIR1P~?44&?L2MBdhL`IPPZ}i~{!< z+Y{eA@V@tOmcDn9&1OfkKwE~pVpBh-&z5GP=@$RAE(CH0Z%GyrOl{S9c91Li%wtKN zSU2-m{{$~rH$0ZEebc_^SL1`3yjeZ_&hE!-krc^Hi0k5 zfc3=%wjhC)tOtBYukkfIaO_D>ou0ti^_A=G0rm+O_>O;wIPih%^Ma^P2|W7^_&-kO zzgl4DdNuUz0vm=;hF=5Z3^ytHx0Z2z=dYb$c3#lD=7MLLBbWLX2BrgiiA?hPpEP5G zEWbE#EiaH(GGO=@e68ro2V>W*eBBi$uP*R1ec`>ff%j-a@Vy4UD+_pUU*LT(f$#PK zW2Ps(4=(V|?cn?WneTQ(*8>5*mkWwtEr?#9!S{;6l#j*KD!hcFh3`cI--#r?oipP9 zhVuVNjTaR0`N1T1ghgyVla}7KHUVM7tmpiy3DVmO)rBwk{X0;0c(ETx0&kfj-%108 z9|!oEGWvc981y%A2^ceQ8}KhI$nJ1xENb9*#K6Aj0-yH<#`_BFodfceGS$i1-_sS zY^S!dEi>nMaDc73fv>{hALm;Kj)@6;(>8FtNZ^{Tz`yzf=Vyn=Pan8DTX|Pc<$ZX- z?e+%#^)L7zFz9_vM z_8@^H^8w!!2aY!h98(MUY7$asU*%iL(7N#e_m>CUt3~-P9B@k#;VW!$xR<2=jmhS@ z#s|b=djli_8U=dYS(jurVFrU0lR}V3OrC3*TQKIBGXIrx@5i+%WI^ zVz&nkyr&I;v z0VMg!CJfaUiT*z>p;lt1tWCotY|UaQU=v)x6(_*H-(kYT3#=KhSe-8LIu$TqH(*gaz{@&;fvuD2 zUIU|s0AHa2>IQysDU<(UdLJJt z2^quLYa;mVo<-}ljZjS%Wn$&^PTy>D40HT z;OY6mp0=Qj=b`T230#{#aNiK%`x?n}@dMA52HyJ&yeAoWuNf@3Zm|7+K-V<~o{I&% z_Y&scci_G9p_Yw{PvVz-lefvPQu`MZ_~v);y;@KlaG9^3Nn_8B1+z3dUoh}LGf4b= zK{fG{Wg3&%xfea@&8wLe8FLiXc@)&c0=VuZ^s*GN**VDW6p(A(()&iRVTbh^rW0jP z7&u-8#JpX=Y}vrq&cJoSfLq`rU)}@O6Aer68?ZPF@H#(WJ*L1C_pgALCxGFC1Czl7 z9Tp>J@FH2$OfJ&0kVI$Zj~v;J(l!^Q`3hK^x}|>^FtIo=1_|wA?%17iQtqjN!s#eJ!6{sy8<;~s z@GTVJ+F!sU_>s@4fF~=8=T#JsvjF=A1s10U-dG04{R|9jA9&jv*lsH@NEECvy}%oI zfa!VxvmXO5ivjcX35=2#cqJDw-8En~e88*C!KZX`X7mSMKLytJ46KkTg##f!d za)BWsTq*JA1Kz0tk$W$2|6^LoPB zpPmbjZs5K0V8NXa_In+8I1CrO{E%SE%~R!v|B0im`Z;U?7n0ZldCCnqCqL!>b%A^T2L8k?_E#S8 zKWtE$V6D2aI8*17$dYV<35|TJA5QKP%;t1pteL=fw_%H}$eQOndS#cgzkR?laRJ|s zKYUgREUzYTF8si^R)Kwg!yfjD{3j>auqU!zSiRo)1J`A3mrq~$*sC}uF)#>z;FfY= zy;8s&yMa6K!>tny@!uTypCxbwC2&bCU^*YbEZM;KX*c&Ob%*|IdUrN(MK9o5tIivB zfMs`sz{&-zo&VNyi9h8&e}MmL0PnlW*QTiHrB%rD2`Sz&l=w4&yZ!;w-o!O(MJ(P2 zcq&VX9M=R3;3EB@aT!N zy>(#8{J^(Jpz-q$?zIg9KN>g!8U&tNv1~SAneXtJO_5(FflESxWxoLH>staF6S(vR zn0E; zD8*U$_%5SYW?)|9z`E&!z`7U>Ej)&uzoT&Iue(4Eo<2{8*p&xln+EBa!p*E-sEjR`CXb%?}vs9C+CS zc>)uTuzlq7ci>=8Thc|+W?27z4P~9K@Lgrrf@$`#({Ab*|TdmIDGqG%b)WqLkGG!L|KXgd_70Q?5T2mRp`*D&_ z@>F)I_nJZone%$HqnzpI921zQ4MoZiUy&->kjyTeJV| zTl#tWxx4!-KmWUW`n$jU{`$WX)^m1*d`dYr$u(`s^!H0nPWcyB_3s;xZv39q4|2Yn zzIRTtt=oO3^XI2^qAMyp9ril6WW+9t+TWzR^|)5woQR@53of5f?mJer=v>B$EM~_)l-R_Xznf6oeWzx^n@>{b0t*hncskrx`GWF}r z-|h43q`F^hI>qN=;Mgm6>y1iBT+#~J;wKZA&pmWUafK}B!N}*b1@|J^Wr_|7w$I7; zt5KV}^pB%DuT#X%Ba`w>PAPHs?y^)Ccrj^$o3iz~1@6k_#~hL;IaoQWPL1ul_;lu{ zd7ka_DnIRXpI@`?j=RHgxvCG2C$tuwa9};IQtaBT_j&o;vmXvFpI;sK>Wy4gRpURF zx#205?9-~>M5gqWe4B7|UVww7`icU(lge|7P6fL1pPHrU!e_baA_te>nnx^adgfI& zUFu2t;4IO%i<70n&+o%San%|HedVl@6;AWKk6m2OZ}%zks6=&KWt)7)yp89V<}rA? z%N=?ZsAE_s(VU@Vc)DeqPn#Fh=Y?f+?)J=|a&OOb@#2z)uJgQ7UK-5HJ1}Fhbfk-? zx?toX&Zoi!4wf!~hH8aNHihh&z`V2P-HKLA*LkNoW{EF3<-zG*_Tq$mkkrS6?RfzK zi)L)yccO7#VcNpweXhSMTc_5Ay!<*n>&MRZ^Y{M=JbvTQzmx0^+S0ev7cnkAYI%$4 ze2dSLdDs87w98g~n;5K6|7u~oT;-0<%jK%?RsMQewIFZ#Y*o`q%h}b9U#az)Y&)jG ztzi=NtjBP{?j)(+u9hXCeLp;pPS0B4c=VC){E6*ywHj~S?z!k$Bxs?Ch6K*n1cHi^2SLRI6N2b>kxI`y4o zyWWeBTnRUvB^xKXGX6{a$XVU+PByH-#VCbwxAUDuqyj`)%|(fb0UMCF;o@~$nC z4L=wc)LnVw{jOQbFz{ZQmDd6De@%cIkli+R?R2an})b{&`e_^_|6 zhFMB#rMr~Q3PC3yrgDjov)uMA?DEKHkxt&w<`xpzn_8nRxoQT>CkrF~*d>SZBo?w+ z?Fu|n7o#a3d8^%N%MyVOlO^eaEKg@}Jz1*eH&N-wg5$s5IPz3^D9ii_U^98v*mIiE zS@N5rtL=>~-sj(J>X{(W>-OiLW1oQ0av7aH9ty{%P0aRKC}b|x_}PG|CH_kT`~C+9 z`P3Ra+|!P*r!d@h-KEH8@F7`r^#gVlzk~em{xU@zUEyzjL2zHmpT(*FBce7jg=|i1 zy)<9)rq6VbLlX>2k11Z*;AXc+u&=u2vBZlV$DWog>^5mSEI0S{QvHvD{jvX;L=WY- z8ya6SNr^fl^rS)7*hR}Pf=5l+@4;2$GmgFaC5t5%XS5_532_J?xS(`-gOmKW<6X6H z4vGEKXfu4~%v&GQyzf&m*TY){h!&qb{Ur2BZ`q(`y zc8OfiiEy_r#m+-sDN^@09JiIawAI;rj^bTUw$0(J=ZP#j)z%h&day9b}a6P@?2ydR3y8pG#d0= zVV2oj5oW$XaLI&*$KpLZIqan_HqDN0>Ak7Tro88b+P@1|ZWs$6JnnKue8F*D?b=?) zjkV6wYB_JG7cyo|*fwR4d8Nn_h0HhaqUXA~?P_}5C;rksq}8)0KIJ=4+JzJPlRk34 z=(@}kzV1Xqec{?8jE8tS4{{_P&J@fPVV2ELnm^%d%*=L=C0k;IUJJfF$p7xk_T8;{ z?5&qR^3`zcxcKNoj_s?1x25)r%G59Av2~epH+{kOBh%FiAJtt<>Yj1<)UmG3mJF|W z3j&;#e=T4$eDYCEM!4@p^|7z+Wnn4pZ=B`+bDIhs zp272;Y;n*2 z{OG1NpCiA|f7$s7FOOf4TN2r3^2Gk%3L)nw3;WMV&Aw5swezu!b8fc&Qdu$ATh=W1 z9_H;>oVn&L+Z^jlyk{;Yue#b^`%opU3=oSpr%~ki<~5JQji;JxWPB4V%(6NB`TUQo#$ArQu`m89 zeQ3(G-2NtTYo5ba*_RpZDk}wZJ=J^VoEE!V?K14W$R8;8a>8Ggw;PMvJUr#@EjVVf zB9ZR_^M2{uAKa|JCcG~{Wm5rX_ww!QeeOTV*8nj z4)0si4<@UW7_dKEJVDoK50hrcAq^$2os;Tr?Rc+z@O$F?qcc0Sx_ah2>Rxu*Io-p) zEuv>r&_T99&dIwc{lCDIa9F6NfT!+&%9=$2-<^5Z-fDko&GE;oLv@Ra&c`)+H`o99 zwWdt_pq5I$u!s(4S++p>L(}xgX;slO(kd%dpQv=KP-;D)!WihRZ0-D~NT9xB{@Dz3 zlb3edTMm~OJKH@LGJJA)O}3$!%7hiW4?C(HaWXmL>~h2<Q%P5$_{Me6AeveR9N4XL17rgEatT*T~8M literal 0 HcmV?d00001 diff --git a/doc/tutorial/doc/theme/l_arr.gif b/doc/tutorial/doc/theme/l_arr.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b3cb1cbf07e316c3655ac84c9ba72dfbe2e25a1 GIT binary patch literal 147 zcmZ?wbhEHb6k!l%*vtR|#>U2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB# zGyG3u_&<~3{~3n=|3LN)qoiR2(lV*Hortz6G#%KN;|7S4%Z*2TO z&G`RJEK^{soP6L6NX=!KD(*A?| zH`6$6W?I_JnQ1f6q|N*f^6nX9kmQ+}X=l!)o%x^kpCRqPaoYd1wEr{H{+~(v|9>VZ z?2KoELTBbokpKUK!Up7}w3#4BpP6a=9~4v|i_>O;j6O3n?LR2wK+Kwg@82IT1fpg5Un4D!LunP)&o{|80U8Do%#K>Raj&ip^~pW)1Z z<1_!$&itQw=Kq;9|Nny`5FGs=SAb&_6rbQo0yzpC?x5%e2PMdj;LriZHrT@;CxiU} ziu^OiprAT46J#*h=>PvgvGo5x$WQ;l0FoBzOe+3lVPs&q!Jq@O7nCO$IN}&Ka$aFv zpuix@B&?>hV!}eF9QO5|J|4^sPEA7VZEbc4+&y* uYH+E(K1hDVYLKk1ld!4J(;3Md8en8xd?Q4AuZ=(r&5% literal 0 HcmV?d00001 diff --git a/doc/tutorial/doc/theme/note.gif b/doc/tutorial/doc/theme/note.gif new file mode 100644 index 0000000000000000000000000000000000000000..bd92f07555d06e0744b408acc0fbf463e280f2f4 GIT binary patch literal 151 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 U=h+`HFfcH9y85}Sb4q9e0E&RLWB>pF literal 0 HcmV?d00001 diff --git a/doc/tutorial/doc/theme/r_arr.gif b/doc/tutorial/doc/theme/r_arr.gif new file mode 100644 index 0000000000000000000000000000000000000000..2dcdad117debc34257b746cbe843bf5ca8737b59 GIT binary patch literal 147 zcmZ?wbhEHb6k!l%*vtR|#>U2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#&gTE>G6muSe93zS-%fd>Q)&EUbx3v}%NcRk;>%V0Cvz}Z0{|MoM2G+Y literal 0 HcmV?d00001 diff --git a/doc/tutorial/doc/theme/r_arr_disabled.gif b/doc/tutorial/doc/theme/r_arr_disabled.gif new file mode 100644 index 0000000000000000000000000000000000000000..2100f78bf35a47e09ca76ffcc6e80c5a2b11e359 GIT binary patch literal 91 zcmZ?wbhEHb6k!l%n8?5|bLPzZ_wWDz|DS<@LGdRGs|W)VgAM}&0|Q8&fk|gd|H|rv v@(cz3o}Svfg4O3$GVLgQHgm3)*?|1&XIvGFi0itr1TiFoeP&p1C|3gi5M|Dy8)Dq>pVFYM_y+=U^T ztHBMdj+tQ(A2Y*wF$RYE_4D-@jtU##9xMTW{_9v6c`wK7#J8B1sE6<80-`n z7><}aTg5mA1O&%;g!uX}*f26MGK54pa~u~3ne&L_xcGT71qKC%`|QWX?G$<#K=P%G z=f$!jvLf=G=8H2hFfyd8*(n?_D`m7(uv4gs=yaGbo~{-bxlJUa@tDY4zP5<9g6(Q8 z@$VV#2iy??g*_vVXy`OS*Qv? literal 0 HcmV?d00001 diff --git a/doc/tutorial/doc/theme/style.css b/doc/tutorial/doc/theme/style.css new file mode 100644 index 00000000..53a6205e --- /dev/null +++ b/doc/tutorial/doc/theme/style.css @@ -0,0 +1,170 @@ +body +{ + background-image: url(bkd.gif); + background-color: #FFFFFF; + margin: 1em 2em 1em 2em; +} + +h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; } +h2 { font: 140% sans-serif; font-weight: bold; text-align: left; } +h3 { font: 120% sans-serif; font-weight: bold; text-align: left; } +h4 { font: bold 100% sans-serif; font-weight: bold; text-align: left; } +h5 { font: italic 100% sans-serif; font-weight: bold; text-align: left; } +h6 { font: small-caps 100% sans-serif; font-weight: bold; text-align: left; } + +pre +{ + border-top: gray 1pt solid; + border-right: gray 1pt solid; + border-left: gray 1pt solid; + border-bottom: gray 1pt solid; + + padding-top: 2pt; + padding-right: 2pt; + padding-left: 2pt; + padding-bottom: 2pt; + + display: block; + font-family: "courier new", courier, mono; + background-color: #eeeeee; font-size: small +} + +code +{ + font-family: "Courier New", Courier, mono; + font-size: small +} + +tt +{ + display: inline; + font-family: "Courier New", Courier, mono; + color: #000099; + font-size: small +} + +p +{ + text-align: justify; + font-family: Georgia, "Times New Roman", Times, serif +} + +ul +{ + list-style-image: url(bullet.gif); + font-family: Georgia, "Times New Roman", Times, serif +} + +ol +{ + font-family: Georgia, "Times New Roman", Times, serif +} + +a +{ + font-weight: bold; + color: #003366; + text-decoration: none; +} + +a:hover { color: #8080FF; } + +.literal { color: #666666; font-style: italic} +.keyword { color: #000099} +.identifier {} +.comment { font-style: italic; color: #990000} +.special { color: #800040} +.preprocessor { color: #FF0000} +.string { font-style: italic; color: #666666} +.copyright { color: #666666; font-size: small} +.white_bkd { background-color: #FFFFFF} +.dk_grey_bkd { background-color: #999999} +.quotes { color: #666666; font-style: italic; font-weight: bold} + +.note_box +{ + display: block; + + border-top: gray 1pt solid; + border-right: gray 1pt solid; + border-left: gray 1pt solid; + border-bottom: gray 1pt solid; + + padding-right: 12pt; + padding-left: 12pt; + padding-bottom: 12pt; + padding-top: 12pt; + + font-family: Arial, Helvetica, sans-serif; + background-color: #E2E9EF; + font-size: small; text-align: justify +} + +.table_title +{ + background-color: #648CCA; + + font-family: Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; + font-weight: bold +; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px +} + +.table_cells +{ + background-color: #E2E9EF; + + font-family: Geneva, Arial, Helvetica, san-serif; + font-size: small +; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px +} + +.toc +{ + DISPLAY: block; + background-color: #E2E9EF + font-family: Arial, Helvetica, sans-serif; + + border-top: gray 1pt solid; + border-left: gray 1pt solid; + border-bottom: gray 1pt solid; + border-right: gray 1pt solid; + + padding-top: 24pt; + padding-right: 24pt; + padding-left: 24pt; + padding-bottom: 24pt; +} + +.toc_title +{ + background-color: #648CCA; + padding-top: 4px; + padding-right: 4px; + padding-bottom: 4px; + padding-left: 4px; + font-family: Geneva, Arial, Helvetica, san-serif; + color: #FFFFFF; + font-weight: bold +} + +.toc_cells +{ + background-color: #E2E9EF; + padding-top: 4px; + padding-right: 4px; + padding-bottom: 4px; + padding-left: 4px; + font-family: Geneva, Arial, Helvetica, san-serif; + font-size: small +} + +div.logo +{ + float: right; +} + +.toc_cells_L0 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } +.toc_cells_L1 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 44px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } +.toc_cells_L2 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 88px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } +.toc_cells_L3 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 122px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } +.toc_cells_L4 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 166px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } diff --git a/doc/tutorial/doc/theme/u_arr.gif b/doc/tutorial/doc/theme/u_arr.gif new file mode 100644 index 0000000000000000000000000000000000000000..ada3d6e043d2e4314a20d6783f2800f2f21d89c9 GIT binary patch literal 170 zcmZ?wbhEHb6k!l%*vtR|#>U2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#pCE@bTiY5O-A{7vV42g%c7%l^E8u0x + + +Boost Python Tutorial + + + + + + + + + +
      + + Boost Python Tutorial +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Table of contents
      + QuickStart +
      + Building Hello World +
      + Exposing Classes +
      + Constructors +
      + Class Data Members +
      + Class Properties +
      + Inheritance +
      + Class Virtual Functions +
      + Class Operators/Special Functions +
      + Functions +
      + Call Policies +
      + Default Arguments +
      + Object Interface +
      + Basic Interface +
      + Derived Object types +
      + Extracting C++ objects +
      + Iterators +
      + Exception Translation +
      +
      +
      + + From a295ac65907cde81872acb5a8ce1ef7b137dd00e Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 9 Oct 2002 07:44:34 +0000 Subject: [PATCH 0834/1042] Tutorials... [SVN r15818] --- doc/tutorial/doc/building_hello_world.html | 129 +++++++++++++++++- doc/tutorial/doc/quickstart.txt | 147 ++++++++++++++++++++- example/tutorial/Jamfile | 15 +++ example/tutorial/hello.cpp | 17 +++ 4 files changed, 302 insertions(+), 6 deletions(-) create mode 100644 example/tutorial/Jamfile create mode 100644 example/tutorial/hello.cpp diff --git a/doc/tutorial/doc/building_hello_world.html b/doc/tutorial/doc/building_hello_world.html index ce1d2257..68094b60 100644 --- a/doc/tutorial/doc/building_hello_world.html +++ b/doc/tutorial/doc/building_hello_world.html @@ -28,10 +28,131 @@ Now the first thing you'd want to do is to build the Hello World module and try it for yourself in Python. In this section, we shall outline the steps necessary to achieve that. We shall use the build tool that comes bundled -with every boost distribution: bjam. For a complete reference to building -Boost.Python, check out: -building.html

      - +with every boost distribution: bjam.

      +

      +We shall skip over the details. Our objective will be to simply create the +hello world module and run it in Python. For a complete reference to +building Boost.Python, check out: +building.html. +After this brief bjam tutorial, we should have built two DLLs:

      +
      • boost_python.dll
      • hello.pyd

      +This assumes of course that we are running on Windows.

      +

      +The tutorial example can be found in the directory: +/libs/python/example/tutorial. There, you can find:

      +
      • hello.cpp
      • Jamfile

      +The hello.cpp file is our C++ hello world example. The Jamfile is a +minimalist bjam script that builds the DLLs for us.

      +

      +Before anything else, you should have the bjam executable in your boost +directory. Pre-built Boost.Jam executables are available for some +platforms. For example, a pre-built Microsoft Windows bjam executable can +be downloaded +here. +The complete list of bjam pre-built executables can be found +here.

      +

      Lets Jam!

      +Here is our minimalist Jamfile:

      +
      +    subproject libs/python/example/tutorial ;
      +
      +    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
      +    include python.jam ;
      +
      +    extension hello                     # Declare a Python extension called hello
      +    :   hello.cpp                       # source
      +        <dll>../../build/boost_python   # dependencies
      +        ;
      +

      +First, we need to specify our location in the boost project hierarchy. +It so happens that the tutorial example is located in /libs/python/example/tutorial. +Thus:

      +
      +    subproject libs/python/example/tutorial ;
      +

      +Then we will include the definitions needed by Python modules:

      +
      +    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
      +    include python.jam ;
      +

      +Finally we declare our hello extension:

      +
      +    extension hello                     # Declare a Python extension called hello
      +    :   hello.cpp                       # source
      +        <dll>../../build/boost_python   # dependencies
      +        ;
      +

      Running bjam

      +bjam is run using your operating system's command line interpreter.

      +

      Start it up.

      +Make sure that the environment is set so that we can invoke the C++ +compiler. With MSVC, that would mean running the Vcvars32.bat batch +file. For instance:

      +
      +    C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat
      +
      +

      +Some environment variables will have to be setup for proper building of our +Python modules. Example:

      +
      +    set PYTHON_ROOT=c:/dev/tools/python
      +    set PYTHON_VERSION=2.2
      +
      +

      +The above assumes that the Python installation is in c:/dev/tools/python +and that we are using Python version 2.2. Be sure not to include a third +number, e.g. not "2.2.1", even if that's the version you have.

      +

      +Now we are ready... Be sure to cd to libs/python/example/tutorial +where the tutorial "hello.cpp" and the "Jamfile" is situated.

      +

      +Finally:

      +
      +    bjam -sTOOLS=msvc
      +
      +

      +We are again assuming that we are using Microsoft Visual C++ version 6. If +not, then you will have to specify the appropriate tool. See + +Building Boost Libraries for +further details.

      +

      +It should be building now:

      +
      +    cd C:\dev\boost\libs\python\example\tutorial
      +    bjam -sTOOLS=msvc
      +    ...patience...
      +    ...found 1703 targets...
      +    ...updating 40 targets...
      +

      +And so on... Finally:

      +
      +    vc-C++ ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
      +    runtime-link-dynamic\hello.obj
      +    hello.cpp
      +    vc-Link ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
      +    runtime-link-dynamic\hello.pyd ..\..\..\..\libs\python\example\tutorial\bin\
      +    hello.pyd\msvc\debug\runtime-link-dynamic\hello.lib
      +       Creating library ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\
      +       msvc\debug\runtime-link-dynamic\hello.lib and object ..\..\..\..\libs\python\
      +       example\tutorial\bin\hello.pyd\msvc\debug\runtime-link-dynamic\hello.exp
      +    ...updated 40 targets...
      +

      +If all is well, you should now have:

      +
      • boost_python.dll
      • hello.pyd

      +boost_python.dll can be found somewhere in libs\python\build\bin +while hello.pyd can be found somewhere in +libs\python\example\tutorial\bin. After a successful build, you can just +link in these DLLs with the Python interpreter. In Windows for example, you +can simply put these libraries inside the directory where the Python +executable is.

      +

      +You may now fire up Python and run our hello module:

      +
      +    >>> import hello
      +    >>> print hello.greet()
      +    hello, world
      +
      +

      There you go... Have fun!

      diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt index 7c7ad628..ecf3b87d 100644 --- a/doc/tutorial/doc/quickstart.txt +++ b/doc/tutorial/doc/quickstart.txt @@ -55,8 +55,151 @@ resulting DLL is now visible to Python. Here's a sample Python session: Now the first thing you'd want to do is to build the Hello World module and try it for yourself in Python. In this section, we shall outline the steps necessary to achieve that. We shall use the build tool that comes bundled -with every boost distribution: [*bjam]. For a complete reference to building -Boost.Python, check out: [@../../building.html building.html] +with every boost distribution: [*bjam]. + +We shall skip over the details. Our objective will be to simply create the +hello world module and run it in Python. For a complete reference to +building Boost.Python, check out: [@../../building.html building.html]. +After this brief ['bjam] tutorial, we should have built two DLLs: + +* boost_python.dll +* hello.pyd + +This assumes of course that we are running on Windows. + +The tutorial example can be found in the directory: +[^/libs/python/example/tutorial]. There, you can find: + +* hello.cpp +* Jamfile + +The [^hello.cpp] file is our C++ hello world example. The [^Jamfile] is a +minimalist ['bjam] script that builds the DLLs for us. + +Before anything else, you should have the bjam executable in your boost +directory. Pre-built Boost.Jam executables are available for some +platforms. For example, a pre-built Microsoft Windows bjam executable can +be downloaded [@http://boost.sourceforge.net/jam-executables/bin.ntx86/bjam.zip here]. +The complete list of bjam pre-built executables can be found [@../../../../../tools/build/index.html#Jam here]. + +[h2 Lets Jam!] + +Here is our minimalist Jamfile: + +[pre + subproject libs/python/example/tutorial ; + + SEARCH on python.jam = $(BOOST_BUILD_PATH) ; + include python.jam ; + + extension hello # Declare a Python extension called hello + : hello.cpp # source + ../../build/boost_python # dependencies + ; +] + +First, we need to specify our location in the boost project hierarchy. +It so happens that the tutorial example is located in [^/libs/python/example/tutorial]. +Thus: + +[pre + subproject libs/python/example/tutorial ; +] + +Then we will include the definitions needed by Python modules: + +[pre + SEARCH on python.jam = $(BOOST_BUILD_PATH) ; + include python.jam ; +] + +Finally we declare our [^hello] extension: + +[pre + extension hello # Declare a Python extension called hello + : hello.cpp # source + ../../build/boost_python # dependencies + ; +] + +[h2 Running bjam] + +['bjam] is run using your operating system's command line interpreter. + +[:Start it up.] + +Make sure that the environment is set so that we can invoke the C++ +compiler. With MSVC, that would mean running the [^Vcvars32.bat] batch +file. For instance: + + C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat + +Some environment variables will have to be setup for proper building of our +Python modules. Example: + + set PYTHON_ROOT=c:/dev/tools/python + set PYTHON_VERSION=2.2 + +The above assumes that the Python installation is in [^c:/dev/tools/python] +and that we are using Python version 2.2. Be sure not to include a third +number, e.g. [*not] "2.2.1", even if that's the version you have. + +Now we are ready... Be sure to [^cd] to [^libs/python/example/tutorial] +where the tutorial [^"hello.cpp"] and the [^"Jamfile"] is situated. + +Finally: + + bjam -sTOOLS=msvc + +We are again assuming that we are using Microsoft Visual C++ version 6. If +not, then you will have to specify the appropriate tool. See +[@../../../../../tools/build/index.html Building Boost Libraries] for +further details. + +It should be building now: + +[pre + cd C:\dev\boost\libs\python\example\tutorial + bjam -sTOOLS=msvc + ...patience... + ...found 1703 targets... + ...updating 40 targets... +] + +And so on... Finally: + +[pre + vc-C++ ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\ + runtime-link-dynamic\hello.obj + hello.cpp + vc-Link ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\ + runtime-link-dynamic\hello.pyd ..\..\..\..\libs\python\example\tutorial\bin\ + hello.pyd\msvc\debug\runtime-link-dynamic\hello.lib + Creating library ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\ + msvc\debug\runtime-link-dynamic\hello.lib and object ..\..\..\..\libs\python\ + example\tutorial\bin\hello.pyd\msvc\debug\runtime-link-dynamic\hello.exp + ...updated 40 targets... +] + +If all is well, you should now have: + +* boost_python.dll +* hello.pyd + +[^boost_python.dll] can be found somewhere in [^libs\python\build\bin] +while [^hello.pyd] can be found somewhere in +[^libs\python\example\tutorial\bin]. After a successful build, you can just +link in these DLLs with the Python interpreter. In Windows for example, you +can simply put these libraries inside the directory where the Python +executable is. + +You may now fire up Python and run our hello module: + + >>> import hello + >>> print hello.greet() + hello, world + +[:[*There you go... Have fun!]] [page Exposing Classes] diff --git a/example/tutorial/Jamfile b/example/tutorial/Jamfile new file mode 100644 index 00000000..c05463c1 --- /dev/null +++ b/example/tutorial/Jamfile @@ -0,0 +1,15 @@ +# Hello World Example from the tutorial +# [Joel de Guzman 10/9/2002] + +# Specify our location in the boost project hierarchy +subproject libs/python/example/tutorial ; + +# Include definitions needed for Python modules +SEARCH on python.jam = $(BOOST_BUILD_PATH) ; +include python.jam ; + +extension hello # Declare a Python extension called hello +: hello.cpp # source + ../../build/boost_python # dependencies + ; + diff --git a/example/tutorial/hello.cpp b/example/tutorial/hello.cpp new file mode 100644 index 00000000..01ed60c3 --- /dev/null +++ b/example/tutorial/hello.cpp @@ -0,0 +1,17 @@ +// Hello World Example from the tutorial +// [Joel de Guzman 10/9/2002] + +char const* greet() +{ + return "hello, world"; +} + +#include +#include +using namespace boost::python; + +BOOST_PYTHON_MODULE(hello) +{ + def("greet", greet); +} + From 8c8b4ee3320ac62360c49fedc22f3472ceef1385 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 9 Oct 2002 11:57:17 +0000 Subject: [PATCH 0835/1042] Fix up a small build specification problem [SVN r15822] --- test/Jamfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Jamfile b/test/Jamfile index 7a888842..4f554cc4 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -120,7 +120,8 @@ if $(TEST_BIENSTMAN_NON_BUGS) # --- unit tests of library components --- -local UNIT_TEST_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION ; +local UNIT_TEST_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION + [ difference $(PYTHON_PROPERTIES) : BOOST_PYTHON_DYNAMIC_LIB ] BOOST_PYTHON_STATIC_LIB ; run indirect_traits_test.cpp ; run destroy_test.cpp ; From 8a9a3a00bda066821277b79e3d77a2c43c6850b0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 9 Oct 2002 13:18:26 +0000 Subject: [PATCH 0836/1042] Fix a major problem of path specification [SVN r15825] --- include/boost/python.hpp | 104 +++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/include/boost/python.hpp b/include/boost/python.hpp index dd87d2bc..ca81cce2 100644 --- a/include/boost/python.hpp +++ b/include/boost/python.hpp @@ -6,57 +6,57 @@ #ifndef PYTHON_DWA2002810_HPP # define PYTHON_DWA2002810_HPP -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include #endif PYTHON_DWA2002810_HPP From 8a94c597a050e05940c95822fcc353e3af6c461b Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 9 Oct 2002 14:31:39 +0000 Subject: [PATCH 0837/1042] More tweaks (tutorial) [SVN r15826] --- doc/tutorial/doc/building_hello_world.html | 19 ++++-- doc/tutorial/doc/call_policies.html | 2 +- doc/tutorial/doc/class_data_members.html | 7 +-- doc/tutorial/doc/class_virtual_functions.html | 7 ++- doc/tutorial/doc/constructors.html | 2 +- doc/tutorial/doc/derived_object_types.html | 27 +++++---- doc/tutorial/doc/quickstart.txt | 54 ++++++++++++------ doc/tutorial/doc/theme/jam.png | Bin 0 -> 3884 bytes 8 files changed, 76 insertions(+), 42 deletions(-) create mode 100644 doc/tutorial/doc/theme/jam.png diff --git a/doc/tutorial/doc/building_hello_world.html b/doc/tutorial/doc/building_hello_world.html index 68094b60..8595ea56 100644 --- a/doc/tutorial/doc/building_hello_world.html +++ b/doc/tutorial/doc/building_hello_world.html @@ -36,22 +36,26 @@ building Boost.Python, check out: building.html. After this brief bjam tutorial, we should have built two DLLs:

      • boost_python.dll
      • hello.pyd

      -This assumes of course that we are running on Windows.

      +if you are on Windows, and

      +
      • libboost_python.so
      • hello.so

      +if you are on Unix.

      The tutorial example can be found in the directory: -/libs/python/example/tutorial. There, you can find:

      +libs/python/example/tutorial. There, you can find:

      • hello.cpp
      • Jamfile

      The hello.cpp file is our C++ hello world example. The Jamfile is a minimalist bjam script that builds the DLLs for us.

      Before anything else, you should have the bjam executable in your boost -directory. Pre-built Boost.Jam executables are available for some +directory. Pre-built Boost.Jam executables are available for most platforms. For example, a pre-built Microsoft Windows bjam executable can be downloaded here. The complete list of bjam pre-built executables can be found here.

      Lets Jam!

      +

      +

      Here is our minimalist Jamfile:

           subproject libs/python/example/tutorial ;
      @@ -99,8 +103,9 @@ Python modules. Example:

      The above assumes that the Python installation is in c:/dev/tools/python -and that we are using Python version 2.2. Be sure not to include a third -number, e.g. not "2.2.1", even if that's the version you have.

      +and that we are using Python version 2.2. You'll have to tweak this path +appropriately. Be sure not to include a third number, e.g. not "2.2.1", +even if that's the version you have.

      Now we are ready... Be sure to cd to libs/python/example/tutorial where the tutorial "hello.cpp" and the "Jamfile" is situated.

      @@ -139,6 +144,10 @@ And so on... Finally:

      If all is well, you should now have:

      • boost_python.dll
      • hello.pyd

      +if you are on Windows, and

      +
      • libboost_python.so
      • hello.so

      +if you are on Unix.

      +

      boost_python.dll can be found somewhere in libs\python\build\bin while hello.pyd can be found somewhere in libs\python\example\tutorial\bin. After a successful build, you can just diff --git a/doc/tutorial/doc/call_policies.html b/doc/tutorial/doc/call_policies.html index f0decf84..194097df 100644 --- a/doc/tutorial/doc/call_policies.html +++ b/doc/tutorial/doc/call_policies.html @@ -142,7 +142,7 @@ or more policies can be composed by chaining. Here's the general syntax:

      Here is the list of predefined call policies. A complete reference detailing -these can be found +these can be found here.

      • with_custodian_and_ward
        Ties lifetimes of the arguments
      • with_custodian_and_ward_postcall
        Ties lifetimes of the arguments and results
      • return_internal_reference
        Ties lifetime of one argument to that of result
      • return_value_policy<T> with T one of:
      • reference_existing_object
        naïve (dangerous) approach
      • copy_const_reference
        Boost.Python v1 approach
      • copy_non_const_reference
      • manage_new_object
        Adopt a pointer and hold the instance
      diff --git a/doc/tutorial/doc/class_data_members.html b/doc/tutorial/doc/class_data_members.html index 4718880c..39847ba8 100644 --- a/doc/tutorial/doc/class_data_members.html +++ b/doc/tutorial/doc/class_data_members.html @@ -56,12 +56,11 @@ Then, in Python:

      Note that name is exposed as read-only while value is exposed as read-write.

      -    >>> x.name = 'e' #can't change name
      +    >>> x.name = 'e' # can't change name
           Traceback (most recent call last):
             File "<stdin>", line 1, in ?
      -    AttributeError: can't set attribute
      -
      -
      + AttributeError: can't set attribute +
      diff --git a/doc/tutorial/doc/class_virtual_functions.html b/doc/tutorial/doc/class_virtual_functions.html index dea828c4..72c3fe3d 100644 --- a/doc/tutorial/doc/class_virtual_functions.html +++ b/doc/tutorial/doc/class_virtual_functions.html @@ -92,15 +92,16 @@ polymorphically fromC++.

      Wrapping Base and the free function call_f:

      -    class_<Base, BaseWrap, noncopyable>("Base", no_init)
      +    class_<Base, BaseWrap, boost::noncopyable>("Base", no_init)
               ;
           def("call_f", call_f);
       

      Notice that we parameterized the class_ template with BaseWrap as the second parameter. What is noncopyable? Without it, the library will try -to instantiate a copy constructor for returning Base objects from -functions.

      +to create code for converting Base return values of wrapped functions to +Python. To do that, it needs Base's copy constructor... which isn't +available, since Base is an abstract class.

      In Python, let us try to instantiate our Base class:

      diff --git a/doc/tutorial/doc/constructors.html b/doc/tutorial/doc/constructors.html
      index 621387f5..79237526 100644
      --- a/doc/tutorial/doc/constructors.html
      +++ b/doc/tutorial/doc/constructors.html
      @@ -64,7 +64,7 @@ expose instead.

      init<std::string>() exposes the constructor taking in a std::string (in Python, constructors are spelled -"__init__(...)").

      +""__init__"").

      We can expose additional constructors by passing more init<...>s to the def() member function. Say for example we have another World diff --git a/doc/tutorial/doc/derived_object_types.html b/doc/tutorial/doc/derived_object_types.html index 4d08db05..303774f7 100644 --- a/doc/tutorial/doc/derived_object_types.html +++ b/doc/tutorial/doc/derived_object_types.html @@ -70,18 +70,21 @@ member functions.

      Demonstrates that you can write the C++ equivalent of "format" % x,y,z in Python, which is useful since there's no easy way to do that in std C++.

      -
      - - - -
      - Beware the common pitfall of -forgetting that the constructors of most of Python's mutable types -make copies, just as in Python.

      - - dict d(x.attr("__dict__")); # makes a copy of x's dict
      - d['whatever'] = 3; # modifies a copy of x.__dict__ (not the original)
      -
      +

      + Beware the common pitfall of forgetting that the constructors +of most of Python's mutable types make copies, just as in Python.

      +

      +Python:

      +
      +    >>> d = dict(x.__dict__)     #copies x.__dict__
      +    >>> d['whatever']            #modifies the copy
      +
      +

      +C++:

      +
      +    dict d(x.attr("__dict__"));  #copies x.__dict__
      +    d['whatever'] = 3;           #modifies the copy
      +

      class_<T> as objects

      Due to the dynamic nature of Boost.Python objects, any class_<T> may also be one of these types! The following code snippet wraps the class diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt index ecf3b87d..a8176ec1 100644 --- a/doc/tutorial/doc/quickstart.txt +++ b/doc/tutorial/doc/quickstart.txt @@ -65,10 +65,15 @@ After this brief ['bjam] tutorial, we should have built two DLLs: * boost_python.dll * hello.pyd -This assumes of course that we are running on Windows. +if you are on Windows, and + +* libboost_python.so +* hello.so + +if you are on Unix. The tutorial example can be found in the directory: -[^/libs/python/example/tutorial]. There, you can find: +[^libs/python/example/tutorial]. There, you can find: * hello.cpp * Jamfile @@ -77,12 +82,13 @@ The [^hello.cpp] file is our C++ hello world example. The [^Jamfile] is a minimalist ['bjam] script that builds the DLLs for us. Before anything else, you should have the bjam executable in your boost -directory. Pre-built Boost.Jam executables are available for some +directory. Pre-built Boost.Jam executables are available for most platforms. For example, a pre-built Microsoft Windows bjam executable can be downloaded [@http://boost.sourceforge.net/jam-executables/bin.ntx86/bjam.zip here]. The complete list of bjam pre-built executables can be found [@../../../../../tools/build/index.html#Jam here]. [h2 Lets Jam!] +[$theme/jam.png] Here is our minimalist Jamfile: @@ -141,8 +147,9 @@ Python modules. Example: set PYTHON_VERSION=2.2 The above assumes that the Python installation is in [^c:/dev/tools/python] -and that we are using Python version 2.2. Be sure not to include a third -number, e.g. [*not] "2.2.1", even if that's the version you have. +and that we are using Python version 2.2. You'll have to tweak this path +appropriately. __note__ Be sure not to include a third number, e.g. [*not] "2.2.1", +even if that's the version you have. Now we are ready... Be sure to [^cd] to [^libs/python/example/tutorial] where the tutorial [^"hello.cpp"] and the [^"Jamfile"] is situated. @@ -186,6 +193,13 @@ If all is well, you should now have: * boost_python.dll * hello.pyd +if you are on Windows, and + +* libboost_python.so +* hello.so + +if you are on Unix. + [^boost_python.dll] can be found somewhere in [^libs\python\build\bin] while [^hello.pyd] can be found somewhere in [^libs\python\example\tutorial\bin]. After a successful build, you can just @@ -276,7 +290,7 @@ expose instead. [^init()] exposes the constructor taking in a [^std::string] (in Python, constructors are spelled -"[^__init__(...)]"). +"[^"__init__"]"). We can expose additional constructors by passing more [^init<...>]s to the [^def()] member function. Say for example we have another World @@ -326,10 +340,12 @@ Then, in Python: Note that [^name] is exposed as [*read-only] while [^value] is exposed as [*read-write]. +[pre >>> x.name = 'e' # can't change name Traceback (most recent call last): File "", line 1, in ? AttributeError: can't set attribute +] [page:1 Class Properties] @@ -482,14 +498,15 @@ polymorphically ['from] [*C++].] Wrapping [^Base] and the free function [^call_f]: - class_("Base", no_init) + class_("Base", no_init) ; def("call_f", call_f); Notice that we parameterized the [^class_] template with [^BaseWrap] as the second parameter. What is [^noncopyable]? Without it, the library will try -to instantiate a copy constructor for returning Base objects from -functions. +to create code for converting Base return values of wrapped functions to +Python. To do that, it needs Base's copy constructor... which isn't +available, since Base is an abstract class. In Python, let us try to instantiate our [^Base] class: @@ -820,7 +837,7 @@ or more policies can be composed by chaining. Here's the general syntax: policy3 > > Here is the list of predefined call policies. A complete reference detailing -these can be found [@../../v2/CallPolicies.html here]. +these can be found [@../../v2/reference.html#models_of_call_policies here]. * [*with_custodian_and_ward][br] Ties lifetimes of the arguments * [*with_custodian_and_ward_postcall][br] Ties lifetimes of the arguments and results @@ -1007,13 +1024,18 @@ member functions. Demonstrates that you can write the C++ equivalent of [^"format" % x,y,z] in Python, which is useful since there's no easy way to do that in std C++. -[blurb __alert__ Beware the common pitfall of -forgetting that the constructors of most of Python's mutable types -make copies, just as in Python.[br][br] +__alert__ [*Beware] the common pitfall of forgetting that the constructors +of most of Python's mutable types make copies, just as in Python. - [^dict d(x.attr("__dict__")); # makes a copy of x's dict[br] - '''d['whatever']''' = 3; # modifies a copy of x.__dict__ (not the original)[br]] -] +Python: + + >>> d = dict(x.__dict__) # copies x.__dict__ + >>> d['whatever'] # modifies the copy + +C++: + + dict d(x.attr("__dict__")); # copies x.__dict__ + d['whatever'] = 3; # modifies the copy [h2 class_ as objects] diff --git a/doc/tutorial/doc/theme/jam.png b/doc/tutorial/doc/theme/jam.png new file mode 100644 index 0000000000000000000000000000000000000000..224ed7914bb5a31a407511093500aa1fe9d9e571 GIT binary patch literal 3884 zcmeAS@N?(olHy`uVBq!ia0y~yV5nzcU~uJNV_;xNjW#hE=bLrwBlWk7u9BNWG%WIzG^?ia{Jx0?d2cu65lo_tIq4R{ZpB|^Gj6) zSQHbUotHf@zxm;v$tNPW%s1Luc2<|6?FW0^VrZqF7Q%Y`1Ew|lr=xYj$EHQEz3mDMmMpd z>ejiX)97pynn`5kW z|CRi$_`uF-U0Tl!|N5S1TOOPDXU~o+TYOinI`YoqQ_`=^1)VOOpVS2UPMZHtf92(U zF(~lpmyJ~=b>FwfdM6w>w@64vPjkD9T!BlS8{-PeFW+C~FR$XwJ;(0LL4_y0b2(bBrxt6b;~fkM&QareVtIlX>mx{c)k=f}URyJiaR zcRjOF;pM%D1^TaQcvl$+gnzii-F1xrciDrp+t{xBlnQwM`lzw)`c>DOBDhY4PWZnt zR)FQek=PkocKsFVcH$fQ_AtJdIN(>n{=t*q-~sQq@h3+fzfG`F{L=O>KV|n{Gpl%-%i!=JgyXArJMZ($hYaT!{XP6Jj;Fo) z|Aw2nSEX5*73

      m`0On#VPL z(`-H6pYI}XPFPiH`tH!Kb;Un6?Qy%i{QJk7Kgwo3X;m_c?qD_-v=DX5Fi847WiQi| zOos3Fb}>PHhgF}RNnUp>c14!$A=P;at9~2T{H^G|>zKLjeb$}USKF@hI=QIlzxh#q zizPj~PF#1{BZ2k33I*Hv7cN|p85}u{mC-BY{M`GWeC#f|xhKE=$1~Zz-}%+flv{nO zAzQA!X10lXExuOF|7hbTuh(TazbR^dS1j1ZFPr|mLf1Mal5fVO{Aq#4#$Tr;zxmgr z&2Tk$z4W)2TkUrJW!Jd9Nsd9l=ZJXQ6U|dc&v-c$NiiNfE7rbfl~~=cck4f87pnbB zzwxyGdGa*T8``Hg?O^Jf@%J*Hy^^P9l@*`w@6|HD8oc=bku@x5{FpZj9XZHxpIvcqk*@0k_3 z7MK1VF?R@(?6(kU{eOJx%j9*Zwn)#MDx&C_m2UMYK&1Nq&xrca(yxGtLj* zi!1zlDEirLvrxhF=&#zjyKc|F+jn5|ZP9FnkLl(zk4zPwv?pwS(C~EfS^?=^WwTih zf6ZKrI?Ik96MC`Bpy}Chxu)gIf^6kLa?>1gOd6-k?|Hw&UM*v--^@Jgz`}KcQe94a z?r{G<%>Pk3aLKFMvg0@HTm$acHC6AD{P^V&pJIGVU(K}r@xMJM*eCEMEiNpH-LtSx zZC2d=tzz?Lae;WhDw+I!Rg;oAkJm~%aGY=cnbxqg>e#7;Ea$#CF7dTseiSf8d(Ogz z8ZFQ5J)#-!R;o$KFWPUR_27)kiPyU-n7>A6hvvSM?^t!DI!o(eWcb22x0h{E6l;iJ zZ|b}p9$34e@v=7;&s(wfML!j8f19;a=XBj(hL)fspAyVF-Wbe3XQ=O6pE&9Kr7G?C z`D zi(M-Gyp~5WO*p^fP>KxWuispoj6?0-O0<+P?6|*~^KWzD)Ee82Vn2^%Tj#6IW2s}A zoUUst`zD_CY*Jowe`4WXJKw6zNY-mt z^1}Kv&wO`?lCUuqJ)jWeviz*=#k$&R2TlXert~F`m3?v}xmBjB-fvu|f2C|TLynVR z-Q&swMQ zmE`s2YdL?P|60rSk!1_Rgni+BHLMTMJePR!%gK39@DH!pjFl@6+1v0hDE%sR_+yP- zq|WJ0@zYWpZ!xX(J@cU|=~azlXu~Z=H(jOExfh?TR)3>o6t?G8^IqP#);TXV%R>B= zDuhl5R$L2}SX90BZiLfTj*{7{t|_l#n6PTW{ChK7!;Ru!Z)c8QdHO@g^}Re^GkjVZ zA7uQSYME@fOzxh@&yOD^K3C+J9Q@<+yEf@rzla1-r5WNE&Q7<~eUV9&lNMK#@Zb{Ft-JUJ0w%n5U z@tM_ExU$J}pX_}8C8qPGzx1lkc(%7LTle}F;TfWJ0*VR=nL8t2&XAj<8E-u$s$G@a z_NVLv7VABaxF3CA`u=gjT9a4yCvQ#cbr5A~6Zmjy-?47ip7kE~e(qd0a|PDAKQE6@ zuX(qZFYmzjduL>OUp}As{_C|zVJdAeSGIWV`%)XTmCg2U;FbK#>l{jBB`)gRxxkd* zw&&kMo?TN`SC#qAWt_3Feri!)uX@F|S#cSh2LiX)U#vVMkSn}jUcO&)S#7T`zx29~ z58Z2b`0k9TwVL5-^LioAy!m-6jp~DLxW(3UoSJ>u2X~T z8cU7pOQ!PWN4Xy``YH3N_@~g)rl#E8RjGMw(^slHNzImXdmXL+_@(+(OWT>NtM_iT zsK}6KaQ*!Fv7w3muE@1FSl4v2-#948&Hb0_aVQ!;6cq48-?D-TTb)VXPq*y z{9$h|F zb@iUP|J8e=&WBaG5t?_MYW?fhO$d~{K6R($Ri+z)47J4lAo1cLc!v{A+|dhx);1Ub%$r(>|MDWEOQUM z;hj4trY@s0Z@%rDeHE4r(ofH%>E}OkeE<05Ws@hy>eJ_czP?yoDQADt-IM)08y9^mUe%y%zQN~ Date: Wed, 9 Oct 2002 16:14:19 +0000 Subject: [PATCH 0838/1042] Bug fix (thanks to Leonardo Rochael Almeida ). [SVN r15828] --- doc/v2/scope.html | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/v2/scope.html b/doc/v2/scope.html index 5a6c4be2..61794628 100644 --- a/doc/v2/scope.html +++ b/doc/v2/scope.html @@ -64,11 +64,16 @@

      Class scope

      -

      The scope class has an associated global Python object - which controls the Python namespace in which new extension classes and - wrapped functions will be defined as attributes. Default-constructing a - new scope object binds that object to the associated Python - object. Constructing a is associated with , and

      +

      The scope class has an associated global Python + object which controls the Python namespace in which new extension + classes and wrapped functions will be defined as + attributes. Default-constructing a new scope object + binds it to the associated global Python object. Constructing a + scope object with an argument changes the associated + global Python object to the one held by the argument, until the + lifetime of the scope object ends, at which time the + associated global Python object reverts to what it was before the + scope object was constructed.

      Class scope synopsis

      From a06540e4719edc8d1deee1f5acdb32865cb35af5 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Thu, 10 Oct 2002 00:08:37 +0000 Subject: [PATCH 0839/1042] grammar correction [SVN r15835] --- doc/tutorial/doc/extracting_c___objects.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial/doc/extracting_c___objects.html b/doc/tutorial/doc/extracting_c___objects.html index 6000821b..a6ba5444 100644 --- a/doc/tutorial/doc/extracting_c___objects.html +++ b/doc/tutorial/doc/extracting_c___objects.html @@ -57,7 +57,7 @@ test for extractibility:

      The astute reader might have noticed that the extract<T> -facility in fact solves mutable copying problem:

      +facility in fact solves the mutable copying problem:

           dict d = extract<dict>(x.attr("__dict__"));
           d['whatever'] = 3;          #modifies x.__dict__ !
      
      From 1d5fb9798136c625127a818c3f0de496e2c0e996 Mon Sep 17 00:00:00 2001
      From: Joel de Guzman 
      Date: Thu, 10 Oct 2002 07:13:17 +0000
      Subject: [PATCH 0840/1042] Tutorial updates
      
      [SVN r15840]
      ---
       doc/tutorial/doc/basic_interface.html         |  10 +-
       doc/tutorial/doc/building_hello_world.html    |  17 ++-
       doc/tutorial/doc/call_policies.html           |   2 +-
       .../class_operators_special_functions.html    |  18 +++-
       doc/tutorial/doc/class_virtual_functions.html |   6 +-
       doc/tutorial/doc/derived_object_types.html    |   2 +-
       doc/tutorial/doc/enums.html                   |  95 +++++++++++++++++
       doc/tutorial/doc/extracting_c___objects.html  |   6 +-
       doc/tutorial/doc/iterators.html               |   8 +-
       doc/tutorial/doc/object_interface.html        |   2 +-
       doc/tutorial/doc/quickstart.txt               | 100 ++++++++++++++----
       doc/tutorial/index.html                       |   5 +
       12 files changed, 227 insertions(+), 44 deletions(-)
       create mode 100644 doc/tutorial/doc/enums.html
      
      diff --git a/doc/tutorial/doc/basic_interface.html b/doc/tutorial/doc/basic_interface.html
      index cb4a28f4..a9326c80 100644
      --- a/doc/tutorial/doc/basic_interface.html
      +++ b/doc/tutorial/doc/basic_interface.html
      @@ -32,11 +32,11 @@ Class object wraps PyObject*. All the intricacies of dealing w
       

      To illustrate, this Python code snippet:

      -    def f(x, f):
      +    def f(x, y):
                if (y == 'foo'):
                    x[3:7] = 'bar'
                else:
      -             x.items += f(3, x)
      +             x.items += y(3, x)
                return x
       
           def getfunc():
      @@ -45,11 +45,11 @@ To illustrate, this Python code snippet:

      Can be rewritten in C++ using Boost.Python facilities this way:

      -    object f(object x, object f) {
      -         if (f == "foo")
      +    object f(object x, object y) {
      +         if (y == "foo")
                    x.slice(3,7) = "bar";
                else
      -             x.attr("items") += f(3, x);
      +             x.attr("items") += y(3, x);
                return x;
           }
           object getfunc() {
      diff --git a/doc/tutorial/doc/building_hello_world.html b/doc/tutorial/doc/building_hello_world.html
      index 8595ea56..297757ea 100644
      --- a/doc/tutorial/doc/building_hello_world.html
      +++ b/doc/tutorial/doc/building_hello_world.html
      @@ -29,6 +29,17 @@ Now the first thing you'd want to do is to build the Hello World module and
       try it for yourself in Python. In this section, we shall outline the steps
       necessary to achieve that. We shall use the build tool that comes bundled
       with every boost distribution: bjam.

      + + + + +
      + Building without bjam

      + +Besides bjam, there are of course other ways to get your module built. +What's written here should not be taken as "the one and only way". +There are of course other build tools apart from bjam. +

      We shall skip over the details. Our objective will be to simply create the hello world module and run it in Python. For a complete reference to @@ -47,11 +58,13 @@ The hello.cpp file is our C++ hello world example. The Jamfile minimalist bjam script that builds the DLLs for us.

      Before anything else, you should have the bjam executable in your boost -directory. Pre-built Boost.Jam executables are available for most +directory or somewhere in your path such that bjam can be executed in +the command line. Pre-built Boost.Jam executables are available for most platforms. For example, a pre-built Microsoft Windows bjam executable can be downloaded here. -The complete list of bjam pre-built executables can be found +The complete list of bjam pre-built +executables can be found here.

      Lets Jam!

      diff --git a/doc/tutorial/doc/call_policies.html b/doc/tutorial/doc/call_policies.html index 194097df..4f836700 100644 --- a/doc/tutorial/doc/call_policies.html +++ b/doc/tutorial/doc/call_policies.html @@ -131,7 +131,7 @@ first argument. In short: "return an internal reference X& own

      Informs Boost.Python that the lifetime of the argument indicated by ward (i.e. the 2nd argument: Z* z) is dependent on the lifetime of the -argument indicated by custodian (i.e. the 1st argument: Z* z).

      +argument indicated by custodian (i.e. the 1st argument: Y& y).

      It is also important to note that we have defined two policies above. Two or more policies can be composed by chaining. Here's the general syntax:

      diff --git a/doc/tutorial/doc/class_operators_special_functions.html b/doc/tutorial/doc/class_operators_special_functions.html index 74a952a2..ca7f6c0b 100644 --- a/doc/tutorial/doc/class_operators_special_functions.html +++ b/doc/tutorial/doc/class_operators_special_functions.html @@ -25,7 +25,7 @@

      Python Operators

      -C is well known for the abundance of oparators. C++ extends this to the +C is well known for the abundance of operators. C++ extends this to the extremes by allowing operator overloading. Boost.Python takes advantage of this and makes it easy to wrap C++ operator-powered classes.

      @@ -76,14 +76,22 @@ that correspond to these Python special functions. Example:

      ostream& operator<<(ostream&,Rational); class_<Rational>() - .def(float_(self)) // __float__ - .def(pow(self)) // __pow__ - .def(abs(self)) // __abs__ - .def(str(self)) // __str__ + .def(float_(self)) // __float__ + .def(pow(self, other<Rational>)) // __pow__ + .def(abs(self)) // __abs__ + .def(str(self)) // __str__ ;

      Need we say more?

      + + + + +
      + What is the business of operator<< .def(str(self))? +Well, the method str requires the operator<< to do its work (i.e. +operator<< is used by the method defined by def(str(self)).
      diff --git a/doc/tutorial/doc/class_virtual_functions.html b/doc/tutorial/doc/class_virtual_functions.html index 72c3fe3d..6116678a 100644 --- a/doc/tutorial/doc/class_virtual_functions.html +++ b/doc/tutorial/doc/class_virtual_functions.html @@ -137,14 +137,14 @@ Calling derived.f():

      Will yield the expected result. Finally, calling calling the free function call_f with derived as argument:

      -    >>> call_f(derived())
      +    >>> call_f(derived)
           42
       

      Will also yield the expected result.

      Here's what's happening:

      -
      1. call_f(derived()) is called in Python
      2. This corresponds to def("call_f", call_f);. Boost.Python dispatches this call.
      3. int call_f(Base& b) { return b.f(); } accepts the call.
      4. The overridden virtual function f of BaseWrap is called.
      5. call_method<int>(self, "f"); dispatches the call back to Python.
      6. def f(self): return 42 is finally called.

      +

      1. call_f(derived) is called in Python
      2. This corresponds to def("call_f", call_f);. Boost.Python dispatches this call.
      3. int call_f(Base& b) { return b.f(); } accepts the call.
      4. The overridden virtual function f of BaseWrap is called.
      5. call_method<int>(self, "f"); dispatches the call back to Python.
      6. def f(self): return 42 is finally called.

      Rewind back to our Base class, if its member function f was not declared as pure virtual:

      @@ -207,7 +207,7 @@ Calling call_f, passing in a base object:

      Calling call_f, passing in a derived object:

      -    >>> call_f(derived())
      +    >>> call_f(derived)
           42
       
      diff --git a/doc/tutorial/doc/derived_object_types.html b/doc/tutorial/doc/derived_object_types.html index 303774f7..54ffccb3 100644 --- a/doc/tutorial/doc/derived_object_types.html +++ b/doc/tutorial/doc/derived_object_types.html @@ -27,7 +27,7 @@

      Boost.Python comes with a set of derived object types corresponding to that of Python's:

      -
      • list
      • dict
      • tuple
      • str
      • long_

      +

      • list
      • dict
      • tuple
      • str
      • long_
      • enum

      These derived object types act like real Python types. For instance:

           str(1) ==> "1"
      diff --git a/doc/tutorial/doc/enums.html b/doc/tutorial/doc/enums.html
      new file mode 100644
      index 00000000..7626c948
      --- /dev/null
      +++ b/doc/tutorial/doc/enums.html
      @@ -0,0 +1,95 @@
      +
      +
      +
      +Enums
      +
      +
      +
      +
      +
      +
      + + + + +
      + + Enums +
      +
      + + + + + + +
      +

      +Boost.Python has a nifty facility to capture and wrap C++ enums. While +Python has no enum type, we'll often want to expose our C++ enums to +Python as an int while taking care of the proper conversions from +Python's dynamic typing to C++'s strong static typing (in C++, ints cannot +be implicitly converted to enums). Boost.Python's enum facility makes this +easy. To illustrate, given a C++ enum:

      +
      +    enum choice { red, blue };
      +
      +

      +the construct:

      +
      +    enum_<choice>("choice")
      +        .value("red", red)
      +        .value("blue", blue)
      +        ;
      +
      +

      +can be used to expose it to Python. The new enum type is created in the +current scope(), which is usually the current module. The snippet above +creates a Python class derived from Python's int type which is +associated with the C++ type passed as its first parameter.

      + + + + +
      + what is a scope?

      The scope is a class that has an +associated global Python object which controls the Python namespace in +which new extension classes and wrapped functions will be defined as +attributes. Details can be found +here
      +

      +You can access those values in Python as

      +
      +    >>> my_module.choice.red
      +    my_module.choice.red
      +
      +

      +where my_module is the module where the enum is declared. You can create a +new scope around a class:

      +
      +    scope in_X(class_<X>("X")
      +                    .def( ... )
      +                    .def( ... )
      +                );
      +
      +    // Expose X::nested as X.nested
      +    enum_<X::nested>("nested")
      +        .value("red", red)
      +        .value("blue", blue)
      +        ;
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/extracting_c___objects.html b/doc/tutorial/doc/extracting_c___objects.html index a6ba5444..36b8bf85 100644 --- a/doc/tutorial/doc/extracting_c___objects.html +++ b/doc/tutorial/doc/extracting_c___objects.html @@ -4,7 +4,7 @@ Extracting C++ objects - + @@ -21,7 +21,7 @@ - +

      @@ -66,7 +66,7 @@ facility in fact solves the mutable copying problem:

      - +
      diff --git a/doc/tutorial/doc/iterators.html b/doc/tutorial/doc/iterators.html index 7e4282cb..00e8dc44 100644 --- a/doc/tutorial/doc/iterators.html +++ b/doc/tutorial/doc/iterators.html @@ -3,7 +3,7 @@ Iterators - + @@ -20,7 +20,7 @@ - +
      @@ -34,7 +34,7 @@ iterators, but these are two very different beasts.

      • 1 category (forward)
      • 1 operation category (next())
      • Raises StopIteration exception at end

      The typical Python iteration protocol: for y in x... is as follows:

      -    iter iter = x.__iter__()    #get iterator
      +    iter = x.__iter__()         #get iterator
           try:
               while 1:
               y = iter.next()         #get each item
      @@ -87,7 +87,7 @@ Now, our C++ Wrapper:

      - +
      diff --git a/doc/tutorial/doc/object_interface.html b/doc/tutorial/doc/object_interface.html index 2279a60c..d18a40bb 100644 --- a/doc/tutorial/doc/object_interface.html +++ b/doc/tutorial/doc/object_interface.html @@ -26,7 +26,7 @@

      Python is dynamically typed, unlike C++ which is statically typed. Python -variables may hold an integers, a float, list, dict, tuple, str, long etc., +variables may hold an integer, a float, list, dict, tuple, str, long etc., among other things. In the viewpoint of Boost.Python and C++, these Pythonic variables are just instances of class object. We shall see in this chapter how to deal with Python objects.

      diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt index a8176ec1..8541612a 100644 --- a/doc/tutorial/doc/quickstart.txt +++ b/doc/tutorial/doc/quickstart.txt @@ -57,6 +57,13 @@ try it for yourself in Python. In this section, we shall outline the steps necessary to achieve that. We shall use the build tool that comes bundled with every boost distribution: [*bjam]. +[blurb __detail__ [*Building without bjam][br][br] + +Besides bjam, there are of course other ways to get your module built. +What's written here should not be taken as "the one and only way". +There are of course other build tools apart from [^bjam]. +] + We shall skip over the details. Our objective will be to simply create the hello world module and run it in Python. For a complete reference to building Boost.Python, check out: [@../../building.html building.html]. @@ -82,10 +89,12 @@ The [^hello.cpp] file is our C++ hello world example. The [^Jamfile] is a minimalist ['bjam] script that builds the DLLs for us. Before anything else, you should have the bjam executable in your boost -directory. Pre-built Boost.Jam executables are available for most +directory or somewhere in your path such that [^bjam] can be executed in +the command line. Pre-built Boost.Jam executables are available for most platforms. For example, a pre-built Microsoft Windows bjam executable can be downloaded [@http://boost.sourceforge.net/jam-executables/bin.ntx86/bjam.zip here]. -The complete list of bjam pre-built executables can be found [@../../../../../tools/build/index.html#Jam here]. +The complete list of bjam pre-built +executables can be found [@../../../../../tools/build/index.html#Jam here]. [h2 Lets Jam!] [$theme/jam.png] @@ -540,14 +549,14 @@ Calling [^derived.f()]: Will yield the expected result. Finally, calling calling the free function [^call_f] with [^derived] as argument: - >>> call_f(derived()) + >>> call_f(derived) 42 Will also yield the expected result. Here's what's happening: -# [^call_f(derived())] is called in Python +# [^call_f(derived)] is called in Python # This corresponds to [^def("call_f", call_f);]. Boost.Python dispatches this call. # [^int call_f(Base& b) { return b.f(); }] accepts the call. # The overridden virtual function [^f] of [^BaseWrap] is called. @@ -609,14 +618,14 @@ Calling [^call_f], passing in a [^base] object: Calling [^call_f], passing in a [^derived] object: - >>> call_f(derived()) + >>> call_f(derived) 42 [page:1 Class Operators/Special Functions] [h2 Python Operators] -C is well known for the abundance of oparators. C++ extends this to the +C is well known for the abundance of operators. C++ extends this to the extremes by allowing operator overloading. Boost.Python takes advantage of this and makes it easy to wrap C++ operator-powered classes. @@ -667,14 +676,18 @@ that correspond to these Python ['special functions]. Example: ostream& operator<<(ostream&,Rational); class_() - .def(float_(self)) // __float__ - .def(pow(self)) // __pow__ - .def(abs(self)) // __abs__ - .def(str(self)) // __str__ + .def(float_(self)) // __float__ + .def(pow(self, other)) // __pow__ + .def(abs(self)) // __abs__ + .def(str(self)) // __str__ ; Need we say more? +[blurb __detail__ What is the business of [^operator<<] [^.def(str(self))]? +Well, the method [^str] requires the [^operator<<] to do its work (i.e. +[^operator<<] is used by the method defined by def(str(self)).] + [page Functions] In this chapter, we'll look at Boost.Python powered functions in closer @@ -827,7 +840,7 @@ first argument. In short: "return an internal reference [^X&] owned by the Informs Boost.Python that the lifetime of the argument indicated by ward (i.e. the 2nd argument: [^Z* z]) is dependent on the lifetime of the -argument indicated by custodian (i.e. the 1st argument: [^Z* z]). +argument indicated by custodian (i.e. the 1st argument: [^Y& y]). It is also important to note that we have defined two policies above. Two or more policies can be composed by chaining. Here's the general syntax: @@ -928,7 +941,7 @@ Notice the use of [^init<...>] and [^optional<...>] to signify the default [page Object Interface] Python is dynamically typed, unlike C++ which is statically typed. Python -variables may hold an integers, a float, list, dict, tuple, str, long etc., +variables may hold an integer, a float, list, dict, tuple, str, long etc., among other things. In the viewpoint of Boost.Python and C++, these Pythonic variables are just instances of class [^object]. We shall see in this chapter how to deal with Python objects. @@ -949,11 +962,11 @@ Class [^object] wraps [^PyObject*]. All the intricacies of dealing with To illustrate, this Python code snippet: - def f(x, f): + def f(x, y): if (y == 'foo'): x[3:7] = 'bar' else: - x.items += f(3, x) + x.items += y(3, x) return x def getfunc(): @@ -961,11 +974,11 @@ To illustrate, this Python code snippet: Can be rewritten in C++ using Boost.Python facilities this way: - object f(object x, object f) { - if (f == "foo") + object f(object x, object y) { + if (y == "foo") x.slice(3,7) = "bar"; else - x.attr("items") += f(3, x); + x.attr("items") += y(3, x); return x; } object getfunc() { @@ -986,6 +999,7 @@ that of Python's: * tuple * str * long_ +* enum These derived [^object] types act like real Python types. For instance: @@ -1084,11 +1098,59 @@ test for extractibility: Vec2& v = x(); ... __tip__ The astute reader might have noticed that the [^extract] -facility in fact solves mutable copying problem: +facility in fact solves the mutable copying problem: dict d = extract(x.attr("__dict__")); d['whatever'] = 3; # modifies x.__dict__ ! + +[page:1 Enums] + +Boost.Python has a nifty facility to capture and wrap C++ enums. While +Python has no [^enum] type, we'll often want to expose our C++ enums to +Python as an [^int] while taking care of the proper conversions from +Python's dynamic typing to C++'s strong static typing (in C++, ints cannot +be implicitly converted to enums). Boost.Python's enum facility makes this +easy. To illustrate, given a C++ enum: + + enum choice { red, blue }; + +the construct: + + enum_("choice") + .value("red", red) + .value("blue", blue) + ; + +can be used to expose it to Python. The new enum type is created in the +current [^scope()], which is usually the current module. The snippet above +creates a Python class derived from Python's [^int] type which is +associated with the C++ type passed as its first parameter. + +[blurb __detail__ [*what is a scope?][br][br] The scope is a class that has an +associated global Python object which controls the Python namespace in +which new extension classes and wrapped functions will be defined as +attributes. Details can be found [@../../v2/scope.html here]] + +You can access those values in Python as + + >>> my_module.choice.red + my_module.choice.red + +where my_module is the module where the enum is declared. You can create a +new scope around a class: + + scope in_X(class_("X") + .def( ... ) + .def( ... ) + ); + + // Expose X::nested as X.nested + enum_("nested") + .value("red", red) + .value("blue", blue) + ; + [page Iterators] In C++, and STL in particular, we see iterators everywhere. Python also has @@ -1108,7 +1170,7 @@ iterators, but these are two very different beasts. The typical Python iteration protocol: [^[*for y in x...]] is as follows: - iter iter = x.__iter__() # get iterator + iter = x.__iter__() # get iterator try: while 1: y = iter.next() # get each item diff --git a/doc/tutorial/index.html b/doc/tutorial/index.html index 14554d97..4e1333da 100644 --- a/doc/tutorial/index.html +++ b/doc/tutorial/index.html @@ -100,6 +100,11 @@ Extracting C++ objects + + + Enums + + Iterators From 51264c30cc4d1944f716bca085106cdc7ea43c8b Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Thu, 10 Oct 2002 07:18:22 +0000 Subject: [PATCH 0841/1042] Typo... [SVN r15841] --- doc/tutorial/doc/enums.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial/doc/enums.html b/doc/tutorial/doc/enums.html index 7626c948..78263303 100644 --- a/doc/tutorial/doc/enums.html +++ b/doc/tutorial/doc/enums.html @@ -43,7 +43,7 @@ the construct:

      ;

      -can be used to expose it to Python. The new enum type is created in the +can be used to expose to Python. The new enum type is created in the current scope(), which is usually the current module. The snippet above creates a Python class derived from Python's int type which is associated with the C++ type passed as its first parameter.

      From df8c8f025c510d90ce96ee2c8854e1cadb74cc71 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Thu, 10 Oct 2002 07:21:33 +0000 Subject: [PATCH 0842/1042] tweak [SVN r15842] --- doc/tutorial/doc/enums.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/tutorial/doc/enums.html b/doc/tutorial/doc/enums.html index 78263303..c42f1820 100644 --- a/doc/tutorial/doc/enums.html +++ b/doc/tutorial/doc/enums.html @@ -3,7 +3,7 @@ Enums - + @@ -20,17 +20,17 @@ - +

      Boost.Python has a nifty facility to capture and wrap C++ enums. While Python has no enum type, we'll often want to expose our C++ enums to -Python as an int while taking care of the proper conversions from -Python's dynamic typing to C++'s strong static typing (in C++, ints cannot -be implicitly converted to enums). Boost.Python's enum facility makes this -easy. To illustrate, given a C++ enum:

      +Python as an int. Boost.Python's enum facility makes this easy while +taking care of the proper conversions from Python's dynamic typing to C++'s +strong static typing (in C++, ints cannot be implicitly converted to +enums). To illustrate, given a C++ enum:

           enum choice { red, blue };
       
      @@ -43,7 +43,7 @@ the construct:

      ;

      -can be used to expose to Python. The new enum type is created in the +can be used to expose it Python. The new enum type is created in the current scope(), which is usually the current module. The snippet above creates a Python class derived from Python's int type which is associated with the C++ type passed as its first parameter.

      @@ -81,7 +81,7 @@ new scope around a class:

      - +
      From 7d9770762cb5a755b65878d476a1b1df92377cf1 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Thu, 10 Oct 2002 07:27:10 +0000 Subject: [PATCH 0843/1042] more minor tweaks [SVN r15843] --- doc/tutorial/doc/enums.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/tutorial/doc/enums.html b/doc/tutorial/doc/enums.html index c42f1820..7eec613e 100644 --- a/doc/tutorial/doc/enums.html +++ b/doc/tutorial/doc/enums.html @@ -43,7 +43,7 @@ the construct:

      ;

      -can be used to expose it Python. The new enum type is created in the +can be used to expose to Python. The new enum type is created in the current scope(), which is usually the current module. The snippet above creates a Python class derived from Python's int type which is associated with the C++ type passed as its first parameter.

      @@ -54,7 +54,7 @@ associated with the C++ type passed as its first parameter.

      associated global Python object which controls the Python namespace in which new extension classes and wrapped functions will be defined as attributes. Details can be found -here +here.

      @@ -64,8 +64,8 @@ You can access those values in Python as

      my_module.choice.red

      -where my_module is the module where the enum is declared. You can create a -new scope around a class:

      +where my_module is the module where the enum is declared. You can also +create a new scope around a class:

           scope in_X(class_<X>("X")
                           .def( ... )
      
      From 6bb7c2d7b30531cc61fee391cb0fcb6d6ea936d4 Mon Sep 17 00:00:00 2001
      From: Joel de Guzman 
      Date: Thu, 10 Oct 2002 07:28:03 +0000
      Subject: [PATCH 0844/1042] minor tweaks
      
      [SVN r15844]
      ---
       doc/tutorial/doc/quickstart.txt | 16 ++++++++--------
       1 file changed, 8 insertions(+), 8 deletions(-)
      
      diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt
      index 8541612a..2c1116cb 100644
      --- a/doc/tutorial/doc/quickstart.txt
      +++ b/doc/tutorial/doc/quickstart.txt
      @@ -1108,10 +1108,10 @@ facility in fact solves the mutable copying problem:
       
       Boost.Python has a nifty facility to capture and wrap C++ enums. While
       Python has no [^enum] type, we'll often want to expose our C++ enums to
      -Python as an [^int] while taking care of the proper conversions from
      -Python's dynamic typing to C++'s strong static typing (in C++, ints cannot
      -be implicitly converted to enums). Boost.Python's enum facility makes this
      -easy. To illustrate, given a C++ enum:
      +Python as an [^int]. Boost.Python's enum facility makes this easy while
      +taking care of the proper conversions from Python's dynamic typing to C++'s
      +strong static typing (in C++, ints cannot be implicitly converted to
      +enums). To illustrate, given a C++ enum:
       
           enum choice { red, blue };
       
      @@ -1122,7 +1122,7 @@ the construct:
               .value("blue", blue)
               ;
       
      -can be used to expose it to Python. The new enum type is created in the
      +can be used to expose to Python. The new enum type is created in the
       current [^scope()], which is usually the current module. The snippet above
       creates a Python class derived from Python's [^int] type which is
       associated with the C++ type passed as its first parameter.
      @@ -1130,15 +1130,15 @@ associated with the C++ type passed as its first parameter.
       [blurb __detail__ [*what is a scope?][br][br] The scope is a class that has an
       associated global Python object which controls the Python namespace in
       which new extension classes and wrapped functions will be defined as
      -attributes. Details can be found [@../../v2/scope.html here]]
      +attributes. Details can be found [@../../v2/scope.html here].]
       
       You can access those values in Python as
       
           >>> my_module.choice.red
           my_module.choice.red
       
      -where my_module is the module where the enum is declared. You can create a
      -new scope around a class:
      +where my_module is the module where the enum is declared. You can also
      +create a new scope around a class:
       
           scope in_X(class_("X")
                           .def( ... )
      
      From 87b011e7e842feb26368c554aed3262a8fba5f5f Mon Sep 17 00:00:00 2001
      From: Joel de Guzman 
      Date: Thu, 10 Oct 2002 07:31:08 +0000
      Subject: [PATCH 0845/1042] Python V1 Archive (tested)
      
      [SVN r15845]
      ---
       build/Attic/python_v1.zip | Bin 0 -> 236665 bytes
       build/python_v1.zip       | Bin 0 -> 236665 bytes
       2 files changed, 0 insertions(+), 0 deletions(-)
       create mode 100644 build/Attic/python_v1.zip
       create mode 100644 build/python_v1.zip
      
      diff --git a/build/Attic/python_v1.zip b/build/Attic/python_v1.zip
      new file mode 100644
      index 0000000000000000000000000000000000000000..0377a07bb35337fd47e14de78bc55819015567fd
      GIT binary patch
      literal 236665
      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	!
      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
      
      literal 0
      HcmV?d00001
      
      diff --git a/build/python_v1.zip b/build/python_v1.zip
      new file mode 100644
      index 0000000000000000000000000000000000000000..0377a07bb35337fd47e14de78bc55819015567fd
      GIT binary patch
      literal 236665
      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	!
      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
      
      literal 0
      HcmV?d00001
      
      
      From f1a709e07419458a186e921f785979fef89bc39e Mon Sep 17 00:00:00 2001
      From: Joel de Guzman 
      Date: Thu, 10 Oct 2002 08:59:19 +0000
      Subject: [PATCH 0846/1042] final tweaks
      
      [SVN r15846]
      ---
       doc/tutorial/doc/enums.html | 6 +++---
       1 file changed, 3 insertions(+), 3 deletions(-)
      
      diff --git a/doc/tutorial/doc/enums.html b/doc/tutorial/doc/enums.html
      index 7eec613e..0cee713c 100644
      --- a/doc/tutorial/doc/enums.html
      +++ b/doc/tutorial/doc/enums.html
      @@ -3,7 +3,7 @@
       
       Enums
       
      -
      +
       
       
       
      @@ -20,7 +20,7 @@
       
      -    
      +    
      @@ -81,7 +81,7 @@ create a new scope around a class:

      - +
      From 654354e681bd72901f3c809ade564136b2d8790a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 10 Oct 2002 15:59:12 +0000 Subject: [PATCH 0847/1042] GCC 2.96 bug workaround [SVN r15864] --- test/iterator.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/iterator.cpp b/test/iterator.cpp index 93d4c009..a52e0710 100644 --- a/test/iterator.cpp +++ b/test/iterator.cpp @@ -79,6 +79,7 @@ private: BOOST_PYTHON_MODULE(iterator_ext) { + using boost::python::iterator; // gcc 2.96 bug workaround def("range", &::range); class_("list_int") From 65b6eb0c27babcfb6bae83f3b6a4a6960a51ecaa Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 10 Oct 2002 18:01:58 +0000 Subject: [PATCH 0848/1042] Move final RC_1_29_0 changes back to trunk [SVN r15871] --- doc/building.html | 7 +- doc/index.html | 37 +++++++++- doc/v2/acknowledgments.html | 32 +++++++-- doc/v2/platforms.html | 131 ++++++++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+), 12 deletions(-) create mode 100644 doc/v2/platforms.html diff --git a/doc/building.html b/doc/building.html index d76a708c..5bb509a2 100644 --- a/doc/building.html +++ b/doc/building.html @@ -52,8 +52,11 @@

      Requirements

      - Boost.Python requires Python 2.2 or - later. + Boost.Python version 2 requires Python 2.2 or newer. An unsupported archive of + Boost.Python version 1, which works with versions of Python since 1.5.2, + is available here.

      Building Boost.Python

      diff --git a/doc/index.html b/doc/index.html index c3090a64..f5ca838e 100644 --- a/doc/index.html +++ b/doc/index.html @@ -28,6 +28,36 @@
      +

      Synopsis

      + Welcome to version 2 of Boost.Python, a C++ library which enables + seamless interoperability between C++ and the Python programming language. The new version + has been rewritten from the ground up, with a more convenient and + flexible interface, and many new capabilities, including support for: + +
        +
      • References and Pointers
      • + +
      • Globally Registered Type Coercions
      • + +
      • Automatic Cross-Module Type Conversions
      • + +
      • Efficient Function Overloading
      • + +
      • C++ to Python Exception Translation
      • + +
      • Default Arguments
      • + +
      • Keyword Arguments
      • + +
      • Manipulating Python objects in C++
      • + +
      • Exporting C++ Iterators as Python Iterators
      • + +
      • Documentation Strings
      • +
      +
      +

      Contents

      @@ -39,7 +69,8 @@
      Configuration Information
      -
      Rationale
      +
      Known Working Platforms and + Compilers
      Definitions
      @@ -51,9 +82,9 @@

      -

      Revised +

      Revised - 08 October, 2002 + 08 October, 2002

      diff --git a/doc/v2/acknowledgments.html b/doc/v2/acknowledgments.html index b2591e6d..5f149a64 100644 --- a/doc/v2/acknowledgments.html +++ b/doc/v2/acknowledgments.html @@ -32,18 +32,36 @@ the architect, designer, and implementor of Boost.Python.

      Joel de Guzman implemented the default - argument support and wrote the excellent tutorial documentation.

      + argument support and wrote the excellent tutorial documentation.

      Ralf W. Grosse-Kunstleve implemented the pickle support, and has enthusiastically supported the library since its birth, contributing to design decisions and providing invaluable - real-world insight into user requirements. Ralf has written some - extensions for converting C++ containers that I hope will be incorporated - into the library soon. He also implemented the cross-module support in - the first version of Boost.Python. More importantly, Ralf makes sure - nobody forgets the near-perfect synergy of C++ and Python for solving the - problems of large-scale software construction.

      + real-world insight into user requirements. Ralf has written some extensions for converting C++ containers that I + hope will be incorporated into the library soon. He also implemented the + cross-module support in the first version of Boost.Python. More + importantly, Ralf makes sure nobody forgets the near-perfect synergy of + C++ and Python for solving the problems of large-scale software + construction.

      + +

      Aleksey Gurtovoy + wrote an incredible C++ Template + Metaprogramming Library which allows Boost.Python to perform much of + its compile-time magic. In addition, Aleksey very generously contributed + his time and deep knowledge of the quirks of various buggy compilers to + help us get around problems at crucial moments.

      + +

      Paul Mensonides, + building on the work Vesa + Karvonen, wrote a similarly amazing Preprocessor Metaprogramming + Library, and generously contributed the time and expertise to get it + working in the Boost.Python library, rewriting much of Boost.Python to + use the new preproccessor metaprogramming constructs and helping us to + work around buggy and slow C++ preprocessors.

      Achim Domma contributed some of the Object Wrappers and diff --git a/doc/v2/platforms.html b/doc/v2/platforms.html new file mode 100644 index 00000000..10ec5d15 --- /dev/null +++ b/doc/v2/platforms.html @@ -0,0 +1,131 @@ + + + + + + + + + Boost.Python - Known Working Platforms and Compilers + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Known Working Platforms and Compilers

      +
      +


      + Boost.Python has been successfully tested on the following + platforms and compilers: + +
      +
      Unix Platforms:
      + +
      +
      +
      with Python 2.2 and 2.2.2b1:
      + +
      +
      +
      GCC 2.95.3, 2.96, 3.0.4, + 3.1, and 3.2 on RedHat Linux 7.3 + for Intel x86
      + +
      Tru64 CXX + 6.5.1 on OSF v. 5.1 for Dec/Compaq Alpha
      + +
      + MIPSPro 7.3.1.2m on IRIX 6.5 for SGI + mips
      + +
      GCC 3.1 on SunOS 5.8
      +
      +
      + +
      with Python 2.2.1
      + +
      +
      +
      KCC + 3.4d on OSF v. 5.1 for Dec/Compaq Alpha
      + +
      KCC + 3.4d on AIX
      +
      +
      +
      +
      +
      + +
      Microsoft + Windows XP Professional with Python 2.2, 2.2.1, and 2.2.2b1:
      + +
      +
      +
      Microsoft Visual + C++ 6, 7, and 7.1 beta
      + +
      Microsoft Visual + C++ 6 with STLPort + 4.5.3
      + +
      Metrowerks CodeWarrior 7.2, 8.0, 8.2 and 8.3 beta
      + +
      Intel + C++ 5.0, 6.0, and 7.0 beta
      + +
      Intel C++ + 5.0 with STLPort + 4.5.3
      + +
      Cygwin GCC 3.0.4 and 3.2
      + +
      MinGW-1.1 (GCC 2.95.3-5)
      + +
      MinGW-2.0 (GCC 3.2)
      +
      +
      +
      +
      + +

      Revised + + 10 October, 2002 + +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + From adb02376ebc379d2456272c546ec9fe7ec0e9ca2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 10 Oct 2002 18:05:51 +0000 Subject: [PATCH 0849/1042] Move final RC_1_29_0 changes back to trunk [SVN r15872] --- doc/v2/platforms.html | 4 +++- doc/v2/reference.html | 6 +++--- doc/v2/scope.html | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/doc/v2/platforms.html b/doc/v2/platforms.html index 10ec5d15..c956f4c5 100644 --- a/doc/v2/platforms.html +++ b/doc/v2/platforms.html @@ -93,7 +93,9 @@ C++ 6 with STLPort 4.5.3 -
      Metrowerks CodeWarrior 7.2, 8.0, 8.2 and 8.3 beta
      +
      + Metrowerks CodeWarrior 7.2, 8.0, 8.2 and 8.3 beta
      Intel diff --git a/doc/v2/reference.html b/doc/v2/reference.html index fed0e92a..be866666 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -352,8 +352,8 @@
      object
      -
      -
      + + @@ -898,7 +898,7 @@

      Revised - 3 June, 2002 + 08 October, 2002

      © Copyright -

      Revised 03 October, 2002

      +

      Revised 09 October, 2002

      © Copyright Dave Abrahams 2002. All Rights From f6990fedc703eaf2558b57bffbfeadd033ec6cf2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 10 Oct 2002 18:09:46 +0000 Subject: [PATCH 0850/1042] Move final RC_1_29_0 changes back to trunk [SVN r15875] --- doc/v2/platforms.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/platforms.html b/doc/v2/platforms.html index c956f4c5..a064c36f 100644 --- a/doc/v2/platforms.html +++ b/doc/v2/platforms.html @@ -106,7 +106,7 @@ 5.0 with STLPort 4.5.3 -

      Cygwin Cygwin GCC 3.0.4 and 3.2
      MinGW-1.1 ( Date: Thu, 10 Oct 2002 18:11:14 +0000 Subject: [PATCH 0851/1042] Move final RC_1_29_0 changes back to trunk [SVN r15877] --- doc/v2/platforms.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/platforms.html b/doc/v2/platforms.html index a064c36f..05882830 100644 --- a/doc/v2/platforms.html +++ b/doc/v2/platforms.html @@ -41,7 +41,7 @@
      GCC 2.95.3, 2.96, 3.0.4, - 3.1, and 3.2 on RedHat Linux 7.3 + 3.1, and 3.2 on RedHat Linux 7.3 for Intel x86
      Date: Sat, 12 Oct 2002 15:37:34 +0000 Subject: [PATCH 0852/1042] Patches to support Synopsis [SVN r15906] --- .../boost/python/converter/pyobject_type.hpp | 1 + .../converter/rvalue_from_python_data.hpp | 3 +- include/boost/python/detail/call_object.hpp | 66 ------------------- .../boost/python/detail/exception_handler.hpp | 1 + include/boost/python/detail/make_tuple.hpp | 16 +++-- include/boost/python/detail/module_base.hpp | 46 ------------- include/boost/python/detail/scope.hpp | 2 + .../boost/python/detail/type_list_impl.hpp | 2 + .../python/detail/type_list_impl_no_pts.hpp | 2 + .../boost/python/detail/type_list_utils.hpp | 28 -------- .../boost/python/object/add_to_namespace.hpp | 1 + include/boost/python/object/construct.hpp | 24 ------- .../boost/python/object/pickle_support.hpp | 4 +- include/boost/python/object_call.hpp | 12 ++-- include/boost/python/object_protocol_core.hpp | 1 + include/boost/python/operators.hpp | 22 +++---- 16 files changed, 42 insertions(+), 189 deletions(-) delete mode 100644 include/boost/python/detail/call_object.hpp delete mode 100644 include/boost/python/detail/module_base.hpp delete mode 100644 include/boost/python/detail/type_list_utils.hpp delete mode 100644 include/boost/python/object/construct.hpp diff --git a/include/boost/python/converter/pyobject_type.hpp b/include/boost/python/converter/pyobject_type.hpp index 63127d5b..59ff7244 100644 --- a/include/boost/python/converter/pyobject_type.hpp +++ b/include/boost/python/converter/pyobject_type.hpp @@ -6,6 +6,7 @@ #ifndef PYOBJECT_TYPE_DWA2002720_HPP # define PYOBJECT_TYPE_DWA2002720_HPP +# include # include # include diff --git a/include/boost/python/converter/rvalue_from_python_data.hpp b/include/boost/python/converter/rvalue_from_python_data.hpp index 7f512830..91b5afd8 100644 --- a/include/boost/python/converter/rvalue_from_python_data.hpp +++ b/include/boost/python/converter/rvalue_from_python_data.hpp @@ -94,7 +94,8 @@ struct rvalue_from_python_data : rvalue_from_python_storage { # if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) \ && (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) \ - && (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) + && (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) \ + && !defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing this */ // This must always be a POD struct with m_data its first member. BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage,stage1) == 0); # endif diff --git a/include/boost/python/detail/call_object.hpp b/include/boost/python/detail/call_object.hpp deleted file mode 100644 index 5595e5c0..00000000 --- a/include/boost/python/detail/call_object.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CALL_OBJECT_DWA20011222_HPP -# define CALL_OBJECT_DWA20011222_HPP -# include -# include -# include - -namespace boost { namespace python { - -namespace detail -{ - // A function object adaptor which turns a function returning R into - // an "equivalent" function returning void, but taking an R& in - // which the adapted function's result is stored. - template - struct return_by_reference - { - typedef void return_type; - - return_by_reference(R& result, F f) - : m_result(result) - , m_f(f) - { - } - - void operator()() const - { - m_result = m_f(); - } - - R& m_result; - F m_f; - }; - - // An object generator for the above adaptors - template - return_by_reference bind_return(R& result, F f) - { - return return_by_reference(result, f); - } - - // Given a function object f with signature - // - // R f(PyTypeObject*,PyObject*) - // - // calls f inside of handle_exception_impl, placing f's result in - // ret. Returns true iff an exception is thrown by f, leaving ret - // unmodified. - template - bool call_object(R& ret, PyObject* obj, F f) - { - return handle_exception( - detail::bind_return( - ret - , boost::bind( - f, static_cast(obj->ob_type), obj))); - } -} // namespace detail - -}} // namespace boost::python - -#endif // CALL_OBJECT_DWA20011222_HPP diff --git a/include/boost/python/detail/exception_handler.hpp b/include/boost/python/detail/exception_handler.hpp index 9a9aa4d2..3e36a7a5 100644 --- a/include/boost/python/detail/exception_handler.hpp +++ b/include/boost/python/detail/exception_handler.hpp @@ -6,6 +6,7 @@ #ifndef EXCEPTION_HANDLER_DWA2002810_HPP # define EXCEPTION_HANDLER_DWA2002810_HPP +# include # include # include diff --git a/include/boost/python/detail/make_tuple.hpp b/include/boost/python/detail/make_tuple.hpp index cb5c6fc6..399498bc 100644 --- a/include/boost/python/detail/make_tuple.hpp +++ b/include/boost/python/detail/make_tuple.hpp @@ -1,16 +1,17 @@ +# ifndef BOOST_PYTHON_SYNOPSIS # // Copyright David Abrahams 2002. Permission to copy, use, # // modify, sell and distribute this software is granted provided this # // copyright notice appears in all copies. This software is provided # // "as is" without express or implied warranty, and with no claim as # // to its suitability for any purpose. -#if !defined(BOOST_PP_IS_ITERATING) -# error Boost.Python - do not include this file! -#endif +# if !defined(BOOST_PP_IS_ITERATING) +# error Boost.Python - do not include this file! +# endif -#define N BOOST_PP_ITERATION() +# define N BOOST_PP_ITERATION() -#define BOOST_PYTHON_MAKE_TUPLE_ARG(z, N, ignored) \ +# define BOOST_PYTHON_MAKE_TUPLE_ARG(z, N, ignored) \ PyTuple_SET_ITEM( \ result.ptr() \ , N \ @@ -26,6 +27,7 @@ return result; } -#undef BOOST_PYTHON_MAKE_TUPLE_ARG +# undef BOOST_PYTHON_MAKE_TUPLE_ARG -#undef N +# undef N +# endif // BOOST_PYTHON_SYNOPSIS diff --git a/include/boost/python/detail/module_base.hpp b/include/boost/python/detail/module_base.hpp deleted file mode 100644 index 39056d63..00000000 --- a/include/boost/python/detail/module_base.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#error obsolete -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef MODULE_BASE_DWA2002227_HPP -# define MODULE_BASE_DWA2002227_HPP -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -class BOOST_PYTHON_DECL module_base -{ - public: - // Create a module. REQUIRES: only one module is created per module. - module_base(char const* name, char const* doc = 0); - ~module_base(); - - // Add elements to the module - void add(type_handle const&); // just use the type's name - - // Return a reference to the Python module object being built - inline handle<> object() const; - - protected: - void setattr_doc(const char* name, python::object const&, char const* doc); - - private: - handle<> m_module; - static PyMethodDef initial_methods[1]; -}; - -// -// inline implementations -// -inline handle<> module_base::object() const -{ - return m_module; -} - -}}} // namespace boost::python::detail - -#endif // MODULE_BASE_DWA2002227_HPP diff --git a/include/boost/python/detail/scope.hpp b/include/boost/python/detail/scope.hpp index f8ece8f9..94528fa1 100644 --- a/include/boost/python/detail/scope.hpp +++ b/include/boost/python/detail/scope.hpp @@ -6,6 +6,8 @@ #ifndef SCOPE_DWA2002927_HPP # define SCOPE_DWA2002927_HPP +# include + namespace boost { namespace python { namespace detail { void BOOST_PYTHON_DECL scope_setattr_doc(char const* name, object const& obj, char const* doc); diff --git a/include/boost/python/detail/type_list_impl.hpp b/include/boost/python/detail/type_list_impl.hpp index 831ca5c0..50ab2446 100644 --- a/include/boost/python/detail/type_list_impl.hpp +++ b/include/boost/python/detail/type_list_impl.hpp @@ -7,6 +7,8 @@ # ifndef TYPE_LIST_IMPL_DWA2002913_HPP # define TYPE_LIST_IMPL_DWA2002913_HPP +# include + # include # include # include diff --git a/include/boost/python/detail/type_list_impl_no_pts.hpp b/include/boost/python/detail/type_list_impl_no_pts.hpp index d4d282aa..7c9d7fab 100644 --- a/include/boost/python/detail/type_list_impl_no_pts.hpp +++ b/include/boost/python/detail/type_list_impl_no_pts.hpp @@ -7,6 +7,8 @@ # ifndef TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP # define TYPE_LIST_IMPL_NO_PTS_DWA2002913_HPP +# include + # include # include # include diff --git a/include/boost/python/detail/type_list_utils.hpp b/include/boost/python/detail/type_list_utils.hpp deleted file mode 100644 index ebb5488b..00000000 --- a/include/boost/python/detail/type_list_utils.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#error obsolete -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef TYPE_LIST_UTILS_JDG20020826_HPP -# define TYPE_LIST_UTILS_JDG20020826_HPP - - -# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace boost { namespace python { namespace detail { - -template< typename T > -struct is_list_arg -{ - enum { value = true }; -}; - -template<> -struct is_list_arg -{ - enum { value = false }; -}; - -}}} -# endif -#endif // TYPE_LIST_UTILS_JDG20020826_HPP diff --git a/include/boost/python/object/add_to_namespace.hpp b/include/boost/python/object/add_to_namespace.hpp index 6a862b3d..e075bafd 100644 --- a/include/boost/python/object/add_to_namespace.hpp +++ b/include/boost/python/object/add_to_namespace.hpp @@ -6,6 +6,7 @@ #ifndef ADD_TO_NAMESPACE_DWA200286_HPP # define ADD_TO_NAMESPACE_DWA200286_HPP +# include # include namespace boost { namespace python { namespace objects { diff --git a/include/boost/python/object/construct.hpp b/include/boost/python/object/construct.hpp deleted file mode 100644 index 1eb73e4a..00000000 --- a/include/boost/python/object/construct.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright David Abrahams 2001. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef CONSTRUCT_DWA20011215_HPP -# define CONSTRUCT_DWA20011215_HPP - -namespace boost { namespace python { namespace objects { - -template -struct construct -{ - static - template namespace boost { namespace python { diff --git a/include/boost/python/object_call.hpp b/include/boost/python/object_call.hpp index 362446b2..dd0c0dc0 100644 --- a/include/boost/python/object_call.hpp +++ b/include/boost/python/object_call.hpp @@ -1,14 +1,15 @@ +# if !defined(BOOST_PYTHON_SYNOPSIS) # // Copyright David Abrahams 2002. Permission to copy, use, # // modify, sell and distribute this software is granted provided this # // copyright notice appears in all copies. This software is provided # // "as is" without express or implied warranty, and with no claim as # // to its suitability for any purpose. -#if !defined(BOOST_PP_IS_ITERATING) -# error Boost.Python - do not include this file! -#endif +# if !defined(BOOST_PP_IS_ITERATING) +# error Boost.Python - do not include this file! +# endif -#define N BOOST_PP_ITERATION() +# define N BOOST_PP_ITERATION() template typename detail::dependent::type @@ -19,4 +20,5 @@ return call(get_managed_object(self, tag), BOOST_PP_ENUM_PARAMS_Z(1, N, a)); } -#undef N +# undef N +# endif // BOOST_PYTHON_SYNOPSIS diff --git a/include/boost/python/object_protocol_core.hpp b/include/boost/python/object_protocol_core.hpp index c5c41c6a..50d2f454 100755 --- a/include/boost/python/object_protocol_core.hpp +++ b/include/boost/python/object_protocol_core.hpp @@ -6,6 +6,7 @@ #ifndef OBJECT_PROTOCOL_CORE_DWA2002615_HPP # define OBJECT_PROTOCOL_CORE_DWA2002615_HPP +# include # include namespace boost { namespace python { diff --git a/include/boost/python/operators.hpp b/include/boost/python/operators.hpp index 7087f83a..3292efa7 100644 --- a/include/boost/python/operators.hpp +++ b/include/boost/python/operators.hpp @@ -169,16 +169,16 @@ namespace detail \ }; \ } -# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \ -BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \ -namespace self_ns \ -{ \ - template \ - inline detail::operator_ \ - operator##op(L const&, R const&) \ - { \ - return detail::operator_(); \ - } \ +# define BOOST_PYTHON_BINARY_OPERATOR(id, rid, op) \ +BOOST_PYTHON_BINARY_OPERATION(id, rid, l op r) \ +namespace self_ns \ +{ \ + template \ + inline detail::operator_ \ + operator op(L const&, R const&) \ + { \ + return detail::operator_(); \ + } \ } BOOST_PYTHON_BINARY_OPERATOR(add, radd, +) @@ -262,7 +262,7 @@ namespace self_ns \ { \ template \ inline detail::operator_ \ - operator##op(self_t const&, R const&) \ + operator op(self_t const&, R const&) \ { \ return detail::operator_(); \ } \ From 2c7829f50e96a7b6a1c2281ce865392e90436087 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 15 Oct 2002 11:59:39 +0000 Subject: [PATCH 0853/1042] initial checkin [SVN r15930] --- build/Jamfile.v2 | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 build/Jamfile.v2 diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 new file mode 100644 index 00000000..21a8177a --- /dev/null +++ b/build/Jamfile.v2 @@ -0,0 +1,47 @@ +import os ; + +if [ os.name ] in CYGWIN NT +{ + lib_condition = true: ; + defines = USE_DL_IMPORT ; +} + +project boost/python + : source-location ../src + : requirements /usr/local/include/python2.2 + $(lib_condition)/usr/local/lib/python2.2/config + $(lib_condition)python2.2.dll + $(defines) + ; + +lib boost_python + : + numeric.cpp + + list.cpp + long.cpp + dict.cpp + tuple.cpp + str.cpp + + aix_init_module.cpp + converter/from_python.cpp + converter/registry.cpp + converter/type_id.cpp + object/enum.cpp + object/class.cpp + object/function.cpp + object/inheritance.cpp + object/life_support.cpp + object/pickle_support.cpp + errors.cpp + module.cpp + converter/builtin_converters.cpp + converter/arg_to_python_base.cpp + object/iterator.cpp + object_protocol.cpp + object_operators.cpp + : false:BOOST_PYTHON_STATIC_LIB + BOOST_PYTHON_SOURCE + : true + ; From c389e057b428f36d364f9226cb131aa70b74b159 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 15 Oct 2002 15:46:34 +0000 Subject: [PATCH 0854/1042] Added return_by_value, enhanced data member support to handle constant members [SVN r15935] --- doc/v2/reference.html | 24 +++- doc/v2/return_by_value.html | 147 +++++++++++++++++++++++ include/boost/python/data_members.hpp | 4 +- include/boost/python/object/iterator.hpp | 15 +-- include/boost/python/return_by_value.hpp | 30 +++++ test/data_members.cpp | 25 ++++ test/data_members.py | 16 ++- 7 files changed, 241 insertions(+), 20 deletions(-) create mode 100644 doc/v2/return_by_value.html create mode 100644 include/boost/python/return_by_value.hpp diff --git a/doc/v2/reference.html b/doc/v2/reference.html index be866666..8ec51d9b 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -13,7 +13,7 @@ p.c3 {font-style: italic} h2.c2 {text-align: center} h1.c1 {text-align: center} - + @@ -352,8 +352,8 @@
      object
      -
      -
      +
      +
      @@ -716,6 +716,21 @@ + +
      return_by_value.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      return_by_value
      +
      +
      +
      +
      @@ -898,7 +913,8 @@

      Revised - 08 October, 2002 + 15 October, 2002 +

      © Copyright + + + + + + + + Boost.Python - <boost/python/return_by_value.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header + <boost/python/return_by_value.hpp>

      +
      +


      + +

      Contents

      + +
      +
      Classes
      + +
      +
      +
      Class + return_by_value
      + +
      +
      +
      Class + return_by_value synopsis
      + +
      Class + return_by_value metafunctions
      +
      +
      +
      +
      + +
      Example
      +
      +
      + +

      Classes

      + +

      Class + return_by_value

      + +

      return_by_value is a model of ResultConverterGenerator + which can be used to wrap C++ functions returning any reference or value + type such that the return value is copied into a new Python object.

      + +

      Class + return_by_value synopsis

      +
      +namespace boost { namespace python
      +{
      +    struct return_by_value
      +    {
      +        template <class T> struct apply;
      +    };
      +}}
      +
      + +

      Class + return_by_value metafunctions

      +
      +template <class T> struct apply
      +
      + +
      +
      Returns: typedef to_python_value<T> + type;
      +
      + +

      Example

      + +

      C++ Module Definition

      +
      +#include <boost/python/module.hpp>
      +#include <boost/python/class.hpp>
      +#include <boost/python/return_by_value.hpp>
      +#include <boost/python/return_value_policy.hpp>
      +
      +// classes to wrap
      +struct Bar { };
      +
      +Bar global_bar;
      +
      +// functions to wrap:
      +Bar b1();
      +Bar& b2();
      +Bar const& b3();
      +
      +// Wrapper code
      +using namespace boost::python;
      +template <class R>
      +void def_void_function(char const* name, R (*f)())
      +{
      +   def(name, f, return_value_policy<return_by_value>());
      +}
      +
      +BOOST_PYTHON_MODULE(my_module)
      +{
      +    class_<Bar>("Bar");
      +    def_void_function("b1", b1);
      +    def_void_function("b2", b2);
      +    def_void_function("b3", b3);
      +}
      +
      + +

      Python Code

      +
      +>>> from my_module import *
      +>>> b = b1() # each of these calls
      +>>> b = b2() # creates a brand
      +>>> b = b3() # new Bar object
      +
      + +

      Revised + + 15 October, 2002 + +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp index 01190811..62a38570 100644 --- a/include/boost/python/data_members.hpp +++ b/include/boost/python/data_members.hpp @@ -11,7 +11,7 @@ # include # include # include -# include +# include # include # include # include @@ -65,7 +65,7 @@ namespace detail template object make_getter(D C::*pm) { - typedef return_value_policy default_policy; + typedef return_value_policy default_policy; return objects::function_object( ::boost::bind( diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 01bef3f1..65c206d7 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -10,7 +10,7 @@ # include # include # include -# include +# include # include # include # include @@ -29,18 +29,7 @@ namespace boost { namespace python { namespace objects { // iterators are copied, so we just replace the result_converter from // the default_iterator_call_policies with a permissive one which // always copies the result. -struct default_iterator_call_policies - : default_call_policies -{ - struct result_converter - { - template - struct apply - { - typedef to_python_value type; - }; - }; -}; +typedef return_value_policy default_iterator_call_policies; // Instantiations of these are wrapped to produce Python iterators. template diff --git a/include/boost/python/return_by_value.hpp b/include/boost/python/return_by_value.hpp new file mode 100644 index 00000000..97f9f245 --- /dev/null +++ b/include/boost/python/return_by_value.hpp @@ -0,0 +1,30 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef BY_VALUE_DWA20021015_HPP +# define BY_VALUE_DWA20021015_HPP + +# include +# include +# include + +namespace boost { namespace python { + +struct return_by_value +{ + template + struct apply + { + typedef to_python_value< + typename add_reference< + typename add_const::type + >::type + > type; + }; +}; + +}} // namespace boost::python + +#endif // BY_VALUE_DWA20021015_HPP diff --git a/test/data_members.cpp b/test/data_members.cpp index 2345634a..5a87eeae 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -5,6 +5,8 @@ // to its suitability for any purpose. #include #include +#include +#include #include "test_class.hpp" #if defined(_AIX) && defined(__EDG_VERSION__) && __EDG_VERSION__ < 245 @@ -20,6 +22,16 @@ typedef test_class<1> Y; double get_fair_value(X const& x) { return x.value(); } +struct Var +{ + Var(std::string name_) : name(name_), value(), name2(name.c_str()) {} + std::string const name; + std::string get_name1() const { return name; } + std::string const& get_name2() const { return name; } + float value; + char const* name2; +}; + BOOST_PYTHON_MODULE(data_members_ext) { class_("X", init()) @@ -34,6 +46,19 @@ BOOST_PYTHON_MODULE(data_members_ext) .def("set", &Y::set) .def_readwrite("x", &Y::x) ; + + class_("Var", init()) + .def_readonly("name", &Var::name) + .def_readonly("name2", &Var::name2) + .def_readwrite("value", &Var::value) + + // Test return_by_value for plain values and for + // pointers... return_by_value was implemented as a + // side-effect of implementing data member support, so it made + // sense to add the test here. + .def("get_name1", &Var::get_name1, return_value_policy()) + .def("get_name2", &Var::get_name2, return_value_policy()) + ; } #include "module_tail.cpp" diff --git a/test/data_members.py b/test/data_members.py index ab79a90a..c908f515 100644 --- a/test/data_members.py +++ b/test/data_members.py @@ -1,5 +1,6 @@ ''' >>> from data_members_ext import * + >>> x = X(42) >>> x.x 42 @@ -9,13 +10,26 @@ >>> x.fair_value 42.0 - >>> y = Y(69) >>> y.x 69 >>> y.x = 77 >>> y.x 77 + +>>> v = Var("pi") +>>> v.value = 3.14 +>>> v.name +'pi' +>>> v.name2 +'pi' + +>>> v.get_name1() +'pi' + +>>> v.get_name2() +'pi' + ''' def run(args = None): From 7fc441801d9813d978bee8e2f959f521eb86ed9e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 16 Oct 2002 20:24:38 +0000 Subject: [PATCH 0855/1042] Allow embedded nulls in std::string <-> Python string conversions, patch from greg Landrum . Tests by Dave A. [SVN r15945] --- include/boost/python/converter/builtin_converters.hpp | 2 +- src/converter/builtin_converters.cpp | 4 ++-- test/test_builtin_converters.py | 7 ++++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index aebfd459..3b3a473b 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -102,7 +102,7 @@ BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned LONG_LONG, PyLong_FromUnsignedLongLong( BOOST_PYTHON_TO_PYTHON_BY_VALUE(char, converter::do_return_to_python(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(char const*, converter::do_return_to_python(x)) -BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromString(x.c_str())) +BOOST_PYTHON_TO_PYTHON_BY_VALUE(std::string, PyString_FromStringAndSize(x.c_str(),x.size())) BOOST_PYTHON_TO_PYTHON_BY_VALUE(float, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(double, PyFloat_FromDouble(x)) BOOST_PYTHON_TO_PYTHON_BY_VALUE(long double, PyFloat_FromDouble(x)) diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index b5916dde..ce842b12 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -222,9 +222,9 @@ namespace }; // Remember that this will be used to construct the result object - static char const* extract(PyObject* intermediate) + static std::string extract(PyObject* intermediate) { - return PyString_AsString(intermediate); + return std::string(PyString_AsString(intermediate),PyString_Size(intermediate)); } }; diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index f6caf56b..e4d8b335 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -1,4 +1,4 @@ -""" +r""" >>> from builtin_converters import * # Synthesize idendity functions in case long long not supported @@ -73,6 +73,11 @@ >>> rewrap_value_string('yo, wassup?') 'yo, wassup?' + wrap strings with embedded nulls: + +>>> rewrap_value_string('yo,\0wassup?') +'yo,\x00wassup?' + >>> rewrap_value_handle(1) 1 >>> x = 'hi' From 037f9521369995702b6c611766572442de18c691 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 16 Oct 2002 22:47:44 +0000 Subject: [PATCH 0856/1042] Added funding credit [SVN r15948] --- doc/index.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/index.html b/doc/index.html index f5ca838e..320361b0 100644 --- a/doc/index.html +++ b/doc/index.html @@ -56,6 +56,11 @@
    • Documentation Strings
    • + The development of these features was funded in part by grants to Boost Consulting from the Lawrence Livermore National Laboratories + and by the Computational Crystallography + Initiative at Lawrence Berkeley National Laboratories.

      Contents

      From 3cb4a029e06851bc8c7d38878e7a2b0c0d07f196 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Wed, 23 Oct 2002 12:12:00 +0000 Subject: [PATCH 0857/1042] Improve Boost.Python building. * libs/python/build/Jamfile.v2: Sense the location of python headers. Export include paths. * libs/python/example/Jamfile.v2: New file. * new/targets.jam: Use refined properties for constructed dependency properties * new/gcc.jam: Handle 'find-library'. Set soname for dynamic libraries. * new/builtin.jam: New feature 'find-library'. [SVN r15966] --- build/Jamfile.v2 | 28 +++++++++++++++++++++++++--- example/Jamfile.v2 | 10 ++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 example/Jamfile.v2 diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 21a8177a..b069cca7 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -1,17 +1,38 @@ import os ; +# Use a very crude way to sense there python is locatted + +local PYTHON_PATH ; + +if [ GLOB /usr/include/python2.2 : * ] +{ + PYTHON_PATH = /usr ; +} +else if [ GLOB /usr/local/include/python2.2 : * ] +{ + PYTHON_PATH = /usr/local ; +} + +PYTHON_LIB = python2.2 ; + if [ os.name ] in CYGWIN NT { lib_condition = true: ; defines = USE_DL_IMPORT ; + PYTHON_LIB = python2.2.dll ; } +if $(PYTHON_PATH) { + + project boost/python : source-location ../src - : requirements /usr/local/include/python2.2 - $(lib_condition)/usr/local/lib/python2.2/config - $(lib_condition)python2.2.dll + : requirements $(PYTHON_PATH)/include/python2.2 + $(lib_condition)$(PYTHON_PATH)/lib/python2.2/config + true:$(PYTHON_LIB) $(defines) + : use-requirements # requirement that will be propageted to *users* of this library + $(PYTHON_PATH)/include/python2.2 ; lib boost_python @@ -45,3 +66,4 @@ lib boost_python BOOST_PYTHON_SOURCE : true ; +} diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 new file mode 100644 index 00000000..0b6e2e76 --- /dev/null +++ b/example/Jamfile.v2 @@ -0,0 +1,10 @@ + +use-project /boost/python : ../build ; + +project + : requirements @/boost/python/boost_python + ; + +lib getting_started1 : getting_started1.cpp : true ; +lib getting_started2 : getting_started2.cpp : true ; + From 8c2d6bb31ba9eedb8c089a2e38227d9d086d0e26 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Thu, 24 Oct 2002 20:50:04 +0000 Subject: [PATCH 0858/1042] correction Var-->Num [SVN r15977] --- doc/tutorial/doc/class_properties.html | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/tutorial/doc/class_properties.html b/doc/tutorial/doc/class_properties.html index cd2267d5..22d2921a 100644 --- a/doc/tutorial/doc/class_properties.html +++ b/doc/tutorial/doc/class_properties.html @@ -44,11 +44,13 @@ However, in Python attribute access is fine; it doesn't neccessarily break encapsulation to let users handle attributes directly, because the attributes can just be a different syntax for a method call. Wrapping our Num class using Boost.Python:

      -
      +
      +
           class_<Num>("Num")
      -        .add_property("rovalue", &Var::get)
      -        .add_property("value", &Var::get, &Var::set);
      -
      + .add_property("rovalue", &Num::get) + .add_property("value", &Num::get, &Var::set); +
      +

      And at last, in Python:

      
      From da273519fd32fa0829751a449605064bef99b41c Mon Sep 17 00:00:00 2001
      From: Joel de Guzman 
      Date: Thu, 24 Oct 2002 21:12:37 +0000
      Subject: [PATCH 0859/1042] added non_copyable to second version of
       class_
       

      In Python, let us try to instantiate our Base class:

      -
      +
      +
           >>> base = Base()
      -    AttributeError: ...
      -
      + RuntimeError: This class cannot be instantiated from Python
      +

      Why is it an error? Base is an abstract class. As such it is advisable to define the Python wrapper with no_init as we have done above. Doing @@ -167,11 +168,12 @@ And instead is implemented to return 0, as shown above.

      then, our Boost.Python wrapper:

      -
      -    class_<Base, BaseWrap>("Base")
      +
      +
          class_<Base, BaseWrap, boost::non_copyable>("Base")
               .def("f", &BaseWrap::default_f)
               ;
      -
      +
      +

      Note that we are allowing Base objects to be instantiated this time, unlike before where we specifically defined the class_<Base> with From 387e8aadc6dd1826878b91f75f19bed0976b03a9 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Thu, 24 Oct 2002 21:33:40 +0000 Subject: [PATCH 0860/1042] changes to no_init and deriving classes [SVN r15979] --- doc/tutorial/doc/class_virtual_functions.html | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/doc/tutorial/doc/class_virtual_functions.html b/doc/tutorial/doc/class_virtual_functions.html index 96fa2b1d..ebe943bf 100644 --- a/doc/tutorial/doc/class_virtual_functions.html +++ b/doc/tutorial/doc/class_virtual_functions.html @@ -113,14 +113,22 @@ In Python, let us try to instantiate our Base class:

      Why is it an error? Base is an abstract class. As such it is advisable to define the Python wrapper with no_init as we have done above. Doing so will disallow abstract base classes such as Base to be instantiated.

      -

      Deriving a Python class

      -Now, at last, we can even derive from our base class Base in Python:

      -
      +

      Deriving a Python class

      +

      Now, at last, we can even derive from our base class Base in Python. + Before we can do that, we have to set up our class_ wrapper as:

      +
          class_<Base, BaseWrap, boost::noncopyable>("Base")
      +        ;
      +

      Otherwise, we have to suppress the Base class' no_init by adding an + __init__() method to all our derived classes. no_init actually + adds an __init__ method that raises a Python RuntimeError exception.

      + +
           >>> class Derived(Base):
           ...     def f(self):
           ...         return 42
           ...
      -
      +
      +

      Cool eh? A Python class deriving from a C++ class!

      From a682dd936259a6c1ae4fe4bce49e7baa4844fa5c Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 25 Oct 2002 04:47:39 +0000 Subject: [PATCH 0861/1042] Fix a doc bug [SVN r15981] --- doc/v2/reference_existing_object.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/v2/reference_existing_object.html b/doc/v2/reference_existing_object.html index 88016dd8..c1bc46d0 100644 --- a/doc/v2/reference_existing_object.html +++ b/doc/v2/reference_existing_object.html @@ -143,7 +143,9 @@ Singleton& get_it() using namespace boost::python; BOOST_PYTHON_MODULE(singleton) { - def("get_it", get_it, reference_existing_object()); + def("get_it", get_it, + return_value_policy<reference_existing_object>()); + class_<Singleton>("Singleton") .def("exchange", &Singleton::exchange) ; From 038be89766b791261f3417fcd1cba5150ce00e25 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 28 Oct 2002 04:22:14 +0000 Subject: [PATCH 0862/1042] Build with Cygwin [SVN r16000] --- build/Jamfile.v2 | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index b069cca7..62f3b344 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -4,14 +4,14 @@ import os ; local PYTHON_PATH ; -if [ GLOB /usr/include/python2.2 : * ] -{ - PYTHON_PATH = /usr ; -} -else if [ GLOB /usr/local/include/python2.2 : * ] +if [ GLOB /usr/local/include/python2.2 : * ] { PYTHON_PATH = /usr/local ; } +else if [ GLOB /usr/include/python2.2 : * ] +{ + PYTHON_PATH = /usr ; +} PYTHON_LIB = python2.2 ; @@ -33,6 +33,14 @@ project boost/python $(defines) : use-requirements # requirement that will be propageted to *users* of this library $(PYTHON_PATH)/include/python2.2 + +# We have a bug which causes us to conclude that conditionalized +# properties in this section are not free. +# $(lib_condition)$(PYTHON_PATH)/lib/python2.2/config +# true:$(PYTHON_LIB) + + $(PYTHON_PATH)/lib/python2.2/config + $(PYTHON_LIB) ; lib boost_python From f346eaf693c0cd43c8d8754086bf7391e86d6077 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 28 Oct 2002 07:33:01 +0000 Subject: [PATCH 0863/1042] grammar fix [SVN r16001] --- doc/tutorial/doc/quickstart.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt index 2c1116cb..7b4f1f1c 100644 --- a/doc/tutorial/doc/quickstart.txt +++ b/doc/tutorial/doc/quickstart.txt @@ -1122,7 +1122,7 @@ the construct: .value("blue", blue) ; -can be used to expose to Python. The new enum type is created in the +can be used to expose it to Python. The new enum type is created in the current [^scope()], which is usually the current module. The snippet above creates a Python class derived from Python's [^int] type which is associated with the C++ type passed as its first parameter. From 7b091b86d27cfae8bd390ea222717ee0a93a4ac4 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Mon, 28 Oct 2002 08:30:31 +0000 Subject: [PATCH 0864/1042] tutorial tweaks [SVN r16004] --- doc/tutorial/doc/quickstart.txt | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt index 7b4f1f1c..ec3917cc 100644 --- a/doc/tutorial/doc/quickstart.txt +++ b/doc/tutorial/doc/quickstart.txt @@ -378,8 +378,8 @@ attributes can just be a different syntax for a method call. Wrapping our [^Num] class using Boost.Python: class_("Num") - .add_property("rovalue", &Var::get) - .add_property("value", &Var::get, &Var::set); + .add_property("rovalue", &Num::get) + .add_property("value", &Num::get, &Num::set); And at last, in Python: @@ -392,7 +392,7 @@ And at last, in Python: Take note that the class property [^rovalue] is exposed as [*read-only] since the [^rovalue] setter member function is not passed in: - .add_property("rovalue", &Var::get) + .add_property("rovalue", &Num::get) [page:1 Inheritance] @@ -520,7 +520,7 @@ available, since Base is an abstract class. In Python, let us try to instantiate our [^Base] class: >>> base = Base() - AttributeError: ... + RuntimeError: This class cannot be instantiated from Python Why is it an error? [^Base] is an abstract class. As such it is advisable to define the Python wrapper with [^no_init] as we have done above. Doing @@ -528,7 +528,15 @@ so will disallow abstract base classes such as [^Base] to be instantiated. [h2 Deriving a Python class] -Now, at last, we can even derive from our base class [^Base] in Python: +Now, at last, we can even derive from our base class Base in Python. Before +we can do that, we have to set up our class_ wrapper as: + + class_("Base") + ; + +Otherwise, we have to suppress the Base class' [^no_init] by adding an +[^__init__()] method to all our derived classes. [^no_init] actually adds +an [^__init__] method that raises a Python RuntimeError exception. >>> class Derived(Base): ... def f(self): @@ -1122,7 +1130,7 @@ the construct: .value("blue", blue) ; -can be used to expose it to Python. The new enum type is created in the +can be used to expose to Python. The new enum type is created in the current [^scope()], which is usually the current module. The snippet above creates a Python class derived from Python's [^int] type which is associated with the C++ type passed as its first parameter. From 42a0441cb8f77e7d53c5e3c3ccc2e4c4021d52e3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 7 Nov 2002 13:12:05 +0000 Subject: [PATCH 0865/1042] Doc fix from "Brett Calcott" [SVN r16145] --- doc/v2/call_method.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/call_method.html b/doc/v2/call_method.html index 86f6c9d5..59d93a09 100644 --- a/doc/v2/call_method.html +++ b/doc/v2/call_method.html @@ -112,7 +112,7 @@ class Base_callback : public Base public: Base_callback(PyObject* self) : m_self(self) {} - char const* class_name() const { return call_method(m_self, "class_name"); } + char const* class_name() const { return call_method<char const*>(m_self, "class_name"); } char const* Base_name() const { return Base::class_name(); } private: PyObject* const m_self; From 8e3ba0bba34640a52f66617f2fae4e2d3138f070 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 7 Nov 2002 14:41:40 +0000 Subject: [PATCH 0866/1042] Improve error messages [SVN r16147] --- include/boost/python/default_call_policies.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/default_call_policies.hpp b/include/boost/python/default_call_policies.hpp index f964990f..e796bee5 100644 --- a/include/boost/python/default_call_policies.hpp +++ b/include/boost/python/default_call_policies.hpp @@ -17,7 +17,7 @@ template struct to_python_value; namespace detail { // for "readable" error messages - template struct specify_a_result_policy_to_wrap_functions_returning + template struct specify_a_return_value_policy_to_wrap_functions_returning # if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) {} # endif @@ -52,7 +52,7 @@ struct default_result_converter typedef typename mpl::if_c< is_illegal - , detail::specify_a_result_policy_to_wrap_functions_returning + , detail::specify_a_return_value_policy_to_wrap_functions_returning , boost::python::to_python_value< typename add_reference::type>::type > From 1f93827b635358b30a7b974f3e45eeec232427c8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 11 Nov 2002 13:49:09 +0000 Subject: [PATCH 0867/1042] Squash bogus warnings [SVN r16196] --- include/boost/python/detail/config.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/config.hpp b/include/boost/python/detail/config.hpp index fb263dbe..4e2b85ab 100644 --- a/include/boost/python/detail/config.hpp +++ b/include/boost/python/detail/config.hpp @@ -32,7 +32,10 @@ # define BOOST_MSVC6_OR_EARLIER 1 # endif -# pragma warning (disable : 4786) +# pragma warning (disable : 4786) // disable truncated debug symbols +# pragma warning (disable : 4251) // disable exported dll function +# pragma warning (disable : 4800) //'int' : forcing value to bool 'true' or 'false' +# pragma warning (disable : 4275) // non dll-interface class # elif defined(__ICL) && __ICL < 600 // Intel C++ 5 From 88b1c1b926b984e298af8d2826d24a1af4209f20 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 12 Nov 2002 17:48:56 +0000 Subject: [PATCH 0868/1042] Allow member pointers from base classes in def_readonly and def_readwrite. [SVN r16214] --- include/boost/python/class.hpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 3ec153b4..af4ce1fd 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -256,16 +256,18 @@ class class_ : public objects::class_base // // Data member access // - template - self& def_readonly(char const* name, D T::*pm) + template + self& def_readonly(char const* name, D B::*pm_) { + D T::*pm = pm_; this->add_property(name, make_getter(pm)); return *this; } - template - self& def_readwrite(char const* name, D T::*pm) + template + self& def_readwrite(char const* name, D B::*pm_) { + D T::*pm = pm_; return this->add_property(name, make_getter(pm), make_setter(pm)); } From 0168d8fbc84a1d5a26a681f00ef0e0559a3f9b56 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 12 Nov 2002 19:36:19 +0000 Subject: [PATCH 0869/1042] Be more explicit about the Cygwin stuff [SVN r16215] --- doc/building.html | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/doc/building.html b/doc/building.html index 5bb509a2..489d56a4 100644 --- a/doc/building.html +++ b/doc/building.html @@ -138,10 +138,11 @@ - Cygwin only. This and the - following two settings are useful when building with multiple - toolsets on Windows, since Cygwin requires a different build of - Python. + Use only when building with Cygwin GCC from a regular Win32 build of + bjam. This and the following two settings are useful when building + with multiple toolsets on Windows, since Cygwin GCC requires a + different build of Python. @@ -151,7 +152,9 @@ $(CYGWIN_ROOT)/usr/local - Cygwin only + Use only when building with Cygwin GCC from a regular Win32 build of + bjam. @@ -162,7 +165,9 @@ $(CYGWIN_ROOT)/usr/local/pydebug - Cygwin only + Use only when building with Cygwin GCC from a regular Win32 build of + bjam. From bcf864fce3839694d0fbed5358c07cdeaee4d8fd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 13 Nov 2002 17:22:48 +0000 Subject: [PATCH 0870/1042] Attempt to handle derived target types [SVN r16224] --- example/Jamfile.v2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index 0b6e2e76..f80168e2 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -5,6 +5,6 @@ project : requirements @/boost/python/boost_python ; -lib getting_started1 : getting_started1.cpp : true ; -lib getting_started2 : getting_started2.cpp : true ; +python-extension getting_started1 : getting_started1.cpp : true ; +python-extension getting_started2 : getting_started2.cpp : true ; From 6b4dc2901ddfd0b1d399caaedcc374158a10f9ed Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 13 Nov 2002 22:56:41 +0000 Subject: [PATCH 0871/1042] Fix broken link [SVN r16227] --- doc/v2/class.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/class.html b/doc/v2/class.html index f2fd15c5..fb748a99 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -529,7 +529,7 @@ void add_property(char const* name, Get const& fget, Set const& fset); naming rules.

      Effects: Creates a new Python property + "http://www.python.org/2.2.2/descrintro.html#property">property class instance, passing object(fget) (and object(fset) in the From 0e76fcf7069cadb55e6ef8f2d1c8bde899abd3b9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 14 Nov 2002 01:40:16 +0000 Subject: [PATCH 0872/1042] auto_ptr support [SVN r16228] --- .../python/converter/arg_from_python.hpp | 4 +- .../python/converter/arg_to_python_base.hpp | 1 - .../python/converter/return_from_python.hpp | 13 +++- .../converter/to_python_function_type.hpp | 29 +++++++- .../boost/python/object/class_converters.hpp | 2 - include/boost/python/object/class_wrapper.hpp | 17 ++++- .../boost/python/object/pointer_holder.hpp | 1 - include/boost/python/object/select_holder.hpp | 3 +- test/Jamfile | 20 +++--- test/auto_ptr.cpp | 70 +++++++++++++++++++ test/auto_ptr.py | 54 ++++++++++++++ test/test_builtin_converters.cpp | 24 +++++-- test/test_builtin_converters2.cpp | 10 +++ 13 files changed, 225 insertions(+), 23 deletions(-) create mode 100644 test/auto_ptr.cpp create mode 100644 test/auto_ptr.py create mode 100644 test/test_builtin_converters2.cpp diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp index 1e3dfa26..78d00052 100755 --- a/include/boost/python/converter/arg_from_python.hpp +++ b/include/boost/python/converter/arg_from_python.hpp @@ -103,7 +103,9 @@ template struct arg_rvalue_from_python { typedef typename boost::add_reference< - typename boost::add_const::type + T + // We can't add_const here, or it would be impossible to pass + // auto_ptr args from Python to C++ >::type result_type; arg_rvalue_from_python(PyObject*); diff --git a/include/boost/python/converter/arg_to_python_base.hpp b/include/boost/python/converter/arg_to_python_base.hpp index 385a7839..850da036 100755 --- a/include/boost/python/converter/arg_to_python_base.hpp +++ b/include/boost/python/converter/arg_to_python_base.hpp @@ -5,7 +5,6 @@ // to its suitability for any purpose. #ifndef ARG_TO_PYTHON_BASE_DWA200237_HPP # define ARG_TO_PYTHON_BASE_DWA200237_HPP -# include # include # include diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index c487aa22..18c2d227 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -11,9 +11,11 @@ # include # include # include -# include # include # include +# include +# include +# include namespace boost { namespace python { namespace converter { @@ -38,7 +40,14 @@ namespace detail template struct return_rvalue_from_python { - typedef typename call_traits::param_type result_type; + typedef typename mpl::if_< + mpl::logical_and< + has_trivial_copy, mpl::bool_c<(sizeof(T) <= 2 * sizeof(double))> + > + , T + , T& + >::type result_type; + return_rvalue_from_python(); result_type operator()(PyObject*); private: diff --git a/include/boost/python/converter/to_python_function_type.hpp b/include/boost/python/converter/to_python_function_type.hpp index 197654e5..debad150 100644 --- a/include/boost/python/converter/to_python_function_type.hpp +++ b/include/boost/python/converter/to_python_function_type.hpp @@ -6,6 +6,7 @@ #ifndef TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP # define TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP # include +# include namespace boost { namespace python { namespace converter { @@ -19,9 +20,35 @@ typedef PyObject* (*to_python_function_t)(void const*); template struct as_to_python_function { + // Assertion functions used to prevent wrapping of converters + // which take non-const reference parameters. The T* argument in + // the first overload ensures it isn't used in case T is a + // reference. + template + static int convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0); + template + static int convert_function_must_take_value_or_const_reference(U(*)(T const&), long ...); + static PyObject* convert(void const* x) { - return ToPython::convert(*(T const*)x); + + BOOST_STATIC_ASSERT( + sizeof( + convert_function_must_take_value_or_const_reference(&ToPython::convert, 1L)) + == sizeof(int)); + + // Yes, the const_cast below opens a hole in const-correctness, + // but it's needed to convert auto_ptr to python. + // + // How big a hole is it? It allows ToPython::convert() to be + // a function which modifies its argument. The upshot is that + // client converters applied to const objects may invoke + // undefined behavior. The damage, however, is limited by the + // use of the assertion function. Thus, the only way this can + // modify its argument is if T is an auto_ptr-like type. There + // is still a const-correctness hole w.r.t. auto_ptr const, + // but c'est la vie. + return ToPython::convert(*const_cast(static_cast(x))); } }; diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index 79119ef7..83a16ac8 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -6,9 +6,7 @@ #ifndef CLASS_CONVERTERS_DWA2002119_HPP # define CLASS_CONVERTERS_DWA2002119_HPP -# include # include -# include # include # include # include diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp index 61364d9d..fe802989 100644 --- a/include/boost/python/object/class_wrapper.hpp +++ b/include/boost/python/object/class_wrapper.hpp @@ -13,14 +13,27 @@ namespace boost { namespace python { namespace objects { // Used to convert objects of type Src to wrapped C++ classes by // building a new instance object and installing a Holder constructed -// from the Src object. +// from a Src const&. template struct class_wrapper : to_python_converter > { static PyObject* convert(Src const& x) { - return MakeInstance::execute(cref(x)); + return MakeInstance::execute(boost::ref(x)); + } +}; + +// Used to convert objects of type Src to wrapped C++ classes by +// building a new instance object and installing a Holder constructed +// from a Src value. +template +struct class_value_wrapper + : to_python_converter > +{ + static PyObject* convert(Src x) + { + return MakeInstance::execute(x); } }; diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index d0196941..3a65dcb3 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -16,7 +16,6 @@ # include # include # include -# include # include # include # include diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index 3535fd29..c1396169 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -11,6 +11,7 @@ # include # include # include +# include # include # include # include @@ -97,7 +98,7 @@ namespace detail static inline void register_(mpl::bool_c) { python::detail::force_instantiate( - objects::class_wrapper< + objects::class_value_wrapper< Ptr , type , make_instance >()); diff --git a/test/Jamfile b/test/Jamfile index 4f554cc4..81f1f99a 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -55,15 +55,19 @@ rule bpl-test ( name ? : files * : requirements * ) boost-python-runtest $(name) : $(py) $(modules) ; } +bpl-test auto_ptr ; bpl-test minimal ; bpl-test args ; bpl-test numpy ; bpl-test enum ; -bpl-test docstring ; bpl-test exception_translator ; bpl-test pearu1 : test_cltree.py cltree.cpp ; bpl-test try : newtest.py m1.cpp m2.cpp ; -bpl-test builtin_converters : test_builtin_converters.py test_builtin_converters.cpp ; + +# Had to break this up into two files for MSVC6 +extension builtin_converters : test_builtin_converters.cpp test_builtin_converters2.cpp ../build/boost_python ; +boost-python-runtest builtin_converters : test_builtin_converters.py builtin_converters ; + bpl-test test_pointer_adoption ; bpl-test operators ; bpl-test callbacks ; @@ -112,6 +116,8 @@ bpl-test pickle3 ; bpl-test nested ; +bpl-test docstring ; + if $(TEST_BIENSTMAN_NON_BUGS) { bpl-test bienstman4 ; @@ -161,11 +167,9 @@ run select_arg_to_python_test.cpp ../src/converter/type_id.cpp ../../test/ : $(UNIT_TEST_PROPERTIES) ; -if $(TEST_EXPECTED_FAILURES) -{ - compile-fail ./raw_pyobject_fail1.cpp : $(PYTHON_PROPERTIES) ; - compile-fail ./raw_pyobject_fail2.cpp : $(PYTHON_PROPERTIES) ; - compile-fail ./object_fail1.cpp : $(PYTHON_PROPERTIES) ; -} +compile-fail ./raw_pyobject_fail1.cpp : $(PYTHON_PROPERTIES) ; +compile-fail ./raw_pyobject_fail2.cpp : $(PYTHON_PROPERTIES) ; +compile-fail ./as_to_python_function.cpp : $(PYTHON_PROPERTIES) ; +compile-fail ./object_fail1.cpp : $(PYTHON_PROPERTIES) ; diff --git a/test/auto_ptr.cpp b/test/auto_ptr.cpp new file mode 100644 index 00000000..39c3941b --- /dev/null +++ b/test/auto_ptr.cpp @@ -0,0 +1,70 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include +#include +#include +#include +#include "test_class.hpp" + +#include + +using namespace boost::python; + +typedef test_class<> X; + +int look(std::auto_ptr const& x) +{ + return (x.get()) ? x->value() : -1; +} + +int steal(std::auto_ptr x) +{ + return x->value(); +} + +int maybe_steal(std::auto_ptr& x, bool doit) +{ + int n = x->value(); + if (doit) + x.release(); + return n; +} + +std::auto_ptr make() +{ + return std::auto_ptr(new X(77)); +} + +std::auto_ptr callback(object f) +{ + std::auto_ptr x(new X(77)); +// call(f.ptr(),x); +// return std::auto_ptr(new X(77)); + return call >(f.ptr(), x); +} + +std::auto_ptr extract_(object o) +{ + return extract >(o); +} + +BOOST_PYTHON_MODULE(auto_ptr_ext) +{ + class_, boost::noncopyable>("X", init()) + .def("value", &X::value) + ; + + def("look", look); + def("steal", steal); + def("maybe_steal", maybe_steal); + def("make", make); + def("callback", callback); + def("extract", extract_); +} + +#include "module_tail.cpp" + diff --git a/test/auto_ptr.py b/test/auto_ptr.py new file mode 100644 index 00000000..7c6ce51f --- /dev/null +++ b/test/auto_ptr.py @@ -0,0 +1,54 @@ +''' +>>> from auto_ptr_ext import * +>>> x = X(42) +>>> x.value() +42 + +>>> look(x), look(x) +(42, 42) + +>>> maybe_steal(x, 0) +42 +>>> look(x) +42 + +>>> maybe_steal(x, 1) +42 +>>> (not '--broken-auto-ptr' in sys.argv) and look(x) or -1 +-1 + +>>> x = X(69) +>>> steal(x) +69 +>>> (not '--broken-auto-ptr' in sys.argv) and look(x) or -1 +-1 + +>>> if not '--broken-auto-ptr' in sys.argv: +... try: x.value() +... except TypeError: pass +... else: print 'expected a TypeError exception' + +>>> x = make() +>>> look(x) +77 + +>>> y = callback(lambda y: y) +>>> y.value() +77 + +>>> extract(x).value() +77 +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp index 917a468a..a078d41f 100644 --- a/test/test_builtin_converters.cpp +++ b/test/test_builtin_converters.cpp @@ -44,6 +44,10 @@ using boost::python::handle; using boost::python::object; using boost::python::borrowed; +// MSVC6 can't process this whole file at once, so we break it up into +// two parts. See test_builtin_converters2.cpp +#ifndef BOOST_PYTHON_WRAP_MORE_BUILTIN_CONVERTERS + // Used to test that arbitrary handle<>s can be returned handle get_type(handle<> x) { @@ -57,6 +61,8 @@ handle<> return_null_handle() char const* rewrap_value_mutable_cstring(char* x) { return x; } +void wrap_more(); + BOOST_PYTHON_MODULE(builtin_converters) { def("get_type", get_type); @@ -74,10 +80,10 @@ BOOST_PYTHON_MODULE(builtin_converters) def("rewrap_value_unsigned_long", by_value::rewrap); // using Python's macro instead of Boost's - we don't seem to get the // config right all the time. -#ifdef HAVE_LONG_LONG +# ifdef HAVE_LONG_LONG def("rewrap_value_long_long", by_value::rewrap); def("rewrap_value_unsigned_long_long", by_value::rewrap); -#endif +# endif def("rewrap_value_float", by_value::rewrap); def("rewrap_value_double", by_value::rewrap); def("rewrap_value_long_double", by_value::rewrap); @@ -92,6 +98,14 @@ BOOST_PYTHON_MODULE(builtin_converters) // Expose this to illustrate our failings ;-). See test_builtin_converters.py def("rewrap_value_mutable_cstring", rewrap_value_mutable_cstring); + wrap_more(); +} + +#else // BOOST_PYTHON_WRAP_MORE_BUILTIN_CONVERTERS -- this part + // compiled into test_builtin_converters2.cpp + +void wrap_more() +{ def("rewrap_const_reference_bool", by_const_reference::rewrap); def("rewrap_const_reference_char", by_const_reference::rewrap); @@ -105,10 +119,10 @@ BOOST_PYTHON_MODULE(builtin_converters) def("rewrap_const_reference_unsigned_long", by_const_reference::rewrap); // using Python's macro instead of Boost's - we don't seem to get the // config right all the time. -#ifdef HAVE_LONG_LONG +# ifdef HAVE_LONG_LONG def("rewrap_const_reference_long_long", by_const_reference::rewrap); def("rewrap_const_reference_unsigned_long_long", by_const_reference::rewrap); -#endif +# endif def("rewrap_const_reference_float", by_const_reference::rewrap); def("rewrap_const_reference_double", by_const_reference::rewrap); def("rewrap_const_reference_long_double", by_const_reference::rewrap); @@ -124,3 +138,5 @@ BOOST_PYTHON_MODULE(builtin_converters) def("rewrap_reference_object", by_reference::rewrap); } +#endif // BOOST_PYTHON_WRAP_MORE_BUILTIN_CONVERTERS + diff --git a/test/test_builtin_converters2.cpp b/test/test_builtin_converters2.cpp new file mode 100644 index 00000000..37807637 --- /dev/null +++ b/test/test_builtin_converters2.cpp @@ -0,0 +1,10 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +// This file just defines the rest of the tests that MSVC6 can't +// compile unless we break the file up. It's a hack, I'll admit... +#define BOOST_PYTHON_WRAP_MORE_BUILTIN_CONVERTERS +#include "test_builtin_converters.cpp" From 5f022269b105f97b66585c745e698ccf1b6ac061 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 14 Nov 2002 02:09:43 +0000 Subject: [PATCH 0873/1042] Added News page, links back to top of docs [SVN r16229] --- doc/building.html | 2 +- doc/index.html | 10 +++-- doc/new-conversions.html | 4 +- doc/news.html | 56 +++++++++++++++++++++++++++ doc/v2/Apr2002.html | 4 +- doc/v2/CallPolicies.html | 5 ++- doc/v2/Dereferenceable.html | 4 +- doc/v2/Extractor.html | 4 +- doc/v2/HolderGenerator.html | 4 +- doc/v2/Jun2002.html | 4 +- doc/v2/Mar2002.html | 4 +- doc/v2/May2002.html | 4 +- doc/v2/ObjectWrapper.html | 5 ++- doc/v2/ResultConverter.html | 2 +- doc/v2/acknowledgments.html | 6 +-- doc/v2/args.html | 2 +- doc/v2/bibliography.html | 4 +- doc/v2/call.html | 2 +- doc/v2/call_method.html | 5 ++- doc/v2/callbacks.html | 5 ++- doc/v2/class.html | 5 ++- doc/v2/configuration.html | 6 +-- doc/v2/copy_const_reference.html | 6 +-- doc/v2/copy_non_const_reference.html | 6 +-- doc/v2/data_members.html | 6 +-- doc/v2/def.html | 6 +-- doc/v2/default_call_policies.html | 6 +-- doc/v2/definitions.html | 6 +-- doc/v2/dict.html | 2 +- doc/v2/enum.html | 5 ++- doc/v2/errors.html | 6 +-- doc/v2/exception_translator.html | 2 +- doc/v2/extract.html | 2 +- doc/v2/faq.html | 6 +-- doc/v2/feb2002.html | 6 +-- doc/v2/from_python.html | 6 +-- doc/v2/handle.html | 5 ++- doc/v2/has_back_reference.html | 6 +-- doc/v2/header.html | 6 +-- doc/v2/implicit.html | 6 +-- doc/v2/init.html | 6 +-- doc/v2/instance_holder.html | 6 +-- doc/v2/iterator.html | 6 +-- doc/v2/list.html | 2 +- doc/v2/long.html | 2 +- doc/v2/lvalue_from_pytype.html | 6 +-- doc/v2/make_function.html | 6 +-- doc/v2/manage_new_object.html | 6 +-- doc/v2/module.html | 6 +-- doc/v2/numeric.html | 2 +- doc/v2/object.html | 6 +-- doc/v2/operators.html | 5 ++- doc/v2/overloads.html | 6 +-- doc/v2/overview.html | 4 +- doc/v2/platforms.html | 6 +-- doc/v2/pointee.html | 6 +-- doc/v2/progress_reports.html | 4 +- doc/v2/ptr.html | 6 +-- doc/v2/python.html | 6 +-- doc/v2/rationale.html | 4 +- doc/v2/reference.html | 6 +-- doc/v2/reference_existing_object.html | 6 +-- doc/v2/return_by_value.html | 6 +-- doc/v2/return_internal_reference.html | 6 +-- doc/v2/return_value_policy.html | 6 +-- doc/v2/scope.html | 2 +- doc/v2/str.html | 2 +- doc/v2/to_python_converter.html | 6 +-- doc/v2/to_python_indirect.html | 6 +-- doc/v2/to_python_value.html | 6 +-- doc/v2/tuple.html | 2 +- doc/v2/type_id.html | 6 +-- doc/v2/with_custodian_and_ward.html | 6 +-- 73 files changed, 238 insertions(+), 170 deletions(-) create mode 100644 doc/news.html diff --git a/doc/building.html b/doc/building.html index 489d56a4..39b69569 100644 --- a/doc/building.html +++ b/doc/building.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Building and Testing

      diff --git a/doc/index.html b/doc/index.html index 320361b0..e9c3a10d 100644 --- a/doc/index.html +++ b/doc/index.html @@ -70,7 +70,7 @@
      Building and Testing
      -
      Reference
      +
      Reference Manual
      Configuration Information
      @@ -81,7 +81,9 @@
      Frequently Asked Questions (FAQs)
      -
      Progress Reports
      +
      News/Change Log
      + +
      LLNL Progress Reports
      Acknowledgments
      @@ -89,8 +91,8 @@

      Revised - 08 October, 2002 - + 13 November, 2002 +

      © Copyright Dave diff --git a/doc/new-conversions.html b/doc/new-conversions.html index cd8a5b19..a5fe0c73 100644 --- a/doc/new-conversions.html +++ b/doc/new-conversions.html @@ -318,7 +318,9 @@ until the result object is retrieved. Special Edition Addison-Wesley, ISBN 0-201-70073-5.


      -

      Revised 19 December 2001

      +

      Revised + 13 November, 2002 +

      © Copyright David Abrahams, 2001

      diff --git a/doc/news.html b/doc/news.html new file mode 100644 index 00000000..0fca1204 --- /dev/null +++ b/doc/news.html @@ -0,0 +1,56 @@ + + + + + + + + + Boost.Python - News/Change Log + + + + + + + + + +
      +

      +

      +
      +

      Boost.Python

      + +

      News/Change Log

      +
      +
      + +
      +
      13 November 2002
      + +
      Full Support for std::auto_ptr<> added.
      + +
      October 2002
      + +
      Ongoing updates and improvements to tutorial documentation
      + +
      10 October 2002
      + +
      Boost.Python V2 is released!
      +
      +
      + +

      Revised + + 13 November, 2002 + +

      + +

      © Copyright Dave + Abrahams 2002. All Rights Reserved.

      + + + diff --git a/doc/v2/Apr2002.html b/doc/v2/Apr2002.html index 5789b3f8..1f2853c0 100644 --- a/doc/v2/Apr2002.html +++ b/doc/v2/Apr2002.html @@ -13,7 +13,7 @@ "C++ Boost" src="../../../../c++boost.gif" border="0"> -

      Boost.Python

      +

      Boost.Python

      April 2002 Progress Report

      @@ -154,7 +154,7 @@ documentation).

      Revised - 3 May, 2002 + 13 November, 2002

      © Copyright Dave Abrahams diff --git a/doc/v2/CallPolicies.html b/doc/v2/CallPolicies.html index 9d582e7d..b1fec484 100644 --- a/doc/v2/CallPolicies.html +++ b/doc/v2/CallPolicies.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      CallPolicies Concept

      @@ -136,7 +136,8 @@

      Revised - 19 May, 2002 + 13 November, 2002 +

      © Copyright C++ Boost -

      Boost.Python

      +

      Boost.Python

      Dereferenceable Concept

      @@ -52,7 +52,7 @@ type is a model of Dereferenceable.

      Revised - 10 May, 2002 + 13 November, 2002

      © Copyright Dave diff --git a/doc/v2/Extractor.html b/doc/v2/Extractor.html index 97ef6fd4..f70b39d4 100755 --- a/doc/v2/Extractor.html +++ b/doc/v2/Extractor.html @@ -12,7 +12,7 @@

      C++ Boost

      -

      Boost.Python

      +

      Boost.Python

      Extractor Concept

      @@ -79,7 +79,7 @@ are layout-compatible with PyObject.

      Revised - 22 May, 2002 + 13 November, 2002

      © Copyright Dave diff --git a/doc/v2/HolderGenerator.html b/doc/v2/HolderGenerator.html index 1b9b8d89..281d5c4a 100755 --- a/doc/v2/HolderGenerator.html +++ b/doc/v2/HolderGenerator.html @@ -12,7 +12,7 @@

      C++ Boost

      -

      Boost.Python

      +

      Boost.Python

      HolderGenerator Concept

      @@ -57,7 +57,7 @@ type.

      Revised - 20 May, 2002 + 13 November, 2002

      © Copyright Dave diff --git a/doc/v2/Jun2002.html b/doc/v2/Jun2002.html index 7863ff27..9c396ed7 100644 --- a/doc/v2/Jun2002.html +++ b/doc/v2/Jun2002.html @@ -13,7 +13,7 @@ "C++ Boost" src="../../../../c++boost.gif" border="0"> -

      Boost.Python

      +

      Boost.Python

      June 2002 Progress Report

      @@ -217,7 +217,7 @@ you'll just have to wait till next month (hopefully the beginning).

      Revised - 19 July, 2002 + 13 November, 2002

      © Copyright Dave Abrahams diff --git a/doc/v2/Mar2002.html b/doc/v2/Mar2002.html index 0425c3e5..a8a165d8 100644 --- a/doc/v2/Mar2002.html +++ b/doc/v2/Mar2002.html @@ -13,7 +13,7 @@ "C++ Boost" src="../../../../c++boost.gif" border="0"> -

      Boost.Python

      +

      Boost.Python

      March 2002 Progress Report

      @@ -225,7 +225,7 @@ worth doing anything about it.

      Revised - 1 April, 2002 + 13 November, 2002

      © Copyright Dave Abrahams diff --git a/doc/v2/May2002.html b/doc/v2/May2002.html index d94481cb..b5eb4e4f 100644 --- a/doc/v2/May2002.html +++ b/doc/v2/May2002.html @@ -13,7 +13,7 @@ "C++ Boost" src="../../../../c++boost.gif" border="0"> -

      Boost.Python

      +

      Boost.Python

      May 2002 Progress Report

      @@ -300,7 +300,7 @@ to these issues will probably have to be formalized before long.

      Revised - 11 June, 2002 + 13 November, 2002

      © Copyright Dave Abrahams diff --git a/doc/v2/ObjectWrapper.html b/doc/v2/ObjectWrapper.html index c7d555cd..82a940e3 100644 --- a/doc/v2/ObjectWrapper.html +++ b/doc/v2/ObjectWrapper.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      ObjectWrapper and TypeWrapper Concepts

      @@ -139,7 +139,8 @@ instances of the associated Python type will be considered a match.

      Revised - 30 Sept, 2002 + 13 November, 2002 +

      © Copyright C++ Boost -

      Boost.Python

      +

      Boost.Python

      ResultConverter Concept

      diff --git a/doc/v2/acknowledgments.html b/doc/v2/acknowledgments.html index 5f149a64..38455564 100644 --- a/doc/v2/acknowledgments.html +++ b/doc/v2/acknowledgments.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Acknowledgments

      @@ -91,8 +91,8 @@

      Revised - 08 October, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/args.hpp>

      diff --git a/doc/v2/bibliography.html b/doc/v2/bibliography.html index b59320d9..7ebd477b 100644 --- a/doc/v2/bibliography.html +++ b/doc/v2/bibliography.html @@ -13,7 +13,7 @@ "C++ Boost" src="../../../../c++boost.gif" border="0"> -

      Boost.Python

      +

      Boost.Python

      Bibliography

      @@ -23,7 +23,7 @@

      Revised - 05 November, 2002 + 13 November, 2002

      © Copyright Dave Abrahams diff --git a/doc/v2/call.html b/doc/v2/call.html index e959b1ce..b5478a4b 100644 --- a/doc/v2/call.html +++ b/doc/v2/call.html @@ -13,7 +13,7 @@ "C++ Boost" src="../../../../c++boost.gif" border="0"> -

      Boost.Python

      +

      Boost.Python

      Header <call.hpp>

      diff --git a/doc/v2/call_method.html b/doc/v2/call_method.html index 59d93a09..eaa91ec9 100644 --- a/doc/v2/call_method.html +++ b/doc/v2/call_method.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <call_method.hpp>

      @@ -147,7 +147,8 @@ BOOST_PYTHON_MODULE(my_module)

      Revised - 28 Sept, 2002 + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Calling Python Functions and Methods

      @@ -240,7 +240,8 @@ void apply(PyObject* callable, X& x)

      Revised - 17 April, 2002 + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Headers <boost/python/class.hpp>, <boost/python/class_fwd.hpp>

      @@ -685,7 +685,8 @@ class_<Derived, bases<Base> >("Derived"); Revised - 29 Sept, 2002 + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Configuration

      @@ -129,8 +129,8 @@

      Revised - 04 October, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/copy_const_reference.hpp>

      @@ -135,8 +135,8 @@ BOOST_PYTHON_MODULE(my_module)

      Revised - 29 September, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/copy_non_const_reference.hpp>

      @@ -135,8 +135,8 @@ BOOST_PYTHON_MODULE(my_module)

      Revised - 29 September, 2001 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/data_members.hpp>

      @@ -147,8 +147,8 @@ BOOST_PYTHON_MODULE_INIT(data_members_example)

      - 29 September 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/def.hpp>

      @@ -184,8 +184,8 @@ BOOST_PYTHON_MODULE(def_test)

      - 03 October, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/default_call_policies.hpp>

      @@ -161,8 +161,8 @@ struct return_value_policy : Base

      Revised - 05 November, 2001 - + 13 November, 2002 +

      © Copyright Dave diff --git a/doc/v2/definitions.html b/doc/v2/definitions.html index 5268b9c5..625e9b74 100644 --- a/doc/v2/definitions.html +++ b/doc/v2/definitions.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Definitions

      @@ -88,8 +88,8 @@

      Revised - 03 October, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/dict.hpp>

      diff --git a/doc/v2/enum.html b/doc/v2/enum.html index 38d878b1..3e0c5a64 100644 --- a/doc/v2/enum.html +++ b/doc/v2/enum.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/enum.hpp>

      @@ -192,7 +192,8 @@ TypeError: bad argument type for built-in operation Revised - 03 October, 2002 + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/errors.hpp>

      @@ -275,8 +275,8 @@ same_name2(PyObject* args, PyObject* keywords)

      Revised - 29 September, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/exception_translator.hpp>

      diff --git a/doc/v2/extract.html b/doc/v2/extract.html index b49d587b..ade6c936 100644 --- a/doc/v2/extract.html +++ b/doc/v2/extract.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/extract.hpp>

      diff --git a/doc/v2/faq.html b/doc/v2/faq.html index d15f536a..398c8ea0 100644 --- a/doc/v2/faq.html +++ b/doc/v2/faq.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Frequently Asked Questions (FAQs)

      @@ -154,8 +154,8 @@ cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx

      Revised - 05 November, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      February 2002 Progress Report

      @@ -356,8 +356,8 @@

      Revised - 4 April, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/from_python.hpp>

      @@ -157,8 +157,8 @@ std::size_t length_if_string(PyObject* p)

      Revised - 05 November, 2001 - + 13 November, 2002 +

      © Copyright Dave diff --git a/doc/v2/handle.html b/doc/v2/handle.html index 2c0ffcc2..3e44aa32 100644 --- a/doc/v2/handle.html +++ b/doc/v2/handle.html @@ -27,7 +27,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/handle.hpp>

      @@ -311,7 +311,8 @@ null_ok* allow_null(T* p)

      Revised - 03 October, 2002 + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/has_back_reference.hpp>

      @@ -202,8 +202,8 @@ BOOST_PYTHON_MODULE(back_references)

      Revised - 29 September, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <{{header}}>

      @@ -279,8 +279,8 @@ namespace boost

      Revised - 05 November, 2001 - + 13 November, 2002 +

      © Copyright Dave diff --git a/doc/v2/implicit.html b/doc/v2/implicit.html index ea24c567..c830a6c9 100644 --- a/doc/v2/implicit.html +++ b/doc/v2/implicit.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/implicit.hpp>

      @@ -149,8 +149,8 @@ BOOST_PYTHON_MODULE(implicit_ext)

      Revised - 29 September, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Headers <boost/python/init.hpp>

      @@ -237,8 +237,8 @@ class_<X>("X", "This is X's docstring.",
      Revised - 1 October, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/instance_holder.hpp>

      @@ -199,8 +199,8 @@ struct pointer_holder : instance_holder

      Revised - 29 May, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/iterator.hpp>

      @@ -383,8 +383,8 @@ BOOST_PYTHON_MODULE(demo)

      Revised - 29 September, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/list.hpp>

      diff --git a/doc/v2/long.html b/doc/v2/long.html index 13079684..a9683fd3 100644 --- a/doc/v2/long.html +++ b/doc/v2/long.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/long.hpp>

      diff --git a/doc/v2/lvalue_from_pytype.html b/doc/v2/lvalue_from_pytype.html index 74b18f06..1788f284 100755 --- a/doc/v2/lvalue_from_pytype.html +++ b/doc/v2/lvalue_from_pytype.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/lvalue_from_pytype.hpp>

      @@ -285,8 +285,8 @@ BOOST_PYTHON_MODULE(noddy_cache)

      Revised - 29 September, 2001 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/make_function.hpp>

      @@ -170,8 +170,8 @@ BOOST_PYTHON_MODULE(make_function_test)

      - 29 September 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/manage_new_object.hpp>

      @@ -131,8 +131,8 @@ BOOST_PYTHON_MODULE(my_module)

      Revised - 29 September 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/module.hpp>

      @@ -99,8 +99,8 @@ RuntimeError: Unidentifiable C++ Exception

      Revised - 2 October, 2002 - + 13 November, 2002 +

      © Copyright Dave diff --git a/doc/v2/numeric.html b/doc/v2/numeric.html index 554d7611..a1d59ca9 100644 --- a/doc/v2/numeric.html +++ b/doc/v2/numeric.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/numeric.hpp>

      diff --git a/doc/v2/object.html b/doc/v2/object.html index 9d6c6b53..93b9027e 100644 --- a/doc/v2/object.html +++ b/doc/v2/object.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/object.hpp>

      @@ -919,8 +919,8 @@ object sum_items(object seq)

      Revised - 02 October, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/operators.hpp>

      @@ -876,7 +876,8 @@ BOOST_PYTHON_MODULE(demo)

      Revised - 29 Sept, 2002 + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/overloads.hpp>

      @@ -213,8 +213,8 @@ BOOST_PYTHON_MODULE(args_ext)

      Revised - 01 October, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Overview

      @@ -39,7 +39,7 @@

      Revised - 05 November, 2002 + 13 November, 2002

      © Copyright Dave Abrahams diff --git a/doc/v2/platforms.html b/doc/v2/platforms.html index 05882830..42429b2e 100644 --- a/doc/v2/platforms.html +++ b/doc/v2/platforms.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Known Working Platforms and Compilers

      @@ -121,8 +121,8 @@

      Revised - 10 October, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/pointee.hpp>

      @@ -107,8 +107,8 @@ BOOST_PYTHON_MODULE(pointee_demo)

      Revised - 03 October, 2002 - + 13 November, 2002 +

      © Copyright Dave diff --git a/doc/v2/progress_reports.html b/doc/v2/progress_reports.html index 684fb254..f5441edd 100644 --- a/doc/v2/progress_reports.html +++ b/doc/v2/progress_reports.html @@ -13,7 +13,7 @@ "C++ Boost" src="../../../../c++boost.gif" border="0"> -

      Boost.Python

      +

      Boost.Python

      Progress Reports

      @@ -35,7 +35,7 @@ design decisions and links to relevant discussions.

      Revised - 18 July, 2002 + 13 November, 2002

      © Copyright Dave Abrahams diff --git a/doc/v2/ptr.html b/doc/v2/ptr.html index 98bfd195..0633be80 100644 --- a/doc/v2/ptr.html +++ b/doc/v2/ptr.html @@ -13,7 +13,7 @@ "C++ Boost" src="../../../../c++boost.gif" border="0"> -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/ptr.hpp>

      @@ -254,8 +254,8 @@ void pass_as_arg(expensive_to_copy* x, PyObject* f)

      Revised - 29 May, 2002 - + 13 November, 2002 +

      © Copyright Dave diff --git a/doc/v2/python.html b/doc/v2/python.html index 78706681..64d0c135 100644 --- a/doc/v2/python.html +++ b/doc/v2/python.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python.hpp>

      @@ -96,8 +96,8 @@

      Revised - 08 October, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Rationale

      @@ -39,7 +39,7 @@

      Revised - 05 November, 2002 + 13 November, 2002

      © Copyright Dave Abrahams diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 8ec51d9b..55a3da34 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -26,7 +26,7 @@ -

      Boost.Python

      +

      Boost.Python

      Reference

      @@ -913,8 +913,8 @@

      Revised - 15 October, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/reference_existing_object.hpp>

      @@ -166,8 +166,8 @@ BOOST_PYTHON_MODULE(singleton)

      Revised - 29 September 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/return_by_value.hpp>

      @@ -135,8 +135,8 @@ BOOST_PYTHON_MODULE(my_module)

      Revised - 15 October, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/return_internal_reference.hpp>

      @@ -215,8 +215,8 @@ BOOST_PYTHON_MODULE(internal_refs)

      Revised - 15 February, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/return_value_policy.hpp>

      @@ -153,8 +153,8 @@ BOOST_PYTHON_MODULE(my_module)

      Revised - 15 February, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/scope.hpp>

      diff --git a/doc/v2/str.html b/doc/v2/str.html index 842dc660..79ae74f1 100644 --- a/doc/v2/str.html +++ b/doc/v2/str.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/str.hpp>

      diff --git a/doc/v2/to_python_converter.html b/doc/v2/to_python_converter.html index 757d9f0e..33e3b684 100644 --- a/doc/v2/to_python_converter.html +++ b/doc/v2/to_python_converter.html @@ -21,7 +21,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/to_python_converter.hpp>

      @@ -192,8 +192,8 @@ BOOST_PYTHON_MODULE(to_python_converter)

      Revised - 29 September, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/to_python_indirect.hpp>

      @@ -185,8 +185,8 @@ struct reference_existing_object

      Revised - 16 February, 2002 - + 13 November, 2002 +

      © Copyright Dave diff --git a/doc/v2/to_python_value.html b/doc/v2/to_python_value.html index 990cea41..76446024 100644 --- a/doc/v2/to_python_value.html +++ b/doc/v2/to_python_value.html @@ -13,7 +13,7 @@ "C++ Boost" src="../../../../c++boost.gif" border="0"> -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/to_python_value.hpp>

      @@ -92,8 +92,8 @@ PyObject* operator()(argument_type x) const;

      Revised - 15 February, 2002 - + 13 November, 2002 +

      © Copyright Dave diff --git a/doc/v2/tuple.html b/doc/v2/tuple.html index 8fb672fa..3108cc5f 100644 --- a/doc/v2/tuple.html +++ b/doc/v2/tuple.html @@ -20,7 +20,7 @@ -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/tuple.hpp>

      diff --git a/doc/v2/type_id.html b/doc/v2/type_id.html index 6407f913..62300206 100755 --- a/doc/v2/type_id.html +++ b/doc/v2/type_id.html @@ -22,7 +22,7 @@ "0"> -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/type_id.hpp>

      @@ -209,8 +209,8 @@ bool is_int(T x)

      Revised - 18 November, 2002 - + 13 November, 2002 +

      © Copyright -

      Boost.Python

      +

      Boost.Python

      Header <boost/python/with_custodian_and_ward.hpp>

      @@ -283,8 +283,8 @@ struct return_internal_reference

      Revised - 29 May, 2002 - + 13 November, 2002 +

      © Copyright Dave Abrahams 2002. All Rights Reserved. From a21727741f1487b020c483ea6c690cef6ae480a4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 14 Nov 2002 12:16:40 +0000 Subject: [PATCH 0874/1042] c1204 workaround documented [SVN r16235] --- doc/v2/faq.html | 69 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/doc/v2/faq.html b/doc/v2/faq.html index 398c8ea0..e78ce612 100644 --- a/doc/v2/faq.html +++ b/doc/v2/faq.html @@ -34,8 +34,12 @@

      How can I wrap containers which take C++ containers as arguments?
      + +
      fatal error C1204:Compiler limit:internal + structure overflow
      +

      Is return_internal reference efficient?

      @@ -150,12 +154,73 @@ void foo(std::vector<double>& array) cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx + + +

      fatal error C1204:Compiler limit:internal + structure overflow

      + +
      + Q: I get this error message when compiling a large source + file. What can I do? + +

      A: You have two choices:

      + +
        +
      1. Upgrade your compiler (preferred)
      2. + +
      3. + Break your source file up into multiple translation units. + +

        my_module.cpp:

        +
        +...
        +void more_of_my_module();
        +BOOST_PYTHON_MODULE(my_module)
        +{
        +   def("foo", foo);
        +   def("bar", bar);
        +   ...
        +   more_of_my_module();
        +}
        +
        + more_of_my_module.cpp: +
        +void more_of_my_module()
        +{
        +   def("baz", baz);
        +   ...
        +}
        +
        + If you find that a class_<...> declaration + can't fit in a single source file without triggering the error, you + can always pass a reference to the class_ object to a + function in another source file, and call some of its member + functions (e.g. .def(...)) in the auxilliary source + file: + +

        more_of_my_class.cpp: +

        +void more_of_my_class(class<my_class>& x)
        +{
        +   x
        +     .def("baz", baz)
        +     .add_property("xx", &my_class::get_xx, &my_class::set_xx)
        +     ;
        +
        +   ...
        +}
        +
        +
      4. +
      +
      +

      Revised - 13 November, 2002 - + 13 November, 2002 +

      © Copyright Date: Thu, 14 Nov 2002 17:41:13 +0000 Subject: [PATCH 0875/1042] Auto-detection of class memebers wrapped with make_getter() [SVN r16241] --- doc/news.html | 5 +++ doc/v2/data_members.html | 14 ++++++-- .../python/converter/builtin_converters.hpp | 5 +++ include/boost/python/data_members.hpp | 34 +++++++++++++++---- include/boost/python/to_python_value.hpp | 10 ++++++ test/data_members.cpp | 4 ++- test/data_members.py | 5 +++ todo.txt | 18 +++++++--- 8 files changed, 81 insertions(+), 14 deletions(-) diff --git a/doc/news.html b/doc/news.html index 0fca1204..6ae58360 100644 --- a/doc/news.html +++ b/doc/news.html @@ -29,6 +29,11 @@


      +
      14 November 2002
      + +
      Auto-detection of class data members wrapped with make_getter
      +
      13 November 2002
      Full Support for std::auto_ptr<> added.
      diff --git a/doc/v2/data_members.html b/doc/v2/data_members.html index 1bf16cd4..0f015780 100644 --- a/doc/v2/data_members.html +++ b/doc/v2/data_members.html @@ -77,7 +77,15 @@ template <class C, class D, class Policies> C*, and returns the corresponding member D member of the C object, converted to_python. If policies is supplied, it will be applied to the - function as described here. + function as described here. Otherwise, + the library attempts to determine whether D is a + user-defined class type, and if so uses return_internal_reference<> + +
      for Policies. Note that this test may inappropriately + choose return_internal_reference<> in some cases + when D is a smart pointer type. This is a known + defect.
      Returns: An instance of object which holds the new Python @@ -147,8 +155,8 @@ BOOST_PYTHON_MODULE_INIT(data_members_example)

      - 13 November, 2002 - + 13 November, 2002 +

      © Copyright # include # include -# include +# include +# include # include # include +# include # include # include +# include +# include # include namespace boost { namespace python { @@ -44,7 +48,7 @@ namespace detail static PyObject* set(Data Class::*pm, PyObject* args_, PyObject*, Policies const& policies) { // check that each of the arguments is convertible - arg_from_python c0(PyTuple_GET_ITEM(args_, 0)); + arg_from_python c0(PyTuple_GET_ITEM(args_, 0)); if (!c0.convertible()) return 0; typedef typename add_const::type target1; @@ -55,22 +59,40 @@ namespace detail if (!policies.precall(args_)) return 0; - (c0(PyTuple_GET_ITEM(args_, 0)))->*pm = c1(PyTuple_GET_ITEM(args_, 1)); + (c0(PyTuple_GET_ITEM(args_, 0))).*pm = c1(PyTuple_GET_ITEM(args_, 1)); return policies.postcall(args_, detail::none()); } }; + + // If it's a regular class type (not an object manager or other + // type for which we have to_python specializations, use + // return_internal_reference so that we can do things like + // x.y.z = 1 + // and get the right result. + template + struct default_getter_policy + : mpl::if_c< + to_python_value< + typename add_reference< + typename add_const::type + >::type + >::uses_registry + , return_internal_reference<> + , return_value_policy + > + {}; } template object make_getter(D C::*pm) { - typedef return_value_policy default_policy; + typedef typename detail::default_getter_policy::type policy; return objects::function_object( ::boost::bind( - &detail::member::get, pm, _1, _2 - , default_policy()) + &detail::member::get, pm, _1, _2 + , policy()) , 1); } diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp index 3b9cd76c..de5122a2 100644 --- a/include/boost/python/to_python_value.hpp +++ b/include/boost/python/to_python_value.hpp @@ -29,6 +29,11 @@ namespace detail static bool convertible(); PyObject* operator()(argument_type) const; + + // This information helps make_getter() decide whether to try to + // return an internal reference or not. I don't like it much, + // but it will have to serve for now. + BOOST_STATIC_CONSTANT(bool, uses_registry = false); }; @@ -41,6 +46,11 @@ namespace detail static bool convertible(); PyObject* operator()(argument_type) const; + + // This information helps make_getter() decide whether to try to + // return an internal reference or not. I don't like it much, + // but it will have to serve for now. + BOOST_STATIC_CONSTANT(bool, uses_registry = true); }; } diff --git a/test/data_members.cpp b/test/data_members.cpp index 5a87eeae..e5affba4 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -24,12 +24,13 @@ double get_fair_value(X const& x) { return x.value(); } struct Var { - Var(std::string name_) : name(name_), value(), name2(name.c_str()) {} + Var(std::string name_) : name(name_), value(), name2(name.c_str()), y(6) {} std::string const name; std::string get_name1() const { return name; } std::string const& get_name2() const { return name; } float value; char const* name2; + Y y; }; BOOST_PYTHON_MODULE(data_members_ext) @@ -51,6 +52,7 @@ BOOST_PYTHON_MODULE(data_members_ext) .def_readonly("name", &Var::name) .def_readonly("name2", &Var::name2) .def_readwrite("value", &Var::value) + .def_readonly("y", &Var::y) // Test return_by_value for plain values and for // pointers... return_by_value was implemented as a diff --git a/test/data_members.py b/test/data_members.py index c908f515..820b4f12 100644 --- a/test/data_members.py +++ b/test/data_members.py @@ -30,6 +30,11 @@ >>> v.get_name2() 'pi' +>>> v.y.x +6 +>>> v.y.x = -7 +>>> v.y.x +-7 ''' def run(args = None): diff --git a/todo.txt b/todo.txt index 3bcd16ac..6ee55157 100644 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,21 @@ -Wrap enums as a subclass of Python int +High Priority: +-------------- +Document builtin correspondences between builtiin Python types and C++ +types + + +Medium Priority: +---------------- + +Implement type_info streaming for GCC +(http://mail.python.org/pipermail/c++-sig/2002-June/001277.html) + +Low Priority: +------------ Write "inside the Python type system", a survey of typeobject.c in Python source -- may go hand-in-hand with enum wrapping Better overload resolution - choose best match -Implement type_info streaming for GCC -(http://mail.python.org/pipermail/c++-sig/2002-June/001277.html) - From bbc052bedc57f68db7dd8bb54b4647b5b99d9d26 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Nov 2002 12:25:29 +0000 Subject: [PATCH 0876/1042] Fix example [SVN r16256] --- doc/v2/extract.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/v2/extract.html b/doc/v2/extract.html index ade6c936..bec97f28 100644 --- a/doc/v2/extract.html +++ b/doc/v2/extract.html @@ -216,11 +216,11 @@ BOOST_PYTHON_MODULE(extract_ext) object x_obj = x_class(3); // Get a reference to the C++ object out of the Python object - X const& x = extract<X&>(x_obj); + X& x = extract<X&>(x_obj); assert(x.value() == 3); } -

      Revised 30 September, 2002

      +

      Revised 15 November, 2002

      © Copyright Dave Abrahams 2002. All Rights From cb1901e111095c3b09b7bf743c7484a7980623f1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Nov 2002 17:02:31 +0000 Subject: [PATCH 0877/1042] initial commit [SVN r16259] --- doc/projects.html | 107 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 doc/projects.html diff --git a/doc/projects.html b/doc/projects.html new file mode 100644 index 00000000..2d58b598 --- /dev/null +++ b/doc/projects.html @@ -0,0 +1,107 @@ + + + + + + + + + Boost.Python - Projects using Boost.Python + + + + + + + + + +
      +

      +

      +
      +

      Boost.Python

      + +

      Projects using Boost.Python

      +
      +


      + +
      +
      PythonMagick
      + +
      + PythonMagick makes it possible to access ImageMagick from Python. + +

       

      +
      + +
      OpenWBEM
      + +
      + The OpenWBEM project is an effort to develop an open-source + implementation of Web Based Enterprise Management suitable for + commercial and non-commercial application + +

      Dan Nuffer writes:

      + +
      + I'm using Boost.Python to wrap the client API of OpenWBEM.This will + make it easier to do rapid prototyping, testing, and scripting when + developing management solutions that use WBEM. +
      +
      + +
      CAMFR
      + +
      + CAMFR is a photonics and electromagnetics modelling tool. Python is + used for computational steering. + +

      Peter Bienstman + writes:

      + +
      + Thanks for providing such a great tool! +
      +
      + +
      HippoDraw - Stanford + Linear Accelerator Center
      + +
      + HippoDraw is a data analysis environment consisting of a canvas upon + which graphs such as histograms, scattter plots, etc, are prsented. + It has a highly interactive GUI interface, but some things you need + to do with scripts. HippoDraw can be run as Python extension module + so that all the manipulation can be done from either Python or the + GUI. + +

      Paul F. Kunz + writes:

      + +
      + Don't have a web page for the project, but the organization's is http://www.slac.stanford.edu + (the first web server site in America, I installed it). +
      + Which was just too cool a piece of trivia to omit. +
      +
      +
      + +

      Revised + + 13 November, 2002 + +

      + +

      © Copyright Dave + Abrahams 2002. All Rights Reserved.

      + + + From ae109f13a201cbb9a80ac2e47e2d9e85fa686f5e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Nov 2002 17:29:15 +0000 Subject: [PATCH 0878/1042] *** empty log message *** [SVN r16260] --- doc/projects.html | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/doc/projects.html b/doc/projects.html index 2d58b598..7dc8a13f 100644 --- a/doc/projects.html +++ b/doc/projects.html @@ -29,15 +29,23 @@
      +
      OpenSceneGraph
      + +
      Gideon May has created a + set of bindings for OpenSceneGraph, a cross-platform C++/OpenGL library + for the real-time visualization. You can read the release announcement + at www.hypereyes.com. Contact Gideon for more + information.
      +  
      +
      PythonMagick
      -
      - PythonMagick makes it possible to access ImageMagick from Python. - -

       

      -
      +
      PythonMagick makes it possible to access ImageMagick from Python.
      +  
      OpenWBEM
      From b3311fd59db6d2876102c8427ad70927cf626d19 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 15 Nov 2002 22:19:40 +0000 Subject: [PATCH 0879/1042] *** empty log message *** [SVN r16266] --- todo.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/todo.txt b/todo.txt index 6ee55157..0123d9bd 100644 --- a/todo.txt +++ b/todo.txt @@ -4,6 +4,8 @@ High Priority: Document builtin correspondences between builtiin Python types and C++ types +FILE* conversions: http://aspn.activestate.com/ASPN/Mail/Message/1411366 + Medium Priority: ---------------- From 0adf4477a3addd2cdd193a6ab1620ffdd4dcde80 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 00:45:26 +0000 Subject: [PATCH 0880/1042] vc7.1 workaround [SVN r16267] --- include/boost/python/converter/arg_from_python.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp index 78d00052..e552fcd5 100755 --- a/include/boost/python/converter/arg_from_python.hpp +++ b/include/boost/python/converter/arg_from_python.hpp @@ -110,7 +110,10 @@ struct arg_rvalue_from_python arg_rvalue_from_python(PyObject*); bool convertible() const; - + +# if BOOST_MSVC < 1301 || _MSC_FULL_VER > 13102196 + typename arg_rvalue_from_python:: +# endif result_type operator()(PyObject*); private: From 7ea2447246ed360ff82c0a15ef643c2280bc9f3e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 03:38:24 +0000 Subject: [PATCH 0881/1042] Bug fix [SVN r16273] --- test/auto_ptr.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/auto_ptr.cpp b/test/auto_ptr.cpp index 39c3941b..4007df9f 100644 --- a/test/auto_ptr.cpp +++ b/test/auto_ptr.cpp @@ -42,14 +42,12 @@ std::auto_ptr make() std::auto_ptr callback(object f) { std::auto_ptr x(new X(77)); -// call(f.ptr(),x); -// return std::auto_ptr(new X(77)); return call >(f.ptr(), x); } std::auto_ptr extract_(object o) { - return extract >(o); + return extract&>(o); } BOOST_PYTHON_MODULE(auto_ptr_ext) From 06fe0f1bcc3d2882a6d911b1c7649dc922abf484 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 06:00:52 +0000 Subject: [PATCH 0882/1042] is_reference_to_function implementation [SVN r16276] --- .../boost/python/detail/indirect_traits.hpp | 20 ++- .../python/detail/is_function_ref_tester.hpp | 136 ++++++++++++++++++ test/indirect_traits_test.cpp | 3 +- 3 files changed, 150 insertions(+), 9 deletions(-) create mode 100644 include/boost/python/detail/is_function_ref_tester.hpp diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index 5d1a2697..5bcc4191 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -19,6 +19,10 @@ # include # include +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# include +# endif + namespace boost { namespace python { namespace detail { # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -42,7 +46,6 @@ struct is_reference_to_const }; # endif -# if 0 // Corresponding code doesn't work on MSVC yet template struct is_reference_to_function { @@ -72,7 +75,6 @@ struct is_reference_to_function { BOOST_STATIC_CONSTANT(bool, value = is_function::value); }; -# endif template struct is_pointer_to_function @@ -231,15 +233,19 @@ struct is_class_help >::type type; }; -# if 0 // doesn't seem to work yet template -struct is_reference_to_function +struct is_reference_to_function_aux { static T t; BOOST_STATIC_CONSTANT( - bool, value - = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)); -# endif + bool, value = sizeof(is_function_ref_tester(t,0)) == sizeof(::boost::type_traits::yes_type)); + }; + +template +struct is_reference_to_function + : mpl::if_, is_reference_to_function_aux, mpl::bool_c >::type +{ +}; template struct is_pointer_to_function diff --git a/include/boost/python/detail/is_function_ref_tester.hpp b/include/boost/python/detail/is_function_ref_tester.hpp new file mode 100644 index 00000000..c9ab4818 --- /dev/null +++ b/include/boost/python/detail/is_function_ref_tester.hpp @@ -0,0 +1,136 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied warranty, +// and with no claim as to its suitability for any purpose. + +#if !defined(BOOST_PP_IS_ITERATING) + +///// header body + +#ifndef BOOST_TT_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED +#define BOOST_TT_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED + +#include "boost/type_traits/detail/yes_no_type.hpp" +#include "boost/type_traits/config.hpp" + +#if defined(BOOST_TT_PREPROCESSING_MODE) +# include "boost/preprocessor/iterate.hpp" +# include "boost/preprocessor/enum_params.hpp" +# include "boost/preprocessor/comma_if.hpp" +#endif + +namespace boost { +namespace python { +namespace detail { + +template +boost::type_traits::no_type BOOST_TT_DECL is_function_ref_tester(T& ...); + +#if !defined(BOOST_TT_PREPROCESSING_MODE) +// preprocessor-generated part, don't edit by hand! + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24), int); + +#else + +#define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, 25, "boost/type_traits/detail/is_function_ref_tester.hpp")) +#include BOOST_PP_ITERATE() + +#endif // BOOST_TT_PREPROCESSING_MODE + +} // namespace detail +} // namespace python +} // namespace boost + +#endif // BOOST_TT_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED + +///// iteration + +#else +#define i BOOST_PP_FRAME_ITERATION(1) + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(BOOST_PP_ENUM_PARAMS(i,T)), int); + +#undef i +#endif // BOOST_PP_IS_ITERATING diff --git a/test/indirect_traits_test.cpp b/test/indirect_traits_test.cpp index 7160b8eb..1f52afcd 100644 --- a/test/indirect_traits_test.cpp +++ b/test/indirect_traits_test.cpp @@ -11,10 +11,9 @@ int main() { using namespace boost::python::detail; -#if 0 // not yet supported assert(is_reference_to_function::value); assert(!is_reference_to_function::value); -#endif + assert(!is_reference_to_function::value); assert(!is_pointer_to_function::value); assert(is_pointer_to_function::value); From f2ac0145daa763f17994806dd64b966e2ef7e95b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 06:55:04 +0000 Subject: [PATCH 0883/1042] is_reference_to_function_pointer implementation [SVN r16278] --- include/boost/python/detail/def_helper.hpp | 40 +++++++++++++------ .../boost/python/detail/indirect_traits.hpp | 39 ++++++++++++++++-- test/indirect_traits_test.cpp | 12 ++++++ 3 files changed, 76 insertions(+), 15 deletions(-) diff --git a/include/boost/python/detail/def_helper.hpp b/include/boost/python/detail/def_helper.hpp index 4135af55..4c70fd8f 100644 --- a/include/boost/python/detail/def_helper.hpp +++ b/include/boost/python/detail/def_helper.hpp @@ -12,6 +12,7 @@ # include # include # include +# include # include # include # include @@ -101,29 +102,37 @@ namespace detail : tuple_extract< Tuple, mpl::logical_and< - is_reference_to_class > + mpl::logical_not > + , is_reference_to_class > , mpl::logical_not > > > > { }; + template + struct default_implementation_extract + : tuple_extract< + Tuple, + mpl::logical_or< + is_reference_to_function_pointer + , is_reference_to_function + , is_same + > + > + { + }; + # define BOOST_PYTHON_DEF_HELPER_TAIL default_call_policies, keywords<0>, char const* template struct def_helper { - typedef typename mpl::if_< - is_same - , boost::tuples::tuple - , typename mpl::if_< - is_same - , boost::tuples::tuple - , boost::tuples::tuple - >::type - >::type all_t; + typedef boost::tuples::tuple< + T1 const&, T2 const&, T3 const&, default_call_policies, keywords<0>, char const* + > all_t; - def_helper(T1 const& a1) : m_all(a1) {} - def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2) {} + def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil) {} + def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil) {} def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3) {} char const* doc() const @@ -140,8 +149,15 @@ namespace detail { return policy_extract::extract(m_all); } + + typedef + typename default_implementation_extract::result_type default_implementation() const + { + return policy_extract::extract(m_all); + } all_t m_all; + not_specified m_nil; }; # undef BOOST_PYTHON_DEF_HELPER_TAIL } diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index 5bcc4191..23d14a64 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -58,6 +58,7 @@ struct is_reference_to_function BOOST_STATIC_CONSTANT(bool, value = is_function::value); }; +# if 0 template struct is_reference_to_function { @@ -75,7 +76,7 @@ struct is_reference_to_function { BOOST_STATIC_CONSTANT(bool, value = is_function::value); }; - +# endif template struct is_pointer_to_function { @@ -89,6 +90,25 @@ struct is_pointer_to_function BOOST_STATIC_CONSTANT(bool, value = is_function::value); }; +template +struct is_reference_to_function_pointer_aux +{ + // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those + BOOST_STATIC_CONSTANT(bool, value = ( + is_reference::value + & is_pointer_to_function< + typename remove_cv< + typename remove_reference::type + >::type + >::value)); +}; + +template +struct is_reference_to_function_pointer + : mpl::if_c::value, mpl::bool_c, is_reference_to_function_pointer_aux >::type +{ +}; + template struct is_reference_to_non_const { @@ -238,7 +258,7 @@ struct is_reference_to_function_aux { static T t; BOOST_STATIC_CONSTANT( - bool, value = sizeof(is_function_ref_tester(t,0)) == sizeof(::boost::type_traits::yes_type)); + bool, value = sizeof(detail::is_function_ref_tester(t,0)) == sizeof(::boost::type_traits::yes_type)); }; template @@ -248,7 +268,7 @@ struct is_reference_to_function }; template -struct is_pointer_to_function +struct is_pointer_to_function_aux { static T t; BOOST_STATIC_CONSTANT( @@ -256,6 +276,12 @@ struct is_pointer_to_function = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)); }; +template +struct is_pointer_to_function + : mpl::if_, is_pointer_to_function_aux, mpl::bool_c >::type +{ +}; + struct false_helper1 { template @@ -368,6 +394,13 @@ struct is_reference_to_pointer ); }; +template +struct is_reference_to_function_pointer + : mpl::if_ + , is_pointer_to_function_aux, mpl::bool_c >::type +{ +}; + template typename is_class_help::type reference_to_class_helper(V const volatile&); outer_no_type reference_to_class_helper(...); diff --git a/test/indirect_traits_test.cpp b/test/indirect_traits_test.cpp index 1f52afcd..561a946a 100644 --- a/test/indirect_traits_test.cpp +++ b/test/indirect_traits_test.cpp @@ -17,11 +17,23 @@ using namespace boost::python::detail; assert(!is_pointer_to_function::value); assert(is_pointer_to_function::value); + assert(!is_pointer_to_function::value); + assert(!is_pointer_to_function::value); + assert(!is_reference_to_function_pointer::value); + assert(!is_reference_to_function_pointer::value); + assert(!is_reference_to_function_pointer::value); + assert(is_reference_to_function_pointer::value); + assert(is_reference_to_function_pointer::value); + assert(is_reference_to_pointer::value); assert(is_reference_to_pointer::value); assert(is_reference_to_pointer::value); assert(is_reference_to_pointer::value); + assert(is_reference_to_pointer::value); + assert(is_reference_to_pointer::value); + assert(is_reference_to_pointer::value); + assert(is_reference_to_pointer::value); assert(!is_reference_to_pointer::value); assert(!is_reference_to_pointer::value); From 8b7527318d4aa36106b0bbc9980d0724cc860334 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 20:01:44 +0000 Subject: [PATCH 0884/1042] vc6/7 workaround [SVN r16286] --- test/auto_ptr.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/auto_ptr.cpp b/test/auto_ptr.cpp index 4007df9f..36b4b5dc 100644 --- a/test/auto_ptr.cpp +++ b/test/auto_ptr.cpp @@ -47,7 +47,11 @@ std::auto_ptr callback(object f) std::auto_ptr extract_(object o) { - return extract&>(o); + return extract&>(o) +#if BOOST_MSVC <= 1300 + () +#endif + ; } BOOST_PYTHON_MODULE(auto_ptr_ext) From bb536a0eaa0ab22589fe61e43989d141fe497e87 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 20:03:59 +0000 Subject: [PATCH 0885/1042] One more step towards handling polymorphism: now we can sort out a 4th parameter [SVN r16287] --- include/boost/python/detail/def_helper.hpp | 28 +++++++++++-------- .../boost/python/detail/indirect_traits.hpp | 4 +++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/include/boost/python/detail/def_helper.hpp b/include/boost/python/detail/def_helper.hpp index 4c70fd8f..106f3677 100644 --- a/include/boost/python/detail/def_helper.hpp +++ b/include/boost/python/detail/def_helper.hpp @@ -65,7 +65,7 @@ namespace detail struct tuple_extract_base_select { typedef typename Tuple::head_type head_type; - typedef typename mpl::apply1::type match_t; + typedef typename mpl::apply1::type>::type match_t; BOOST_STATIC_CONSTANT(bool, match = match_t::value); typedef typename tuple_extract_impl::template apply type; }; @@ -85,7 +85,7 @@ namespace detail Tuple, mpl::logical_not< is_reference_to_class< - add_reference + mpl::_1 > > > { @@ -93,7 +93,7 @@ namespace detail template struct keyword_extract - : tuple_extract > > + : tuple_extract > { }; @@ -103,8 +103,8 @@ namespace detail Tuple, mpl::logical_and< mpl::logical_not > - , is_reference_to_class > - , mpl::logical_not > > + , is_reference_to_class + , mpl::logical_not > > > { @@ -115,20 +115,18 @@ namespace detail : tuple_extract< Tuple, mpl::logical_or< - is_reference_to_function_pointer - , is_reference_to_function - , is_same + is_reference_to_function_pointer + , is_reference_to_function > > { }; -# define BOOST_PYTHON_DEF_HELPER_TAIL default_call_policies, keywords<0>, char const* template struct def_helper { typedef boost::tuples::tuple< - T1 const&, T2 const&, T3 const&, default_call_policies, keywords<0>, char const* + T1 const&, T2 const&, T3 const&, default_call_policies, keywords<0>, char const*, void(*)() > all_t; def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil) {} @@ -150,8 +148,14 @@ namespace detail return policy_extract::extract(m_all); } - typedef - typename default_implementation_extract::result_type default_implementation() const + private: + typedef typename default_implementation_extract::result_type default_implementation_t; + public: + BOOST_STATIC_CONSTANT( + bool, has_default_implementation = ( + !is_same::value)); + + default_implementation_t default_implementation() const { return policy_extract::extract(m_all); } diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index 23d14a64..cd4ad666 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -101,6 +101,7 @@ struct is_reference_to_function_pointer_aux typename remove_reference::type >::type >::value)); + typedef mpl::bool_c type; }; template @@ -274,12 +275,14 @@ struct is_pointer_to_function_aux BOOST_STATIC_CONSTANT( bool, value = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)); + typedef mpl::bool_c type; }; template struct is_pointer_to_function : mpl::if_, is_pointer_to_function_aux, mpl::bool_c >::type { + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_function,(T)) }; struct false_helper1 @@ -399,6 +402,7 @@ struct is_reference_to_function_pointer : mpl::if_ , is_pointer_to_function_aux, mpl::bool_c >::type { + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) }; template From 50ecc751d1b46b6344c9c9c128570a58b6f5c0d3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 20:39:56 +0000 Subject: [PATCH 0886/1042] Added Fortress entry [SVN r16288] --- doc/projects.html | 53 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/doc/projects.html b/doc/projects.html index 7dc8a13f..47cd3a21 100644 --- a/doc/projects.html +++ b/doc/projects.html @@ -28,7 +28,42 @@
      +

      Introduction

      + +

      + + This is a partial list of projects using Boost.Python. If you are + using Boost.Python as your Python/C++ binding solution, we'd be + proud to list your project on this page. Just post a short description of + your project and how Boost.Python helps you get the job done, and we'll add it to .


      +
      +
      TSLib - Fortress Investment Group LLC
      + +
      + Fortress Investment Group has contracted Boost Consulting to + develop core internal financial analysis tools in C++ and to + prepare Python bindings for them using Boost.Python. + +

      Tom Barket writes:

      + +
      + We have a large C++ analytical library specialized for research in + finance and economics, built for speed and mission critical + stability. Yet Python offers us the flexibility to test out new + ideas quickly and increase the productivity of our time versus + working in C++. There are several key features which make Python + stand out. Its elegance, stability, and breadth of resources on the + web are all valuable, but the most important is its extensibility, + due to its open source transparency. Boost.Python makes Python + extensibility extremely simple and straightforward, yet preserves a + great deal of power and control. +
      +
      +
      OpenSceneGraph
      @@ -43,9 +78,9 @@
      PythonMagick
      -
      PythonMagick makes it possible to access ImageMagick from Python.
      -  
      +
      PythonMagick binds the ImageMagick image manipulation + library to Python.
       
      OpenWBEM
      @@ -57,10 +92,10 @@

      Dan Nuffer writes:

      - I'm using Boost.Python to wrap the client API of OpenWBEM.This will + I'm using Boost.Python to wrap the client API of OpenWBEM.This will make it easier to do rapid prototyping, testing, and scripting when developing management solutions that use WBEM. -
      +
      CAMFR
      @@ -73,8 +108,8 @@ writes:

      - Thanks for providing such a great tool! -
      + Thanks for providing such a great tool! +
      HippoDraw - Stanford @@ -92,11 +127,11 @@ writes:

      - Don't have a web page for the project, but the organization's is Don't have a web page for the project, but the organization's is http://www.slac.stanford.edu (the first web server site in America, I installed it). -
      +
      Which was just too cool a piece of trivia to omit. From 61b7094dbd1abfb374ff7c9532cccc9a97bfad44 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 20:48:43 +0000 Subject: [PATCH 0887/1042] Added EMSolve entry [SVN r16289] --- doc/projects.html | 65 ++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/doc/projects.html b/doc/projects.html index 47cd3a21..5d1db847 100644 --- a/doc/projects.html +++ b/doc/projects.html @@ -30,29 +30,29 @@

      Introduction

      -

      - - This is a partial list of projects using Boost.Python. If you are - using Boost.Python as your Python/C++ binding solution, we'd be - proud to list your project on this page. Just post a short description of - your project and how Boost.Python helps you get the job done, and we'll add it to .


      +

      This is a partial list of projects using Boost.Python. If you are + using Boost.Python as your Python/C++ binding solution, we'd be proud to + list your project on this page. Just post a short description of your project + and how Boost.Python helps you get the job done, and we'll add it to + .

      +
      -
      TSLib - Fortress Investment Group LLC
      +
      TSLib - Fortress + Investment Group LLC
      Fortress Investment Group has contracted Boost Consulting to - develop core internal financial analysis tools in C++ and to - prepare Python bindings for them using Boost.Python. + "http://www.boost-consulting.com">Boost Consulting to develop + core internal financial analysis tools in C++ and to prepare Python + bindings for them using Boost.Python.

      Tom Barket writes:

      - We have a large C++ analytical library specialized for research in - finance and economics, built for speed and mission critical + We have a large C++ analytical library specialized for research + in finance and economics, built for speed and mission critical stability. Yet Python offers us the flexibility to test out new ideas quickly and increase the productivity of our time versus working in C++. There are several key features which make Python @@ -60,10 +60,16 @@ web are all valuable, but the most important is its extensibility, due to its open source transparency. Boost.Python makes Python extensibility extremely simple and straightforward, yet preserves a - great deal of power and control. -
      + great deal of power and control. +
      +
      EMSolve
      + +
      EMSolve is a provably stable, charge conserving, and energy + conserving solver for Maxwell's equations.
      +  
      +
      OpenSceneGraph
      @@ -79,8 +85,9 @@ "http://pythonmagick.procoders.net/">PythonMagick
      PythonMagick binds the ImageMagick image manipulation - library to Python.
       
      + "http://www.imagemagick.org">ImageMagick image manipulation library + to Python.
      +  
      OpenWBEM
      @@ -92,10 +99,10 @@

      Dan Nuffer writes:

      - I'm using Boost.Python to wrap the client API of OpenWBEM.This will - make it easier to do rapid prototyping, testing, and scripting when - developing management solutions that use WBEM. -
      + I'm using Boost.Python to wrap the client API of OpenWBEM.This + will make it easier to do rapid prototyping, testing, and scripting + when developing management solutions that use WBEM. +
      CAMFR
      @@ -108,8 +115,8 @@ writes:

      - Thanks for providing such a great tool! -
      + Thanks for providing such a great tool! +
      HippoDraw - Stanford @@ -127,11 +134,11 @@ writes:

      - Don't have a web page for the project, but the organization's is Don't have a web page for the project, but the organization's is + http://www.slac.stanford.edu - (the first web server site in America, I installed it). -
      + (the first web server site in America, I installed it).
      + Which was just too cool a piece of trivia to omit. @@ -139,7 +146,7 @@

      Revised - 13 November, 2002 + 16 November, 2002

      From 9e3589ec4dcbca606abcca155ef67240c38946d0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 20:50:21 +0000 Subject: [PATCH 0888/1042] Added projects page link [SVN r16290] --- doc/index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/index.html b/doc/index.html index e9c3a10d..afd5ddae 100644 --- a/doc/index.html +++ b/doc/index.html @@ -79,6 +79,8 @@
      Definitions
      +
      Projects using Boost.Python
      +
      Frequently Asked Questions (FAQs)
      News/Change Log
      @@ -91,7 +93,7 @@

      Revised - 13 November, 2002 + 16 November, 2002

      From ae2931ba1b154881b373093822ea60eebac8fe2e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 22:12:46 +0000 Subject: [PATCH 0889/1042] initial commit [SVN r16292] --- doc/polymorphism.txt | 142 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 doc/polymorphism.txt diff --git a/doc/polymorphism.txt b/doc/polymorphism.txt new file mode 100644 index 00000000..3041a2c7 --- /dev/null +++ b/doc/polymorphism.txt @@ -0,0 +1,142 @@ +How Runtime Polymorphism is expressed in Boost.Python: +----------------------------------------------------- + + struct A { virtual std::string f(); virtual ~A(); }; + + std::string call_f(A& x) { return x.f(); } + + struct B { virtual std::string f() { return "B"; } }; + + struct Bcb : B + { + virtual std::string f() { return "B"; } + static std::string f_default(B& b) { return b.B::f(); } + }; + + struct C : B + { + virtual std::string f() { return "C"; } + }; + + >>> class D(B): + ... def f(): + ... return 'D' + ... + >>> class E(B): pass + ... + + +When we write, "invokes B::f non-virtually", we mean: + + void g(B& x) { x.B::f(); } + +This will call B::f() regardless of the dynamic type of x. Any other +way of invoking B::f, including through a function pointer, is a +"virtual invocation", and will call the most-derived override of f(). + +Case studies + + C++\Python class + \___A_____B_____C_____D____E___ + | + A | 1 + | + B | 2 3 + | + Bcb | 4 5 6 + | + C | 7 8 + | + + +1. Simple case + +2. Python A holds a B*. Probably won't happen once we have forced + downcasting. + + Requires: + x.f() -> 'B' + call_f(x) -> 'B' + + Implies: A.f invokes A::f() (virtually or otherwise) + +3. Python B holds a B*. + + Requires: + x.f() -> 'B' + call_f(x) -> 'B' + + Implies: B.f invokes B::f (virtually or otherwise) + + +4. B constructed from Python + + Requires: + + x.f() -> 'B' + call_f(x) -> 'B' + + Implies: B.f invokes B::f non-virtually. Bcb::f invokes B::f + non-virtually. + + Question: Does it help if we arrange for Python B construction to + build a true B object? Then this case doesn't arise. + + +5. D is a Python class derived from B + + Requires: + + x.f() -> 'D' + call_f(x) -> 'D' + + Implies: Bcb::f must invoke call_method to look up the Python + method override, otherwise call_f wouldn't work. + +6. E is like D, but doesn't override f + + Requires: + + x.f() -> 'B' + call_f(x) -> 'B' + + Implies: B.f invokes B::f non-virtually. If it were virtual, x.f() + would cause infinite recursion, because we've already + determined that Bcb::f must invoke call_method to look up + the Python method override. + +7. Python B object holds a C* + + Requires: + + x.f() -> 'C' + call_f(x) -> 'C' + + Implies: B.f invokes B::f virtually. + +8. C object constructed from Python + + Requires: + + x.f() -> 'C' + call_f(x) -> 'C' + + Implies: nothing new + +------ + +Total implications: + +2: A.f invokes A::f() (virtually or otherwise) +3: B.f invokes B::f (virtually or otherwise) +7: B.f invokes B::f virtually. +6: B.f invokes B::f non-virtually. +4: B.f invokes B::f non-virtually. Bcb::f invokes B::f non-virtually + +5: Bcb::f invokes call_method to look up the Python method + +Though (4) is avoidable, clearly 6 and 7 are not, and they +conflict. The implication is that B.f must choose its behavior +according to the type of the contained C++ object. If it is Bcb, a +non-virtual call to B::f must occur. Otherwise, a virtual call to B::f +must occur. From 56c5227cf7434f96c51d89d10fc61bddd4d69635 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 22:28:28 +0000 Subject: [PATCH 0890/1042] added note [SVN r16293] --- doc/polymorphism.txt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/doc/polymorphism.txt b/doc/polymorphism.txt index 3041a2c7..f407f296 100644 --- a/doc/polymorphism.txt +++ b/doc/polymorphism.txt @@ -129,9 +129,9 @@ Total implications: 2: A.f invokes A::f() (virtually or otherwise) 3: B.f invokes B::f (virtually or otherwise) -7: B.f invokes B::f virtually. -6: B.f invokes B::f non-virtually. 4: B.f invokes B::f non-virtually. Bcb::f invokes B::f non-virtually +6: B.f invokes B::f non-virtually. +7: B.f invokes B::f virtually. 5: Bcb::f invokes call_method to look up the Python method @@ -139,4 +139,13 @@ Though (4) is avoidable, clearly 6 and 7 are not, and they conflict. The implication is that B.f must choose its behavior according to the type of the contained C++ object. If it is Bcb, a non-virtual call to B::f must occur. Otherwise, a virtual call to B::f -must occur. +must occur. This is essentially the same scheme we had with +Boost.Python v1. + +Note: in early versions of Boost.Python v1, we solved this problem by +introducing a new Python class in the hierarchy, so that D and E +actually derive from a B', and B'.f invokes B::f non-virtually, while +B.f invokes B::f virtually. However, people complained about the +artificial class in the hierarchy, which was revealed when they tried +to do normal kinds of Python introspection. + From b321b6d9db8a6df958a90f4cff33dded8f209e8e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 22:45:46 +0000 Subject: [PATCH 0891/1042] Tweaks, pseudocode [SVN r16294] --- doc/polymorphism.txt | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/doc/polymorphism.txt b/doc/polymorphism.txt index f407f296..05afe517 100644 --- a/doc/polymorphism.txt +++ b/doc/polymorphism.txt @@ -9,8 +9,12 @@ How Runtime Polymorphism is expressed in Boost.Python: struct Bcb : B { - virtual std::string f() { return "B"; } + Bcb(PyObject* self) : m_self(self) {} + + virtual std::string f() { return call_method(m_sef, "f"); } static std::string f_default(B& b) { return b.B::f(); } + + PyObject* m_self; }; struct C : B @@ -149,3 +153,22 @@ B.f invokes B::f virtually. However, people complained about the artificial class in the hierarchy, which was revealed when they tried to do normal kinds of Python introspection. +------- + +Assumption: we will have a function which builds a virtual function +dispatch callable Python object. + + make_virtual_function(pvmf, default_impl, call_policies, dispatch_type) + +Pseudocode: + + Get first argument from Python arg tuple + if it contains /only/ dispatch_type + call default_impl + else + call through pvmf + + + + + From 57f54952c3bcb6f71232c25068e75fa1729ea7be Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 16 Nov 2002 23:22:30 +0000 Subject: [PATCH 0892/1042] Bug fix thanks to Mark Russell [SVN r16295] --- doc/v2/lvalue_from_pytype.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/v2/lvalue_from_pytype.html b/doc/v2/lvalue_from_pytype.html index 1788f284..91679b64 100755 --- a/doc/v2/lvalue_from_pytype.html +++ b/doc/v2/lvalue_from_pytype.html @@ -238,8 +238,8 @@ static MemberType& execute(InstanceType& c);

      C++ module definition

      -#include <boost/python/reference.hpp>
       #include <boost/python/module.hpp>
      +#include <boost/python/lvalue_from_pytype.hpp>
       
       // definition lifted from the Python docs
       typedef struct {
      @@ -247,7 +247,7 @@ typedef struct {
       } noddy_NoddyObject;
       
       using namespace boost::python;
      -static reference<PyObject> cache;
      +static handle<> cache;
       
       bool is_cached(noddy_NoddyObject* x)
       {
      @@ -256,7 +256,7 @@ bool is_cached(noddy_NoddyObject* x)
       
       void set_cache(noddy_NoddyObject* x)
       {
      -   cache.reset((PyObject*)x, ref::increment_count);
      +   cache = handle<>(borrowed(x));
       }
       
       BOOST_PYTHON_MODULE(noddy_cache)
      
      From 4f7af97f8c4011657eb3fbf1509ad104088aedcf Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Sat, 16 Nov 2002 23:23:45 +0000
      Subject: [PATCH 0893/1042] Bug fix thanks to Mark Russell
       
      
      [SVN r16296]
      ---
       doc/v2/lvalue_from_pytype.html | 2 ++
       1 file changed, 2 insertions(+)
      
      diff --git a/doc/v2/lvalue_from_pytype.html b/doc/v2/lvalue_from_pytype.html
      index 91679b64..a2020a46 100755
      --- a/doc/v2/lvalue_from_pytype.html
      +++ b/doc/v2/lvalue_from_pytype.html
      @@ -239,6 +239,8 @@ static MemberType& execute(InstanceType& c);
           

      C++ module definition

       #include <boost/python/module.hpp>
      +#include <boost/python/handle.hpp>
      +#include <boost/python/borrowed.hpp>
       #include <boost/python/lvalue_from_pytype.hpp>
       
       // definition lifted from the Python docs
      
      From c2af21169d4f2cb3b2c3efa92931a92110843775 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Sat, 16 Nov 2002 23:48:09 +0000
      Subject: [PATCH 0894/1042] More notes
      
      [SVN r16297]
      ---
       doc/polymorphism.txt | 18 ++++++++++++++++--
       1 file changed, 16 insertions(+), 2 deletions(-)
      
      diff --git a/doc/polymorphism.txt b/doc/polymorphism.txt
      index 05afe517..95fe67cc 100644
      --- a/doc/polymorphism.txt
      +++ b/doc/polymorphism.txt
      @@ -125,7 +125,7 @@ Case studies
               x.f() -> 'C'
               call_f(x) -> 'C'
       
      -   Implies: nothing new
      +   Implies: nothing new.
       
       ------
       
      @@ -163,12 +163,26 @@ dispatch callable Python object.
       Pseudocode:
       
            Get first argument from Python arg tuple
      -     if it contains /only/ dispatch_type
      +     if it contains dispatch_type
               call default_impl
            else
               call through pvmf
       
       
      +Open questions:
       
      +   1. What about Python multiple inheritance? Do we have the right
      +      check in the if clause above?
      +      
      +      A: Not quite. The correct test looks like:
      +
      +      Deduce target type of pvmf, i.e. T in R(T::*)(A1...AN).
      +      Find holder in first argument which holds T
      +      if it holds dispatch_type...
      +      
      +   2. Can we make this more efficient?
            
      +     The current "returning" mechanism will look up a holder for T
      +     again. I don't know if we know how to avoid that.
      +
       
      
      From e6b40f54cd01f18cfd049a01977f82fff57e7844 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Sun, 17 Nov 2002 05:58:45 +0000
      Subject: [PATCH 0895/1042] initial commit
      
      [SVN r16298]
      ---
       doc/support.html | 68 ++++++++++++++++++++++++++++++++++++++++++++++++
       1 file changed, 68 insertions(+)
       create mode 100644 doc/support.html
      
      diff --git a/doc/support.html b/doc/support.html
      new file mode 100644
      index 00000000..1f0e932c
      --- /dev/null
      +++ b/doc/support.html
      @@ -0,0 +1,68 @@
      +
      +
      +
      +  
      +    
      +    
      +    
      +
      +    Boost.Python - Support Resources
      +  
      +
      +  
      +    
      +      
      +        
      +
      +        
      +      
      +    
      +

      +

      +
      +

      Boost.Python

      + +

      Support Resources

      +
      +
      + +

      Synopsis

      + +

      This is a list of available resources for support with Boost.Python + problems and feature requests.

      +
      + +
      +
      Boost + Consulting - Commercial support, development, training, and + distribution for all the Boost libraries, from the people who brought + you Boost.Python.
      +  
      + +
      The Python + C++-sig mailing list is a forum for discussing Python/C++ + interoperability, and Boost.Python in particular.
      +  
      + +
      The Boost.Python Wiki + Pages established by Mike Rovner as part of the PythonInfo Wiki serves as + a forum to gather peoples' experience and as a cookbook.
      +  
      +
      +
      + +

      Revised + + 17 November, 2002 + +

      + +

      © Copyright Dave + Abrahams 2002. All Rights Reserved.

      + + + From e660cc50c6d6153d211b19455ae048295dcfcee5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 17 Nov 2002 05:59:12 +0000 Subject: [PATCH 0896/1042] Added Support link [SVN r16299] --- doc/index.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/index.html b/doc/index.html index afd5ddae..599a8ca6 100644 --- a/doc/index.html +++ b/doc/index.html @@ -81,6 +81,8 @@
      Projects using Boost.Python
      +
      Support Resources
      +
      Frequently Asked Questions (FAQs)
      News/Change Log
      @@ -93,8 +95,8 @@

      Revised - 16 November, 2002 - + 17 November, 2002 +

      © Copyright Dave From 6e0733afa2b7be7b84f749187172e7aa2c99a466 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 19 Nov 2002 01:33:07 +0000 Subject: [PATCH 0897/1042] Remove Tom's email address [SVN r16315] --- doc/projects.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/projects.html b/doc/projects.html index 5d1db847..4beee700 100644 --- a/doc/projects.html +++ b/doc/projects.html @@ -48,7 +48,7 @@ core internal financial analysis tools in C++ and to prepare Python bindings for them using Boost.Python. -

      Tom Barket writes:

      +

      Tom Barket of Fortress writes:

      We have a large C++ analytical library specialized for research From 72d5bac69fb553676007e0c49f473b3f9b4e00c2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 19 Nov 2002 16:56:55 +0000 Subject: [PATCH 0898/1042] Add PSF copyright and change summary [SVN r16327] --- include/boost/python/detail/python22_fixed.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/python22_fixed.h b/include/boost/python/detail/python22_fixed.h index 3caff6dd..74ba44e4 100644 --- a/include/boost/python/detail/python22_fixed.h +++ b/include/boost/python/detail/python22_fixed.h @@ -1,4 +1,14 @@ -// Copy of Python 2.2/2.2.1 Python.h . +// This file is a modified version of Python 2.2/2.2.1 Python.h. As +// such it is: +// +// Copyright (c) 2001, 2002 Python Software Foundation; All Rights +// Reserved +// +// Changes from the original: +// 1. #includes for Python 2.2.1 +// 2. Provides missing extern "C" wrapper for "iterobject.h" and "descrobject.h". +// + // Changes marked with "Boost.Python modification" #ifndef Py_PYTHON_H #define Py_PYTHON_H From c9af6ca94b3cf69c7c48045384e0133570c7a710 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 19 Nov 2002 17:39:17 +0000 Subject: [PATCH 0899/1042] Add missing copyright notices [SVN r16329] --- include/boost/python/detail/api_placeholder.hpp | 5 +++++ include/boost/python/dict.hpp | 5 +++++ include/boost/python/str.hpp | 5 +++++ include/boost/python/tuple.hpp | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/include/boost/python/detail/api_placeholder.hpp b/include/boost/python/detail/api_placeholder.hpp index 9a4672ab..38a0d029 100644 --- a/include/boost/python/detail/api_placeholder.hpp +++ b/include/boost/python/detail/api_placeholder.hpp @@ -1,3 +1,8 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. #ifndef BOOST_PYTHON_API_PLACE_HOLDER_HPP #define BOOST_PYTHON_API_PLACE_HOLDER_HPP diff --git a/include/boost/python/dict.hpp b/include/boost/python/dict.hpp index 6bda6e2c..c1565bcc 100644 --- a/include/boost/python/dict.hpp +++ b/include/boost/python/dict.hpp @@ -1,3 +1,8 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. #ifndef DICT_20020706_HPP #define DICT_20020706_HPP diff --git a/include/boost/python/str.hpp b/include/boost/python/str.hpp index d283fe8a..2ebae5e7 100644 --- a/include/boost/python/str.hpp +++ b/include/boost/python/str.hpp @@ -1,3 +1,8 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. #ifndef STR_20020703_HPP #define STR_20020703_HPP diff --git a/include/boost/python/tuple.hpp b/include/boost/python/tuple.hpp index af5bbf8a..8e3cb210 100644 --- a/include/boost/python/tuple.hpp +++ b/include/boost/python/tuple.hpp @@ -1,3 +1,8 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. #ifndef TUPLE_20020706_HPP #define TUPLE_20020706_HPP From 71ea2bec86a00ab4dbc91bd3224a27a67f33e884 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 19 Nov 2002 17:39:40 +0000 Subject: [PATCH 0900/1042] more notes [SVN r16330] --- doc/polymorphism.txt | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/doc/polymorphism.txt b/doc/polymorphism.txt index 95fe67cc..c6f89416 100644 --- a/doc/polymorphism.txt +++ b/doc/polymorphism.txt @@ -179,10 +179,39 @@ Open questions: Deduce target type of pvmf, i.e. T in R(T::*)(A1...AN). Find holder in first argument which holds T if it holds dispatch_type... - + 2. Can we make this more efficient? The current "returning" mechanism will look up a holder for T again. I don't know if we know how to avoid that. + OK, the solution involves reworking the call mechanism. This is + neccesary anyway in order to enable wrapping of function objects. + + It can result in a reduction in the overall amount of source code, + because returning<> won't need to be specialized for every + combination of function and member function... though it will still + need a void specialization. We will still need a way to dispatch to + member functions through a regular function interface. mem_fn is + almost the right tool, but it only goes up to 8 + arguments. Forwarding is tricky if you don't want to incur copies. + I think the trick is to use arg_from_python::result_type for each + argument to the forwarder. + + Another option would be to use separate function, function object, + and member function dispatchers. Once you know you have a member + function, you don't need cv-qualified overloads to call it. + + Hmm, while we're at this, maybe we should solve the write-back + converter problem. Can we do it? Maybe not. Ralf doesn't want to + write special write-back functions here, does he? He wants the + converter to do the work automatically. We could add + cleanup/destructor registration. That would relieve the client from + having accessible destructors for types which are being converted by + rvalue. I'm not sure that this will really save any code, + however. It rather depends on the linker, doesn't it? I wonder if + this can be done in a backwards-compatible fashion by generating the + delete function when it's not supplied? + + From 39eab7229372478872a23330a3f149792ef75e13 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Nov 2002 01:14:16 +0000 Subject: [PATCH 0901/1042] bugfixes add_property now uses member_function_cast [SVN r16335] --- include/boost/python/class.hpp | 24 +++++++-- include/boost/python/detail/def_helper.hpp | 2 +- .../boost/python/detail/indirect_traits.hpp | 49 ++++++------------- test/data_members.cpp | 15 ++++-- test/data_members.py | 4 ++ 5 files changed, 50 insertions(+), 44 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index af4ce1fd..26ca5bfd 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -273,19 +273,33 @@ class class_ : public objects::class_base // Property creation template - self& add_property(char const* name, Get const& fget) + self& add_property(char const* name, Get fget) { - base::add_property(name, object(fget)); + base::add_property( + name + , object( + detail::member_function_cast::stage1(fget).stage2((T*)0).stage3(fget) + ) + ); + return *this; } template - self& add_property(char const* name, Get const& fget, Set const& fset) + self& add_property(char const* name, Get fget, Set fset) { - base::add_property(name, object(fget), object(fset)); + base::add_property( + name + , object( + detail::member_function_cast::stage1(fget).stage2((T*)0).stage3(fget) + ) + , object( + detail::member_function_cast::stage1(fset).stage2((T*)0).stage3(fset) + ) + ); return *this; } - + template self& setattr(char const* name, U const& x) { diff --git a/include/boost/python/detail/def_helper.hpp b/include/boost/python/detail/def_helper.hpp index 106f3677..78a1649f 100644 --- a/include/boost/python/detail/def_helper.hpp +++ b/include/boost/python/detail/def_helper.hpp @@ -65,7 +65,7 @@ namespace detail struct tuple_extract_base_select { typedef typename Tuple::head_type head_type; - typedef typename mpl::apply1::type>::type match_t; + typedef typename mpl::apply1::type>::type match_t; BOOST_STATIC_CONSTANT(bool, match = match_t::value); typedef typename tuple_extract_impl::template apply type; }; diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index cd4ad666..ee361adf 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -47,47 +47,26 @@ struct is_reference_to_const # endif template -struct is_reference_to_function +struct is_reference_to_function : mpl::bool_c +{ +}; + +template +struct is_reference_to_function : is_function +{ +}; + +template +struct is_pointer_to_function : mpl::bool_c { BOOST_STATIC_CONSTANT(bool, value = false); }; +// There's no such thing as a pointer-to-cv-function, so we don't need +// specializations for those template -struct is_reference_to_function +struct is_pointer_to_function : is_function { - BOOST_STATIC_CONSTANT(bool, value = is_function::value); -}; - -# if 0 -template -struct is_reference_to_function -{ - BOOST_STATIC_CONSTANT(bool, value = is_function::value); -}; - -template -struct is_reference_to_function -{ - BOOST_STATIC_CONSTANT(bool, value = is_function::value); -}; - -template -struct is_reference_to_function -{ - BOOST_STATIC_CONSTANT(bool, value = is_function::value); -}; -# endif -template -struct is_pointer_to_function -{ - BOOST_STATIC_CONSTANT(bool, value = false); -}; - -template -struct is_pointer_to_function -{ - // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those - BOOST_STATIC_CONSTANT(bool, value = is_function::value); }; template diff --git a/test/data_members.cpp b/test/data_members.cpp index e5affba4..889ea9d1 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -22,11 +22,18 @@ typedef test_class<1> Y; double get_fair_value(X const& x) { return x.value(); } -struct Var + +struct VarBase { - Var(std::string name_) : name(name_), value(), name2(name.c_str()), y(6) {} + VarBase(std::string name_) : name(name_) {} + std::string const name; std::string get_name1() const { return name; } +}; + +struct Var : VarBase +{ + Var(std::string name_) : VarBase(name_), value(), name2(name.c_str()), y(6) {} std::string const& get_name2() const { return name; } float value; char const* name2; @@ -39,7 +46,7 @@ BOOST_PYTHON_MODULE(data_members_ext) .def("value", &X::value) .def("set", &X::set) .def_readonly("x", &X::x) - .add_property("fair_value", &get_fair_value) + .add_property("fair_value", get_fair_value) ; class_("Y", init()) @@ -60,6 +67,8 @@ BOOST_PYTHON_MODULE(data_members_ext) // sense to add the test here. .def("get_name1", &Var::get_name1, return_value_policy()) .def("get_name2", &Var::get_name2, return_value_policy()) + + .add_property("name3", &Var::get_name1) ; } diff --git a/test/data_members.py b/test/data_members.py index 820b4f12..989c3c32 100644 --- a/test/data_members.py +++ b/test/data_members.py @@ -35,6 +35,10 @@ >>> v.y.x = -7 >>> v.y.x -7 + +>>> v.name3 +'pi' + ''' def run(args = None): From 409ff3c1796cac979f287fa216f6435eb06fa2a3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Nov 2002 03:04:51 +0000 Subject: [PATCH 0902/1042] Added missing test [SVN r16337] --- test/as_to_python_function.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 test/as_to_python_function.cpp diff --git a/test/as_to_python_function.cpp b/test/as_to_python_function.cpp new file mode 100644 index 00000000..814749d1 --- /dev/null +++ b/test/as_to_python_function.cpp @@ -0,0 +1,14 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +#include + +struct hopefully_illegal +{ + static PyObject* convert(int&); +}; + +PyObject* x = boost::python::converter::as_to_python_function::convert(0); From ed2da9bedb41290f125dd51df6a4f94768f62e2e Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 20 Nov 2002 18:01:44 +0000 Subject: [PATCH 0903/1042] list cctbx [SVN r16348] --- doc/projects.html | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/doc/projects.html b/doc/projects.html index 4beee700..fadf59ae 100644 --- a/doc/projects.html +++ b/doc/projects.html @@ -141,6 +141,30 @@
      Which was just too cool a piece of trivia to omit. + +
      cctbx - Computational Crystallography Toolbox
      +
      + Computational Crystallography is concerned with the derivation + of atomic models of crystal structures, given experimental + X-ray diffraction data. The cctbx is an open-source library of + fundamental algorithms for crystallographic computations. The + core algorithms are implemented in C++ and accessed through + higher-level Python interfaces. The cctbx grew together + with Boost.Python and is designed from the ground up as + a hybrid Python/C++ system. With one minor exception, + run-time polymorphism is completely handled by Python. C++ + compile-time polymorphism is used to implement performance + critical algorithms. The Python and C++ layers are seamlessly + integrated using Boost.Python. + + The SourceForge cctbx project is organized in modules to + facilitate use in non-crystallographic applications. + The scitbx module implements a general purpose + array family for scientific applications and pure C++ + ports of FFTPACK and the LBFGS conjugate gradient + minimizer. +

      From 983b23db92b8be90dacd751805386138802b144d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 20 Nov 2002 18:09:17 +0000 Subject: [PATCH 0904/1042] some missing html markup added [SVN r16349] --- doc/projects.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/projects.html b/doc/projects.html index fadf59ae..9d1484bb 100644 --- a/doc/projects.html +++ b/doc/projects.html @@ -139,8 +139,8 @@ "http://www.slac.stanford.edu">http://www.slac.stanford.edu (the first web server site in America, I installed it).
      - Which was just too cool a piece of trivia to omit. - + Which was just too cool a piece of trivia to omit.
      +  
      cctbx - Computational Crystallography Toolbox
      @@ -157,7 +157,7 @@ compile-time polymorphism is used to implement performance critical algorithms. The Python and C++ layers are seamlessly integrated using Boost.Python. - +

      The SourceForge cctbx project is organized in modules to facilitate use in non-crystallographic applications. The scitbx module implements a general purpose From c30e12f9561d6d71f8ac7440bc1cb53f47454209 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Nov 2002 22:58:57 +0000 Subject: [PATCH 0905/1042] Make scope constructor explicit [SVN r16350] --- doc/v2/scope.html | 4 ++-- include/boost/python/scope.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/v2/scope.html b/doc/v2/scope.html index 0dab0a70..20a29063 100644 --- a/doc/v2/scope.html +++ b/doc/v2/scope.html @@ -85,7 +85,7 @@ namespace boost { namespace python "../../../utility/utility.htm#Class noncopyable">noncopyable { public: - scope(object const&); + explicit scope(object const&); scope(); ~scope() }; @@ -95,7 +95,7 @@ namespace boost { namespace python

      Class scope constructors and destructor

      -scope(object const& x);
      +explicit scope(object const& x);
       
      Stores a reference to the current associated scope object, and sets the associated scope object to the one referred to by x.ptr(). diff --git a/include/boost/python/scope.hpp b/include/boost/python/scope.hpp index 7262f8da..086c7d87 100644 --- a/include/boost/python/scope.hpp +++ b/include/boost/python/scope.hpp @@ -16,7 +16,7 @@ class BOOST_PYTHON_DECL scope : public object, private noncopyable { public: - inline scope(object const&); + explicit inline scope(object const&); inline scope(); inline ~scope(); From e3deb8275da4417161198fd7acc095875a30d718 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 20 Nov 2002 23:07:32 +0000 Subject: [PATCH 0906/1042] update [SVN r16351] --- doc/news.html | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/news.html b/doc/news.html index 6ae58360..1b02a9a9 100644 --- a/doc/news.html +++ b/doc/news.html @@ -29,6 +29,12 @@
      +
      19 November 2002
      + +
      Removed the need for users to cast base class member + function pointers when used as arguments to add_property
      +
      14 November 2002
      Auto-detection of class data members wrapped with Date: Thu, 21 Nov 2002 00:19:27 +0000 Subject: [PATCH 0907/1042] Bugfix [SVN r16353] --- doc/v2/lvalue_from_pytype.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/v2/lvalue_from_pytype.html b/doc/v2/lvalue_from_pytype.html index a2020a46..4bcd4c4c 100755 --- a/doc/v2/lvalue_from_pytype.html +++ b/doc/v2/lvalue_from_pytype.html @@ -249,7 +249,7 @@ typedef struct { } noddy_NoddyObject; using namespace boost::python; -static handle<> cache; +static handle<noddy_NoddyObject> cache; bool is_cached(noddy_NoddyObject* x) { @@ -287,7 +287,7 @@ BOOST_PYTHON_MODULE(noddy_cache)

      Revised - 13 November, 2002 + 20 November, 2002

      From 75bd427b8e196a3d9d7a899a0771e9f7218d3fe4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 21 Nov 2002 00:21:23 +0000 Subject: [PATCH 0908/1042] Bugfix [SVN r16354] --- doc/v2/lvalue_from_pytype.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/lvalue_from_pytype.html b/doc/v2/lvalue_from_pytype.html index 4bcd4c4c..9ccccd7a 100755 --- a/doc/v2/lvalue_from_pytype.html +++ b/doc/v2/lvalue_from_pytype.html @@ -258,7 +258,7 @@ bool is_cached(noddy_NoddyObject* x) void set_cache(noddy_NoddyObject* x) { - cache = handle<>(borrowed(x)); + cache = handle<noddy_NoddyObject>(borrowed(x)); } BOOST_PYTHON_MODULE(noddy_cache) From 60924e82e21921be1a3d9cca70d247c621d6b903 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 23 Nov 2002 02:59:45 +0000 Subject: [PATCH 0909/1042] On our way to polymorphism [SVN r16374] --- include/boost/python/arg_from_python.hpp | 32 +++++++ .../python/converter/arg_from_python.hpp | 4 +- include/boost/python/detail/defaults_gen.hpp | 2 +- include/boost/python/signature.hpp | 85 +++++++------------ 4 files changed, 68 insertions(+), 55 deletions(-) diff --git a/include/boost/python/arg_from_python.hpp b/include/boost/python/arg_from_python.hpp index 1d033acd..b30c70eb 100755 --- a/include/boost/python/arg_from_python.hpp +++ b/include/boost/python/arg_from_python.hpp @@ -7,6 +7,7 @@ # define ARG_FROM_PYTHON_DWA2002128_HPP # include +# include namespace boost { namespace python { @@ -38,6 +39,37 @@ struct arg_from_python PyObject*const& operator()(PyObject*const& source) const { return source; } }; +namespace detail +{ + // + // Meta-iterators for use with caller<> + // + + // temporary hack + template struct nullary : T + { + nullary(PyObject* x) : T(x), m_p(x) {} + typename T::result_type operator()() { return this->T::operator()(m_p); } + PyObject* m_p; + }; + + // An MPL metafunction class which returns arg_from_python + struct gen_arg_from_python + { + template struct apply + { + typedef nullary > type; + }; + }; + + // An MPL iterator over an endless sequence of gen_arg_from_python + struct args_from_python + { + typedef gen_arg_from_python type; + typedef args_from_python next; + }; +} + // // implementations // diff --git a/include/boost/python/converter/arg_from_python.hpp b/include/boost/python/converter/arg_from_python.hpp index e552fcd5..b835e633 100755 --- a/include/boost/python/converter/arg_from_python.hpp +++ b/include/boost/python/converter/arg_from_python.hpp @@ -159,11 +159,11 @@ struct select_arg_from_python = boost::python::detail::is_reference_to_pointer::value && boost::python::detail::is_reference_to_const::value && !boost::python::detail::is_reference_to_volatile::value); - + BOOST_STATIC_CONSTANT( bool, ref = - boost::python::detail::is_reference_to_non_const::value + boost::python::detail::is_reference_to_non_const::value || boost::python::detail::is_reference_to_volatile::value); BOOST_STATIC_CONSTANT( diff --git a/include/boost/python/detail/defaults_gen.hpp b/include/boost/python/detail/defaults_gen.hpp index 4c4bf217..00c42167 100644 --- a/include/boost/python/detail/defaults_gen.hpp +++ b/include/boost/python/detail/defaults_gen.hpp @@ -162,7 +162,7 @@ namespace detail #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) \ + ClassT obj BOOST_PP_COMMA_IF(index) \ BOOST_PP_ENUM_BINARY_PARAMS_Z(1, index, T, arg) \ ) \ { \ diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index e4545ea8..fd613940 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -26,13 +26,9 @@ # include # include -# define BOOST_PYTHON_FUNCTION_SIGNATURE_LIST(n) \ +# define BOOST_PYTHON_LIST_INC(n) \ BOOST_PP_CAT(mpl::list, BOOST_PP_INC(n)) -# define BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(n) \ - BOOST_PP_CAT(mpl::list, BOOST_PP_INC(BOOST_PP_INC(n))) - - /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace python { namespace detail { @@ -47,18 +43,13 @@ namespace boost { namespace python { namespace detail { // return mpl::list(); // } // -// template -// inline mpl::list -// get_signature(RT(ClassT::*)(T0...TN))) -// { -// return mpl::list(); -// } +// And, for an appropriate assortment of cv-qualifications // // template -// inline mpl::list -// get_signature(RT(ClassT::*)(T0...TN) const)) +// inline mpl::list +// get_signature(RT(ClassT::*)(T0...TN) cv)) // { -// return mpl::list(); +// return mpl::list(); // } // // These functions extract the return type, class (for member functions) @@ -68,7 +59,7 @@ namespace boost { namespace python { namespace detail { /////////////////////////////////////////////////////////////////////////////// # define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, BOOST_PYTHON_MAX_ARITY-1, )) + (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() @@ -77,59 +68,49 @@ namespace boost { namespace python { namespace detail { }} // namespace boost::python -# undef BOOST_PYTHON_FUNCTION_SIGNATURE_LIST -# undef BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST +# undef BOOST_PYTHON_LIST_INC /////////////////////////////////////////////////////////////////////////////// # endif // SIGNATURE_JDG20020813_HPP -#else // defined(BOOST_PP_IS_ITERATING) +#elif BOOST_PP_ITERATION_DEPTH() == 1 // defined(BOOST_PP_IS_ITERATING) # define N BOOST_PP_ITERATION() -# define BOOST_PYTHON_SIGNATURE_PARAMS BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T) -# define BOOST_PYTHON_SIGNATURE_TYPES BOOST_PP_ENUM_PARAMS_Z(1, N, T) -# define BOOST_PYTHON_TRAILING_SIGNATURE_TYPES BOOST_PP_COMMA_IF(N) BOOST_PYTHON_SIGNATURE_TYPES - template < - class RT BOOST_PYTHON_SIGNATURE_PARAMS> -inline BOOST_PYTHON_FUNCTION_SIGNATURE_LIST(N)< - RT BOOST_PYTHON_TRAILING_SIGNATURE_TYPES> -get_signature(RT(*)(BOOST_PYTHON_SIGNATURE_TYPES)) + class RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> +inline BOOST_PYTHON_LIST_INC(N)< + RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> +get_signature(RT(*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T))) { - return BOOST_PYTHON_FUNCTION_SIGNATURE_LIST(N)< - RT BOOST_PYTHON_TRAILING_SIGNATURE_TYPES + return BOOST_PYTHON_LIST_INC(N)< + RT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) >(); } -/////////////////////////////////////////////////////////////////////////////// -#if N <= (BOOST_PYTHON_MAX_ARITY - 2) +# undef N + +# define BOOST_PP_ITERATION_PARAMS_2 \ + (3, (0, BOOST_PYTHON_CV_COUNT - 1, )) +# include BOOST_PP_ITERATE() + +#else + +# define N BOOST_PP_RELATIVE_ITERATION(1) +# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_ITERATION()) template < - class RT, class ClassT BOOST_PYTHON_SIGNATURE_PARAMS> -inline BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< - RT, ClassT BOOST_PYTHON_TRAILING_SIGNATURE_TYPES > -get_signature(RT(ClassT::*)(BOOST_PYTHON_SIGNATURE_TYPES)) + class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> +inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< + RT, ClassT Q& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> +get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q) { - return BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< - RT, ClassT BOOST_PYTHON_TRAILING_SIGNATURE_TYPES>(); + return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< + RT, ClassT Q & BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) + >(); } -/////////////////////////////////////// -template < - class RT, class ClassT BOOST_PYTHON_SIGNATURE_PARAMS> -inline BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< - RT, ClassT const BOOST_PYTHON_TRAILING_SIGNATURE_TYPES> -get_signature(RT(ClassT::*)(BOOST_PYTHON_SIGNATURE_TYPES) const) -{ - return BOOST_PYTHON_MEMBER_FUNCTION_SIGNATURE_LIST(N)< - RT, ClassT const BOOST_PYTHON_TRAILING_SIGNATURE_TYPES>(); -} - -#endif // N < (BOOST_PYTHON_MAX_ARITY - 2) - -# undef BOOST_PYTHON_SIGNATURE_PARAMS -# undef BOOST_PYTHON_SIGNATURE_TYPES -# undef BOOST_PYTHON_TRAILING_SIGNATURE_TYPES +# undef Q +# undef N #endif // !defined(BOOST_PP_IS_ITERATING) From f6f4e594735cccf6cf5dcfe318f3ca7ab5c1ebcb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 23 Nov 2002 20:03:24 +0000 Subject: [PATCH 0910/1042] Add notes about targeting Cygwin GCC [SVN r16380] --- doc/building.html | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/doc/building.html b/doc/building.html index 39b69569..941bfdcd 100644 --- a/doc/building.html +++ b/doc/building.html @@ -41,6 +41,8 @@
      Results
      +
      Notes for Cygwin GCC Users
      +
      Testing
      @@ -171,6 +173,27 @@ +

      Notes for Cygwin GCC Users

      + +

      If you are using Cygwin GCC to build extension modules, you + must use a Cygwin build of Python. The regular Win32 Python + installation that you can download from python.org will not work with + your compiler because the dynamic linking conventions are + different (you can use MinGW + GCC if you want to build extension modules which are compatible + with a stock Win32 Python). The Cygwin installer may be able to + install an appropriate version of Python, or you can follow the + traditional Unix + installation process to build Python from source. + +

      The special build configuration variables listed above as + "Cygwin only" make it possible to use a regular Win32 + build of bjam to build and test Boost.Python and Boost.Python + extensions using Cygwin GCC and targeting a Cygwin build of Python. + +

      Results

      The build process will create a From 791b7e1a1b121b4f3977781cf477cb758d1296db Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 23 Nov 2002 20:03:49 +0000 Subject: [PATCH 0911/1042] Tidy [SVN r16381] --- doc/building.html | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/doc/building.html b/doc/building.html index 941bfdcd..000aeb3e 100644 --- a/doc/building.html +++ b/doc/building.html @@ -175,24 +175,21 @@

      Notes for Cygwin GCC Users

      -

      If you are using Cygwin GCC to build extension modules, you - must use a Cygwin build of Python. The regular Win32 Python - installation that you can download from python.org will not work with - your compiler because the dynamic linking conventions are - different (you can use MinGW - GCC if you want to build extension modules which are compatible - with a stock Win32 Python). The Cygwin installer may be able to - install an appropriate version of Python, or you can follow the - traditional Unix - installation process to build Python from source. +

      If you are using Cygwin GCC to build extension modules, you must use a + Cygwin build of Python. The regular Win32 Python installation that you + can download from python.org will not + work with your compiler because the dynamic linking conventions are + different (you can use MinGW GCC if + you want to build extension modules which are compatible with a stock + Win32 Python). The Cygwin installer may be able to install an appropriate + version of Python, or you can follow the traditional Unix installation + process to build Python from source.

      -

      The special build configuration variables listed above as - "Cygwin only" make it possible to use a regular Win32 - build of bjam to build and test Boost.Python and Boost.Python - extensions using Cygwin GCC and targeting a Cygwin build of Python. - +

      The special build configuration variables listed above as "Cygwin + only" make it possible to use a regular Win32 build of bjam to build and + test Boost.Python and Boost.Python extensions using Cygwin GCC and + targeting a Cygwin build of Python.

      Results

      From 2df120af7287a78b6088631fd618f5752ef694a4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 23 Nov 2002 22:16:00 +0000 Subject: [PATCH 0912/1042] Suppress a VC6 ICE [SVN r16383] --- include/boost/python/exception_translator.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/boost/python/exception_translator.hpp b/include/boost/python/exception_translator.hpp index 830d50d2..c7581780 100644 --- a/include/boost/python/exception_translator.hpp +++ b/include/boost/python/exception_translator.hpp @@ -5,10 +5,11 @@ // to its suitability for any purpose. #ifndef EXCEPTION_TRANSLATOR_DWA2002810_HPP # define EXCEPTION_TRANSLATOR_DWA2002810_HPP + +# include +# include # include # include -# include -# include namespace boost { namespace python { From 0461d25de6648d9c1a58d9196be0c4d0b6fb3e19 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 23 Nov 2002 22:16:55 +0000 Subject: [PATCH 0913/1042] Add some qualification [SVN r16384] --- include/boost/python/detail/defaults_def.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index db807a08..efb1c395 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -54,7 +54,7 @@ namespace detail objects::add_to_namespace( name_space, name, - make_keyword_range_function( + detail::make_keyword_range_function( // This bit of nastiness casts F to a member function of T if possible. member_function_cast::stage1(f).stage2((wrapped_type*)0).stage3(f) , policies, kw) From 4c630512fe44cf7e213ee49d8736c642f7df4f09 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 23 Nov 2002 22:18:23 +0000 Subject: [PATCH 0914/1042] Add missing add_const #include [SVN r16385] --- include/boost/python/detail/translate_exception.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/translate_exception.hpp b/include/boost/python/detail/translate_exception.hpp index aa617a2a..62f931a5 100644 --- a/include/boost/python/detail/translate_exception.hpp +++ b/include/boost/python/detail/translate_exception.hpp @@ -7,8 +7,11 @@ # define TRANSLATE_EXCEPTION_DWA2002810_HPP # include -# include + # include +# include + +# include namespace boost { namespace python { namespace detail { From b952e450362026c750dc9bb70d61c5110fd149ff Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 23 Nov 2002 22:30:48 +0000 Subject: [PATCH 0915/1042] Clip unneeded bind.hpp #include [SVN r16386] --- src/object/class.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index 201499e2..ad659cd5 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include From 05ce65d9d260bab02022627871067684a3571227 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 23 Nov 2002 22:31:13 +0000 Subject: [PATCH 0916/1042] cleanup [SVN r16387] --- test/callbacks.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/callbacks.cpp b/test/callbacks.cpp index 036c532a..1cfe2914 100644 --- a/test/callbacks.cpp +++ b/test/callbacks.cpp @@ -5,7 +5,6 @@ // to its suitability for any purpose. #include #include -//#include #include #include #include From e14e4e156ce79fd62003977874fbd7ea00ccee9f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Nov 2002 02:43:24 +0000 Subject: [PATCH 0917/1042] New function invocation mechanism. This is the major groundwork for handling virtual functions with default implementations properly [SVN r16388] --- include/boost/python/class.hpp | 8 +- .../boost/python/converter/registrations.hpp | 15 +- .../boost/python/detail/arg_tuple_size.hpp | 1 + include/boost/python/detail/caller.hpp | 229 ++++++++++++------ include/boost/python/detail/invoke.hpp | 130 ++++++++++ .../python/detail/make_keyword_range_fn.hpp | 46 ++-- .../python/detail/this_arg_from_python.hpp | 122 ++++++++++ include/boost/python/make_function.hpp | 130 ++++++---- .../boost/python/object/function_handle.hpp | 19 +- src/converter/arg_to_python_base.cpp | 34 ++- src/converter/registry.cpp | 2 +- test/m1.cpp | 5 + test/newtest.py | 11 + 13 files changed, 563 insertions(+), 189 deletions(-) create mode 100644 include/boost/python/detail/invoke.hpp create mode 100644 include/boost/python/detail/this_arg_from_python.hpp diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 26ca5bfd..10d11c1b 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -107,12 +107,8 @@ namespace detail }; } -// -// class_ -// -// This is the primary mechanism through which users will expose -// C++ classes to Python. The three template arguments are: -// +// This is the primary mechanism through which users will expose +// C++ classes to Python. template < class T // class being wrapped , class X1 // = detail::not_specified diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp index af2dd510..8bbe1621 100644 --- a/include/boost/python/converter/registrations.hpp +++ b/include/boost/python/converter/registrations.hpp @@ -27,10 +27,15 @@ struct rvalue_from_python_chain rvalue_from_python_chain* next; }; -struct registration +struct BOOST_PYTHON_DECL registration { + public: // member functions explicit registration(type_info); + // Convert the appropriately-typed data to Python + PyObject* to_python(void const volatile*) const; + + public: // data members. So sue me. const python::type_info target_type; // The chain of eligible from_python converters when an lvalue is required @@ -39,11 +44,11 @@ struct registration // The chain of eligible from_python converters when an rvalue is acceptable rvalue_from_python_chain* rvalue_chain; - // The unique to_python converter for the associated C++ type. - to_python_function_t to_python; - // The class object associated with this type PyTypeObject* class_object; + + // The unique to_python converter for the associated C++ type. + to_python_function_t m_to_python; }; // @@ -53,7 +58,7 @@ inline registration::registration(type_info target_type) : target_type(target_type) , lvalue_chain(0) , rvalue_chain(0) - , to_python(0) + , m_to_python(0) , class_object(0) {} diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp index 88900702..cad72c39 100644 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ b/include/boost/python/detail/arg_tuple_size.hpp @@ -1,3 +1,4 @@ +#error obsolete #if !defined(BOOST_PP_IS_ITERATING) // (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index 9d390dbd..808f95f5 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -1,106 +1,175 @@ #if !defined(BOOST_PP_IS_ITERATING) -// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// The author gratefully acknowleges the support of Dragon Systems, Inc., in -// producing this work. -// -// This file generated for 10-argument member functions and 11-argument free -// functions by gen_caller.python +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. -# ifndef CALLER_DWA20011214_HPP -# define CALLER_DWA20011214_HPP +# ifndef CALLER_DWA20021121_HPP +# define CALLER_DWA20021121_HPP + +# include + +# include +# include +# include +# include -# include -# include # include - -# include -# include - -# include # include -# include +# include # include +# include +# include +# include +# include -namespace boost { namespace python +# include + +namespace boost { namespace python { namespace detail { + +// This "result converter" is really just used as +// a dispatch tag to invoke(...), selecting the appropriate +// implementation +typedef int void_result_to_python; + +// A metafunction taking an iterator FunctionIter to a metafunction +// class and an iterator ArgIter to an argument, which applies the +// result of dereferencing FunctionIter to the result of dereferencing +// ArgIter +template +struct apply_iter1 + : mpl::apply1 {}; + +// Given a model of CallPolicies and a C++ result type, this +// metafunction selects the appropriate converter to use for +// converting the result to python. +template +struct select_result_converter + : mpl::if_< + is_same + , void_result_to_python + , typename mpl::apply1::type* + > { - template struct to_python; -}} - -namespace boost { namespace python { namespace detail { - -struct caller -{ - typedef PyObject* result_type; - - // function pointers -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) -# include BOOST_PP_ITERATE() - - // pointers-to-members -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, 3, , BOOST_PYTHON_POINTER_TO_MEMBER)) -# include BOOST_PP_ITERATE() - }; + +template struct caller_gen; + +# define BOOST_PYTHON_NEXT(init,name,n) \ + typedef BOOST_PP_IF(n,typename BOOST_PP_CAT(name,BOOST_PP_DEC(n)) ::next, init) name##n; + +# define BOOST_PYTHON_ARG_CONVERTER(n) \ + BOOST_PYTHON_NEXT(typename first::next, arg_iter,n) \ + BOOST_PYTHON_NEXT(ConverterGenerators, conv_iter,n) \ + typedef typename apply_iter1::type c_t##n; \ + c_t##n c##n(PyTuple_GET_ITEM(args_, n)); \ + if (!c##n.convertible()) \ + return 0; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY + 1, )) +# include BOOST_PP_ITERATE() + +# undef BOOST_PYTHON_ARG_CONVERTER +# undef BOOST_PYTHON_NEXT + +// A metafunction returning the base class used for caller. +template +struct caller_base_select +{ + enum { n_arguments = mpl::size::value - 1 }; + typedef typename caller_gen::template impl type; +}; + +// A function object type which wraps C++ objects as Python callable +// objects. +// +// Template Arguments: +// +// F - +// the C++ `function object' that will be called. Might +// actually be any data for which an appropriate invoke_tag() can +// be generated. invoke(...) takes care of the actual invocation syntax. +// +// ConverterGenerators - +// An MPL iterator type over a sequence of metafunction classes +// that can be applied to element 1...N of Sig to produce +// argument from_python converters for the arguments +// +// CallPolicies - +// The precall, postcall, and what kind of resultconverter to +// generate for mpl::front::type +// +// Sig - +// The `intended signature' of the function. An MPL sequence +// beginning with a result type and continuing with a list of +// argument types. +template +struct caller + : caller_base_select::type +{ + typedef typename caller_base_select< + F,ConverterGenerators,CallPolicies,Sig + >::type base; + + typedef PyObject* result_type; + + caller(F f, CallPolicies p) : base(f,p) {} +}; + + }}} // namespace boost::python::detail -# endif // CALLER_DWA20011214_HPP +# endif // CALLER_DWA20021121_HPP -/* ---------- function pointers --------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER -# line BOOST_PP_LINE(__LINE__, detail/caller.hpp(function pointers)) +#else # define N BOOST_PP_ITERATION() -template < - class P, class R - BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) - > -PyObject* operator()( - R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) - , PyObject* args - , PyObject* keywords - , P const& policies) const +template <> +struct caller_gen { - return returning::call(pf, args, keywords, &policies); -} + template + struct impl + { + impl(F f, Policies p) : m_data(f,p) {} -# undef N + PyObject* operator()(PyObject* args_, PyObject*) // eliminate + // this + // trailing + // keyword dict + { + typedef typename mpl::begin::type first; + typedef typename first::type result_t; + typedef typename select_result_converter::type result_converter; +# if N +# define BOOST_PP_LOCAL_MACRO(i) BOOST_PYTHON_ARG_CONVERTER(i) +# define BOOST_PP_LOCAL_LIMITS (0, N-1) +# include BOOST_PP_LOCAL_ITERATE() +# endif + // all converters have been checked. Now we can do the + // precall part of the policy + if (!m_data.second().precall(args_)) + return 0; -/* ---------- pointers-to-members ---------- */ -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER -// outer over cv-qualifiers + typedef typename detail::invoke_tag::type tag; -# define BOOST_PP_ITERATION_PARAMS_2 (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() + PyObject* result = detail::invoke( + tag(), result_converter(), m_data.first() BOOST_PP_ENUM_TRAILING_PARAMS(N, c)); + + return m_data.second().postcall(args_, result); + } + private: + compressed_pair m_data; + }; +}; -#elif BOOST_PP_ITERATION_DEPTH() == 2 -// inner over arities -#define N BOOST_PP_ITERATION() -#define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) -template < - class P, class R, class T - BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class A) - > -PyObject* operator()( - R (T::*pmf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q - , PyObject* args, PyObject* keywords - , P const& policies - ) const -{ - return returning::call(pmf, args, keywords, &policies); -} +#endif // BOOST_PP_IS_ITERATING -#undef N -#undef Q -#endif diff --git a/include/boost/python/detail/invoke.hpp b/include/boost/python/detail/invoke.hpp new file mode 100644 index 00000000..4f59f44c --- /dev/null +++ b/include/boost/python/detail/invoke.hpp @@ -0,0 +1,130 @@ +#if !defined(BOOST_PP_IS_ITERATING) + +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +# ifndef INVOKE_DWA20021122_HPP +# define INVOKE_DWA20021122_HPP + +# include +# include +# include +# include + +# include + +# include +# include +# include +# include +# include +# include + +// This file declares a series of overloaded invoke(...) functions, +// used to invoke wrapped C++ function (object)s from Python. Each one +// accepts: +// +// - a tag which identifies the invocation syntax (e.g. member +// functions must be invoked with a different syntax from regular +// functions) +// +// - a pointer to a result converter type, used solely as a way of +// transmitting the type of the result converter to the function (or +// an int, if the return type is void). +// +// - the "function", which may be a function object, a function or +// member function pointer, or a defaulted_virtual_fn. +// +// - The arg_from_python converters for each of the arguments to be +// passed to the function being invoked. + +namespace boost { namespace python { namespace detail { + +// This "result converter" is really just used as a dispatch tag to +// invoke(...), selecting the appropriate implementation +typedef int void_result_to_python; + +// Trait forward declaration. +template struct is_defaulted_virtual_fn; + +// Tag types describing invocation methods +struct fn_tag {}; +struct mem_fn_tag {}; +struct virtual_fn_tag {}; + +// A metafunction returning the appropriate tag type for invoking an +// object of type T. +template +struct invoke_tag + : mpl::if_< + is_member_function_pointer + , mem_fn_tag + , typename mpl::if_< + is_defaulted_virtual_fn + , virtual_fn_tag + , fn_tag + >::type + > +{}; + +# define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, BOOST_PYTHON_MAX_ARITY, )) +# include BOOST_PP_ITERATE() + +}}} // namespace boost::python::detail + +# endif // INVOKE_DWA20021122_HPP +#else + +# define N BOOST_PP_ITERATION() + +template +inline PyObject* invoke(fn_tag, RC*, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) +{ + return RC()(f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) )); +} + +template +inline PyObject* invoke(fn_tag, void_result_to_python, F& f BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) +{ + f( BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT) ); + return none(); +} + +template +inline PyObject* invoke(mem_fn_tag, RC*, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) +{ + return RC()( (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) ); +} + +template +inline PyObject* invoke(mem_fn_tag, void_result_to_python, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) +{ + (tc().*f)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)); + return none(); +} + +template +inline PyObject* invoke(virtual_fn_tag, RC*, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) +{ + return RC()( + tc.use_default() + ? f.default_impl(tc() BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) + : (tc().*f.dispatch)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) ); +} + +template +inline PyObject* invoke(virtual_fn_tag, void_result_to_python, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) +{ + if (tc.use_default()) + f.default_impl(tc() BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, ac,()BOOST_PP_INTERCEPT)); + else + (tc().*f.dispatch)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac,()BOOST_PP_INTERCEPT)); + return none(); +} + +# undef N + +#endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/make_keyword_range_fn.hpp b/include/boost/python/detail/make_keyword_range_fn.hpp index e807f158..b7d78fdd 100644 --- a/include/boost/python/detail/make_keyword_range_fn.hpp +++ b/include/boost/python/detail/make_keyword_range_fn.hpp @@ -6,38 +6,48 @@ #ifndef MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP # define MAKE_KEYWORD_RANGE_FN_DWA2002927_HPP +# include # include -# include -# include + # include +# include + + namespace boost { namespace python { namespace detail { +// Think of this as a version of make_function without a compile-time +// check that the size of kw is no greater than the expected arity of +// F. This version is needed when defining functions with default +// arguments, because compile-time information about the number of +// keywords is missing for all but the initial function definition. template object make_keyword_range_function(F f, Policies const& policies, keyword_range const& kw) { - enum { n_arguments = detail::arg_tuple_size::value }; - return objects::function_object( - ::boost::bind(detail::caller(), f, _1, _2, policies) - , n_arguments - , kw); + return detail::make_function_aux( + f, policies, args_from_python(), detail::get_signature(f), kw, mpl::int_c<0>()); } -template +// Builds an '__init__' function which inserts the given Holder type +// in a wrapped C++ class instance. ArgList is an MPL type sequence +// describing the C++ argument types to be passed to Holder's +// constructor. +// +// Holder and ArgList are intended to be explicitly specified. +template object make_keyword_range_constructor( - Policies const& policies - , detail::keyword_range const& kw - , HolderGenerator* = 0 + CallPolicies const& policies // The CallPolicies with which to invoke the Holder's constructor + , detail::keyword_range const& kw // The (possibly empty) set of associated argument keywords + , Holder* = 0 , ArgList* = 0) { - enum { nargs = mpl::size::value }; + BOOST_STATIC_CONSTANT(unsigned, arity = mpl::size::value); - return objects::function_object( - ::boost::bind(detail::caller(), - objects::make_holder - ::template apply::execute - , _1, _2, policies) - , nargs + 1, kw); + return detail::make_keyword_range_function( + objects::make_holder + ::template apply::execute + , policies + , kw); } }}} // namespace boost::python::detail diff --git a/include/boost/python/detail/this_arg_from_python.hpp b/include/boost/python/detail/this_arg_from_python.hpp new file mode 100644 index 00000000..aa8c6c7b --- /dev/null +++ b/include/boost/python/detail/this_arg_from_python.hpp @@ -0,0 +1,122 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef THIS_ARG_FROM_PYTHON_DWA20021122_HPP +# define THIS_ARG_FROM_PYTHON_DWA20021122_HPP + +# include + +# include + +# include + +namespace boost { namespace python { namespace detail { + + template + struct this_ptr_arg_from_python : converter::arg_lvalue_from_python_base + { + this_ptr_arg_from_python(PyObject* x) + : converter::arg_lvalue_from_python_base( + converter::get_lvalue_from_python(x, converter::registered::converters)) + {} + + typedef T* result_type; + T* operator()() const + { + return static_cast(this->result()); + } + + bool use_default() const + { + return dynamic_cast((*this)()); + } + }; + + template + struct this_ref_arg_from_python : this_ptr_arg_from_python + { + typedef this_ptr_arg_from_python base; + this_ref_arg_from_python(PyObject* x) : base(x) {} + typedef T& result_type; + + result_type operator()() const + { + return *this->base::operator()(); + } + }; + + // An MPL metafunction class which returns a `this' converter + // appropriate for ArgType, where the target of the member function is + // a class of type T. + template + struct gen_this_from_python + { + // Note: there will almost always be an compile-time error if the + // argument type is neither a reference nor a pointer, since T* + // will be extracted in that case and passed on to the wrapped + // function. + template struct apply + { + BOOST_STATIC_CONSTANT( + bool, use_ptr + = is_pointer::value + || boost::python::detail::is_reference_to_pointer::value + && boost::python::detail::is_reference_to_const::value + && !boost::python::detail::is_reference_to_volatile::value); + + typedef typename mpl::if_c< + use_ptr + , this_ptr_arg_from_python + , this_ref_arg_from_python + >::type type; + }; + }; + + // An MPL iterator which iterates over a sequence whose first element + // is gen_this_from_python and the remainder of which is an endless + // sequence of gen_arg_from_python + template + struct method_args_from_python + { + typedef gen_this_from_python type; + typedef args_from_python next; + }; + +template +struct defaulted_virtual_fn +{ + defaulted_virtual_fn(VirtualFunction dispatch, Default const& default_impl) + : dispatch(dispatch), default_impl(default_impl) {}; + + VirtualFunction dispatch; + Default default_impl; +}; + + + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct is_defaulted_virtual_fn +{ BOOST_STATIC_CONSTANT(bool, value = false); }; + +template +struct is_defaulted_virtual_fn > +{ BOOST_STATIC_CONSTANT(bool, value = true); }; +# else +template +struct is_defaulted_virtual_fn +{ + template + static char helper(defaulted_virtual_fn* x); + static char (& helper(...)) [2]; + + BOOST_STATIC_CONSTANT(bool, value = sizeof(helper((T*)0)) == 1); + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_defaulted_virtual_fn,(T)) +}; +# endif + +}}} // namespace boost::python::detail + +#endif // THIS_ARG_FROM_PYTHON_DWA20021122_HPP diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index 2277371f..99bc0253 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -6,74 +6,98 @@ #ifndef MAKE_FUNCTION_DWA20011221_HPP # define MAKE_FUNCTION_DWA20011221_HPP -# include -# include -# include -# include -# include -# include -# include # include +# include +# include + +# include + +# include +# include namespace boost { namespace python { +namespace detail +{ + // make_function_aux -- + // + // These helper functions for make_function (below) do the raw work + // of constructing a Python object from some invokable entity. See + // for more information about how + // the ConverterGenerators and Sig arguments are used. + template + object make_function_aux( + F f // An object that can be invoked by detail::invoke() + , CallPolicies const& p // CallPolicies to use in the invocation + , ConverterGenerators const& // An MPL iterator over a sequence of arg_from_python generators + , Sig const& // An MPL sequence of argument types expected by F + ) + { + return objects::function_object( + detail::caller(f, p) + , mpl::size::value - 1); + } + + // As above, except that it accepts argument keywords. NumKeywords + // is used only for a compile-time assertion to make sure the user + // doesn't pass more keywords than the function can accept. To + // disable all checking, pass mpl::int_c<0> for NumKeywords. + template + object make_function_aux( + F f + , CallPolicies const& p + , ConverterGenerators const& + , Sig const& + , detail::keyword_range const& kw // a [begin,end) pair of iterators over keyword names + , NumKeywords // An MPL integral type wrapper: the size of kw + ) + { + enum { arity = mpl::size::value - 1 }; + + typedef typename detail::error::more_keywords_than_function_arguments< + NumKeywords::value, arity + >::too_many_keywords assertion; + + return objects::function_object( + detail::caller(f, p) + , arity + , kw); + } +} + +// make_function -- +// +// These overloaded functions wrap a function or member function +// pointer as a Python object, using optional CallPolicies and +// Keywords. template object make_function(F f) { - return objects::function_object( - ::boost::bind(detail::caller(), f, _1, _2, default_call_policies()) - , detail::arg_tuple_size::value); + return detail::make_function_aux( + f,default_call_policies(),detail::args_from_python(), detail::get_signature(f)); } -template -object make_function(F f, Policies const& policies) +template +object make_function(F f, CallPolicies const& policies) { - return objects::function_object( - ::boost::bind(detail::caller(), f, _1, _2, policies) - , detail::arg_tuple_size::value); + return detail::make_function_aux( + f,policies,detail::args_from_python(), detail::get_signature(f)); } -template -object make_function(F f, Policies const& policies, Keywords const& keywords) +template +object make_function(F f, CallPolicies const& policies, Keywords const& keywords) { - enum { n_arguments = detail::arg_tuple_size::value }; - typedef typename detail::error::more_keywords_than_function_arguments< - Keywords::size, n_arguments - >::too_many_keywords assertion; - - return objects::function_object( - ::boost::bind(detail::caller(), f, _1, _2, policies) - , n_arguments - , keywords.range()); + return detail::make_function_aux( + f + , policies + , detail::args_from_python() + , detail::get_signature(f) + , keywords.range() + , mpl::int_c() + ); } -template -object make_constructor(HolderGenerator* = 0, ArgList* = 0) -{ - enum { nargs = mpl::size::value }; - - return objects::function_object( - ::boost::bind( - detail::caller() - , objects::make_holder - ::template apply::execute - , _1, _2, default_call_policies()) - , nargs + 1); -} +}} -template -object make_constructor(Policies const& policies, HolderGenerator* = 0, ArgList* = 0) -{ - enum { nargs = mpl::size::value }; - - return objects::function_object( - ::boost::bind(detail::caller(), - objects::make_holder - ::template apply::execute - , _1, _2, policies) - , nargs + 1); -} - -}} // namespace boost::python #endif // MAKE_FUNCTION_DWA20011221_HPP diff --git a/include/boost/python/object/function_handle.hpp b/include/boost/python/object/function_handle.hpp index f29c2e35..96cf82a5 100644 --- a/include/boost/python/object/function_handle.hpp +++ b/include/boost/python/object/function_handle.hpp @@ -7,10 +7,9 @@ # define FUNCTION_HANDLE_DWA2002725_HPP # include # include -# include # include # include -# include +# include namespace boost { namespace python { namespace objects { @@ -19,10 +18,16 @@ BOOST_PYTHON_DECL handle<> function_handle_impl(py_function const& f, unsigned m // Just like function_object, but returns a handle<> instead. Using // this for arg_to_python<> allows us to break a circular dependency // between object and arg_to_python. -template -inline handle<> function_handle(F const& f, unsigned min_args, unsigned max_args = 0) +template +inline handle<> function_handle(F const& f, Signature) { - return objects::function_handle_impl(objects::py_function(f), min_args, max_args); + enum { n_arguments = mpl::size::value - 1 }; + + return objects::function_handle_impl( + python::detail::caller< + F,python::detail::args_from_python,default_call_policies,Signature>( + f, default_call_policies()) + , n_arguments, n_arguments); } // Just like make_function, but returns a handle<> intead. Same @@ -30,9 +35,7 @@ inline handle<> function_handle(F const& f, unsigned min_args, unsigned max_args template handle<> make_function_handle(F f) { - return objects::function_handle( - ::boost::bind(python::detail::caller(), f, _1, _2, default_call_policies()) - , python::detail::arg_tuple_size::value); + return objects::function_handle(f, python::detail::get_signature(f)); } }}} // namespace boost::python::objects diff --git a/src/converter/arg_to_python_base.cpp b/src/converter/arg_to_python_base.cpp index 1740f6ee..6b143e64 100644 --- a/src/converter/arg_to_python_base.cpp +++ b/src/converter/arg_to_python_base.cpp @@ -12,26 +12,23 @@ namespace boost { namespace python { namespace converter { -namespace +PyObject* registration::to_python(void const volatile* source) const { - inline PyObject* convert_to_python(void const volatile* source, registration const& converters) + if (this->m_to_python == 0) { - if (converters.to_python == 0) - { - handle<> msg( - ::PyString_FromFormat( - "No to_python (by-value) converter found for C++ type: %s" - , converters.target_type.name())); + handle<> msg( + ::PyString_FromFormat( + "No to_python (by-value) converter found for C++ type: %s" + , this->target_type.name())); - PyErr_SetObject(PyExc_TypeError, msg.get()); + PyErr_SetObject(PyExc_TypeError, msg.get()); - throw_error_already_set(); - } - - return source == 0 - ? incref(Py_None) - : converters.to_python(const_cast(source)); + throw_error_already_set(); } + + return source == 0 + ? incref(Py_None) + : this->m_to_python(const_cast(source)); } namespace detail @@ -39,10 +36,11 @@ namespace detail arg_to_python_base::arg_to_python_base( void const volatile* source, registration const& converters) # if !defined(BOOST_MSVC) || BOOST_MSVC <= 1300 || _MSC_FULL_VER > 13102179 - : handle<>(converter::convert_to_python(source, converters)) + : handle<> # else - : m_ptr(converter::convert_to_python(source, converters)) -# endif + : m_ptr +# endif + (converters.to_python(source)) { } diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index 8c495106..87851eed 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -69,7 +69,7 @@ namespace registry # ifdef BOOST_PYTHON_TRACE_REGISTRY std::cout << "inserting to_python " << source_t << "\n"; # endif - to_python_function_t& slot = get(source_t)->to_python; + to_python_function_t& slot = get(source_t)->m_to_python; assert(slot == 0); // we have a problem otherwise if (slot != 0) diff --git a/test/m1.cpp b/test/m1.cpp index 60498d2a..463b51ae 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -199,6 +199,9 @@ D take_d_shared_ptr(boost::shared_ptr d) { return *d; } boost::shared_ptr d_factory() { return boost::shared_ptr(new D); } +struct Unregistered {}; +Unregistered make_unregistered(int) { return Unregistered(); } + BOOST_PYTHON_MODULE(m1) { using namespace boost::python; @@ -222,6 +225,8 @@ BOOST_PYTHON_MODULE(m1) def("new_noddy", new_noddy); def("new_simple", new_simple); + def("make_unregistered", make_unregistered); + // Expose f() in all its variations def("f", f); def("f_mutable_ref", f_mutable_ref); diff --git a/test/newtest.py b/test/newtest.py index 7b68a260..5162486a 100644 --- a/test/newtest.py +++ b/test/newtest.py @@ -3,6 +3,17 @@ >>> from m2 import * + Prove that we get an appropriate error from trying to return a type + for which we have no registered to_python converter + +>>> try: +... make_unregistered(1) +... except TypeError, x: +... if not str(x).startswith('No to_python (by-value) converter found for C++ type'): +... print str(x) +... else: +... print 'expected a TypeError' + >>> n = new_noddy() >>> s = new_simple() >>> unwrap_int(n) From dca5c5108b3bc85e0400422d35b4a96b166b706f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Nov 2002 03:25:13 +0000 Subject: [PATCH 0918/1042] update [SVN r16389] --- doc/v2/faq.html | 83 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/doc/v2/faq.html b/doc/v2/faq.html index e78ce612..cc1df0b9 100644 --- a/doc/v2/faq.html +++ b/doc/v2/faq.html @@ -37,6 +37,8 @@
      fatal error C1204:Compiler limit:internal structure overflow
      + +
      How do I debug my Python extensions?
      @@ -215,11 +217,90 @@ void more_of_my_class(class<my_class>& x) +

      How do I debug my Python extensions?

      + +

      Greg Burley gives the following answer for Unix GCC users: + +

      +Once you have created a boost python extension for your c++ library or +class, you may need to debug the code. Afterall this is one of the +reasons for wrapping the library in python. An expected side-effect or +benefit of using BPL is that debugging should be isolated to the c++ +library that is under test, given that python code is minimal and +boost::python either works or it doesn't. (ie. While errors can occur +when the wrapping method is invalid, most errors are caught by the +compiler ;-). + +

      + +The basic steps required to initiate a gdb session to debug a c++ +library via python are shown here. Note, however that you should start +the gdb session in the directory that contains your BPL my_ext.so +module. + + +

      +(gdb) target exec python
      +(gdb) run
      + >>> from my_ext import *
      + >>> [C-c]
      +(gdb) break MyClass::MyBuggyFunction
      +(gdb) cont
      + >>> pyobj = MyClass()
      + >>> pyobj.MyBuggyFunction()
      +Breakpoint 1, MyClass::MyBuggyFunction ...
      +Current language:  auto; currently c++
      +(gdb) do debugging stuff
      +
      +
      + +

      + +Greg's approach works even better using Emacs' +"gdb" command, since it will show you each line +of source as you step through it. + +

      + +On Windows, my favorite debugging solution is the debugger that comes +with Microsoft Visual C++ 7. This debugger seems to work with code +generated by all versions of Microsoft and Metrowerks toolsets; it's +rock solid and "just works" without requiring any special +tricks from the user. + +

      + +Unfortunately for Cygwin and MinGW users, as of this writing gdb on +Windows has a very hard time dealing with shared libraries, which +could make Greg's approach next to useless for you. My best advice for +you is to use Metrowerks C++ for compiler conformance and Microsoft +Visual Studio as a debugger when you need one. + +

      Debugging extensions through Boost.Build

      + +If you are launching your extension module tests with Boost.Build using the +boost-python-runtest rule, you can ask it to launch your +debugger for you by adding "-sPYTHON_LAUNCH=debugger" +to your bjam command-line: + +
      +bjam -sTOOLS=metrowerks "-sPYTHON_LAUNCH=devenv /debugexe" test
      +bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
      +
      + +It can also be extremely useful to add the -d+2 option +when you run your test, because Boost.Build will then show you the +exact commands it uses to invoke it. This will invariably involve +setting up PYTHONPATH and other important environment variables such +as LD_LIBRARY_PATH which may be needed by your debugger in order to +get things to work right. +

      Revised - 13 November, 2002 + 23 November, 2002

      From a77a83569495af3a84e2a9c02af3084f9a83d50e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Nov 2002 03:26:28 +0000 Subject: [PATCH 0919/1042] New function invocation mechanism. This is the major groundwork for handling virtual functions with default implementations properly [SVN r16390] --- .../boost/python/detail/arg_tuple_size.hpp | 130 ----------- include/boost/python/detail/returning.hpp | 216 ------------------ 2 files changed, 346 deletions(-) delete mode 100644 include/boost/python/detail/arg_tuple_size.hpp delete mode 100644 include/boost/python/detail/returning.hpp diff --git a/include/boost/python/detail/arg_tuple_size.hpp b/include/boost/python/detail/arg_tuple_size.hpp deleted file mode 100644 index cad72c39..00000000 --- a/include/boost/python/detail/arg_tuple_size.hpp +++ /dev/null @@ -1,130 +0,0 @@ -#error obsolete -#if !defined(BOOST_PP_IS_ITERATING) - -// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and -// distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for 5-argument member functions and 6-argument free -// functions by gen_arg_tuple_size.python - -#ifndef ARG_TUPLE_SIZE_DWA20011201_HPP -# define ARG_TUPLE_SIZE_DWA20011201_HPP - -# include - -# include -# include - -# include -# include -# include -# include -# include - -namespace boost { namespace python { namespace detail { - -// Computes (at compile-time) the number of elements that a Python -// argument tuple must have in order to be passed to a wrapped C++ -// (member) function of the given type. -template struct arg_tuple_size; - -// We will use the "sizeof() trick" to work around the lack of -// partial specialization in MSVC6 and its broken-ness in borland. -// See http://opensource.adobe.com or -// http://groups.yahoo.com/group/boost/message/5441 for -// more examples - -// The following helper functions are never actually called, since -// they are only used within a sizeof() expression, but the type of -// their return value is used to discriminate between various free -// and member function pointers at compile-time. - -// Specializations for function pointers -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_MAX_ARITY, , BOOST_PYTHON_FUNCTION_POINTER)) -# include BOOST_PP_ITERATE() - -// Specializations for member function pointers -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_CV_COUNT - 1, , BOOST_PYTHON_POINTER_TO_MEMBER)) -# include BOOST_PP_ITERATE() - -# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - -template -struct arg_tuple_size -{ - // The sizeof() magic happens here - BOOST_STATIC_CONSTANT(std::size_t, value - = sizeof(arg_tuple_size_helper(F(0)).elements) - 1); -}; - -# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -}}} // namespace boost::python::detail - -#endif // ARG_TUPLE_SIZE_DWA20011201_HPP - -// --------------- function pointers --------------- // -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_FUNCTION_POINTER -# line BOOST_PP_LINE(__LINE__, arg_tuple_size.hpp(function pointers)) - -# define N BOOST_PP_ITERATION() - -# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = N); -}; - -# else - -template -char_array arg_tuple_size_helper( - R (*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A))); - -# endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - -# undef N - -// --------------- pointers-to-members --------------- // -#elif BOOST_PP_ITERATION_DEPTH() == 1 && BOOST_PP_ITERATION_FLAGS() == BOOST_PYTHON_POINTER_TO_MEMBER -// Outer iteration over cv-qualifications - -# define BOOST_PP_ITERATION_PARAMS_2 \ - (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -#elif BOOST_PP_ITERATION_DEPTH() == 2 && BOOST_PP_RELATIVE_FLAGS(1) == BOOST_PYTHON_POINTER_TO_MEMBER -# line BOOST_PP_LINE(__LINE__, arg_tuple_size.hpp(pointers-to-members)) -// Inner iteration over arities - -# define N BOOST_PP_ITERATION() -# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) - -# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - -template -struct arg_tuple_size -{ - BOOST_STATIC_CONSTANT(std::size_t, value = N + 1U); -}; - -# else - -template -char_array arg_tuple_size_helper( - R (T::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q); - -# endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - -# undef Q -# undef N - -#endif // !defined(BOOST_PP_IS_ITERATING) diff --git a/include/boost/python/detail/returning.hpp b/include/boost/python/detail/returning.hpp deleted file mode 100644 index 97338ff3..00000000 --- a/include/boost/python/detail/returning.hpp +++ /dev/null @@ -1,216 +0,0 @@ -#if !defined(BOOST_PP_IS_ITERATING) - -// (C) Copyright David Abrahams 2001,2002. Permission to copy, use, modify, sell -// and distribute this software is granted provided this copyright notice appears -// in all copies. This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -// This work was funded in part by Lawrence Berkeley National Labs -// -// This file generated for 5-argument member functions and 6-argument free -// functions by gen_returning.py - -# ifndef RETURNING_DWA20011201_HPP -# define RETURNING_DWA20011201_HPP - -# include - -# include -# include -# include -# include - -# include -# include -# include -# include -# include -# include - -# include - -namespace boost { namespace python { namespace detail { - -# define BOOST_PYTHON_RETURNING_NON_VOID 0x0004 -# define BOOST_PYTHON_RETURNING_VOID 0x0008 - -template -struct returning -{ - // Specializations for function pointers -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_MAX_ARITY, , \ - BOOST_PYTHON_FUNCTION_POINTER | BOOST_PYTHON_RETURNING_NON_VOID)) -# include BOOST_PP_ITERATE() - - // Specializations for member function pointers -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, 3, , \ - BOOST_PYTHON_POINTER_TO_MEMBER | BOOST_PYTHON_RETURNING_NON_VOID)) -# include BOOST_PP_ITERATE() -}; - -template <> -struct returning -{ - typedef void R; - // Specializations for function pointers -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, BOOST_PYTHON_MAX_ARITY, , \ - BOOST_PYTHON_FUNCTION_POINTER | BOOST_PYTHON_RETURNING_VOID)) -# include BOOST_PP_ITERATE() - - // Specializations for member function pointers -# define BOOST_PP_ITERATION_PARAMS_1 \ - (4, (0, 3, , \ - BOOST_PYTHON_POINTER_TO_MEMBER | BOOST_PYTHON_RETURNING_VOID)) -# include BOOST_PP_ITERATE() -}; - -}}} // namespace boost::python::detail - -# undef BOOST_PYTHON_RETURNING_NON_VOID -# undef BOOST_PYTHON_RETURNING_VOID - -# endif // RETURNING_DWA20011201_HPP - -// --------------- function pointers --------------- // -#elif BOOST_PP_ITERATION_DEPTH() == 1 && (BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_FUNCTION_POINTER) -# line BOOST_PP_LINE(__LINE__, returning.hpp(function pointers)) - -# define N BOOST_PP_ITERATION() - -# define BOOST_PYTHON_CALL_ARGS(z, n, _) \ - BOOST_PP_COMMA_IF(n) c##n(PyTuple_GET_ITEM(args_, n)) - -# define BOOST_PYTHON_CHECK_CONVERSION(z, n, _) \ - arg_from_python c##n(PyTuple_GET_ITEM(args_, n)); \ - if (!c##n.convertible()) \ - return 0; - -# if (BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_RETURNING_NON_VOID) - - template - static PyObject* call( - R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) - , PyObject* args_ - , PyObject*, P const* policies) - { - // check that each of the arguments is convertible - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil) - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible() || !policies->precall(args_)) - return 0; - PyObject* result = cr( - (*pf)(BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil)) - ); - return policies->postcall(args_, result); - } -# elif (BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_RETURNING_VOID) - - template - static PyObject* call( - R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) - , PyObject* args_ - , PyObject*, P const* policies) - { - // check that each of the arguments is convertible - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil) - - if (!policies->precall(args_)) - return 0; - (*pf)(BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil)); - return policies->postcall(args_, detail::none()); - } -# endif // returning void / non-void - -# undef N -# undef BOOST_PYTHON_CALL_ARGS -# undef BOOST_PYTHON_CHECK_CONVERSION - -// --------------- pointers to members --------------- // -#elif BOOST_PP_ITERATION_DEPTH() == 1 && (BOOST_PP_ITERATION_FLAGS() & BOOST_PYTHON_POINTER_TO_MEMBER) - - // Outer iteration over cv-qualifications -# define BOOST_PP_ITERATION_PARAMS_2 \ - (3, (0, BOOST_PYTHON_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -#elif BOOST_PP_ITERATION_DEPTH() == 2 && BOOST_PP_RELATIVE_FLAGS(1) & BOOST_PYTHON_POINTER_TO_MEMBER -# line BOOST_PP_LINE(__LINE__, returning.hpp(pointers-to-members)) - - // Inner iteration over arities -# define N BOOST_PP_ITERATION() -# define Q BOOST_PYTHON_CV_QUALIFIER(BOOST_PP_RELATIVE_ITERATION(1)) - -# define BOOST_PYTHON_CALL_ARGS(z, n, _) \ - BOOST_PP_COMMA_IF(n) c##n(PyTuple_GET_ITEM(args_, BOOST_PP_INC(n))) - -# define BOOST_PYTHON_CHECK_CONVERSION(z, n, _) \ - arg_from_python c##n(PyTuple_GET_ITEM(args_, BOOST_PP_INC(n))); \ - if (!c##n.convertible()) \ - return 0; - -# if (BOOST_PP_RELATIVE_FLAGS(1) & BOOST_PYTHON_RETURNING_NON_VOID) - - template - static PyObject* call( - R (T::*pmf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q - , PyObject* args_ - , PyObject*, P const* policies) - { - // check that each of the arguments is convertible - // self is special - arg_from_python ct(PyTuple_GET_ITEM(args_, 0)); - if (!ct.convertible()) - return 0; - - // unroll a loop for the rest of them - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil) - - // find the result converter - typedef typename P::result_converter result_converter; - typename mpl::apply1::type cr; - if (!cr.convertible() || !policies->precall(args_)) - return 0; - PyObject* result = cr( - ((ct(PyTuple_GET_ITEM(args_, 0))).*pmf)( - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil)) - ); - return policies->postcall(args_, result); - } -# elif (BOOST_PP_RELATIVE_FLAGS(1) & BOOST_PYTHON_RETURNING_VOID) - - template - static PyObject* call( - R (T::*pmf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) Q - , PyObject* args_ - , PyObject*, P const* policies) - { - // check that each of the arguments is convertible - // self is special - arg_from_python ct(PyTuple_GET_ITEM(args_, 0)); - if (!ct.convertible()) - return 0; - - // unroll a loop for the rest of them - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil) - - if (!policies->precall(args_)) - return 0; - - ((ct(PyTuple_GET_ITEM(args_, 0))).*pmf)( - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil)); - return policies->postcall(args_, detail::none()); - } -# endif - -# undef N -# undef Q -# undef BOOST_PYTHON_CALL_ARGS -# undef BOOST_PYTHON_CHECK_CONVERSION - -#endif From 31b8b58de95accbf0b8da092e615370a8def55b0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 24 Nov 2002 21:45:09 +0000 Subject: [PATCH 0920/1042] CW workaround [SVN r16393] --- include/boost/python/converter/registrations.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp index 8bbe1621..70c7df68 100644 --- a/include/boost/python/converter/registrations.hpp +++ b/include/boost/python/converter/registrations.hpp @@ -49,6 +49,11 @@ struct BOOST_PYTHON_DECL registration // The unique to_python converter for the associated C++ type. to_python_function_t m_to_python; + +# if defined(__MWERKS__) && __MWERKS__ <= 0x3003 + private: + void operator=(registration); // This is not defined, and just keeps MWCW happy. +# endif }; // From cfbc1a6b4866596397288b5e745051837a9b51db Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Nov 2002 01:57:57 +0000 Subject: [PATCH 0921/1042] Fully removed convertible() test from to_python converter protocol Added tests for detecting unregistered classes when converting indirectly to python. [SVN r16396] --- .../boost/python/converter/arg_to_python.hpp | 8 +----- .../python/converter/builtin_converters.hpp | 2 -- .../boost/python/converter/registrations.hpp | 8 ++++-- include/boost/python/data_members.hpp | 1 - include/boost/python/enum.hpp | 27 ++++++++++++++----- include/boost/python/object/iterator.hpp | 7 ----- include/boost/python/object/make_instance.hpp | 3 ++- include/boost/python/to_python_indirect.hpp | 10 ++----- include/boost/python/to_python_value.hpp | 14 ---------- src/converter/arg_to_python_base.cpp | 8 ------ src/converter/from_python.cpp | 24 ++++++----------- src/converter/registry.cpp | 20 ++++++++++++++ src/object/class.cpp | 4 +-- src/object/enum.cpp | 2 +- test/m1.cpp | 4 +++ test/newtest.py | 18 ++++++++----- 16 files changed, 77 insertions(+), 83 deletions(-) diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index deab7964..192639ed 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -29,8 +29,6 @@ template struct is_object_manager; namespace detail { - BOOST_PYTHON_DECL void throw_no_class_registered(); - template struct function_arg_to_python : handle<> { @@ -209,8 +207,6 @@ namespace detail inline PyObject* reference_arg_to_python::get_object(T& x) { to_python_indirect convert; - if (!convert.convertible()) - throw_no_class_registered(); return convert(x); } @@ -231,9 +227,7 @@ namespace detail inline PyObject* pointer_shallow_arg_to_python::get_object(Ptr x) { to_python_indirect convert; - if (!convert.convertible()) - throw_no_class_registered(); - return x ? convert(x) : python::detail::none(); + return convert(x); } } diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index 38b22cb4..c46e7e8f 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -37,8 +37,6 @@ namespace detail // a converter. struct builtin_to_python { - static bool convertible() { return true; } - // This information helps make_getter() decide whether to try to // return an internal reference or not. I don't like it much, // but it will have to serve for now. diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp index 70c7df68..e5338f67 100644 --- a/include/boost/python/converter/registrations.hpp +++ b/include/boost/python/converter/registrations.hpp @@ -35,6 +35,10 @@ struct BOOST_PYTHON_DECL registration // Convert the appropriately-typed data to Python PyObject* to_python(void const volatile*) const; + // Return the class object, or raise an appropriate Python + // exception if no class has been registered. + PyTypeObject* get_class_object() const; + public: // data members. So sue me. const python::type_info target_type; @@ -45,7 +49,7 @@ struct BOOST_PYTHON_DECL registration rvalue_from_python_chain* rvalue_chain; // The class object associated with this type - PyTypeObject* class_object; + PyTypeObject* m_class_object; // The unique to_python converter for the associated C++ type. to_python_function_t m_to_python; @@ -64,7 +68,7 @@ inline registration::registration(type_info target_type) , lvalue_chain(0) , rvalue_chain(0) , m_to_python(0) - , class_object(0) + , m_class_object(0) {} inline bool operator<(registration const& lhs, registration const& rhs) diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp index 1315c37f..a8ff3871 100644 --- a/include/boost/python/data_members.hpp +++ b/include/boost/python/data_members.hpp @@ -36,7 +36,6 @@ namespace detail typedef typename Policies::result_converter result_converter; typedef typename boost::add_reference::type source; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; if (!policies.precall(args_)) return 0; diff --git a/include/boost/python/enum.hpp b/include/boost/python/enum.hpp index 072a0626..1070c06b 100644 --- a/include/boost/python/enum.hpp +++ b/include/boost/python/enum.hpp @@ -17,12 +17,15 @@ struct enum_ : public objects::enum_base { typedef objects::enum_base base; + // Declare a new enumeration type in the current scope() enum_(char const* name); + + // Add a new enumeration value with the given name and value. inline enum_& value(char const* name, T); private: static PyObject* to_python(void const* x); - static void* convertible(PyObject* obj); + static void* convertible_from_python(PyObject* obj); static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data); }; @@ -31,32 +34,42 @@ inline enum_::enum_(char const* name) : base( name , &enum_::to_python - , &enum_::convertible + , &enum_::convertible_from_python , &enum_::construct , type_id()) { } -// This is the conversion function that gets registered for converting +// This is the conversion function that gets registered for converting +// these enums to Python. template PyObject* enum_::to_python(void const* x) { return base::to_python( - converter::registered::converters.class_object + converter::registered::converters.m_class_object , static_cast(*(T const*)x)); } +// +// The following two static functions serve as the elements of an +// rvalue from_python converter for the enumeration type. +// + +// This checks that a given Python object can be converted to the +// enumeration type. template -void* enum_::convertible(PyObject* obj) +void* enum_::convertible_from_python(PyObject* obj) { return PyObject_IsInstance( obj , upcast( - converter::registered::converters.class_object)) + converter::registered::converters.m_class_object)) ? obj : 0; } - + +// Constructs an instance of the enumeration type in the from_python +// data. template void enum_::construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data) { diff --git a/include/boost/python/object/iterator.hpp b/include/boost/python/object/iterator.hpp index 65c206d7..c97c3994 100644 --- a/include/boost/python/object/iterator.hpp +++ b/include/boost/python/object/iterator.hpp @@ -87,7 +87,6 @@ namespace detail { typedef typename Policies::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; return cr(x); } @@ -96,7 +95,6 @@ namespace detail { typedef typename Policies::result_converter result_converter; typename mpl::apply1::type cr; - if (!cr.convertible()) return 0; return cr(x); } @@ -150,11 +148,6 @@ namespace detail to_python_value > cr; - // This check is probably redundant, since we ensure the - // type is registered above. - if (!cr.convertible()) - return 0; - // Extract x from the first argument PyObject* arg0 = PyTuple_GET_ITEM(args_, 0); arg_from_python c0(arg0); diff --git a/include/boost/python/object/make_instance.hpp b/include/boost/python/object/make_instance.hpp index d5e153b9..ecac7493 100644 --- a/include/boost/python/object/make_instance.hpp +++ b/include/boost/python/object/make_instance.hpp @@ -20,7 +20,8 @@ struct make_instance static PyObject* execute(Arg& x) { BOOST_STATIC_ASSERT(is_class::value); - PyTypeObject* type = converter::registered::converters.class_object; + + PyTypeObject* type = converter::registered::converters.get_class_object(); PyObject* raw_result = type->tp_alloc( type, objects::additional_instance_size::value); diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index 23ff8594..78e95098 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -21,7 +21,6 @@ namespace boost { namespace python { template struct to_python_indirect { - static bool convertible(); PyObject* operator()(T ptr) const; private: static PyTypeObject* type(); @@ -90,16 +89,11 @@ namespace detail } } -template -inline bool to_python_indirect::convertible() -{ - BOOST_STATIC_ASSERT(is_pointer::value || is_reference::value); - return type() != 0; -} - template inline PyObject* to_python_indirect::operator()(T x) const { + BOOST_STATIC_ASSERT(is_pointer::value || is_reference::value); + PyObject* const null_result = detail::null_pointer_to_none(x, 1L); if (null_result != 0) return null_result; diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp index de5122a2..17f6b174 100644 --- a/include/boost/python/to_python_value.hpp +++ b/include/boost/python/to_python_value.hpp @@ -27,7 +27,6 @@ namespace detail typename add_const::type >::type argument_type; - static bool convertible(); PyObject* operator()(argument_type) const; // This information helps make_getter() decide whether to try to @@ -44,7 +43,6 @@ namespace detail typename add_const::type >::type argument_type; - static bool convertible(); PyObject* operator()(argument_type) const; // This information helps make_getter() decide whether to try to @@ -73,24 +71,12 @@ struct to_python_value // namespace detail { - template - inline bool registry_to_python_value::convertible() - { - return converter::registered::converters.to_python != 0; - } - template inline PyObject* registry_to_python_value::operator()(argument_type x) const { return converter::registered::converters.to_python(&x); } - template - inline bool object_manager_to_python_value::convertible() - { - return true; - } - template inline PyObject* object_manager_to_python_value::operator()(argument_type x) const { diff --git a/src/converter/arg_to_python_base.cpp b/src/converter/arg_to_python_base.cpp index 6b143e64..1101f591 100644 --- a/src/converter/arg_to_python_base.cpp +++ b/src/converter/arg_to_python_base.cpp @@ -43,14 +43,6 @@ namespace detail (converters.to_python(source)) { } - - BOOST_PYTHON_DECL void throw_no_class_registered() - { - PyErr_SetString( - PyExc_TypeError - , const_cast("class not registered for to_python type")); - throw_error_already_set(); - } } }}} // namespace boost::python::converter diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index b6ce54ff..49b362e0 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -10,6 +10,8 @@ #include #include #include + +#include #include #include @@ -244,14 +246,6 @@ BOOST_PYTHON_DECL void* pointer_result_from_python( return (lvalue_result_from_python)(source, converters, "pointer"); } -BOOST_PYTHON_DECL void throw_no_class_registered() -{ - PyErr_SetString( - PyExc_TypeError - , const_cast("class not registered for to_python type")); - throw_error_already_set(); -} - BOOST_PYTHON_DECL void void_result_from_python(PyObject* o) { Py_DECREF(expect_non_null(o)); @@ -264,14 +258,12 @@ pytype_check(PyTypeObject* type_, PyObject* source) { if (!PyObject_IsInstance(source, python::upcast(type_))) { - handle<> keeper(source); - handle<> msg( - ::PyString_FromFormat( - "Expecting an object of type %s; got an object of type %s instead" - , type_->tp_name - , source->ob_type->tp_name - )); - PyErr_SetObject(PyExc_TypeError, msg.get()); + ::PyErr_Format( + PyExc_TypeError + , "Expecting an object of type %s; got an object of type %s instead" + , type_->tp_name + , source->ob_type->tp_name + ); throw_error_already_set(); } return source; diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index 87851eed..a3d7913d 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -6,6 +6,9 @@ #include #include #include + +#include + #include #include @@ -15,6 +18,23 @@ namespace boost { namespace python { namespace converter { +PyTypeObject* registration::get_class_object() const +{ + if (this->m_class_object == 0) + { + std::string name = lexical_cast(this->target_type); + ::PyErr_Format( + PyExc_TypeError + , const_cast("No Python class registered for C++ class %s") + , name.c_str()); + + throw_error_already_set(); + } + + return this->m_class_object; +} + + namespace // { typedef registration entry; diff --git a/src/object/class.cpp b/src/object/class.cpp index ad659cd5..3c261026 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -298,7 +298,7 @@ namespace objects converter::registration const* p = converter::registry::query(id); return type_handle( python::borrowed( - python::allow_null(p ? p->class_object : 0)) + python::allow_null(p ? p->m_class_object : 0)) ); } @@ -371,7 +371,7 @@ namespace objects converter::registry::lookup(types[0])); // Class object is leaked, for now - converters.class_object = (PyTypeObject*)incref(this->ptr()); + converters.m_class_object = (PyTypeObject*)incref(this->ptr()); } void class_base::set_instance_size(std::size_t instance_size) diff --git a/src/object/enum.cpp b/src/object/enum.cpp index b09a70a8..d151a486 100644 --- a/src/object/enum.cpp +++ b/src/object/enum.cpp @@ -169,7 +169,7 @@ enum_base::enum_base( = const_cast( converter::registry::lookup(id)); - converters.class_object = downcast(this->ptr()); + converters.m_class_object = downcast(this->ptr()); converter::registry::insert(to_python, id); converter::registry::insert(convertible, construct, id); } diff --git a/test/m1.cpp b/test/m1.cpp index 463b51ae..d9202b8b 100644 --- a/test/m1.cpp +++ b/test/m1.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include // Declare some straightforward extension types @@ -202,6 +203,8 @@ boost::shared_ptr d_factory() { return boost::shared_ptr(new D); } struct Unregistered {}; Unregistered make_unregistered(int) { return Unregistered(); } +Unregistered* make_unregistered2(int) { return new Unregistered; } + BOOST_PYTHON_MODULE(m1) { using namespace boost::python; @@ -226,6 +229,7 @@ BOOST_PYTHON_MODULE(m1) def("new_simple", new_simple); def("make_unregistered", make_unregistered); + def("make_unregistered2", make_unregistered2, return_value_policy()); // Expose f() in all its variations def("f", f); diff --git a/test/newtest.py b/test/newtest.py index 5162486a..da877151 100644 --- a/test/newtest.py +++ b/test/newtest.py @@ -6,13 +6,17 @@ Prove that we get an appropriate error from trying to return a type for which we have no registered to_python converter ->>> try: -... make_unregistered(1) -... except TypeError, x: -... if not str(x).startswith('No to_python (by-value) converter found for C++ type'): -... print str(x) -... else: -... print 'expected a TypeError' +>>> def check_unregistered(f, msgprefix): +... try: +... f(1) +... except TypeError, x: +... if not str(x).startswith(msgprefix): +... print str(x) +... else: +... print 'expected a TypeError' +... +>>> check_unregistered(make_unregistered, 'No to_python (by-value) converter found for C++ type') +>>> check_unregistered(make_unregistered2, 'No Python class registered for C++ class') >>> n = new_noddy() >>> s = new_simple() From 9d4e235cf6ec45e84d68e83eb7d994fea969bb06 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Nov 2002 03:41:34 +0000 Subject: [PATCH 0922/1042] add imul notes [SVN r16397] --- doc/v2/faq.html | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/doc/v2/faq.html b/doc/v2/faq.html index cc1df0b9..c21007ab 100644 --- a/doc/v2/faq.html +++ b/doc/v2/faq.html @@ -39,6 +39,8 @@ structure overflow
      How do I debug my Python extensions?
      + +
      Why doesn't my *= operator work?
      @@ -296,11 +298,39 @@ setting up PYTHONPATH and other important environment variables such as LD_LIBRARY_PATH which may be needed by your debugger in order to get things to work right. +

      Why doesn't my *= operator work?

      + +
      +Q: I have exported my class to python, with many overloaded operators. it +works fine for me except the *= operator. It always tells +me "can't multiply sequence with non int type". If I use +p1.__imul__(p2) instead of p1 *= +p2, it successfully executes my code. What's wrong with +me? + +

      A: There's nothing wrong with you. This is a bug in Python +2.2. You can see the same effect in Pure Python (you can learn a lot +about what's happening in Boost.Python by playing with new-style +classes in Pure Python). + +

      +>>> class X(object):
      +...     def __imul__(self, x):
      +...         print 'imul'
      +...
      +>>> x = X()
      +>>> x *= 1
      +
      + +To cure this problem, all you need to do is upgrade your Python to +version 2.2.1 or later. + +

      Revised - 23 November, 2002 + 24 November, 2002

      From 394037a12755a4e3247fec9cb3a038fcd47a6b1b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Nov 2002 16:12:27 +0000 Subject: [PATCH 0923/1042] updated [SVN r16408] --- doc/projects.html | 170 +++++++++++++++++++++++++++++----------------- 1 file changed, 106 insertions(+), 64 deletions(-) diff --git a/doc/projects.html b/doc/projects.html index 9d1484bb..5db7ec27 100644 --- a/doc/projects.html +++ b/doc/projects.html @@ -34,10 +34,32 @@ using Boost.Python as your Python/C++ binding solution, we'd be proud to list your project on this page. Just post a short description of your project - and how Boost.Python helps you get the job done, and we'll add it to - .

      + and how Boost.Python helps you get the job done, and we'll add it to this + page .


      +

      Enterprise Software

      + +
      +
      OpenWBEM
      + +
      + The OpenWBEM project is an effort to develop an open-source + implementation of Web Based Enterprise Management suitable for + commercial and non-commercial application + +

      Dan Nuffer writes:

      + +
      + I'm using Boost.Python to wrap the client API of OpenWBEM.This will + make it easier to do rapid prototyping, testing, and scripting when + developing management solutions that use WBEM. +
      +
      +
      + +

      Financial Analysis

      +
      TSLib - Fortress Investment Group LLC
      @@ -51,8 +73,8 @@

      Tom Barket of Fortress writes:

      - We have a large C++ analytical library specialized for research - in finance and economics, built for speed and mission critical + We have a large C++ analytical library specialized for research in + finance and economics, built for speed and mission critical stability. Yet Python offers us the flexibility to test out new ideas quickly and increase the productivity of our time versus working in C++. There are several key features which make Python @@ -60,16 +82,14 @@ web are all valuable, but the most important is its extensibility, due to its open source transparency. Boost.Python makes Python extensibility extremely simple and straightforward, yet preserves a - great deal of power and control. + great deal of power and control.
      +
      -
      EMSolve
      - -
      EMSolve is a provably stable, charge conserving, and energy - conserving solver for Maxwell's equations.
      -  
      +

      Graphics

      +
      OpenSceneGraph
      @@ -89,36 +109,6 @@ to Python.
        -
      OpenWBEM
      - -
      - The OpenWBEM project is an effort to develop an open-source - implementation of Web Based Enterprise Management suitable for - commercial and non-commercial application - -

      Dan Nuffer writes:

      - -
      - I'm using Boost.Python to wrap the client API of OpenWBEM.This - will make it easier to do rapid prototyping, testing, and scripting - when developing management solutions that use WBEM. -
      -
      - -
      CAMFR
      - -
      - CAMFR is a photonics and electromagnetics modelling tool. Python is - used for computational steering. - -

      Peter Bienstman - writes:

      - -
      - Thanks for providing such a great tool! -
      -
      -
      HippoDraw - Stanford Linear Accelerator Center
      @@ -134,36 +124,88 @@ writes:

      - Don't have a web page for the project, but the organization's is - http://www.slac.stanford.edu - (the first web server site in America, I installed it). + (the first web server site in America, I installed it).
      Which was just too cool a piece of trivia to omit.
      -   +   + +
      + +

      Scientific Computing

      + +
      +
      CAMFR
      -
      cctbx - Computational Crystallography Toolbox
      - Computational Crystallography is concerned with the derivation - of atomic models of crystal structures, given experimental - X-ray diffraction data. The cctbx is an open-source library of - fundamental algorithms for crystallographic computations. The - core algorithms are implemented in C++ and accessed through - higher-level Python interfaces. The cctbx grew together - with Boost.Python and is designed from the ground up as - a hybrid Python/C++ system. With one minor exception, + CAMFR is a photonics and electromagnetics modelling tool. Python is + used for computational steering. + +

      Peter Bienstman + writes:

      + +
      + Thanks for providing such a great tool! +
      +
      + +
      cctbx - Computational + Crystallography Toolbox
      + +
      + Computational Crystallography is concerned with the derivation of + atomic models of crystal structures, given experimental X-ray + diffraction data. The cctbx is an open-source library of fundamental + algorithms for crystallographic computations. The core algorithms are + implemented in C++ and accessed through higher-level Python + interfaces. + +

      The cctbx grew together with Boost.Python and is designed from the + ground up as a hybrid Python/C++ system. With one minor exception, run-time polymorphism is completely handled by Python. C++ - compile-time polymorphism is used to implement performance - critical algorithms. The Python and C++ layers are seamlessly - integrated using Boost.Python. -

      - The SourceForge cctbx project is organized in modules to - facilitate use in non-crystallographic applications. - The scitbx module implements a general purpose - array family for scientific applications and pure C++ - ports of FFTPACK and the LBFGS conjugate gradient - minimizer. + compile-time polymorphism is used to implement performance critical + algorithms. The Python and C++ layers are seamlessly integrated using + Boost.Python.

      + +

      The SourceForge cctbx project is organized in modules to + facilitate use in non-crystallographic applications. The scitbx + module implements a general purpose array family for scientific + applications and pure C++ ports of FFTPACK and the LBFGS conjugate + gradient minimizer.

      +
      + +
      EMSolve
      + +
      EMSolve is a provably stable, charge conserving, and energy + conserving solver for Maxwell's equations.
      +  
      + +
      Gaudi and RootPython
      + +
      + Gaudi is a framework for particle physics collision data processing + applications developed in the context of the LHCb and ATLAS + experiments at CERN. + +

      Pere Mato Vila writes:

      + +
      + We are using Boost.Python to provide scripting/interactive + capability to our framework. We have a module called "GaudiPython" + implemented using Boost.Python that allows the interaction with any + framework service or algorithm from python. RootPython also uses + Boost.Python to provide a generic "gateway" between the ROOT framework and python + +

      Boost.Python is great. We managed very quickly to interface our + framework to python, which is great language. We are trying to + facilitate to our physicists (end-users) a rapid analysis + application development environment based on python. For that, + Boost.Python plays and essential role.

      +

      From 352e390c7ba2c998acf80fbbb3753212307a64ce Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Nov 2002 18:32:14 +0000 Subject: [PATCH 0924/1042] Added tests for embedding demonstration [SVN r16409] --- test/Jamfile | 6 +++ test/embedding.cpp | 112 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 test/embedding.cpp diff --git a/test/Jamfile b/test/Jamfile index 81f1f99a..65c3bb76 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -55,6 +55,12 @@ rule bpl-test ( name ? : files * : requirements * ) boost-python-runtest $(name) : $(py) $(modules) ; } +run ../test/embedding.cpp ../build/boost_python + : # program args + : # input files + : # requirements + $(PYTHON_PROPERTIES) ; + bpl-test auto_ptr ; bpl-test minimal ; bpl-test args ; diff --git a/test/embedding.cpp b/test/embedding.cpp new file mode 100644 index 00000000..6e12c0f9 --- /dev/null +++ b/test/embedding.cpp @@ -0,0 +1,112 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. + +// embedded_hello -- A simple Boost.Python embedding example -- by +// Dirk Gerrits + +#include +#include +#include + +namespace python = boost::python; + +// An abstract base class +class Base : public boost::noncopyable +{ +public: + virtual ~Base() {}; + + virtual std::string hello() = 0; +}; + +// C++ derived class +class CppDerived : public Base +{ +public: + virtual ~CppDerived() {} + + std::string hello() + { + return "Hello from C++!"; + } +}; + +// Familiar Boost.Python wrapper class for Base +struct BaseWrap : public Base +{ + BaseWrap(PyObject* self_) + : self(self_) {} + + std::string hello() { return python::call_method(self, "hello"); } + + PyObject* self; +}; + +// Pack the Base class wrapper into a module +BOOST_PYTHON_MODULE(embedded_hello) +{ + python::class_("Base") + ; + +} + + +void test() +{ +//- INITIALIZATION -----------------------------------------------------------// + + // Register the module with the interpreter + PyImport_AppendInittab("embedded_hello", initembedded_hello); + + // Initialize the interpreter + Py_Initialize(); + + // Load the module + PyObject* main_module = PyImport_AddModule("__main__"); + PyObject* main_namespace = PyModule_GetDict(main_module); + Py_INCREF(main_namespace); + + // Define the derived class in Python. + // (You'll normally want to put this in a .py file.) + PyObject* result = PyRun_String( + "from embedded_hello import * \n" + "class PythonDerived(Base): \n" + " def hello(self): \n" + " return 'Hello from Python!' \n", + Py_file_input, main_namespace, main_namespace); + Py_XDECREF(result); + + // Extract the raw Python object representing the just defined derived class + python::handle class_ptr(PyRun_String("PythonDerived\n", Py_eval_input, + main_namespace, main_namespace)); + + // Wrap the raw Python object in a Boost.Python object using a handle + python::object PythonDerived(class_ptr); + +//- MAIN PROGRAM -------------------------------------------------------------// + + // Creating and using instances of the C++ class is as easy as always. + CppDerived cpp; + std::cout << cpp.hello() << std::endl; + + // But now creating and using instances of the Python class is just + // as easy! + python::object py_base = PythonDerived(); + Base& py = python::extract(py_base)(); + std::cout << py.hello() << std::endl; +} + +int main() +{ + if (python::handle_exception(test)) + { + if (PyErr_Occurred()) + PyErr_Print(); + return 1; + } + return 0; +} +#include "module_tail.cpp" From 3d0579cc083b569e8a1be6ca8bd9d54b734709a7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Nov 2002 20:52:49 +0000 Subject: [PATCH 0925/1042] Fix for VC7. For some reason lexical_cast doesn't seem to work out too well. We'll need to be careful how we do type_info decoding once we get the G++ fixes in. [SVN r16410] --- src/converter/registry.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index a3d7913d..85ece278 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -22,11 +22,10 @@ PyTypeObject* registration::get_class_object() const { if (this->m_class_object == 0) { - std::string name = lexical_cast(this->target_type); ::PyErr_Format( PyExc_TypeError , const_cast("No Python class registered for C++ class %s") - , name.c_str()); + , target_type.name()); throw_error_already_set(); } From 0d582e0e7957c809921c8eb6391e580b3ae18319 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Nov 2002 20:54:37 +0000 Subject: [PATCH 0926/1042] Suppress GCC warning [SVN r16411] --- include/boost/python.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python.hpp b/include/boost/python.hpp index ca81cce2..c608dbfe 100644 --- a/include/boost/python.hpp +++ b/include/boost/python.hpp @@ -59,4 +59,4 @@ # include # include -#endif PYTHON_DWA2002810_HPP +#endif // PYTHON_DWA2002810_HPP From bb7710a5a2c65d72711cda467a4bcebd0926b6f6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Nov 2002 21:19:35 +0000 Subject: [PATCH 0927/1042] Suppress GCC warning [SVN r16412] --- include/boost/python/converter/registrations.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp index e5338f67..8ed9d04a 100644 --- a/include/boost/python/converter/registrations.hpp +++ b/include/boost/python/converter/registrations.hpp @@ -67,8 +67,8 @@ inline registration::registration(type_info target_type) : target_type(target_type) , lvalue_chain(0) , rvalue_chain(0) - , m_to_python(0) , m_class_object(0) + , m_to_python(0) {} inline bool operator<(registration const& lhs, registration const& rhs) From 087e2d6e357b7647509defc11c4206d1c17158cf Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Nov 2002 21:57:23 +0000 Subject: [PATCH 0928/1042] Add additional argument for default implementation of virtual functions Fully commented [SVN r16413] --- include/boost/python/detail/def_helper.hpp | 100 +++++++++++++++------ 1 file changed, 72 insertions(+), 28 deletions(-) diff --git a/include/boost/python/detail/def_helper.hpp b/include/boost/python/detail/def_helper.hpp index 78a1649f..fa66f04a 100644 --- a/include/boost/python/detail/def_helper.hpp +++ b/include/boost/python/detail/def_helper.hpp @@ -25,9 +25,15 @@ struct default_call_policies; namespace detail { + // tuple_extract::extract(t) returns the first + // element of a Tuple whose type E satisfies the given Predicate + // applied to add_reference. The Predicate must be an MPL + // metafunction class. template struct tuple_extract; - + + // Implementation class for when the tuple's head type does not + // satisfy the Predicate template struct tuple_extract_impl { @@ -42,25 +48,28 @@ namespace detail } }; }; - + + // Implementation specialization for when the tuple's head type + // satisfies the predicate template <> struct tuple_extract_impl { template struct apply - : tuple_extract { - // All of this forwarding would be unneeded if tuples were - // derived from their tails. - typedef tuple_extract base; - typedef typename base::result_type result_type; + // recursive application of tuple_extract on the tail of the tuple + typedef tuple_extract next; + typedef typename next::result_type result_type; + static result_type extract(Tuple const& x) { - return base::extract(x.get_tail()); + return next::extract(x.get_tail()); } }; }; + // A metafunction which selects a version of tuple_extract_impl to + // use for the implementation of tuple_extract template struct tuple_extract_base_select { @@ -79,15 +88,24 @@ namespace detail { }; + + // + // Specialized extractors for the docstring, keywords, CallPolicies, + // and default implementation of virtual functions + // + template struct doc_extract : tuple_extract< - Tuple, - mpl::logical_not< - is_reference_to_class< - mpl::_1 + Tuple, + mpl::logical_not< + mpl::logical_or< + is_reference_to_class + , is_reference_to_function_pointer + , is_reference_to_function + > > - > > + > { }; @@ -122,17 +140,50 @@ namespace detail { }; - template + // + // A helper class for decoding the optional arguments to def() + // invocations, which can be supplied in any order and are + // discriminated by their type properties. The template parameters + // are expected to be the types of the actual (optional) arguments + // passed to def(). + // + template struct def_helper { + // A tuple type which begins with references to the supplied + // arguments and ends with actual representatives of the default + // types. typedef boost::tuples::tuple< - T1 const&, T2 const&, T3 const&, default_call_policies, keywords<0>, char const*, void(*)() + T1 const& + , T2 const& + , T3 const& + , T4 const& + , default_call_policies + , keywords<0> + , char const* + , void(*)() // A function pointer type which is never an + // appropriate default implementation > all_t; - def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil) {} - def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil) {} - def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3) {} + // Constructors; these initialize an member of the tuple type + // shown above. + def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil,m_nil) {} + def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil,m_nil) {} + def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3,m_nil) {} + def_helper(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4) : m_all(a1,a2,a3,a4) {} + private: // type + typedef typename default_implementation_extract::result_type default_implementation_t; + + public: // Constant which can be used for static assertions. Users + // must not supply a default implementation for non-class + // methods. + BOOST_STATIC_CONSTANT( + bool, has_default_implementation = ( + !is_same::value)); + + public: // Extractor functions which pull the appropriate value out + // of the tuple char const* doc() const { return doc_extract::extract(m_all); @@ -148,22 +199,15 @@ namespace detail return policy_extract::extract(m_all); } - private: - typedef typename default_implementation_extract::result_type default_implementation_t; - public: - BOOST_STATIC_CONSTANT( - bool, has_default_implementation = ( - !is_same::value)); - default_implementation_t default_implementation() const { return policy_extract::extract(m_all); } - all_t m_all; - not_specified m_nil; + private: // data members + all_t m_all; + not_specified m_nil; // for filling in not_specified slots }; -# undef BOOST_PYTHON_DEF_HELPER_TAIL } }} // namespace boost::python::detail From 7609a1c7c66031b1edd5c8aa2a3718c3b1481829 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 25 Nov 2002 22:03:42 +0000 Subject: [PATCH 0929/1042] Refactored; added static assertions against the specification of a default implementation [SVN r16414] --- include/boost/python/def.hpp | 112 ++++++++++++++++------------------- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/include/boost/python/def.hpp b/include/boost/python/def.hpp index 5631fb56..8914818b 100644 --- a/include/boost/python/def.hpp +++ b/include/boost/python/def.hpp @@ -18,15 +18,25 @@ namespace boost { namespace python { namespace detail { - template - void - dispatch_def( - void const*, - char const* name, - Fn fn, - A1 const& a1) + namespace error { - def_helper helper(a1); + // Compile-time error messages + template struct multiple_functions_passed_to_def; + template <> struct multiple_functions_passed_to_def { typedef char type; }; + } + + // + // def_from_helper -- + // + // Use a def_helper to define a regular wrapped function in the current scope. + template + void def_from_helper( + char const* name, F const& fn, Helper const& helper) + { + // Must not try to use default implementations except with method definitions. + typedef typename error::multiple_functions_passed_to_def< + Helper::has_default_implementation + >::type assertion; detail::scope_setattr_doc( name, boost::python::make_function( @@ -35,41 +45,37 @@ namespace detail , helper.keywords()) , helper.doc() ); - } + } - template - void dispatch_def( - void const*, - char const* name, - Fn fn, - A1 const& a1, - A2 const& a2) - { - def_helper helper(a1,a2); + // + // These two overloads discriminate between def() as applied to + // regular functions and def() as applied to the result of + // BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to + // discriminate. + // + template + void + def_maybe_overloads( + char const* name + , Fn fn + , A1 const& a1 + , ...) + { + detail::def_from_helper(name, fn, def_helper(a1)); + } - detail::scope_setattr_doc( - name, python::make_function( - fn - , helper.policies() - , helper.keywords()) - , helper.doc() - ); - } - - template - void dispatch_def( - detail::overloads_base const*, - char const* name, - SigT sig, - StubsT const& stubs) - { - // 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, current, detail::get_signature(sig)); - } + template + void def_maybe_overloads( + char const* name + , SigT sig + , StubsT const& stubs + , detail::overloads_base const*) + { + scope current; + + detail::define_with_defaults( + name, stubs, current, detail::get_signature(sig)); + } } template @@ -81,33 +87,19 @@ void def(char const* name, Fn fn) template void def(char const* name, Arg1T arg1, Arg2T const& arg2) { - // The arguments may be: - // def(name, function) - // def(name, function, policy) - // def(name, function, doc_string) - // def(name, signature, stubs) - - detail::dispatch_def(&arg2, name, arg1, arg2); + detail::def_maybe_overloads(name, arg1, arg2, &arg2); } -template -void def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3) +template +void def(char const* name, F f, A1 const& a1, A2 const& a2) { - detail::dispatch_def(&arg2, name, arg1, arg2, arg3); + detail::def_from_helper(name, f, detail::def_helper(a1,a2)); } template void def(char const* name, F f, A1 const& a1, A2 const& a2, A3 const& a3) { - detail::def_helper helper(a1,a2,a3); - - detail::scope_setattr_doc( - name, python::make_function( - f - , helper.policies() - , helper.keywords()) - , helper.doc() - ); + detail::def_from_helper(name, f, detail::def_helper(a1,a2,a3)); } }} // namespace boost::python From a7e19ffb0b8ab9594a3747fd367b48f1e7c997b1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 26 Nov 2002 01:06:41 +0000 Subject: [PATCH 0930/1042] Refactored def() logic; moved assert_default_constructible into the holder selectorbecause it was getting the wrong answer in some cases. [SVN r16415] --- include/boost/python/class.hpp | 204 +++++++----------- include/boost/python/object/select_holder.hpp | 46 ++++ 2 files changed, 128 insertions(+), 122 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 10d11c1b..9676cd32 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -31,6 +31,8 @@ # include # include +# include + # include # include # include @@ -87,24 +89,6 @@ namespace detail { SelectHolder::register_(); } - - // A helpful compile-time assertion which gives a reasonable error - // message if T can't be default-constructed. - template - class assert_default_constructible - { - template - static int specify_init_arguments_or_no_init_for_class_(U const&); - public: - assert_default_constructible() - { - force_instantiate( - sizeof( - specify_init_arguments_or_no_init_for_class_(T()) - )); - - } - }; } // This is the primary mechanism through which users will expose @@ -132,7 +116,7 @@ class class_ : public objects::class_base typedef objects::select_holder holder_selector; - private: + private: // types typedef typename detail::select_bases function template inline class_(char const* name, init_base const& i) : base(name, id_vector::size, id_vector().ids) @@ -185,6 +166,7 @@ class class_ : public objects::class_base this->set_instance_size(holder_selector::additional_size()); } + // Construct with class name, docstring and init<> function template inline class_(char const* name, char const* doc, init_base const& i) : base(name, id_vector::size, id_vector().ids, doc) @@ -194,16 +176,9 @@ class class_ : public objects::class_base this->set_instance_size(holder_selector::additional_size()); } - // 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. - template - self& def(char const* name, F f) - { - this->def_impl(name, f, detail::keywords<>(), default_call_policies(), 0, &f); - return *this; - } - + public: // member functions + + // Define additional constructors template self& def(init_base const& i) { @@ -211,34 +186,46 @@ class class_ : public objects::class_base return *this; } - template - self& def(char const* name, Arg1T arg1, Arg2T const& arg2) + // 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. + template + self& def(char const* name, F f) { - // The arguments may be: - // def(name, function) - // def(name, function, policy) - // def(name, function, doc_string) - // def(name, signature, overloads) - - dispatch_def(&arg2, name, arg1, arg2); + this->def_impl(name, f, detail::def_helper(0), &f); return *this; } - template - self& def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3) + template + self& def(char const* name, A1 a1, A2 const& a2) + { + this->def_maybe_overloads(name, a1, a2, &a2); + return *this; + } + + template + self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2) { // The arguments are definitely: // def(name, function, policy, doc_string) // def(name, function, doc_string, policy) - dispatch_def(&arg2, name, arg1, arg2, arg3); + this->def_impl( + name, fn + , detail::def_helper(a1,a2) + , &fn); + return *this; } - template - self& def(char const* name, Arg1T arg1, Arg2T const& arg2, Arg3T const& arg3, Arg4T const& arg4) + template + self& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3) { - dispatch_def(&arg2, name, arg1, arg2, arg3, arg4); + this->def_impl( + name, fn + , detail::def_helper(a1,a2,a3) + , &fn); + return *this; } @@ -319,13 +306,18 @@ class class_ : public objects::class_base private: // helper functions - template + inline void register_() const; + + // + // These two overloads discriminate between def() as applied to + // things which are already wrapped into callable python::object + // instances and everything else. + // + template inline void def_impl( char const* name , Fn fn - , Keywords const& keywords - , Policies const& policies - , char const* doc + , Helper const& helper , ...) { objects::add_to_namespace( @@ -333,30 +325,39 @@ class class_ : public objects::class_base make_function( // 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, keywords) - , doc); + , helper.policies(), helper.keywords()) + , helper.doc()); } - template + template inline void def_impl( char const* name , F f - , detail::keywords<> const& - , default_call_policies const& - , char const* doc + , detail::def_helper const& helper , object const*) { - objects::add_to_namespace(*this, name, f, doc); + // It's too late to specify anything other than docstrings, if + // the callable object is already wrapped. + BOOST_STATIC_ASSERT( + (is_same::value + || detail::is_string_literal::value)); + + objects::add_to_namespace(*this, name, f, helper.doc()); } - inline void register_() const; - + // + // These two overloads discriminate between def() as applied to + // regular functions and def() as applied to the result of + // BOOST_PYTHON_FUNCTION_OVERLOADS(). The final argument is used to + // discriminate. + // template - void dispatch_def( - detail::overloads_base const*, - char const* name, - SigT sig, - OverloadsT const& overloads) + void def_maybe_overloads( + char const* name + , SigT sig + , OverloadsT const& overloads + , detail::overloads_base const*) + { // convert sig to a type_list (see detail::get_signature in signature.hpp) // before calling detail::define_with_defaults. @@ -365,67 +366,26 @@ class class_ : public objects::class_base } template - void dispatch_def( - void const*, - char const* name, - Fn fn, - A1 const& a1) + void def_maybe_overloads( + char const* name + , Fn fn + , A1 const& a1 + , ...) { - detail::def_helper helper(a1); - this->def_impl( name, fn - , helper.keywords() - , helper.policies() - , helper.doc() + , detail::def_helper(a1) , &fn); } - - template - void dispatch_def( - void const*, - char const* name, - Fn fn, - A1 const& a1, - A2 const& a2) - { - detail::def_helper helper(a1,a2); - - this->def_impl( - name, fn - , helper.keywords() - , helper.policies() - , helper.doc() - , &fn); - } - - template - void dispatch_def( - void const*, - char const* name, - Fn fn, - A1 const& a1, - A2 const& a2, - A3 const& a3 - ) - { - detail::def_helper helper(a1,a2,a3); - - this->def_impl( - name, fn - , helper.keywords() - , helper.policies() - , helper.doc() - , &fn); - } }; // // implementations // - // register converters + +// register converters template inline void class_::register_() const { @@ -442,9 +402,9 @@ inline class_::class_(char const* name, char const* doc) : base(name, id_vector::size, id_vector().ids, doc) { this->register_(); - detail::assert_default_constructible(); - this->def(init<>()); this->set_instance_size(holder_selector::additional_size()); + holder_selector::execute((held_type*)0).assert_default_constructible(); + this->def(init<>()); } template diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index c1396169..2b4b8fbe 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -26,10 +26,51 @@ namespace boost { namespace python { namespace objects { namespace detail { + // A helpful compile-time assertion which gives a reasonable error + // message if T can't be default-constructed. + template + class assert_default_constructible + { + static int specify_init_arguments_or_no_init_for_class_(T const&); + public: + assert_default_constructible() + { + force_instantiate( + sizeof( + specify_init_arguments_or_no_init_for_class_(T()) + )); + + } + }; + + template + static int specify_init_arguments_or_no_init_for_class_(T const&); + + template + void check_default_constructible(T*, U*, mpl::bool_c) + { + python::detail::force_instantiate( + sizeof(specify_init_arguments_or_no_init_for_class_(U((::PyObject*)0))) + ); + } + + template + void check_default_constructible(T*, T*, mpl::bool_c) + { + python::detail::force_instantiate( + sizeof(specify_init_arguments_or_no_init_for_class_(T())) + ); + } + template struct select_value_holder { BOOST_STATIC_CONSTANT(bool, selector = (!is_same::value) | has_back_reference::value); + + static void assert_default_constructible() + { + detail::check_default_constructible((T*)0,(Held*)0,mpl::bool_c()); + } typedef typename mpl::if_c< selector @@ -61,6 +102,11 @@ namespace detail typedef typename python::pointee::type pointee; BOOST_STATIC_CONSTANT(bool, selector = (!is_same::value) | has_back_reference::value); + static void assert_default_constructible() + { + detail::check_default_constructible((T*)0,(pointee*)0,mpl::bool_c()); + } + typedef typename mpl::if_c< selector , pointer_holder_back_reference From f9c8bf15bb7feca467f11c3c14c37d867148c08e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 26 Nov 2002 02:47:17 +0000 Subject: [PATCH 0931/1042] Restore CWPro7.2 to health. Also improve source organization slightly [SVN r16416] --- include/boost/python/signature.hpp | 2 +- src/converter/arg_to_python_base.cpp | 19 ------------------- src/converter/registry.cpp | 20 +++++++++++++++++++- test/data_members.cpp | 9 +++++++-- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index fd613940..5469fd5a 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -91,7 +91,7 @@ get_signature(RT(*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T))) # undef N # define BOOST_PP_ITERATION_PARAMS_2 \ - (3, (0, BOOST_PYTHON_CV_COUNT - 1, )) + (3, (0, 3, )) # include BOOST_PP_ITERATE() #else diff --git a/src/converter/arg_to_python_base.cpp b/src/converter/arg_to_python_base.cpp index 1101f591..9849071e 100644 --- a/src/converter/arg_to_python_base.cpp +++ b/src/converter/arg_to_python_base.cpp @@ -12,25 +12,6 @@ namespace boost { namespace python { namespace converter { -PyObject* registration::to_python(void const volatile* source) const -{ - if (this->m_to_python == 0) - { - handle<> msg( - ::PyString_FromFormat( - "No to_python (by-value) converter found for C++ type: %s" - , this->target_type.name())); - - PyErr_SetObject(PyExc_TypeError, msg.get()); - - throw_error_already_set(); - } - - return source == 0 - ? incref(Py_None) - : this->m_to_python(const_cast(source)); -} - namespace detail { arg_to_python_base::arg_to_python_base( diff --git a/src/converter/registry.cpp b/src/converter/registry.cpp index 85ece278..b4891941 100644 --- a/src/converter/registry.cpp +++ b/src/converter/registry.cpp @@ -18,7 +18,7 @@ namespace boost { namespace python { namespace converter { -PyTypeObject* registration::get_class_object() const +BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const { if (this->m_class_object == 0) { @@ -33,6 +33,24 @@ PyTypeObject* registration::get_class_object() const return this->m_class_object; } +BOOST_PYTHON_DECL PyObject* registration::to_python(void const volatile* source) const +{ + if (this->m_to_python == 0) + { + handle<> msg( + ::PyString_FromFormat( + "No to_python (by-value) converter found for C++ type: %s" + , this->target_type.name())); + + PyErr_SetObject(PyExc_TypeError, msg.get()); + + throw_error_already_set(); + } + + return source == 0 + ? incref(Py_None) + : this->m_to_python(const_cast(source)); +} namespace // { diff --git a/test/data_members.cpp b/test/data_members.cpp index 889ea9d1..13c46b0d 100644 --- a/test/data_members.cpp +++ b/test/data_members.cpp @@ -48,7 +48,7 @@ BOOST_PYTHON_MODULE(data_members_ext) .def_readonly("x", &X::x) .add_property("fair_value", get_fair_value) ; - + class_("Y", init()) .def("value", &Y::value) .def("set", &Y::set) @@ -57,7 +57,12 @@ BOOST_PYTHON_MODULE(data_members_ext) class_("Var", init()) .def_readonly("name", &Var::name) - .def_readonly("name2", &Var::name2) + .def_readonly("name2", +#if __MWERKS__ <= 0x2407 // Old MWerks mis-deduces the type here as `char* Var::*' + (char const* Var::*) +#endif + &Var::name2 + ) .def_readwrite("value", &Var::value) .def_readonly("y", &Var::y) From 98c2bf8ff2bcfb558862c2b8c8e110f393f36a50 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 27 Nov 2002 02:18:52 +0000 Subject: [PATCH 0932/1042] Restored some missing v1 acknowledgements [SVN r16432] --- doc/v2/acknowledgments.html | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/doc/v2/acknowledgments.html b/doc/v2/acknowledgments.html index 38455564..3e12f3d0 100644 --- a/doc/v2/acknowledgments.html +++ b/doc/v2/acknowledgments.html @@ -81,8 +81,21 @@ Laboratories.

      Ullrich - Koethe provided the implementation of inheritance and special - method/operator support in the first version of Boost.Python.

      + Koethe had independently developed a similar system. When he + discovered Boost.Python v1, he generously contributed countless hours of + coding and much insight into improving it. He is responsible for an early + version of the support for function overloading and wrote the support for + reflecting C++ inheritance relationships. He has helped to improve + error-reporting from both Python and C++ (we hope to do as well in v2 + again soon), and has designed the original support for exposing numeric + operators, including a way to avoid explicit coercion by means of + overloading.

      + +

      The members of the boost mailing list and the Python community + supplied invaluable early feedback. In particular, Ron Clarke, Mark + Evans, Anton Gluck, Chuck Ingold, Prabhu Ramachandran, and Barry Scott + took the brave step of trying to use Boost.Python while it was still in + early stages of development.

      The first version of Boost.Python would not have been possible without the support of Dragon Systems, which supported its development and @@ -91,8 +104,8 @@

      Revised - 13 November, 2002 - + 26 November, 2002 +

      © Copyright Date: Wed, 27 Nov 2002 06:19:13 +0000 Subject: [PATCH 0933/1042] Use boost is_polymorphic trait [SVN r16433] --- include/boost/python/object/inheritance.hpp | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/include/boost/python/object/inheritance.hpp b/include/boost/python/object/inheritance.hpp index 88b556ff..de8cae43 100644 --- a/include/boost/python/object/inheritance.hpp +++ b/include/boost/python/object/inheritance.hpp @@ -10,6 +10,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -30,25 +31,6 @@ BOOST_PYTHON_DECL void* find_static_type(void* p, class_id src, class_id dst); BOOST_PYTHON_DECL void* find_dynamic_type(void* p, class_id src, class_id dst); -// is_polymorphic test from John Maddock -template -struct is_polymorphic -{ - struct d1 : public T - { - d1(); - char padding[256]; - }; - struct d2 : public T - { - d2(); - virtual ~d2(); - virtual void foo(); - char padding[256]; - }; - BOOST_STATIC_CONSTANT(bool, value = (sizeof(d2) == sizeof(d1))); -}; - // // a generator with an execute() function which, given a source type // and a pointer to an object of that type, returns its most-derived From fb7c450b7611577d8ccd86f1021b85a90de2d941 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 27 Nov 2002 06:19:45 +0000 Subject: [PATCH 0934/1042] Added is_reference_to_member_function_pointer [SVN r16434] --- .../boost/python/detail/indirect_traits.hpp | 66 +++++++++++++++++-- test/indirect_traits_test.cpp | 16 ++++- 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index ee361adf..31481d76 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -12,6 +12,7 @@ # include # include # include +# include # include # include # include @@ -69,6 +70,25 @@ struct is_pointer_to_function : is_function { }; +template +struct is_reference_to_member_function_pointer_impl : mpl::bool_c +{ +}; + +template +struct is_reference_to_member_function_pointer_impl + : is_member_function_pointer::type> +{ +}; + + +template +struct is_reference_to_member_function_pointer + : is_reference_to_member_function_pointer_impl +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) +}; + template struct is_reference_to_function_pointer_aux { @@ -85,7 +105,11 @@ struct is_reference_to_function_pointer_aux template struct is_reference_to_function_pointer - : mpl::if_c::value, mpl::bool_c, is_reference_to_function_pointer_aux >::type + : mpl::if_c< + is_reference_to_function::value + , mpl::bool_c + , is_reference_to_function_pointer_aux + >::type { }; @@ -372,18 +396,52 @@ struct is_reference_to_pointer BOOST_STATIC_CONSTANT( bool, value = (is_reference::value - && sizeof(reference_to_pointer_helper(t)) == sizeof(inner_yes_type)) + && sizeof((reference_to_pointer_helper)(t)) == sizeof(inner_yes_type)) ); }; template struct is_reference_to_function_pointer - : mpl::if_ - , is_pointer_to_function_aux, mpl::bool_c >::type + : mpl::if_< + is_reference + , is_pointer_to_function_aux + , mpl::bool_c + >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) }; + +template +struct is_member_function_pointer_help + : mpl::if_, inner_yes_type, inner_no_type> +{}; + +template +typename is_member_function_pointer_help::type member_function_pointer_helper(V&); +outer_no_type member_function_pointer_helper(...); + +template +struct is_pointer_to_member_function_aux +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof((member_function_pointer_helper)(t)) == sizeof(inner_yes_type)); + typedef mpl::bool_c type; +}; + +template +struct is_reference_to_member_function_pointer + : mpl::if_< + is_reference + , is_pointer_to_member_function_aux + , mpl::bool_c + >::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) +}; + template typename is_class_help::type reference_to_class_helper(V const volatile&); outer_no_type reference_to_class_helper(...); diff --git a/test/indirect_traits_test.cpp b/test/indirect_traits_test.cpp index 561a946a..26c6e895 100644 --- a/test/indirect_traits_test.cpp +++ b/test/indirect_traits_test.cpp @@ -9,22 +9,27 @@ struct X {}; int main() { -using namespace boost::python::detail; + using namespace boost::python::detail; + + typedef void (X::*pmf)(); assert(is_reference_to_function::value); assert(!is_reference_to_function::value); assert(!is_reference_to_function::value); + assert(!is_reference_to_function::value); assert(!is_pointer_to_function::value); assert(is_pointer_to_function::value); assert(!is_pointer_to_function::value); assert(!is_pointer_to_function::value); + assert(!is_pointer_to_function::value); assert(!is_reference_to_function_pointer::value); assert(!is_reference_to_function_pointer::value); assert(!is_reference_to_function_pointer::value); assert(is_reference_to_function_pointer::value); assert(is_reference_to_function_pointer::value); + assert(!is_reference_to_function_pointer::value); assert(is_reference_to_pointer::value); assert(is_reference_to_pointer::value); @@ -34,6 +39,7 @@ using namespace boost::python::detail; assert(is_reference_to_pointer::value); assert(is_reference_to_pointer::value); assert(is_reference_to_pointer::value); + assert(!is_reference_to_pointer::value); assert(!is_reference_to_pointer::value); assert(!is_reference_to_pointer::value); @@ -86,6 +92,14 @@ using namespace boost::python::detail; assert(is_pointer_to_class::value); assert(is_pointer_to_class::value); assert(is_pointer_to_class::value); + + assert(is_reference_to_member_function_pointer::value); + assert(is_reference_to_member_function_pointer::value); + assert(is_reference_to_member_function_pointer::value); + assert(is_reference_to_member_function_pointer::value); + assert(!is_reference_to_member_function_pointer::value); + assert(!is_reference_to_member_function_pointer::value); + assert(!is_reference_to_member_function_pointer::value); return 0; } From 0ad3bfd0ab43e18c7bb1aacc8a5afeab8a392c6b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 27 Nov 2002 07:04:32 +0000 Subject: [PATCH 0935/1042] Finally fixed polymorphism issues [SVN r16435] --- include/boost/python/class.hpp | 144 ++++++++++++++---- include/boost/python/detail/caller.hpp | 8 +- include/boost/python/detail/def_helper.hpp | 35 ++--- .../boost/python/detail/indirect_traits.hpp | 18 ++- include/boost/python/detail/invoke.hpp | 27 +--- .../python/detail/this_arg_from_python.hpp | 140 ++++++++--------- .../boost/python/object/function_handle.hpp | 1 + test/Jamfile | 1 + test/polymorphism.cpp | 62 ++++++++ test/polymorphism.py | 38 +++++ 10 files changed, 324 insertions(+), 150 deletions(-) create mode 100644 test/polymorphism.cpp create mode 100644 test/polymorphism.py diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 9676cd32..3025c58f 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -8,37 +8,43 @@ # include # include + # include - # include - # include -# include -# include -# include -# include -# include -# include -# include -# include -# include # include -# include -# include # include -# include # include # include # include -# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include +# include +# include +# include +# include + +# include # include # include # include # include # include +# include + namespace boost { namespace python { enum no_init_t { no_init }; @@ -89,6 +95,54 @@ namespace detail { SelectHolder::register_(); } + + namespace error + { + // + // A meta-assertion mechanism which prints nice error messages and + // backtraces on lots of compilers. Usage: + // + // assertion::failed + // + // where C is an MPL metafunction class + // + + template struct assertion_failed { }; + template struct assertion_ok { typedef C failed; }; + + template + struct assertion + : mpl::if_, assertion_failed >::type + {}; + + // + // Checks for validity of arguments used to define virtual + // functions with default implementations. + // + + template + void not_a_derived_class_member(Default) {} + + template + struct virtual_function_default +# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 + : assertion >::failed + , assertion >::failed +# endif + { + template + static void + must_be_derived_class_member(Default const&) + { + typedef typename assertion > >::failed test0; +# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + typedef typename assertion >::failed test1; + typedef typename assertion >::failed test2; +# endif + not_a_derived_class_member(Fn()); + } + }; + } } // This is the primary mechanism through which users will expose @@ -313,22 +367,6 @@ class class_ : public objects::class_base // things which are already wrapped into callable python::object // instances and everything else. // - template - inline void def_impl( - char const* name - , Fn fn - , Helper const& helper - , ...) - { - objects::add_to_namespace( - *this, name, - make_function( - // 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) - , helper.policies(), helper.keywords()) - , helper.doc()); - } - template inline void def_impl( char const* name @@ -345,6 +383,50 @@ class class_ : public objects::class_base objects::add_to_namespace(*this, name, f, helper.doc()); } + template + inline void def_impl( + char const* name + , Fn fn + , Helper const& helper + , ...) + { + objects::add_to_namespace( + *this, name, + make_function( + // 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) + , helper.policies(), helper.keywords()) + , helper.doc()); + + this->def_default(name, fn, helper, mpl::bool_c()); + } + + // + // These two overloads handle the definition of default + // implementation overloads for virtual functions. The second one + // handles the case where no default implementation was specified. + // + template + inline void def_default( + char const* name + , Fn fn + , Helper const& helper + , mpl::bool_c) + { + detail::error::virtual_function_default::must_be_derived_class_member( + helper.default_implementation()); + + objects::add_to_namespace( + *this, name, + make_function( + helper.default_implementation(), helper.policies(), helper.keywords()) + ); + } + + template + inline void def_default(char const*, Fn, Helper const&, mpl::bool_c) + { } + // // These two overloads discriminate between def() as applied to // regular functions and def() as applied to the result of diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index 808f95f5..3477f64d 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -56,7 +56,7 @@ struct select_result_converter }; -template struct caller_gen; +template struct caller_arity; # define BOOST_PYTHON_NEXT(init,name,n) \ typedef BOOST_PP_IF(n,typename BOOST_PP_CAT(name,BOOST_PP_DEC(n)) ::next, init) name##n; @@ -81,8 +81,8 @@ template struct caller_gen; template struct caller_base_select { - enum { n_arguments = mpl::size::value - 1 }; - typedef typename caller_gen::template impl type; + enum { arity = mpl::size::value - 1 }; + typedef typename caller_arity::template impl type; }; // A function object type which wraps C++ objects as Python callable @@ -131,7 +131,7 @@ struct caller # define N BOOST_PP_ITERATION() template <> -struct caller_gen +struct caller_arity { template struct impl diff --git a/include/boost/python/detail/def_helper.hpp b/include/boost/python/detail/def_helper.hpp index fa66f04a..d78ddb81 100644 --- a/include/boost/python/detail/def_helper.hpp +++ b/include/boost/python/detail/def_helper.hpp @@ -97,12 +97,11 @@ namespace detail template struct doc_extract : tuple_extract< - Tuple, - mpl::logical_not< + Tuple + , mpl::logical_not< mpl::logical_or< is_reference_to_class - , is_reference_to_function_pointer - , is_reference_to_function + , is_reference_to_member_function_pointer > > > @@ -118,8 +117,8 @@ namespace detail template struct policy_extract : tuple_extract< - Tuple, - mpl::logical_and< + Tuple + , mpl::logical_and< mpl::logical_not > , is_reference_to_class , mpl::logical_not > @@ -131,12 +130,9 @@ namespace detail template struct default_implementation_extract : tuple_extract< - Tuple, - mpl::logical_or< - is_reference_to_function_pointer - , is_reference_to_function + Tuple + , is_reference_to_member_function_pointer > - > { }; @@ -161,8 +157,8 @@ namespace detail , default_call_policies , keywords<0> , char const* - , void(*)() // A function pointer type which is never an - // appropriate default implementation + , void(not_specified::*)() // A function pointer type which is never an + // appropriate default implementation > all_t; // Constructors; these initialize an member of the tuple type @@ -172,15 +168,16 @@ namespace detail def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3,m_nil) {} def_helper(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4) : m_all(a1,a2,a3,a4) {} - private: // type + private: // types typedef typename default_implementation_extract::result_type default_implementation_t; + + public: // Constants which can be used for static assertions. - public: // Constant which can be used for static assertions. Users - // must not supply a default implementation for non-class - // methods. + // Users must not supply a default implementation for non-class + // methods. BOOST_STATIC_CONSTANT( bool, has_default_implementation = ( - !is_same::value)); + !is_same::value)); public: // Extractor functions which pull the appropriate value out // of the tuple @@ -201,7 +198,7 @@ namespace detail default_implementation_t default_implementation() const { - return policy_extract::extract(m_all); + return default_implementation_extract::extract(m_all); } private: // data members diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index 31481d76..d53e396c 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -302,8 +302,7 @@ typename is_const_help::type reference_to_const_helper(V&); outer_no_type reference_to_const_helper(...); -template -struct is_reference_to_const_helper1 +struct true_helper1 { template struct apply @@ -315,6 +314,21 @@ struct is_reference_to_const_helper1 }; }; +template +struct is_reference_to_const_helper1 : true_helper1 +{ +# if 0 + template + struct apply + { + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); + }; +# endif +}; + template <> struct is_reference_to_const_helper1 : false_helper1 { diff --git a/include/boost/python/detail/invoke.hpp b/include/boost/python/detail/invoke.hpp index 4f59f44c..b83c6e34 100644 --- a/include/boost/python/detail/invoke.hpp +++ b/include/boost/python/detail/invoke.hpp @@ -11,7 +11,6 @@ # include # include # include -# include # include @@ -52,7 +51,6 @@ template struct is_defaulted_virtual_fn; // Tag types describing invocation methods struct fn_tag {}; struct mem_fn_tag {}; -struct virtual_fn_tag {}; // A metafunction returning the appropriate tag type for invoking an // object of type T. @@ -61,11 +59,7 @@ struct invoke_tag : mpl::if_< is_member_function_pointer , mem_fn_tag - , typename mpl::if_< - is_defaulted_virtual_fn - , virtual_fn_tag - , fn_tag - >::type + , fn_tag > {}; @@ -106,25 +100,6 @@ inline PyObject* invoke(mem_fn_tag, void_result_to_python, F& f, TC& tc BOOST_PP return none(); } -template -inline PyObject* invoke(virtual_fn_tag, RC*, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) -{ - return RC()( - tc.use_default() - ? f.default_impl(tc() BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) - : (tc().*f.dispatch)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac, () BOOST_PP_INTERCEPT)) ); -} - -template -inline PyObject* invoke(virtual_fn_tag, void_result_to_python, F& f, TC& tc BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, AC, & ac) ) -{ - if (tc.use_default()) - f.default_impl(tc() BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, ac,()BOOST_PP_INTERCEPT)); - else - (tc().*f.dispatch)(BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, ac,()BOOST_PP_INTERCEPT)); - return none(); -} - # undef N #endif // BOOST_PP_IS_ITERATING diff --git a/include/boost/python/detail/this_arg_from_python.hpp b/include/boost/python/detail/this_arg_from_python.hpp index aa8c6c7b..36ad7ae7 100644 --- a/include/boost/python/detail/this_arg_from_python.hpp +++ b/include/boost/python/detail/this_arg_from_python.hpp @@ -1,3 +1,4 @@ +#error obsolete // Copyright David Abrahams 2002. Permission to copy, use, // modify, sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided @@ -7,6 +8,7 @@ # define THIS_ARG_FROM_PYTHON_DWA20021122_HPP # include +# include # include @@ -14,75 +16,79 @@ namespace boost { namespace python { namespace detail { - template - struct this_ptr_arg_from_python : converter::arg_lvalue_from_python_base - { - this_ptr_arg_from_python(PyObject* x) - : converter::arg_lvalue_from_python_base( - converter::get_lvalue_from_python(x, converter::registered::converters)) - {} +template +struct this_ptr_arg_from_python : converter::arg_lvalue_from_python_base +{ + this_ptr_arg_from_python(PyObject* x) + : converter::arg_lvalue_from_python_base( + converter::get_lvalue_from_python(x, converter::registered::converters)) + {} - typedef T* result_type; - T* operator()() const - { - return static_cast(this->result()); - } - - bool use_default() const - { - return dynamic_cast((*this)()); - } - }; - - template - struct this_ref_arg_from_python : this_ptr_arg_from_python - { - typedef this_ptr_arg_from_python base; - this_ref_arg_from_python(PyObject* x) : base(x) {} - typedef T& result_type; - - result_type operator()() const - { - return *this->base::operator()(); - } - }; + typedef T* result_type; + T* operator()() const + { + return static_cast(this->result()); + } - // An MPL metafunction class which returns a `this' converter - // appropriate for ArgType, where the target of the member function is - // a class of type T. - template - struct gen_this_from_python - { - // Note: there will almost always be an compile-time error if the - // argument type is neither a reference nor a pointer, since T* - // will be extracted in that case and passed on to the wrapped - // function. - template struct apply - { - BOOST_STATIC_CONSTANT( - bool, use_ptr - = is_pointer::value - || boost::python::detail::is_reference_to_pointer::value - && boost::python::detail::is_reference_to_const::value - && !boost::python::detail::is_reference_to_volatile::value); - - typedef typename mpl::if_c< - use_ptr - , this_ptr_arg_from_python - , this_ref_arg_from_python - >::type type; - }; - }; + bool use_default() const + { + return dynamic_cast((*this)()); + } +}; - // An MPL iterator which iterates over a sequence whose first element - // is gen_this_from_python and the remainder of which is an endless - // sequence of gen_arg_from_python - template - struct method_args_from_python - { - typedef gen_this_from_python type; - typedef args_from_python next; - }; +template +struct this_ref_arg_from_python : this_ptr_arg_from_python +{ + typedef this_ptr_arg_from_python base; + this_ref_arg_from_python(PyObject* x) : base(x) {} + typedef T& result_type; + + result_type operator()() const + { + return *this->base::operator()(); + } +}; + +// An MPL metafunction class which returns a `this' converter +// appropriate for ArgType, where the target of the member function is +// a class of type T. +template +struct gen_this_from_python +{ + // Note: there will almost always be an compile-time error if the + // argument type is neither a reference nor a pointer, since T* + // will be extracted in that case and passed on to the wrapped + // function. + template struct apply + { + BOOST_STATIC_CONSTANT( + bool, use_ptr + = is_pointer::value + || boost::python::detail::is_reference_to_pointer::value + && boost::python::detail::is_reference_to_const::value + && !boost::python::detail::is_reference_to_volatile::value); + + typedef typename mpl::if_c< + is_back_reference::value + , nullary > + , typename mpl::if_c< + use_ptr + , this_ptr_arg_from_python + , this_ref_arg_from_python + >::type + >::type type; + }; +}; + +// An MPL iterator which iterates over a sequence whose first element +// is gen_this_from_python and the remainder of which is an endless +// sequence of gen_arg_from_python +template +struct method_args_from_python +{ + typedef gen_this_from_python type; + typedef args_from_python next; +}; template struct defaulted_virtual_fn @@ -94,8 +100,6 @@ struct defaulted_virtual_fn Default default_impl; }; - - # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template struct is_defaulted_virtual_fn diff --git a/include/boost/python/object/function_handle.hpp b/include/boost/python/object/function_handle.hpp index 96cf82a5..29efa2be 100644 --- a/include/boost/python/object/function_handle.hpp +++ b/include/boost/python/object/function_handle.hpp @@ -10,6 +10,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { diff --git a/test/Jamfile b/test/Jamfile index 65c3bb76..d6e8175e 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -61,6 +61,7 @@ run ../test/embedding.cpp ../build/boost_python : # requirements $(PYTHON_PROPERTIES) ; +bpl-test polymorphism ; bpl-test auto_ptr ; bpl-test minimal ; bpl-test args ; diff --git a/test/polymorphism.cpp b/test/polymorphism.cpp new file mode 100644 index 00000000..f648448c --- /dev/null +++ b/test/polymorphism.cpp @@ -0,0 +1,62 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include + +using namespace boost::python; + +struct Callback +{ + Callback(PyObject* o) : mSelf(o) {} + PyObject* mSelf; +}; + +struct A +{ + virtual ~A(){} + virtual std::string f() { return "A::f()"; } +}; + +struct ACallback : A, Callback +{ + ACallback (PyObject* self) : Callback(self) {} + + + std::string f() + { + return call_method(mSelf, "f"); + } + + std::string default_f() + { + return A::f(); + } +}; + +struct B : A +{ + virtual std::string f() { return "B::f()"; } +}; + +A& getBCppObj () +{ + static B b; + return b; +} + +std::string call_f(A& a) { return a.f(); } + +BOOST_PYTHON_MODULE_INIT(polymorphism_ext) +{ + class_("A") + .def("f", &A::f, &ACallback::default_f) + ; + + def("getBCppObj", getBCppObj, return_value_policy()); + + def("call_f", call_f); +} + +//#include "module_tail.cpp" diff --git a/test/polymorphism.py b/test/polymorphism.py new file mode 100644 index 00000000..b1836d79 --- /dev/null +++ b/test/polymorphism.py @@ -0,0 +1,38 @@ +import unittest +from polymorphism_ext import * + +class PolymorphTest(unittest.TestCase): + + def testReturnCpp(self): + + # Python Created Object With Same Id As + # Cpp Created B Object + # b = B(872) + + # Get Reference To Cpp Created B Object + a = getBCppObj() + + # Python Created B Object and Cpp B Object + # Should have same result by calling f() + self.failUnlessEqual ('B::f()', a.f()) + self.failUnlessEqual ('B::f()', call_f(a)) + self.failUnlessEqual ('A::f()', call_f(A())) + + def testReturnPy(self): + + class C(A): + def f(self): + return 'C.f' + + c = C() + + self.failUnlessEqual ('C.f', c.f()) + self.failUnlessEqual ('C.f', call_f(c)) + +if __name__ == "__main__": + + # remove the option which upsets unittest + import sys + sys.argv = [ x for x in sys.argv if x != '--broken-auto-ptr' ] + + unittest.main() From c4df3c65625ed14d5d194bc936b2af42bd35615e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 27 Nov 2002 14:23:07 +0000 Subject: [PATCH 0936/1042] Bug fix [SVN r16442] --- include/boost/python/object/select_holder.hpp | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index 2b4b8fbe..45d8cb31 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -15,6 +15,7 @@ # include # include # include +# include # include # include # include @@ -28,21 +29,6 @@ namespace detail { // A helpful compile-time assertion which gives a reasonable error // message if T can't be default-constructed. - template - class assert_default_constructible - { - static int specify_init_arguments_or_no_init_for_class_(T const&); - public: - assert_default_constructible() - { - force_instantiate( - sizeof( - specify_init_arguments_or_no_init_for_class_(T()) - )); - - } - }; - template static int specify_init_arguments_or_no_init_for_class_(T const&); From bbef71dc7dd852e3a5cf70b0efc9319c943102bb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 29 Nov 2002 20:23:54 +0000 Subject: [PATCH 0937/1042] Progress on embedding example for unix. [SVN r16458] --- test/Jamfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/Jamfile b/test/Jamfile index d6e8175e..54602d8d 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -59,7 +59,9 @@ run ../test/embedding.cpp ../build/boost_python : # program args : # input files : # requirements - $(PYTHON_PROPERTIES) ; + $(PYTHON_PROPERTIES) + $(PYTHON_LIB_PATH) + $(PYTHON_EMBEDDED_LIBRARY) ; bpl-test polymorphism ; bpl-test auto_ptr ; From 43a9571b2c9f7364e3bd644eb30b8d35f63cacbc Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 29 Nov 2002 22:43:27 +0000 Subject: [PATCH 0938/1042] Fixed some technical problems with smart pointer support uncovered by STLPort's debug mode. Unfortunately, had to expand Dereferenceable requirements. [SVN r16459] --- doc/v2/Dereferenceable.html | 17 +++++++++++++- .../boost/python/object/pointer_holder.hpp | 22 +++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/doc/v2/Dereferenceable.html b/doc/v2/Dereferenceable.html index 8f5b38b5..965e4043 100644 --- a/doc/v2/Dereferenceable.html +++ b/doc/v2/Dereferenceable.html @@ -49,10 +49,25 @@ type is a model of Dereferenceable. +If x is not a pointer type, it also must satsify the following expression: + + + + + + + + + + + +
      ExpressionOperational Semantics
      x.get()&*x, or a null pointer +
      +


      Revised - 13 November, 2002 + 29 November, 2002

      © Copyright Dave diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 3a65dcb3..5625f092 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -32,6 +32,18 @@ namespace boost { namespace python { namespace objects { +template +typename bool is_null(T const& p, ...) +{ + return p.get() == 0; +} + +template +bool is_null(T* p, int) +{ + return p == 0; +} + # define BOOST_PYTHON_UNFORWARD_LOCAL(z, n, _) BOOST_PP_COMMA_IF(n) (typename unforward::type)(a##n) template @@ -98,9 +110,12 @@ void* pointer_holder::holds(type_info dst_t) if (dst_t == python::type_id()) return &this->m_p; + if (objects::is_null(this->m_p, 0)) + return 0; + type_info src_t = python::type_id(); - return src_t == dst_t ? &*this->m_p - : find_dynamic_type(&*this->m_p, src_t, dst_t); + Value* p = &*this->m_p; + return src_t == dst_t ? p : find_dynamic_type(p, src_t, dst_t); } template @@ -109,6 +124,9 @@ void* pointer_holder_back_reference::holds(type_info dst_t) if (dst_t == python::type_id()) return &this->m_p; + if (objects::is_null(this->m_p, 0)) + return 0; + if (dst_t == python::type_id()) return &*this->m_p; From 8467f36b80930c32ff44d15d7625350df4c61057 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 1 Dec 2002 04:40:05 +0000 Subject: [PATCH 0939/1042] Kill errant `typename' [SVN r16464] --- include/boost/python/object/pointer_holder.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index 5625f092..c35e012e 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -33,7 +33,7 @@ namespace boost { namespace python { namespace objects { template -typename bool is_null(T const& p, ...) +bool is_null(T const& p, ...) { return p.get() == 0; } From ae9f39490647ee8d726d75d6b7c9e73bbd220d37 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 1 Dec 2002 16:07:54 +0000 Subject: [PATCH 0940/1042] Added reset() [SVN r16465] --- include/boost/python/handle.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/boost/python/handle.hpp b/include/boost/python/handle.hpp index 7fea1134..98534944 100755 --- a/include/boost/python/handle.hpp +++ b/include/boost/python/handle.hpp @@ -109,6 +109,7 @@ class handle T& operator* () const; T* get() const; T* release(); + void reset(); operator bool_type() const // never throws { @@ -227,6 +228,13 @@ inline T* handle::release() return result; } +template +inline void handle::reset() +{ + python::xdecref(m_p); + m_p = 0; +} + // Because get_managed_object must return a non-null PyObject*, we // return Py_None if the handle is null. template From 3c19b89d9acc14d009ab0e06f74ef59466ca6f3e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 1 Dec 2002 16:14:44 +0000 Subject: [PATCH 0941/1042] Added reset() [SVN r16466] --- doc/v2/handle.html | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/v2/handle.html b/doc/v2/handle.html index 3e44aa32..b52689f8 100644 --- a/doc/v2/handle.html +++ b/doc/v2/handle.html @@ -154,6 +154,7 @@ namespace boost { namespace python T* operator-> () const; T& operator* () const; T* get() const; + void reset(); T* release(); operator bool_type() const; // never throws @@ -261,6 +262,14 @@ T* release(); x; +

      +void reset();
      +
      + +
      +
      Effects: *this = handle<T>();
      +
      +

      Class handle observers

      
      From 328697952f74c098a4f0c4a10850d15741153c80 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Mon, 2 Dec 2002 01:37:39 +0000
      Subject: [PATCH 0942/1042] automatic shared_ptr from_python conversions
      
      [SVN r16467]
      ---
       include/boost/python/class.hpp                |   2 +-
       .../converter/as_to_python_function.hpp       |  50 ++++++++
       .../converter/shared_ptr_from_python.hpp      |  53 ++++++++
       .../converter/to_python_function_type.hpp     |  37 ------
       .../boost/python/object/class_converters.hpp  |  10 +-
       include/boost/python/object/class_wrapper.hpp |  23 ++--
       include/boost/python/object/select_holder.hpp |   5 +-
       include/boost/python/to_python_converter.hpp  |   2 +-
       test/Jamfile                                  |   1 +
       test/bienstman1.cpp                           |   2 +-
       test/m1.cpp                                   |   6 +-
       test/multi_arg_constructor.cpp                |   3 +-
       test/shared_ptr.cpp                           | 120 ++++++++++++++++++
       test/shared_ptr.py                            | 102 +++++++++++++++
       test/virtual_functions.cpp                    |   2 +-
       15 files changed, 355 insertions(+), 63 deletions(-)
       create mode 100644 include/boost/python/converter/as_to_python_function.hpp
       create mode 100644 include/boost/python/converter/shared_ptr_from_python.hpp
       create mode 100644 test/shared_ptr.cpp
       create mode 100644 test/shared_ptr.py
      
      diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp
      index 3025c58f..5177e339 100644
      --- a/include/boost/python/class.hpp
      +++ b/include/boost/python/class.hpp
      @@ -85,7 +85,7 @@ namespace detail
         static inline void register_copy_constructor(mpl::bool_c const&, SelectHolder const& , T* = 0)
         {
             typedef typename SelectHolder::type holder;
      -      force_instantiate(objects::class_wrapper >());
      +      force_instantiate(objects::class_cref_wrapper >());
             SelectHolder::register_();
         }
       
      diff --git a/include/boost/python/converter/as_to_python_function.hpp b/include/boost/python/converter/as_to_python_function.hpp
      new file mode 100644
      index 00000000..3c2f97e5
      --- /dev/null
      +++ b/include/boost/python/converter/as_to_python_function.hpp
      @@ -0,0 +1,50 @@
      +// Copyright David Abrahams 2002. Permission to copy, use,
      +// modify, sell and distribute this software is granted provided this
      +// copyright notice appears in all copies. This software is provided
      +// "as is" without express or implied warranty, and with no claim as
      +// to its suitability for any purpose.
      +#ifndef AS_TO_PYTHON_FUNCTION_DWA2002121_HPP
      +# define AS_TO_PYTHON_FUNCTION_DWA2002121_HPP
      +# include 
      +
      +namespace boost { namespace python { namespace converter { 
      +
      +// Given a typesafe to_python conversion function, produces a
      +// to_python_function_t which can be registered in the usual way.
      +template 
      +struct as_to_python_function
      +{
      +    // Assertion functions used to prevent wrapping of converters
      +    // which take non-const reference parameters. The T* argument in
      +    // the first overload ensures it isn't used in case T is a
      +    // reference.
      +    template 
      +    static int convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0);
      +    template 
      +    static int convert_function_must_take_value_or_const_reference(U(*)(T const&), long ...);
      +        
      +    static PyObject* convert(void const* x)
      +    {
      +        BOOST_STATIC_ASSERT(
      +            sizeof(
      +                convert_function_must_take_value_or_const_reference(&ToPython::convert, 1L))
      +            == sizeof(int));
      +        
      +        // Yes, the const_cast below opens a hole in const-correctness,
      +        // but it's needed to convert auto_ptr to python.
      +        //
      +        // How big a hole is it?  It allows ToPython::convert() to be
      +        // a function which modifies its argument. The upshot is that
      +        // client converters applied to const objects may invoke
      +        // undefined behavior. The damage, however, is limited by the
      +        // use of the assertion function. Thus, the only way this can
      +        // modify its argument is if T is an auto_ptr-like type. There
      +        // is still a const-correctness hole w.r.t. auto_ptr const,
      +        // but c'est la vie.
      +        return ToPython::convert(*const_cast(static_cast(x)));
      +    }
      +};
      +
      +}}} // namespace boost::python::converter
      +
      +#endif // AS_TO_PYTHON_FUNCTION_DWA2002121_HPP
      diff --git a/include/boost/python/converter/shared_ptr_from_python.hpp b/include/boost/python/converter/shared_ptr_from_python.hpp
      new file mode 100644
      index 00000000..1535740a
      --- /dev/null
      +++ b/include/boost/python/converter/shared_ptr_from_python.hpp
      @@ -0,0 +1,53 @@
      +// Copyright David Abrahams 2002. Permission to copy, use,
      +// modify, sell and distribute this software is granted provided this
      +// copyright notice appears in all copies. This software is provided
      +// "as is" without express or implied warranty, and with no claim as
      +// to its suitability for any purpose.
      +#ifndef SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
      +# define SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
      +
      +# include 
      +# include 
      +
      +namespace boost { namespace python { namespace converter { 
      +
      +template 
      +struct shared_ptr_from_python
      +{
      +    shared_ptr_from_python()
      +    {
      +        converter::registry::insert(&convertible, &construct, type_id >());
      +    }
      +
      +    static shared_ptr_from_python const registration;
      + private:
      +    static void* convertible(PyObject* p)
      +    {
      +        return p == Py_None
      +            ? p
      +            : converter::get_lvalue_from_python(p, registered::converters)
      +            ;
      +    }
      +    
      +    static void construct(PyObject* source, rvalue_from_python_stage1_data* data)
      +    {
      +        void* const storage = ((converter::rvalue_from_python_storage >*)data)->storage.bytes;
      +        // Deal with the "None" case.
      +        if (data->convertible == source)
      +            new (storage) shared_ptr();
      +        else
      +            new (storage) shared_ptr(
      +                static_cast(data->convertible),
      +                shared_ptr_deleter(handle<>(borrowed(source)))
      +                );
      +        
      +        data->convertible = storage;
      +    }
      +};
      +
      +template 
      +shared_ptr_from_python const shared_ptr_from_python::registration;
      +
      +}}} // namespace boost::python::converter
      +
      +#endif // SHARED_PTR_FROM_PYTHON_DWA20021130_HPP
      diff --git a/include/boost/python/converter/to_python_function_type.hpp b/include/boost/python/converter/to_python_function_type.hpp
      index debad150..b53ff649 100644
      --- a/include/boost/python/converter/to_python_function_type.hpp
      +++ b/include/boost/python/converter/to_python_function_type.hpp
      @@ -15,43 +15,6 @@ namespace boost { namespace python { namespace converter {
       // type-safety is preserved through runtime registration.
       typedef PyObject* (*to_python_function_t)(void const*);
       
      -// Given a typesafe to_python conversion function, produces a
      -// to_python_function_t which can be registered in the usual way.
      -template 
      -struct as_to_python_function
      -{
      -    // Assertion functions used to prevent wrapping of converters
      -    // which take non-const reference parameters. The T* argument in
      -    // the first overload ensures it isn't used in case T is a
      -    // reference.
      -    template 
      -    static int convert_function_must_take_value_or_const_reference(U(*)(T), int, T* = 0);
      -    template 
      -    static int convert_function_must_take_value_or_const_reference(U(*)(T const&), long ...);
      -        
      -    static PyObject* convert(void const* x)
      -    {
      -
      -        BOOST_STATIC_ASSERT(
      -            sizeof(
      -                convert_function_must_take_value_or_const_reference(&ToPython::convert, 1L))
      -            == sizeof(int));
      -        
      -        // Yes, the const_cast below opens a hole in const-correctness,
      -        // but it's needed to convert auto_ptr to python.
      -        //
      -        // How big a hole is it?  It allows ToPython::convert() to be
      -        // a function which modifies its argument. The upshot is that
      -        // client converters applied to const objects may invoke
      -        // undefined behavior. The damage, however, is limited by the
      -        // use of the assertion function. Thus, the only way this can
      -        // modify its argument is if T is an auto_ptr-like type. There
      -        // is still a const-correctness hole w.r.t. auto_ptr const,
      -        // but c'est la vie.
      -        return ToPython::convert(*const_cast(static_cast(x)));
      -    }
      -};
      -
       }}} // namespace boost::python::converter
       
       #endif // TO_PYTHON_FUNCTION_TYPE_DWA200236_HPP
      diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp
      index 83a16ac8..bd7ead82 100644
      --- a/include/boost/python/object/class_converters.hpp
      +++ b/include/boost/python/object/class_converters.hpp
      @@ -6,13 +6,18 @@
       #ifndef CLASS_CONVERTERS_DWA2002119_HPP
       # define CLASS_CONVERTERS_DWA2002119_HPP
       
      -# include 
       # include 
      +# include 
      +
       # include 
       # include 
      +
       # include 
      +
       # include 
       
      +# include 
      +
       namespace boost { namespace python { namespace objects { 
       
       //////////////////////////////////////////////////////////////////////
      @@ -62,13 +67,14 @@ struct register_base_of
           }
       };
       
      -// Brings into existence all converters associated with a class Bases
      +// Brings into existence all converters associated with a class. Bases
       // is expected to be an mpl sequence of base types.
       template 
       inline void register_class_from_python(Derived* = 0, Bases* = 0)
       {
           // cause the static registration to be instantiated.
           python::detail::force_instantiate(instance_finder::registration);
      +    python::detail::force_instantiate(converter::shared_ptr_from_python::registration);
           
           // register all up/downcasts here
           register_dynamic_id();
      diff --git a/include/boost/python/object/class_wrapper.hpp b/include/boost/python/object/class_wrapper.hpp
      index fe802989..f0fad309 100644
      --- a/include/boost/python/object/class_wrapper.hpp
      +++ b/include/boost/python/object/class_wrapper.hpp
      @@ -11,12 +11,16 @@
       
       namespace boost { namespace python { namespace objects { 
       
      -// Used to convert objects of type Src to wrapped C++ classes by
      -// building a new instance object and installing a Holder constructed
      -// from a Src const&.
      -template 
      -struct class_wrapper
      -    : to_python_converter >
      +//
      +// These two classes adapt the static execute function of a class
      +// MakeInstance execute() function returning a new PyObject*
      +// reference. The first one is used for class copy constructors, and
      +// the second one is used to handle smart pointers.
      +//
      +
      +template 
      +struct class_cref_wrapper
      +    : to_python_converter >
       {
           static PyObject* convert(Src const& x)
           {
      @@ -24,12 +28,9 @@ struct class_wrapper
           }
       };
       
      -// Used to convert objects of type Src to wrapped C++ classes by
      -// building a new instance object and installing a Holder constructed
      -// from a Src value.
      -template 
      +template 
       struct class_value_wrapper
      -    : to_python_converter >
      +    : to_python_converter >
       {
           static PyObject* convert(Src x)
           {
      diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp
      index 45d8cb31..67adacb8 100644
      --- a/include/boost/python/object/select_holder.hpp
      +++ b/include/boost/python/object/select_holder.hpp
      @@ -130,10 +130,7 @@ namespace detail
             static inline void register_(mpl::bool_c)
             {
                 python::detail::force_instantiate(
      -              objects::class_value_wrapper<
      -                Ptr
      -                , type
      -                , make_instance >());
      +              objects::class_value_wrapper >());
           
                 python::detail::force_instantiate(
                     instance_finder::registration);
      diff --git a/include/boost/python/to_python_converter.hpp b/include/boost/python/to_python_converter.hpp
      index 814b9ba7..86bf95a3 100644
      --- a/include/boost/python/to_python_converter.hpp
      +++ b/include/boost/python/to_python_converter.hpp
      @@ -7,7 +7,7 @@
       # define TO_PYTHON_CONVERTER_DWA200221_HPP
       
       # include 
      -# include 
      +# include 
       # include 
       
       namespace boost { namespace python { 
      diff --git a/test/Jamfile b/test/Jamfile
      index 54602d8d..f1cc1302 100644
      --- a/test/Jamfile
      +++ b/test/Jamfile
      @@ -63,6 +63,7 @@ run ../test/embedding.cpp ../build/boost_python
           $(PYTHON_LIB_PATH)
           $(PYTHON_EMBEDDED_LIBRARY) ;
       
      +bpl-test shared_ptr ;
       bpl-test polymorphism ;
       bpl-test auto_ptr ;
       bpl-test minimal ;
      diff --git a/test/bienstman1.cpp b/test/bienstman1.cpp
      index 7f1736e0..4f3b107d 100644
      --- a/test/bienstman1.cpp
      +++ b/test/bienstman1.cpp
      @@ -25,7 +25,7 @@ BOOST_PYTHON_MODULE(bienstman1_ext)
         using boost::python::return_value_policy;
         using boost::python::reference_existing_object;
       
      -  class_ >("A");
      +  class_("A");
       
         class_("V", no_init)
             .def("inside", &V::inside, 
      diff --git a/test/m1.cpp b/test/m1.cpp
      index d9202b8b..9efdecb5 100644
      --- a/test/m1.cpp
      +++ b/test/m1.cpp
      @@ -258,15 +258,15 @@ BOOST_PYTHON_MODULE(m1)
       
           // sequence points don't ensure that "A" is constructed before "B"
           // or "C" below if we make them part of the same chain
      -    class_, shared_ptr >("B")
      +    class_ >("B")
               .def("name", &B::name)
               ;
               
      -    class_, shared_ptr >("C")
      +    class_ >("C")
               .def("name", &C::name)
               ;
       
      -    class_, bases >("D")
      +    class_ >("D")
               .def("name", &D::name)
               ;
       
      diff --git a/test/multi_arg_constructor.cpp b/test/multi_arg_constructor.cpp
      index d80f57ab..8c3e8846 100644
      --- a/test/multi_arg_constructor.cpp
      +++ b/test/multi_arg_constructor.cpp
      @@ -13,9 +13,8 @@ struct A
       BOOST_PYTHON_MODULE(multi_arg_constructor_ext)
       {
         using namespace boost::python;
      -  using boost::shared_ptr;
       
      -  class_ >(
      +  class_(
             "A"
             , init()
             )
      diff --git a/test/shared_ptr.cpp b/test/shared_ptr.cpp
      new file mode 100644
      index 00000000..c249547f
      --- /dev/null
      +++ b/test/shared_ptr.cpp
      @@ -0,0 +1,120 @@
      +// Copyright David Abrahams 2002. Permission to copy, use,
      +// modify, sell and distribute this software is granted provided this
      +// copyright notice appears in all copies. This software is provided
      +// "as is" without express or implied warranty, and with no claim as
      +// to its suitability for any purpose.
      +
      +#include 
      +#include 
      +#include 
      +#include 
      +#include 
      +#include 
      +#include "test_class.hpp"
      +
      +#include 
      +
      +using namespace boost::python;
      +using boost::shared_ptr;
      +
      +typedef test_class<> X;
      +typedef test_class<1> Y;
      +
      +template 
      +struct functions
      +{
      +    static int look(shared_ptr const& x)
      +    {
      +        return (x.get()) ? x->value() : -1;
      +    }
      +
      +    static void store(shared_ptr x)
      +    {
      +        storage = x;
      +    }
      +
      +    static void release_store()
      +    {
      +        store(shared_ptr());
      +    }
      +    
      +    static void modify(shared_ptr& x)
      +    {
      +        x.reset();
      +    }
      +
      +    static shared_ptr get() { return storage; }
      +        
      +    static int look_store()
      +    {
      +        return look(get());
      +    }
      +    
      +    static void expose()
      +    {
      +        def("look", &look);
      +        def("store", &store);
      +        def("modify", &modify); 
      +        def("look_store", &look_store); 
      +    }
      +
      +    static shared_ptr storage;
      +};
      +
      +template  shared_ptr functions::storage;
      +
      +struct Z : test_class<2>
      +{
      +    Z(int x) : test_class<2>(x) {}
      +    virtual int v() { return this->value(); }
      +};
      +
      +struct ZWrap : Z
      +{
      +    ZWrap(PyObject* self, int x)
      +        : Z(x), m_self(self) {}
      +
      +    
      +    virtual int v() { return call_method(m_self, "v"); }
      +    int default_v() { return Z::v(); }
      +    
      +
      +    PyObject* m_self;
      +};
      +
      +static int stored_v() { return functions::get()->v(); }
      +
      +BOOST_PYTHON_MODULE(shared_ptr_ext)
      +{
      +    class_("X", init())
      +        .def("value", &X::value)
      +        ;
      +
      +    functions::expose();
      +    def("x_count", &X::count);
      +    def("x_release", &functions::release_store);
      +    def("x_look_store", &functions::look_store);
      +    
      +    class_ >("Y", init())
      +        .def("value", &Y::value)
      +        ;
      +    
      +    functions::expose();
      +    def("y_count", &Y::count);
      +    def("y_release", &functions::release_store);
      +    def("y_look_store", &functions::look_store);
      +
      +    class_("Z", init())
      +        .def("value", &Z::value)
      +        .def("v", &Z::v, &ZWrap::default_v)
      +        ;
      +    
      +    functions::expose();
      +    def("z_count", &Z::count);
      +    def("z_release", &functions::release_store);
      +    def("z_look_store", &functions::look_store);
      +    def("stored_v", &stored_v);
      +}
      +
      +#include "module_tail.cpp"
      +
      diff --git a/test/shared_ptr.py b/test/shared_ptr.py
      new file mode 100644
      index 00000000..62e0b4c5
      --- /dev/null
      +++ b/test/shared_ptr.py
      @@ -0,0 +1,102 @@
      +'''
      +>>> from shared_ptr_ext import *
      +>>> class P(Z):
      +...     def v(self):
      +...         return -Z.v(self);
      +...     def __del__(self):
      +...         print 'bye'
      +...
      +>>> p = P(12)
      +>>> p.value()
      +12
      +>>> p.v()
      +-12
      +>>> look(p)
      +12
      +>>> try: modify(p)
      +... except TypeError: pass
      +... else: 'print expected a TypeError'
      +>>> look(None)
      +-1
      +>>> store(p)
      +>>> del p
      +>>> stored_v()
      +-12
      +>>> z_count()
      +1
      +>>> z_look_store()
      +12
      +>>> z_release()
      +bye
      +>>> z_count()
      +0
      +
      +>>> z = Z(13)
      +>>> z.value()
      +13
      +>>> z.v()
      +13
      +>>> try: modify(z)
      +... except TypeError: pass
      +... else: 'print expected a TypeError'
      +>>> store(z)
      +>>> del z
      +>>> stored_v()
      +13
      +>>> z_count()
      +1
      +>>> z_look_store()
      +13
      +>>> z_release()
      +>>> z_count()
      +0
      +
      +>>> x = X(17)
      +>>> x.value()
      +17
      +>>> look(x)
      +17
      +>>> try: modify(x)
      +... except TypeError: pass
      +... else: 'print expected a TypeError'
      +>>> look(None)
      +-1
      +>>> store(x)
      +>>> del x
      +>>> x_count()
      +1
      +>>> x_look_store()
      +17
      +>>> x_release()
      +>>> x_count()
      +0
      +
      +
      +>>> y = Y(19)
      +>>> y.value()
      +19
      +>>> modify(y)
      +>>> look(y)
      +-1
      +>>> store(Y(23))
      +>>> y_count()
      +1
      +>>> y_look_store()
      +23
      +>>> y_release()
      +>>> y_count()
      +0
      +'''
      +
      +def run(args = None):
      +    import sys
      +    import doctest
      +
      +    if args is not None:
      +        sys.argv = args
      +    return doctest.testmod(sys.modules.get(__name__))
      +    
      +if __name__ == '__main__':
      +    print "running..."
      +    import sys
      +    sys.exit(run()[0])
      diff --git a/test/virtual_functions.cpp b/test/virtual_functions.cpp
      index 92a6e78c..4fa6c7ee 100644
      --- a/test/virtual_functions.cpp
      +++ b/test/virtual_functions.cpp
      @@ -96,7 +96,7 @@ BOOST_PYTHON_MODULE(virtual_functions_ext)
               .def("f", &concrete_callback::f_impl)
               ;
               
      -    class_
      +    class_("abstract", init())
                   
               .def("value", &abstract::value)
      
      From bf8bb83ec5c12c143642a4c10cdbadda8a688469 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Mon, 2 Dec 2002 12:40:18 +0000
      Subject: [PATCH 0943/1042] initial commit
      
      [SVN r16473]
      ---
       .../python/converter/shared_ptr_deleter.hpp   | 23 +++++++++++++++++++
       1 file changed, 23 insertions(+)
       create mode 100644 include/boost/python/converter/shared_ptr_deleter.hpp
      
      diff --git a/include/boost/python/converter/shared_ptr_deleter.hpp b/include/boost/python/converter/shared_ptr_deleter.hpp
      new file mode 100644
      index 00000000..eb02e18a
      --- /dev/null
      +++ b/include/boost/python/converter/shared_ptr_deleter.hpp
      @@ -0,0 +1,23 @@
      +// Copyright David Abrahams 2002. Permission to copy, use,
      +// modify, sell and distribute this software is granted provided this
      +// copyright notice appears in all copies. This software is provided
      +// "as is" without express or implied warranty, and with no claim as
      +// to its suitability for any purpose.
      +#ifndef SHARED_PTR_DELETER_DWA2002121_HPP
      +# define SHARED_PTR_DELETER_DWA2002121_HPP
      +
      +namespace boost { namespace python { namespace converter { 
      +
      +struct shared_ptr_deleter
      +{
      +    shared_ptr_deleter(handle<> owner)
      +        : owner(owner) {}
      +
      +    void operator()(void const*) { owner.reset(); }
      +        
      +    handle<> owner;
      +};
      +
      +}}} // namespace boost::python::converter
      +
      +#endif // SHARED_PTR_DELETER_DWA2002121_HPP
      
      From 34c9d895c8e30550d9992690683c754e126188d8 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Mon, 2 Dec 2002 14:29:11 +0000
      Subject: [PATCH 0944/1042] Relaxed rules for using scope()
      
      [SVN r16476]
      ---
       doc/tutorial/doc/enums.html     |  4 ++--
       doc/tutorial/doc/quickstart.txt |  4 ++--
       doc/v2/scope.html               |  9 ++++++---
       include/boost/python/scope.hpp  | 16 ++++++++++++++--
       test/nested.cpp                 |  9 +++++----
       5 files changed, 29 insertions(+), 13 deletions(-)
      
      diff --git a/doc/tutorial/doc/enums.html b/doc/tutorial/doc/enums.html
      index 0cee713c..29c9623b 100644
      --- a/doc/tutorial/doc/enums.html
      +++ b/doc/tutorial/doc/enums.html
      @@ -67,10 +67,10 @@ You can access those values in Python as

      where my_module is the module where the enum is declared. You can also create a new scope around a class:

      -    scope in_X(class_<X>("X")
      +    scope in_X = class_<X>("X")
                           .def( ... )
                           .def( ... )
      -                );
      +                ;
       
           // Expose X::nested as X.nested
           enum_<X::nested>("nested")
      diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt
      index ec3917cc..de75ccf9 100644
      --- a/doc/tutorial/doc/quickstart.txt
      +++ b/doc/tutorial/doc/quickstart.txt
      @@ -1148,10 +1148,10 @@ You can access those values in Python as
       where my_module is the module where the enum is declared. You can also
       create a new scope around a class:
       
      -    scope in_X(class_("X")
      +    scope in_X = class_("X")
                           .def( ... )
                           .def( ... )
      -                );
      +                ;
       
           // Expose X::nested as X.nested
           enum_("nested")
      diff --git a/doc/v2/scope.html b/doc/v2/scope.html
      index 20a29063..1d578d36 100644
      --- a/doc/v2/scope.html
      +++ b/doc/v2/scope.html
      @@ -81,13 +81,15 @@
       namespace boost { namespace python
       {
         class scope : public object, private noncopyable
      +"object.html#object-spec">object
         {
          public:
      -      explicit scope(object const&);
      +      scope(scope const&);
      +      scope(object const&);
             scope();
             ~scope()
      +   private:
      +      void operator=(scope const&);
         };
       }}
       
      @@ -95,6 +97,7 @@ namespace boost { namespace python

      Class scope constructors and destructor

      +explicit scope(scope const& x);
       explicit scope(object const& x);
       
      Stores a reference to the current associated scope object, and sets the diff --git a/include/boost/python/scope.hpp b/include/boost/python/scope.hpp index 086c7d87..2e208bfc 100644 --- a/include/boost/python/scope.hpp +++ b/include/boost/python/scope.hpp @@ -13,16 +13,20 @@ namespace boost { namespace python { class BOOST_PYTHON_DECL scope - : public object, private noncopyable + : public object { public: - explicit inline scope(object const&); + inline scope(scope const&); + inline scope(object const&); inline scope(); inline ~scope(); private: // data members PyObject* m_previous_scope; + private: // unimplemented functions + void operator=(scope const&); + private: // static members // Use a PyObject* to avoid problems with static destruction after Py_Finalize @@ -59,6 +63,14 @@ namespace converter }; } +// Placing this after the specialization above suppresses a CWPro8.3 bug +inline scope::scope(scope const& new_scope) + : object(new_scope) + , m_previous_scope(current_scope) +{ + current_scope = python::incref(new_scope.ptr()); +} + }} // namespace boost::python #endif // SCOPE_DWA2002724_HPP diff --git a/test/nested.cpp b/test/nested.cpp index 12fd7bb1..2ccea6f2 100644 --- a/test/nested.cpp +++ b/test/nested.cpp @@ -33,10 +33,11 @@ BOOST_PYTHON_MODULE(nested_ext) using namespace boost::python; // Establish X as the current scope. - scope x_class( - class_("X", init()) - .def(str(self)) - ); + scope x_class + = class_("X", init()) + .def(str(self)) + ; + // Y will now be defined in the current scope class_("Y", init()) From 8b79380977078e5ce457a8d2e58f05c9551f7d46 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 2 Dec 2002 16:18:35 +0000 Subject: [PATCH 0945/1042] Less-taxing version of MPL lambda support for msvc6/7 [SVN r16480] --- include/boost/python/detail/mpl_lambda.hpp | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 include/boost/python/detail/mpl_lambda.hpp diff --git a/include/boost/python/detail/mpl_lambda.hpp b/include/boost/python/detail/mpl_lambda.hpp new file mode 100644 index 00000000..33918c9b --- /dev/null +++ b/include/boost/python/detail/mpl_lambda.hpp @@ -0,0 +1,35 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MPL_LAMBDA_DWA2002122_HPP +# define MPL_LAMBDA_DWA2002122_HPP + +# include + +# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 +# define BOOST_PYTHON_MPL_LAMBDA_SUPPORT(i,name,params) \ + struct rebind; \ + }; \ + template \ + struct name < BOOST_PP_ENUM_PARAMS_Z(1, i, X) >::rebind \ + { \ + BOOST_STATIC_CONSTANT(int, arity = i); \ + BOOST_PP_LIST_FOR_EACH_I_R( \ + 1 \ + , BOOST_MPL_AUX_LAMBDA_SUPPORT_ARG_TYPEDEF_FUNC \ + , typedef \ + , BOOST_PP_TUPLE_TO_LIST(i,params) \ + ) \ + \ + template< BOOST_MPL_PP_PARAMS(i,typename U) > struct apply \ + : name< BOOST_MPL_PP_PARAMS(i,U) > \ + { \ + }; \ + /**/ +# else +# define BOOST_PYTHON_MPL_LAMBDA_SUPPORT BOOST_MPL_AUX_LAMBDA_SUPPORT +# endif + +#endif // MPL_LAMBDA_DWA2002122_HPP From 9163c40a1a47f86f241916384df67a79d030d0d1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 2 Dec 2002 19:41:45 +0000 Subject: [PATCH 0946/1042] Further suppressed internal structure overflow problems which were cropping up with msvc6/7. [SVN r16482] --- include/boost/python/args.hpp | 6 +- .../boost/python/detail/indirect_traits.hpp | 14 +- include/boost/python/detail/mpl_lambda.hpp | 33 ++++- include/boost/python/detail/msvc_typeinfo.hpp | 96 ++++++------- .../python/detail/this_arg_from_python.hpp | 126 ------------------ include/boost/python/init.hpp | 8 +- test/Jamfile | 3 +- test/test_builtin_converters.cpp | 22 +-- test/test_builtin_converters2.cpp | 10 -- 9 files changed, 87 insertions(+), 231 deletions(-) delete mode 100644 include/boost/python/detail/this_arg_from_python.hpp delete mode 100644 test/test_builtin_converters2.cpp diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index 9a5902ae..eaf5818f 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -20,7 +20,7 @@ # include # include -# include +# include # include # include @@ -66,7 +66,7 @@ namespace detail BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key)); typedef mpl::bool_c type; - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) + BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) }; # else typedef char (&yes_keywords_t)[1]; @@ -90,7 +90,7 @@ namespace detail == sizeof(detail::yes_keywords_t))); typedef mpl::bool_c type; - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) + BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) }; # endif } diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index d53e396c..92748982 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -18,7 +18,7 @@ # include # include # include -# include +# include # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # include @@ -86,7 +86,7 @@ template struct is_reference_to_member_function_pointer : is_reference_to_member_function_pointer_impl { - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) + BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) }; template @@ -192,7 +192,7 @@ struct is_reference_to_class >::value) ); typedef mpl::bool_c type; - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) + BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) }; template @@ -285,7 +285,7 @@ template struct is_pointer_to_function : mpl::if_, is_pointer_to_function_aux, mpl::bool_c >::type { - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_function,(T)) + BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_pointer_to_function,(T)) }; struct false_helper1 @@ -422,7 +422,7 @@ struct is_reference_to_function_pointer , mpl::bool_c >::type { - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) + BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) }; @@ -453,7 +453,7 @@ struct is_reference_to_member_function_pointer , mpl::bool_c >::type { - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) + BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) }; template @@ -470,7 +470,7 @@ struct is_reference_to_class & (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type))) ); typedef mpl::bool_c type; - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) + BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) }; template diff --git a/include/boost/python/detail/mpl_lambda.hpp b/include/boost/python/detail/mpl_lambda.hpp index 33918c9b..edbea72a 100644 --- a/include/boost/python/detail/mpl_lambda.hpp +++ b/include/boost/python/detail/mpl_lambda.hpp @@ -8,12 +8,39 @@ # include -# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 +# if 0 // defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + // This approach fails, unfortunately + +# include +# include + +# define BOOST_PYTHON_LAMBDA_SUPPORT_FORMAL_ARG(R,class_,i,param) \ + BOOST_PP_COMMA_IF(i) class_ param \ + /**/ + +# define BOOST_PYTHON_LAMBDA_SUPPORT_ACTUAL_ARG(R,_,i,param) \ + BOOST_PP_COMMA_IF(i) param \ + /**/ + # define BOOST_PYTHON_MPL_LAMBDA_SUPPORT(i,name,params) \ struct rebind; \ }; \ - template \ - struct name < BOOST_PP_ENUM_PARAMS_Z(1, i, X) >::rebind \ + template < \ + BOOST_PP_LIST_FOR_EACH_I_R( \ + 1 \ + , BOOST_PYTHON_LAMBDA_SUPPORT_FORMAL_ARG \ + , class \ + , BOOST_PP_TUPLE_TO_LIST(i,params) \ + ) \ + > \ + struct name < \ + BOOST_PP_LIST_FOR_EACH_I_R( \ + 1 \ + , BOOST_PYTHON_LAMBDA_SUPPORT_ACTUAL_ARG \ + , class \ + , BOOST_PP_TUPLE_TO_LIST(i,params) \ + ) \ + >::rebind \ { \ BOOST_STATIC_CONSTANT(int, arity = i); \ BOOST_PP_LIST_FOR_EACH_I_R( \ diff --git a/include/boost/python/detail/msvc_typeinfo.hpp b/include/boost/python/detail/msvc_typeinfo.hpp index 92f0f56d..11a8bed4 100644 --- a/include/boost/python/detail/msvc_typeinfo.hpp +++ b/include/boost/python/detail/msvc_typeinfo.hpp @@ -6,12 +6,10 @@ #ifndef MSVC_TYPEINFO_DWA200222_HPP # define MSVC_TYPEINFO_DWA200222_HPP -#include #include -#include -#include -#include -#include +#include +#include + // // Fix for MSVC's broken typeid() implementation which doesn't strip // decoration. This fix doesn't handle cv-qualified array types. It @@ -24,78 +22,62 @@ namespace boost { namespace python { namespace detail { typedef std::type_info const& typeinfo; -templatestruct value_id_accessor; - -template<> -struct value_id_accessor<0> -{ - template - static typeinfo get(T*) { return typeid(T); } -}; - -template<> -struct value_id_accessor<1> -{ - template - static typeinfo get(T const*) { return typeid(T); } -}; - -template<> -struct value_id_accessor<2> -{ - template - static typeinfo get(T volatile*) { return typeid(T); } -}; - -template<> -struct value_id_accessor<3> -{ - template - static typeinfo get(T const volatile*) { return typeid(T); } -}; - -template struct bool_t{}; +template +static typeinfo typeid_nonref(T*, ...) { return typeid(T); } template -inline typeinfo typeid_nonref(boost::type* = 0) -{ - bool const c = is_const::value; - bool const v = is_volatile::value; - return value_id_accessor<(2 * v + c)>::get((T*)0); -} +static typeinfo typeid_nonref(T const*, int) { return typeid(T); } template -inline typeinfo typeid_ref(T&(*)()) -{ - return typeid_nonref(); -} +static typeinfo typeid_nonref(T volatile*, int) { return typeid(T); } template -inline typeinfo array_ref_typeid(bool_t, bool_t, boost::type* = 0) -{ - return typeid_ref((T&(*)())0); -} +static typeinfo typeid_nonref(T const volatile*, long) { return typeid(T); } + +# ifdef BOOST_INTEL_CXX_VERSION +// The const volatile overload above confuses Intel when dealing with arrays +template +static typeinfo typeid_nonref(T(*)[N], long) { return typeid(T[N]); } +# endif template -inline typeinfo array_ref_typeid(bool_t, bool_t, boost::type* = 0) +inline typeinfo typeid_ref_1(T&(*)()) { - return typeid_ref((T(*)())0); + return detail::typeid_nonref((T*)0,0L); } +// A non-reference template -inline typeinfo array_ref_typeid(bool_t, bool_t, boost::type* = 0) +inline typeinfo typeid_ref(type*, T&(*)(type)) { - return typeid_ref((T&(*)())0); + return detail::typeid_nonref((T*)0,0L); } +// A reference +template +inline typeinfo typeid_ref(type*, ...) +{ + return detail::typeid_ref_1((T(*)())0); +} + +template< typename T > T&(* is_ref_tester1(type) )(type) { return 0; } +inline char BOOST_TT_DECL is_ref_tester1(...) { return 0; } + template inline typeinfo msvc_typeid(boost::type* = 0) { - typedef bool_t::value> array_tag; - typedef bool_t::value> ref_tag; - return array_ref_typeid(array_tag(), ref_tag(), (boost::type*)0); + return detail::typeid_ref( + (boost::type*)0, detail::is_ref_tester1(type()) + ); } +# ifndef NDEBUG +inline typeinfo assert_array_typeid_compiles() +{ + return msvc_typeid(), msvc_typeid(); +} +# endif + }}} // namespace boost::python::detail # endif // BOOST_MSVC diff --git a/include/boost/python/detail/this_arg_from_python.hpp b/include/boost/python/detail/this_arg_from_python.hpp deleted file mode 100644 index 36ad7ae7..00000000 --- a/include/boost/python/detail/this_arg_from_python.hpp +++ /dev/null @@ -1,126 +0,0 @@ -#error obsolete -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. -#ifndef THIS_ARG_FROM_PYTHON_DWA20021122_HPP -# define THIS_ARG_FROM_PYTHON_DWA20021122_HPP - -# include -# include - -# include - -# include - -namespace boost { namespace python { namespace detail { - -template -struct this_ptr_arg_from_python : converter::arg_lvalue_from_python_base -{ - this_ptr_arg_from_python(PyObject* x) - : converter::arg_lvalue_from_python_base( - converter::get_lvalue_from_python(x, converter::registered::converters)) - {} - - typedef T* result_type; - T* operator()() const - { - return static_cast(this->result()); - } - - bool use_default() const - { - return dynamic_cast((*this)()); - } -}; - -template -struct this_ref_arg_from_python : this_ptr_arg_from_python -{ - typedef this_ptr_arg_from_python base; - this_ref_arg_from_python(PyObject* x) : base(x) {} - typedef T& result_type; - - result_type operator()() const - { - return *this->base::operator()(); - } -}; - -// An MPL metafunction class which returns a `this' converter -// appropriate for ArgType, where the target of the member function is -// a class of type T. -template -struct gen_this_from_python -{ - // Note: there will almost always be an compile-time error if the - // argument type is neither a reference nor a pointer, since T* - // will be extracted in that case and passed on to the wrapped - // function. - template struct apply - { - BOOST_STATIC_CONSTANT( - bool, use_ptr - = is_pointer::value - || boost::python::detail::is_reference_to_pointer::value - && boost::python::detail::is_reference_to_const::value - && !boost::python::detail::is_reference_to_volatile::value); - - typedef typename mpl::if_c< - is_back_reference::value - , nullary > - , typename mpl::if_c< - use_ptr - , this_ptr_arg_from_python - , this_ref_arg_from_python - >::type - >::type type; - }; -}; - -// An MPL iterator which iterates over a sequence whose first element -// is gen_this_from_python and the remainder of which is an endless -// sequence of gen_arg_from_python -template -struct method_args_from_python -{ - typedef gen_this_from_python type; - typedef args_from_python next; -}; - -template -struct defaulted_virtual_fn -{ - defaulted_virtual_fn(VirtualFunction dispatch, Default const& default_impl) - : dispatch(dispatch), default_impl(default_impl) {}; - - VirtualFunction dispatch; - Default default_impl; -}; - -# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_defaulted_virtual_fn -{ BOOST_STATIC_CONSTANT(bool, value = false); }; - -template -struct is_defaulted_virtual_fn > -{ BOOST_STATIC_CONSTANT(bool, value = true); }; -# else -template -struct is_defaulted_virtual_fn -{ - template - static char helper(defaulted_virtual_fn* x); - static char (& helper(...)) [2]; - - BOOST_STATIC_CONSTANT(bool, value = sizeof(helper((T*)0)) == 1); - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_defaulted_virtual_fn,(T)) -}; -# endif - -}}} // namespace boost::python::detail - -#endif // THIS_ARG_FROM_PYTHON_DWA20021122_HPP diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 882ce756..47e6da3c 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -22,7 +22,9 @@ #include #include #include -#include + +# include + #include #include #include @@ -104,7 +106,7 @@ namespace detail sizeof(f(t())) == sizeof(::boost::type_traits::yes_type)); typedef mpl::bool_c type; - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T)) + BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T)) }; /////////////////////////////////////// @@ -126,7 +128,7 @@ namespace detail struct is_optional : is_optional_impl { typedef mpl::bool_c::value> type; - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_optional,(T)) + BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T)) }; #endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) diff --git a/test/Jamfile b/test/Jamfile index f1cc1302..38e23b2e 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -74,8 +74,7 @@ bpl-test exception_translator ; bpl-test pearu1 : test_cltree.py cltree.cpp ; bpl-test try : newtest.py m1.cpp m2.cpp ; -# Had to break this up into two files for MSVC6 -extension builtin_converters : test_builtin_converters.cpp test_builtin_converters2.cpp ../build/boost_python ; +extension builtin_converters : test_builtin_converters.cpp ../build/boost_python ; boost-python-runtest builtin_converters : test_builtin_converters.py builtin_converters ; bpl-test test_pointer_adoption ; diff --git a/test/test_builtin_converters.cpp b/test/test_builtin_converters.cpp index a078d41f..4f08c534 100644 --- a/test/test_builtin_converters.cpp +++ b/test/test_builtin_converters.cpp @@ -44,10 +44,6 @@ using boost::python::handle; using boost::python::object; using boost::python::borrowed; -// MSVC6 can't process this whole file at once, so we break it up into -// two parts. See test_builtin_converters2.cpp -#ifndef BOOST_PYTHON_WRAP_MORE_BUILTIN_CONVERTERS - // Used to test that arbitrary handle<>s can be returned handle get_type(handle<> x) { @@ -61,10 +57,8 @@ handle<> return_null_handle() char const* rewrap_value_mutable_cstring(char* x) { return x; } -void wrap_more(); - BOOST_PYTHON_MODULE(builtin_converters) -{ +{ def("get_type", get_type); def("return_null_handle", return_null_handle); @@ -80,7 +74,7 @@ BOOST_PYTHON_MODULE(builtin_converters) def("rewrap_value_unsigned_long", by_value::rewrap); // using Python's macro instead of Boost's - we don't seem to get the // config right all the time. -# ifdef HAVE_LONG_LONG +#ifdef HAVE_LONG_LONG def("rewrap_value_long_long", by_value::rewrap); def("rewrap_value_unsigned_long_long", by_value::rewrap); # endif @@ -98,14 +92,6 @@ BOOST_PYTHON_MODULE(builtin_converters) // Expose this to illustrate our failings ;-). See test_builtin_converters.py def("rewrap_value_mutable_cstring", rewrap_value_mutable_cstring); - wrap_more(); -} - -#else // BOOST_PYTHON_WRAP_MORE_BUILTIN_CONVERTERS -- this part - // compiled into test_builtin_converters2.cpp - -void wrap_more() -{ def("rewrap_const_reference_bool", by_const_reference::rewrap); def("rewrap_const_reference_char", by_const_reference::rewrap); @@ -133,10 +119,6 @@ void wrap_more() def("rewrap_const_reference_cstring", by_const_reference::rewrap); def("rewrap_const_reference_handle", by_const_reference >::rewrap); def("rewrap_const_reference_object", by_const_reference::rewrap); - - def("rewrap_reference_object", by_reference::rewrap); } -#endif // BOOST_PYTHON_WRAP_MORE_BUILTIN_CONVERTERS - diff --git a/test/test_builtin_converters2.cpp b/test/test_builtin_converters2.cpp deleted file mode 100644 index 37807637..00000000 --- a/test/test_builtin_converters2.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright David Abrahams 2002. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// This file just defines the rest of the tests that MSVC6 can't -// compile unless we break the file up. It's a hack, I'll admit... -#define BOOST_PYTHON_WRAP_MORE_BUILTIN_CONVERTERS -#include "test_builtin_converters.cpp" From 83c38876fe51a661ffd30b2cde1002af170ed833 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 2 Dec 2002 22:57:47 +0000 Subject: [PATCH 0947/1042] Simplify, simplify!! [SVN r16483] --- include/boost/python/detail/msvc_typeinfo.hpp | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/include/boost/python/detail/msvc_typeinfo.hpp b/include/boost/python/detail/msvc_typeinfo.hpp index 11a8bed4..0139984b 100644 --- a/include/boost/python/detail/msvc_typeinfo.hpp +++ b/include/boost/python/detail/msvc_typeinfo.hpp @@ -23,34 +23,19 @@ namespace boost { namespace python { namespace detail { typedef std::type_info const& typeinfo; template -static typeinfo typeid_nonref(T*, ...) { return typeid(T); } - -template -static typeinfo typeid_nonref(T const*, int) { return typeid(T); } - -template -static typeinfo typeid_nonref(T volatile*, int) { return typeid(T); } - -template -static typeinfo typeid_nonref(T const volatile*, long) { return typeid(T); } - -# ifdef BOOST_INTEL_CXX_VERSION -// The const volatile overload above confuses Intel when dealing with arrays -template -static typeinfo typeid_nonref(T(*)[N], long) { return typeid(T[N]); } -# endif +static typeinfo typeid_nonref(T const volatile*) { return typeid(T); } template inline typeinfo typeid_ref_1(T&(*)()) { - return detail::typeid_nonref((T*)0,0L); + return detail::typeid_nonref((T*)0); } // A non-reference template inline typeinfo typeid_ref(type*, T&(*)(type)) { - return detail::typeid_nonref((T*)0,0L); + return detail::typeid_nonref((T*)0); } // A reference From 59b1a8e71c13b87f7ebd07daaf3fc6731a93ada8 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 3 Dec 2002 18:08:12 +0000 Subject: [PATCH 0948/1042] Apply fixes from Dirk Gerrits [SVN r16491] --- doc/v2/handle.html | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/doc/v2/handle.html b/doc/v2/handle.html index b52689f8..aefe8180 100644 --- a/doc/v2/handle.html +++ b/doc/v2/handle.html @@ -174,7 +174,7 @@ virtual ~handle();
      -
      Effects: Py_XDECREF(m_p)
      +
      Effects: Py_XDECREF(upcast<PyObject*>(m_p))
       template <class Y>
      @@ -182,7 +182,8 @@ explicit handle(detail::borrowed<null_ok<Y> >* p);
       
      -
      Effects: Py_XDECREF(m_p)
      +
      Effects: + Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(p);
       template <class Y>
      @@ -191,7 +192,7 @@ explicit handle(null_ok<detail::borrowed<Y> >* p);
       
           
      Effects: - m_p = upcast<T*>(p);
      + Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(p);
       template <class Y>
      @@ -200,7 +201,7 @@ explicit handle(detail::borrowed<Y>* p);
       
           
      Effects: - m_p = upcast<T*>(Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(expect_non_null(p));
      @@ -210,7 +211,7 @@ explicit handle(null_ok<Y>* p);
       
           
      Effects: - Py_XINCREF(p); m_p = upcast<T*>(p);
      + Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(p);
       template <class Y>
      @@ -219,7 +220,7 @@ explicit handle(Y* p);
       
           
      Effects: - Py_XINCREF(p); m_p = upcast<T*>(Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(expect_non_null(p));
      @@ -238,7 +239,7 @@ handle(handle const& r);
      Effects: - m_p = r.m_p; Py_XINCREF(m_p);
      + m_p = r.m_p; Py_XINCREF(upcast<PyObject*>(m_p));

      Class handle @@ -251,7 +252,7 @@ handle& operator=(handle<Y> const & r); // never throws
      Effects: - Py_XINCREF(r.m_p); Py_XDECREF(m_p); m_p = r.m_p;
      + Py_XINCREF(upcast<PyObject*>(r.m_p)); Py_XDECREF(upcast<PyObject*>(m_p)); m_p = r.m_p;
       T* release();
      
      From c772038e774c6b756a201ead5190a28bcef27573 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Wed, 4 Dec 2002 13:36:03 +0000
      Subject: [PATCH 0949/1042] Apply fixes from Dirk Gerrits
       
      
      [SVN r16506]
      ---
       doc/v2/handle.html | 58 +++++++++++++++++++++++-----------------------
       1 file changed, 29 insertions(+), 29 deletions(-)
      
      diff --git a/doc/v2/handle.html b/doc/v2/handle.html
      index aefe8180..eba16a85 100644
      --- a/doc/v2/handle.html
      +++ b/doc/v2/handle.html
      @@ -14,7 +14,7 @@
        span.c3 {color: #ff0000}
        h2.c2 {text-align: center}
        h1.c1 {text-align: center}
      -    
      +        
         
       
         
      @@ -74,7 +74,6 @@
                 
      allow_null
      -
      @@ -91,13 +90,12 @@

      handle is a smart pointer to a Python object type; it holds a pointer of type T*, where T is its template parameter. T must be either a type derived from - PyObject or a POD - type whose initial sizeof(PyObject) bytes are - layout-compatible with PyObject. Use - handle<> at the boundary between tehe - Python/'C' API and high-level code; prefer PyObject or a POD type + whose initial sizeof(PyObject) bytes are layout-compatible + with PyObject. Use handle<> at the + boundary between tehe Python/'C' API and high-level code; prefer object for a generalized - interface to Python objects. + interface to Python objects.

      In this document, the term "upcast" refers to an operation which converts a pointer Y* to a base class @@ -174,7 +172,8 @@ virtual ~handle();

      -
      Effects: Py_XDECREF(upcast<PyObject*>(m_p))
      +
      Effects: + Py_XDECREF(upcast<PyObject*>(m_p))
       template <class Y>
      @@ -182,8 +181,9 @@ explicit handle(detail::borrowed<null_ok<Y> >* p);
       
      -
      Effects: - Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(p);
      +
      Effects: + Py_XINCREF(upcast<PyObject*>(p)); + m_p = upcast<T*>(p);
       template <class Y>
      @@ -192,7 +192,8 @@ explicit handle(null_ok<detail::borrowed<Y> >* p);
       
           
      Effects: - Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(p);
      + Py_XINCREF(upcast<PyObject*>(p)); + m_p = upcast<T*>(p);
       template <class Y>
      @@ -201,7 +202,8 @@ explicit handle(detail::borrowed<Y>* p);
       
           
      Effects: - Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(Py_XINCREF(upcast<PyObject*>(p)); + m_p = upcast<T*>(expect_non_null(p));
      @@ -211,7 +213,7 @@ explicit handle(null_ok<Y>* p);
       
           
      Effects: - Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(p);
      + m_p = upcast<T*>(p);
       template <class Y>
      @@ -220,8 +222,7 @@ explicit handle(Y* p);
       
           
      Effects: - Py_XINCREF(upcast<PyObject*>(p)); m_p = upcast<T*>(m_p = upcast<T*>(expect_non_null(p));
      @@ -252,7 +253,8 @@ handle& operator=(handle<Y> const & r); // never throws
       
           
      Effects: - Py_XINCREF(upcast<PyObject*>(r.m_p)); Py_XDECREF(upcast<PyObject*>(m_p)); m_p = r.m_p;
      + Py_XINCREF(upcast<PyObject*>(r.m_p)); Py_XDECREF( + upcast<PyObject*>(m_p)); m_p = r.m_p;
       T* release();
      @@ -262,13 +264,13 @@ T* release();
             
      Effects: T* x = m_p; m_p = 0;return x;
      -
       void reset();
       
      -
      Effects: *this = handle<T>();
      +
      Effects: + *this = handle<T>();

      Class handle @@ -301,28 +303,26 @@ operator bool_type() const; // never throws

      borrowed

      -template 
      -detail::borrowed* borrowed(T* p)
      +template <class T>
      +detail::borrowed<T>* borrowed(T* p)
       {
      -    return (detail::borrowed*)p;
      +    return (detail::borrowed<T>*)p;
       }
       

      allow_null

      -
      -template 
      -null_ok* allow_null(T* p)
      +template <class T>
      +null_ok<T>* allow_null(T* p)
       {
      -    return (null_ok*)p;
      +    return (null_ok<T>*)p;
       }
       
      -

      Revised - 13 November, 2002 - + 13 November, 2002 +

      © Copyright Date: Wed, 4 Dec 2002 17:10:55 +0000 Subject: [PATCH 0950/1042] Apply fixes from Dirk Gerrits [SVN r16517] --- test/embedding.cpp | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/test/embedding.cpp b/test/embedding.cpp index 6e12c0f9..5b4db3f4 100644 --- a/test/embedding.cpp +++ b/test/embedding.cpp @@ -59,31 +59,40 @@ void test() //- INITIALIZATION -----------------------------------------------------------// // Register the module with the interpreter - PyImport_AppendInittab("embedded_hello", initembedded_hello); + if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1) + throw std::exception("Failed to add embedded_hello to the interpreters " + "builtin modules"); // Initialize the interpreter Py_Initialize(); - // Load the module - PyObject* main_module = PyImport_AddModule("__main__"); - PyObject* main_namespace = PyModule_GetDict(main_module); - Py_INCREF(main_namespace); + // Retrieve the main module + python::handle<> main_module( + python::borrowed(PyImport_AddModule("__main__")) ); + + // Retrieve the main modules namespace + python::handle<> main_namespace( + python::borrowed(PyModule_GetDict(main_module.get())) ); // Define the derived class in Python. // (You'll normally want to put this in a .py file.) - PyObject* result = PyRun_String( + python::handle<> result( + PyRun_String( "from embedded_hello import * \n" "class PythonDerived(Base): \n" " def hello(self): \n" " return 'Hello from Python!' \n", - Py_file_input, main_namespace, main_namespace); - Py_XDECREF(result); + Py_file_input, main_namespace.get(), main_namespace.get()) + ); + // Result is not needed + result.reset(); // Extract the raw Python object representing the just defined derived class - python::handle class_ptr(PyRun_String("PythonDerived\n", Py_eval_input, - main_namespace, main_namespace)); + python::handle<> class_ptr( + PyRun_String("PythonDerived\n", Py_eval_input, + main_namespace.get(), main_namespace.get()) ); - // Wrap the raw Python object in a Boost.Python object using a handle + // Wrap the raw Python object in a Boost.Python object python::object PythonDerived(class_ptr); //- MAIN PROGRAM -------------------------------------------------------------// @@ -92,7 +101,7 @@ void test() CppDerived cpp; std::cout << cpp.hello() << std::endl; - // But now creating and using instances of the Python class is just + // But now creating and using instances of the Python class is almost // as easy! python::object py_base = PythonDerived(); Base& py = python::extract(py_base)(); From 80ea2383a74fd78befe0d485045a23bc537c7020 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 10 Dec 2002 23:05:38 +0000 Subject: [PATCH 0951/1042] Fix references to test library [SVN r16585] --- test/Jamfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/Jamfile b/test/Jamfile index 38e23b2e..67c2c118 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -140,7 +140,7 @@ local UNIT_TEST_PROPERTIES = $(PYTHON_PROPERTIES) BOOST_PYTHON_SUPPRESS_ run indirect_traits_test.cpp ; run destroy_test.cpp ; -run pointer_type_id_test.cpp ../../test/build/test_exec_monitor : : : $(UNIT_TEST_PROPERTIES) ; +run pointer_type_id_test.cpp ../../test/build/boost_test_exec_monitor : : : $(UNIT_TEST_PROPERTIES) ; run member_function_cast.cpp ; run bases.cpp ; run if_else.cpp ; @@ -151,26 +151,26 @@ compile string_literal.cpp ; compile borrowed.cpp : $(UNIT_TEST_PROPERTIES) ; compile object_manager.cpp : $(UNIT_TEST_PROPERTIES) ; -run upcast.cpp ../../test/build/test_exec_monitor +run upcast.cpp ../../test/build/boost_test_exec_monitor : # command-line args : # input files : $(UNIT_TEST_PROPERTIES) ; -run select_holder.cpp ../../test/build/test_exec_monitor +run select_holder.cpp ../../test/build/boost_test_exec_monitor : # command-line args : # input files : $(UNIT_TEST_PROPERTIES) ; -run select_from_python_test.cpp ../src/converter/type_id.cpp ../../test/build/test_exec_monitor +run select_from_python_test.cpp ../src/converter/type_id.cpp ../../test/build/boost_test_exec_monitor : # command-line args : # input files : $(UNIT_TEST_PROPERTIES) ; -run select_arg_to_python_test.cpp ../src/converter/type_id.cpp ../../test/build/test_exec_monitor +run select_arg_to_python_test.cpp ../src/converter/type_id.cpp ../../test/build/boost_test_exec_monitor : # command-line args : # input files : $(UNIT_TEST_PROPERTIES) From eab084c9a29f2c4c1076c67326e111486e4a621e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 13 Dec 2002 19:58:24 +0000 Subject: [PATCH 0952/1042] enum export [SVN r16603] --- doc/v2/enum.html | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/doc/v2/enum.html b/doc/v2/enum.html index 3e0c5a64..a9c6e261 100644 --- a/doc/v2/enum.html +++ b/doc/v2/enum.html @@ -133,6 +133,21 @@ inline enum_<T>& value(char const* name, T x); +

      +inline enum_<T>& export_values();
      +
      + +
      + +
      Effects: sets attributes in the current scope with the + same names and values as all enumeration values exposed so far + by calling value()
      . + +
      Returns: *this
      + +
      +

      Example(s)

      C++ module definition @@ -152,6 +167,7 @@ BOOST_PYTHON_MODULE(enums) enum_<color>("color") .value("red", red) .value("green", green) + .export_values() .value("blue", blue) ; @@ -162,12 +178,23 @@ BOOST_PYTHON_MODULE(enums)

       >>> from enums import *
       
      +>>> identity(red)
      +enums.color.red
      +
       >>> identity(color.red)
       enums.color.red
       
      +>>> identity(green)
      +enums.color.green
      +
       >>> identity(color.green)
       enums.color.green
       
      +>>> identity(blue)
      +Traceback (most recent call last):
      +  File "<stdin>", line 1, in ?
      +NameError: name blue' is not defined
      +
       >>> identity(color.blue)
       enums.color.blue
       
      
      From 4a5817d8ba3110ea649cd28bc5010cbae84bb86b Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Fri, 13 Dec 2002 20:04:34 +0000
      Subject: [PATCH 0953/1042] enum export
      
      [SVN r16604]
      ---
       doc/v2/enum.html                          |  2 +-
       include/boost/python/enum.hpp             | 10 ++++++++++
       include/boost/python/object/enum_base.hpp |  1 +
       src/object/enum.cpp                       | 14 ++++++++++++++
       test/enum.cpp                             |  1 +
       test/enum.py                              | 11 +++++++++++
       todo.txt                                  |  1 +
       7 files changed, 39 insertions(+), 1 deletion(-)
      
      diff --git a/doc/v2/enum.html b/doc/v2/enum.html
      index a9c6e261..525f9d04 100644
      --- a/doc/v2/enum.html
      +++ b/doc/v2/enum.html
      @@ -219,7 +219,7 @@ TypeError: bad argument type for built-in operation
       
           Revised 
           
      -  13 November, 2002
      +  13 December, 2002
         
            
       
      diff --git a/include/boost/python/enum.hpp b/include/boost/python/enum.hpp
      index 1070c06b..b1fac410 100644
      --- a/include/boost/python/enum.hpp
      +++ b/include/boost/python/enum.hpp
      @@ -23,6 +23,9 @@ struct enum_ : public objects::enum_base
           // Add a new enumeration value with the given name and value.
           inline enum_& value(char const* name, T);
       
      +    // Add all of the defined enumeration values to the current scope with the
      +    // same names used here.
      +    inline enum_& export_values();
        private:
           static PyObject* to_python(void const* x);
           static void* convertible_from_python(PyObject* obj);
      @@ -86,6 +89,13 @@ inline enum_& enum_::value(char const* name, T x)
           return *this;
       }
       
      +template 
      +inline enum_& enum_::export_values()
      +{
      +    this->enum_base::export_values();
      +    return *this;
      +}
      +
       }} // namespace boost::python
       
       #endif // ENUM_DWA200298_HPP
      diff --git a/include/boost/python/object/enum_base.hpp b/include/boost/python/object/enum_base.hpp
      index 37cd8f17..8e4a7301 100644
      --- a/include/boost/python/object/enum_base.hpp
      +++ b/include/boost/python/object/enum_base.hpp
      @@ -25,6 +25,7 @@ struct BOOST_PYTHON_DECL enum_base : python::api::object
               , type_info);
       
           void add_value(char const* name, long value);
      +    void export_values();
           
           static PyObject* to_python(PyTypeObject* type, long x);
       };
      diff --git a/src/object/enum.cpp b/src/object/enum.cpp
      index d151a486..c658ead2 100644
      --- a/src/object/enum.cpp
      +++ b/src/object/enum.cpp
      @@ -12,6 +12,8 @@
       #include 
       #include 
       #include 
      +#include 
      +#include 
       #include 
       #include 
       
      @@ -194,6 +196,18 @@ void enum_base::add_value(char const* name_, long value)
           p->name = incref(name.ptr());
       }
       
      +void enum_base::export_values()
      +{
      +    dict d = extract(this->attr("values"))();
      +    list values = d.values();
      +    scope current;
      +    
      +    for (unsigned i = 0, max = len(values); i < max; ++i)
      +    {
      +        api::setattr(current, object(values[i].attr("name")), values[i]);
      +    }
      + }
      +
       PyObject* enum_base::to_python(PyTypeObject* type_, long x)
       {
           object type((type_handle(borrowed(type_))));
      diff --git a/test/enum.cpp b/test/enum.cpp
      index b0dd02ae..fb1439c7 100644
      --- a/test/enum.cpp
      +++ b/test/enum.cpp
      @@ -19,6 +19,7 @@ BOOST_PYTHON_MODULE(enum_ext)
               .value("red", red)
               .value("green", green)
               .value("blue", blue)
      +        .export_values()
               ;
           
           def("identity", identity_);
      diff --git a/test/enum.py b/test/enum.py
      index e21f8eb8..00484670 100644
      --- a/test/enum.py
      +++ b/test/enum.py
      @@ -20,6 +20,17 @@ enum_ext.color.green
       enum_ext.color(3)
       
       >>> identity(color(4))
      +enum_ext.color.blue
      +
      +  --- check export to scope ---
      +
      +>>> identity(red)
      +enum_ext.color.red
      +
      +>>> identity(green)
      +enum_ext.color.green
      +
      +>>> identity(blue)
       enum_ext.color.blue
       
       >>> try: identity(1)
      diff --git a/todo.txt b/todo.txt
      index 0123d9bd..e6a0f2d3 100644
      --- a/todo.txt
      +++ b/todo.txt
      @@ -6,6 +6,7 @@ types
       
       FILE* conversions: http://aspn.activestate.com/ASPN/Mail/Message/1411366
       
      +Finish shared_ptr support: http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1456023
       
       Medium Priority:
       ----------------
      
      From abd22f12734589a225244018eec8087e1bd66e05 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Sat, 14 Dec 2002 00:10:52 +0000
      Subject: [PATCH 0954/1042] Handle unsigned long values that don't fit in a
       long.
      
      [SVN r16606]
      ---
       .../python/converter/builtin_converters.hpp   | 10 ++-
       src/converter/builtin_converters.cpp          | 63 ++++++++++++++-----
       test/test_builtin_converters.py               |  7 +++
       3 files changed, 61 insertions(+), 19 deletions(-)
      
      diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp
      index c46e7e8f..5ec25056 100644
      --- a/include/boost/python/converter/builtin_converters.hpp
      +++ b/include/boost/python/converter/builtin_converters.hpp
      @@ -10,6 +10,7 @@
       # include 
       # include 
       # include 
      +# include 
       
       // Since all we can use to decide how to convert an object to_python
       // is its C++ type, there can be only one such converter for each
      @@ -80,9 +81,12 @@ namespace detail
               BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr)
       
       // Specialize converters for signed and unsigned T to Python Int
      -# define BOOST_PYTHON_TO_INT(T)                                         \
      -    BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x))        \
      -    BOOST_PYTHON_TO_PYTHON_BY_VALUE(unsigned T, PyInt_FromLong(x))
      +# define BOOST_PYTHON_TO_INT(T)                                                         \
      +    BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x))                        \
      +    BOOST_PYTHON_TO_PYTHON_BY_VALUE(                                                    \
      +        unsigned T, static_cast(x) > std::numeric_limits::max()    \
      +        ? PyLong_FromUnsignedLong(x)                                                    \
      +        : PyInt_FromLong(x))
       
       // Bool is not signed.
       BOOST_PYTHON_TO_PYTHON_BY_VALUE(bool, PyInt_FromLong(x))
      diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp
      index ce842b12..5c08c945 100644
      --- a/src/converter/builtin_converters.cpp
      +++ b/src/converter/builtin_converters.cpp
      @@ -65,8 +65,8 @@ namespace
             }
         };
       
      -  // A SlotPolicy for extracting integer types from Python objects
      -  struct int_rvalue_from_python_base
      +  // A SlotPolicy for extracting signed integer types from Python objects
      +  struct signed_int_rvalue_from_python_base
         {
             static unaryfunc* get_slot(PyObject* obj)
             {
      @@ -80,7 +80,7 @@ namespace
         };
       
         template 
      -  struct int_rvalue_from_python : int_rvalue_from_python_base
      +  struct signed_int_rvalue_from_python : signed_int_rvalue_from_python_base
         {
             static T extract(PyObject* intermediate)
             {
      @@ -88,6 +88,41 @@ namespace
             }
         };
       
      +  // identity_unaryfunc/py_object_identity -- manufacture a unaryfunc
      +  // "slot" which just returns its argument. 
      +  extern "C" PyObject* identity_unaryfunc(PyObject* x)
      +  {
      +      Py_INCREF(x);
      +      return x;
      +  }
      +  unaryfunc py_object_identity = identity_unaryfunc;
      +
      +  // A SlotPolicy for extracting unsigned integer types from Python objects
      +  struct unsigned_int_rvalue_from_python_base
      +  {
      +      static unaryfunc* get_slot(PyObject* obj)
      +      {
      +          PyNumberMethods* number_methods = obj->ob_type->tp_as_number;
      +          if (number_methods == 0)
      +              return 0;
      +
      +          return (PyInt_Check(obj) || PyLong_Check(obj))
      +              ? &py_object_identity : 0;
      +      }
      +  };
      +
      +  template 
      +  struct unsigned_int_rvalue_from_python : unsigned_int_rvalue_from_python_base
      +  {
      +      static T extract(PyObject* intermediate)
      +      {
      +          return numeric_cast(
      +              PyLong_Check(intermediate)
      +              ? PyLong_AsUnsignedLong(intermediate)
      +              : PyInt_AS_LONG(intermediate));
      +      }
      +  };
      +
       // Checking Python's macro instead of Boost's - we don't seem to get
       // the config right all the time. Furthermore, Python's is defined
       // when long long is absent but __int64 is present.
      @@ -155,17 +190,6 @@ namespace
         };
       #endif 
       
      -  // identity_unaryfunc/py_object_identity -- manufacture a unaryfunc
      -  // "slot" which just returns its argument. Used for bool
      -  // conversions, since all Python objects are directly convertible to
      -  // bool
      -  extern "C" PyObject* identity_unaryfunc(PyObject* x)
      -  {
      -      Py_INCREF(x);
      -      return x;
      -  }
      -  unaryfunc py_object_identity = identity_unaryfunc;
      -
         // A SlotPolicy for extracting bool from a Python object
         struct bool_rvalue_from_python
         {
      @@ -282,8 +306,15 @@ BOOST_PYTHON_DECL PyObject* do_arg_to_python(PyObject* x)
           return x;
       }
       
      -#define REGISTER_INT_CONVERTERS(U) slot_rvalue_from_python >()
      -#define REGISTER_INT_CONVERTERS2(U) REGISTER_INT_CONVERTERS(signed U); REGISTER_INT_CONVERTERS(unsigned U)  
      +#define REGISTER_INT_CONVERTERS(signedness, U)                          \
      +        slot_rvalue_from_python<                                        \
      +                signedness U                                            \
      +                ,signedness##_int_rvalue_from_python      \
      +         >()
      +
      +#define REGISTER_INT_CONVERTERS2(U)             \
      +        REGISTER_INT_CONVERTERS(signed, U);     \
      +        REGISTER_INT_CONVERTERS(unsigned, U)  
       
       void initialize_builtin_converters()
       {
      diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py
      index e4d8b335..80e2149d 100644
      --- a/test/test_builtin_converters.py
      +++ b/test/test_builtin_converters.py
      @@ -38,6 +38,13 @@ r"""
       42
       >>> rewrap_value_unsigned_long(42)
       42
      +
      +    test unsigned long values which don't fit in a signed long.
      +    strip any 'L' characters in case the platform has > 32 bit longs
      +        
      +>>> hex(rewrap_value_unsigned_long(0x80000001L)).replace('L','')
      +'0x80000001'
      +
       >>> rewrap_value_long_long(42)
       42L
       >>> rewrap_value_unsigned_long_long(42)
      
      From dd8fc049ff8f8297e49e50a8ba8932417ec36098 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Sat, 14 Dec 2002 00:17:22 +0000
      Subject: [PATCH 0955/1042] update news
      
      [SVN r16607]
      ---
       doc/news.html    | 15 +++++++++++++++
       doc/v2/enum.html |  3 ++-
       2 files changed, 17 insertions(+), 1 deletion(-)
      
      diff --git a/doc/news.html b/doc/news.html
      index 1b02a9a9..f63c52cf 100644
      --- a/doc/news.html
      +++ b/doc/news.html
      @@ -35,6 +35,21 @@
                 function pointers when used as arguments to add_property
       
      +      
      13 December 2002
      + +
      Allow exporting of enum_ values into + enclosing scope. + +
      + Fixed unsigned integer conversions to deal correctly with + numbers that are out-of-range of signed long. + +
      + + +
      14 November 2002
      Auto-detection of class data members wrapped with object { enum_(char const* name); - inline enum_<T>& value(char const* name, T); + enum_<T>& value(char const* name, T); + enum_<T>& export_values(); }; }}
      From 48f9bee21e0b7c38350615b46bc140fcc4378b98 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 16 Dec 2002 03:30:34 +0000 Subject: [PATCH 0956/1042] Fix typo due to "William Trenker" [SVN r16619] --- doc/v2/overloads.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/v2/overloads.html b/doc/v2/overloads.html index 2a4e72b7..a0a37b34 100644 --- a/doc/v2/overloads.html +++ b/doc/v2/overloads.html @@ -180,7 +180,7 @@ tuple f(int x = 1, double y = 4.25, char const* z = "wow") BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3) -stryct Y {}; +struct Y {}; struct X { Y& f(int x, double y = 4.25, char const* z = "wow") @@ -213,7 +213,7 @@ BOOST_PYTHON_MODULE(args_ext)

      Revised - 13 November, 2002 + 15 December, 2002

      From 0d2cdbbdfee4c49c4269e1f1f2466737a5267ba2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 16 Dec 2002 04:01:50 +0000 Subject: [PATCH 0957/1042] GCC-2.95.2 workarounds [SVN r16620] --- .../boost/python/converter/builtin_converters.hpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/include/boost/python/converter/builtin_converters.hpp b/include/boost/python/converter/builtin_converters.hpp index 5ec25056..9772079c 100644 --- a/include/boost/python/converter/builtin_converters.hpp +++ b/include/boost/python/converter/builtin_converters.hpp @@ -10,7 +10,7 @@ # include # include # include -# include +# include // Since all we can use to decide how to convert an object to_python // is its C++ type, there can be only one such converter for each @@ -81,11 +81,13 @@ namespace detail BOOST_PYTHON_ARG_TO_PYTHON_BY_VALUE(T,expr) // Specialize converters for signed and unsigned T to Python Int -# define BOOST_PYTHON_TO_INT(T) \ - BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \ - BOOST_PYTHON_TO_PYTHON_BY_VALUE( \ - unsigned T, static_cast(x) > std::numeric_limits::max() \ - ? PyLong_FromUnsignedLong(x) \ +# define BOOST_PYTHON_TO_INT(T) \ + BOOST_PYTHON_TO_PYTHON_BY_VALUE(signed T, PyInt_FromLong(x)) \ + BOOST_PYTHON_TO_PYTHON_BY_VALUE( \ + unsigned T \ + , static_cast(x) > static_cast( \ + std::numeric_limits::max()) \ + ? PyLong_FromUnsignedLong(x) \ : PyInt_FromLong(x)) // Bool is not signed. From 0e36ac6b72745a024f14dd54f37d4fba600c8f91 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 16 Dec 2002 21:14:30 +0000 Subject: [PATCH 0958/1042] Bug fix with construction of std::exception [SVN r16625] --- test/embedding.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/embedding.cpp b/test/embedding.cpp index 5b4db3f4..5a86f2cf 100644 --- a/test/embedding.cpp +++ b/test/embedding.cpp @@ -8,6 +8,7 @@ // Dirk Gerrits #include +#include #include #include @@ -60,8 +61,8 @@ void test() // Register the module with the interpreter if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1) - throw std::exception("Failed to add embedded_hello to the interpreters " - "builtin modules"); + throw std::runtime_error("Failed to add embedded_hello to the interpreter's " + "builtin modules"); // Initialize the interpreter Py_Initialize(); From 14c7d9ab146f9f9de4d4cdc30730c7da4c51e8c6 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Wed, 18 Dec 2002 01:23:21 +0000 Subject: [PATCH 0959/1042] typo error __rsub__ to __sub__ [SVN r16641] --- doc/tutorial/doc/class_operators_special_functions.html | 2 +- doc/tutorial/doc/quickstart.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tutorial/doc/class_operators_special_functions.html b/doc/tutorial/doc/class_operators_special_functions.html index ca7f6c0b..608f8ca9 100644 --- a/doc/tutorial/doc/class_operators_special_functions.html +++ b/doc/tutorial/doc/class_operators_special_functions.html @@ -50,7 +50,7 @@ and intuitively:

      .def(self + int()) // __add__ .def(int() + self) // __radd__ .def(self - self) // __sub__ - .def(self - int()) // __rsub__ + .def(self - int()) // __sub__ .def(self += int()) // __iadd__ .def(self -= other<int>()) .def(self < self); // __lt__ diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt index de75ccf9..73da42c7 100644 --- a/doc/tutorial/doc/quickstart.txt +++ b/doc/tutorial/doc/quickstart.txt @@ -657,7 +657,7 @@ and intuitively: .def(self + int()) // __add__ .def(int() + self) // __radd__ .def(self - self) // __sub__ - .def(self - int()) // __rsub__ + .def(self - int()) // __sub__ .def(self += int()) // __iadd__ .def(self -= other()) .def(self < self); // __lt__ From df24f29232c97bd579c7b6aa4e43972e71c28e46 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 18 Dec 2002 17:56:42 +0000 Subject: [PATCH 0960/1042] nonconformance workaround from Gottfried.Ganssauge@HAUFE.DE [SVN r16653] --- include/boost/python/object_protocol.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/object_protocol.hpp b/include/boost/python/object_protocol.hpp index 975c9379..8698dd9f 100755 --- a/include/boost/python/object_protocol.hpp +++ b/include/boost/python/object_protocol.hpp @@ -29,7 +29,7 @@ object getattr(Target const& target, Key const& key, Default const& default_) template void setattr(object const& target, Key const& key, Value const& value) { - return setattr(target, object(key), object(value)); + setattr(target, object(key), object(value)); } template @@ -66,7 +66,7 @@ object getslice(Target const& target, Begin const& begin, End const& end) template void setslice(object const& target, Begin const& begin, End const& end, Value const& value) { - return setslice(target, object(begin), object(end), object(value)); + setslice(target, object(begin), object(end), object(value)); } template From 854e957b7871d46b961eb71e93dcf36b8bf8d6c0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 18 Dec 2002 19:09:34 +0000 Subject: [PATCH 0961/1042] Workaround for MacOS GCC problem: #define B0 0 [SVN r16654] --- include/boost/python/bases.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/python/bases.hpp b/include/boost/python/bases.hpp index 6271e0fc..bcb52748 100644 --- a/include/boost/python/bases.hpp +++ b/include/boost/python/bases.hpp @@ -13,10 +13,10 @@ namespace boost { namespace python { -# define BOOST_PYTHON_BASE_PARAMS BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, B) +# define BOOST_PYTHON_BASE_PARAMS BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, Base) // A type list for specifying bases - template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_MAX_BASES, typename B, mpl::void_) > + template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PYTHON_MAX_BASES, typename Base, mpl::void_) > struct bases : detail::type_list< BOOST_PYTHON_BASE_PARAMS >::type {}; @@ -27,13 +27,13 @@ namespace boost { namespace python { { BOOST_STATIC_CONSTANT(bool, value = false); }; - template < BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, class B) > + template < BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, class Base) > struct specifies_bases< bases< BOOST_PYTHON_BASE_PARAMS > > { BOOST_STATIC_CONSTANT(bool, value = true); }; # else - template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class B) > + template < BOOST_PP_ENUM_PARAMS(BOOST_PYTHON_MAX_BASES, class Base) > static char is_bases_helper(bases< BOOST_PYTHON_BASE_PARAMS > const&); static char (& is_bases_helper(...) )[256]; From 809535b934a8b0c3855c0614240b38904ef92c56 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 18 Dec 2002 21:09:15 +0000 Subject: [PATCH 0962/1042] clarifications [SVN r16655] --- include/boost/python/object/forward.hpp | 3 +++ include/boost/python/object/make_holder.hpp | 29 +++++++++++++-------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/include/boost/python/object/forward.hpp b/include/boost/python/object/forward.hpp index 93c1ed21..789dfd23 100644 --- a/include/boost/python/object/forward.hpp +++ b/include/boost/python/object/forward.hpp @@ -15,6 +15,9 @@ namespace boost { namespace python { namespace objects { +// Very much like boost::reference_wrapper, except that in this +// case T can be a reference already without causing a +// reference-to-reference error. template struct reference_to_value { diff --git a/include/boost/python/object/make_holder.hpp b/include/boost/python/object/make_holder.hpp index ebcddc0d..9d33dce4 100644 --- a/include/boost/python/object/make_holder.hpp +++ b/include/boost/python/object/make_holder.hpp @@ -19,11 +19,11 @@ # include # include -# include # include +# include # include # include -# include +# include # include @@ -31,19 +31,12 @@ namespace boost { namespace python { namespace objects { template struct make_holder; -# define BOOST_PYTHON_FORWARD_ARG(z, index, _) \ - typedef typename iter##index::type t##index; \ - typedef typename forward::type f##index; \ - typedef typename mpl::next::type \ - BOOST_PP_CAT(iter,BOOST_PP_INC(index)); - # define BOOST_PYTHON_DO_FORWARD_ARG(z, index, _) , f##index(a##index) // specializations... # define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PYTHON_MAX_ARITY, )) # include BOOST_PP_ITERATE() -# undef BOOST_PYTHON_FORWARD_ARG # undef BOOST_PYTHON_DO_FORWARD_ARG }}} // namespace boost::python::objects @@ -61,11 +54,25 @@ struct make_holder template struct apply { +# if N + // Unrolled iteration through each argument type in ArgList, + // choosing the type that will be forwarded on to the holder's + // templated constructor. typedef typename mpl::begin::type iter0; - BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FORWARD_ARG, nil) + +# define BOOST_PP_LOCAL_MACRO(n) \ + typedef typename iter##n::type t##n; \ + typedef typename forward::type f##n; \ + typedef typename mpl::next::type \ + BOOST_PP_CAT(iter,BOOST_PP_INC(n)); // Next iterator type + +# define BOOST_PP_LOCAL_LIMITS (0, N-1) +# include BOOST_PP_LOCAL_ITERATE() +# endif + static void execute( PyObject* p - BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS_Z(1, N, t, a)) + BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(1, N, t, a)) { typedef instance instance_t; From 0df5ebf0fad2dcac06a85cbdb94d7a310328a2e9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 18 Dec 2002 21:11:16 +0000 Subject: [PATCH 0963/1042] Fix to allow accessing enums as data members [SVN r16656] --- include/boost/python/data_members.hpp | 40 +++++++++++++++++---------- test/enum.cpp | 10 +++++++ test/enum.py | 6 ++++ 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/include/boost/python/data_members.hpp b/include/boost/python/data_members.hpp index a8ff3871..9c4574b4 100644 --- a/include/boost/python/data_members.hpp +++ b/include/boost/python/data_members.hpp @@ -6,18 +6,25 @@ #ifndef DATA_MEMBERS_DWA2002328_HPP # define DATA_MEMBERS_DWA2002328_HPP -# include -# include -# include -# include -# include # include # include # include -# include # include + +# include + # include + +# include +# include +# include + +# include +# include +# include + # include + # include namespace boost { namespace python { @@ -71,16 +78,21 @@ namespace detail // and get the right result. template struct default_getter_policy - : mpl::if_c< - to_python_value< - typename add_reference< - typename add_const::type - >::type - >::uses_registry + { + typedef typename add_reference< + typename add_const::type + >::type t_cref; + + BOOST_STATIC_CONSTANT( + bool, by_ref = to_python_value::uses_registry + && is_reference_to_class::value); + + typedef typename mpl::if_c< + by_ref , return_internal_reference<> , return_value_policy - > - {}; + >::type type; + }; } template diff --git a/test/enum.cpp b/test/enum.cpp index fb1439c7..09a916c3 100644 --- a/test/enum.cpp +++ b/test/enum.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace boost::python; @@ -13,6 +14,11 @@ enum color { red = 1, green = 2, blue = 4 }; color identity_(color x) { return x; } +struct colorized { + colorized() : x(red) {} + color x; +}; + BOOST_PYTHON_MODULE(enum_ext) { enum_("color") @@ -23,6 +29,10 @@ BOOST_PYTHON_MODULE(enum_ext) ; def("identity", identity_); + + class_("colorized") + .def_readwrite("x", &colorized::x) + ; } #include "module_tail.cpp" diff --git a/test/enum.py b/test/enum.py index 00484670..e99e401e 100644 --- a/test/enum.py +++ b/test/enum.py @@ -37,6 +37,12 @@ enum_ext.color.blue ... except TypeError: pass ... else: print 'expected a TypeError' +>>> c = colorized() +>>> c.x +enum_ext.color.red +>>> c.x = green +>>> c.x +enum_ext.color.green ''' def run(args = None): From b8edd99dbdef6434f68c682126d06e733e17eb05 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 18 Dec 2002 21:12:02 +0000 Subject: [PATCH 0964/1042] Fix typo thanks to "William Trenker" [SVN r16657] --- doc/v2/handle.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/v2/handle.html b/doc/v2/handle.html index eba16a85..947bc82c 100644 --- a/doc/v2/handle.html +++ b/doc/v2/handle.html @@ -93,7 +93,7 @@ PyObject or a POD type whose initial sizeof(PyObject) bytes are layout-compatible with PyObject. Use handle<> at the - boundary between tehe Python/'C' API and high-level code; prefer object for a generalized interface to Python objects.

      From 3d874d1618e883f511c01c3d98b8f5e64d8bcd8f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 20 Dec 2002 00:04:40 +0000 Subject: [PATCH 0965/1042] Major simplification of from_python conversion avoids registering converters for every class. [SVN r16669] --- include/boost/python/class.hpp | 20 ++-- .../boost/python/converter/from_python.hpp | 2 +- include/boost/python/converter/implicit.hpp | 38 ++----- .../boost/python/converter/registrations.hpp | 10 +- .../boost/python/object/class_converters.hpp | 3 - include/boost/python/object/find_instance.hpp | 21 ---- include/boost/python/object/make_instance.hpp | 33 +++--- .../boost/python/object/pointer_holder.hpp | 1 - include/boost/python/object/select_holder.hpp | 107 +++++++++++------- include/boost/python/object/value_holder.hpp | 4 +- include/boost/python/to_python_indirect.hpp | 4 +- src/converter/from_python.cpp | 85 +++++++++----- 12 files changed, 177 insertions(+), 151 deletions(-) diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 5177e339..c67faae3 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -77,21 +77,21 @@ namespace detail template struct operator_; - // Register a to_python converter for a class T, depending on the - // type of the first (tag) argument. The 2nd argument is a pointer - // to the type of holder that must be created. The 3rd argument is a + // Register to_python converters for a class T. The first argument + // will be mpl::true_c unless noncopyable was specified as a + // class_<...> template parameter. The 2nd argument is a pointer to + // the type of holder that must be created. The 3rd argument is a // reference to the Python type object to be created. template - static inline void register_copy_constructor(mpl::bool_c const&, SelectHolder const& , T* = 0) + inline void register_class_to_python(mpl::true_c copyable, SelectHolder selector, T* = 0) { typedef typename SelectHolder::type holder; force_instantiate(objects::class_cref_wrapper >()); SelectHolder::register_(); } - // Tag dispatched to have no effect. template - static inline void register_copy_constructor(mpl::bool_c const&, SelectHolder const&, T* = 0) + inline void register_class_to_python(mpl::false_c copyable, SelectHolder selector, T* = 0) { SelectHolder::register_(); } @@ -125,20 +125,14 @@ namespace detail template struct virtual_function_default -# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 - : assertion >::failed - , assertion >::failed -# endif { template static void must_be_derived_class_member(Default const&) { typedef typename assertion > >::failed test0; -# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 typedef typename assertion >::failed test1; typedef typename assertion >::failed test2; -# endif not_a_derived_class_member(Fn()); } }; @@ -473,7 +467,7 @@ inline void class_::register_() const { objects::register_class_from_python(); - detail::register_copy_constructor( + detail::register_class_to_python( mpl::bool_c() , holder_selector::execute((held_type*)0) ); diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp index dabafcaa..0822e563 100644 --- a/include/boost/python/converter/from_python.hpp +++ b/include/boost/python/converter/from_python.hpp @@ -18,7 +18,7 @@ struct rvalue_from_python_chain; BOOST_PYTHON_DECL void* get_lvalue_from_python( PyObject* source, registration const&); -BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( +BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python( PyObject* source, registration const&); BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( diff --git a/include/boost/python/converter/implicit.hpp b/include/boost/python/converter/implicit.hpp index 79a398aa..fd588f6b 100644 --- a/include/boost/python/converter/implicit.hpp +++ b/include/boost/python/converter/implicit.hpp @@ -5,10 +5,13 @@ // to its suitability for any purpose. #ifndef IMPLICIT_DWA2002326_HPP # define IMPLICIT_DWA2002326_HPP + # include # include # include +# include + namespace boost { namespace python { namespace converter { template @@ -16,39 +19,22 @@ struct implicit { static void* convertible(PyObject* obj) { - // Find a converter chain which can produce a Source instance - // from obj. The user has told us that Source can be converted - // to Target, and instantiating construct() below, ensures - // that at compile-time. - return const_cast( - converter::implicit_conversion_chain(obj, registered::converters)); + // Find a converter which can produce a Source instance from + // obj. The user has told us that Source can be converted to + // Target, and instantiating construct() below, ensures that + // at compile-time. + return implicit_rvalue_convertible_from_python(obj, registered::converters) + ? obj : 0; } static void construct(PyObject* obj, rvalue_from_python_stage1_data* data) { - // This is the chain we got from the convertible step - rvalue_from_python_chain const* chain - = static_cast(data->convertible); - - // Call the convertible function again - rvalue_from_python_data intermediate_data(chain->convertible(obj)); - - // Use the result to construct the source type if the first - // converter was an rvalue converter. - if (chain->construct != 0) - chain->construct(obj, &intermediate_data.stage1); - void* storage = ((rvalue_from_python_storage*)data)->storage.bytes; -# if !defined(BOOST_MSVC) || _MSC_FULL_VER != 13012108 // vc7.01 alpha workaround - new (storage) Target(*static_cast(intermediate_data.stage1.convertible)); -# else - Target x(*static_cast(intermediate_data.stage1.convertible)); - new (storage) Target(x); -# endif - + + new (storage) Target(extract(obj)()); + // record successful construction data->convertible = storage; - } }; diff --git a/include/boost/python/converter/registrations.hpp b/include/boost/python/converter/registrations.hpp index 8ed9d04a..973e052f 100644 --- a/include/boost/python/converter/registrations.hpp +++ b/include/boost/python/converter/registrations.hpp @@ -6,11 +6,15 @@ #ifndef REGISTRATIONS_DWA2002223_HPP # define REGISTRATIONS_DWA2002223_HPP -# include +# include + # include # include # include -# include + +# include + +# include namespace boost { namespace python { namespace converter { @@ -54,7 +58,7 @@ struct BOOST_PYTHON_DECL registration // The unique to_python converter for the associated C++ type. to_python_function_t m_to_python; -# if defined(__MWERKS__) && __MWERKS__ <= 0x3003 +# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) private: void operator=(registration); // This is not defined, and just keeps MWCW happy. # endif diff --git a/include/boost/python/object/class_converters.hpp b/include/boost/python/object/class_converters.hpp index bd7ead82..e902a40f 100644 --- a/include/boost/python/object/class_converters.hpp +++ b/include/boost/python/object/class_converters.hpp @@ -9,7 +9,6 @@ # include # include -# include # include # include @@ -72,8 +71,6 @@ struct register_base_of template inline void register_class_from_python(Derived* = 0, Bases* = 0) { - // cause the static registration to be instantiated. - python::detail::force_instantiate(instance_finder::registration); python::detail::force_instantiate(converter::shared_ptr_from_python::registration); // register all up/downcasts here diff --git a/include/boost/python/object/find_instance.hpp b/include/boost/python/object/find_instance.hpp index 44c79550..113b622d 100644 --- a/include/boost/python/object/find_instance.hpp +++ b/include/boost/python/object/find_instance.hpp @@ -7,7 +7,6 @@ # define FIND_INSTANCE_DWA2002312_HPP # include -# include namespace boost { namespace python { namespace objects { @@ -15,26 +14,6 @@ namespace boost { namespace python { namespace objects { // return 0 in case no such type is held. BOOST_PYTHON_DECL void* find_instance_impl(PyObject*, type_info); -// This produces a function with the right signature for use in from_python conversions -template -struct instance_finder -{ - instance_finder() - { - converter::registry::insert(&execute, python::type_id()); - } - - static instance_finder const registration; - private: - static inline void* execute(PyObject* p) - { - return find_instance_impl(p, python::type_id()); - } -}; - -template -instance_finder const instance_finder::registration; - }}} // namespace boost::python::objects #endif // FIND_INSTANCE_DWA2002312_HPP diff --git a/include/boost/python/object/make_instance.hpp b/include/boost/python/object/make_instance.hpp index ecac7493..b9e0c981 100644 --- a/include/boost/python/object/make_instance.hpp +++ b/include/boost/python/object/make_instance.hpp @@ -11,6 +11,15 @@ namespace boost { namespace python { namespace objects { +struct decref_guard +{ + decref_guard(PyObject* o) : obj(o) {} + ~decref_guard() { Py_XDECREF(obj); } + void cancel() { obj = 0; } + private: + PyObject* obj; +}; + template struct make_instance { @@ -28,22 +37,20 @@ struct make_instance if (raw_result != 0) { - instance_t* result = (instance_t*)raw_result; - try - { - // construct the new C++ object and install the pointer - // in the Python object. - construct(result, x)->install(raw_result); - } - catch(...) - { - Py_DECREF(raw_result); // reclaim the Python object - throw; - } + decref_guard protect(raw_result); + + instance_t* instance = (instance_t*)raw_result; + + // construct the new C++ object and install the pointer + // in the Python object. + construct(instance, x)->install(raw_result); // Note the position of the internally-stored Holder, // for the sake of destruction - result->ob_size = offsetof(instance_t, storage); + instance->ob_size = offsetof(instance_t, storage); + + // Release ownership of the python object + protect.cancel(); } return raw_result; } diff --git a/include/boost/python/object/pointer_holder.hpp b/include/boost/python/object/pointer_holder.hpp index c35e012e..4400abe6 100644 --- a/include/boost/python/object/pointer_holder.hpp +++ b/include/boost/python/object/pointer_holder.hpp @@ -14,7 +14,6 @@ # include # include # include -# include # include # include # include diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index 67adacb8..46f3e212 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -12,7 +12,6 @@ # include # include # include -# include # include # include # include @@ -27,11 +26,22 @@ namespace boost { namespace python { namespace objects { namespace detail { + + // check_default_constructible -- + // + // Used to give a clean error message when the user doesn't specify + // any __init__ functions, but when the class being wrapped doesn't + // have an appropriate default constructor (or if + // has_back_reference is true, a constructor taking PyObject*). + // A helpful compile-time assertion which gives a reasonable error // message if T can't be default-constructed. template static int specify_init_arguments_or_no_init_for_class_(T const&); - + + // U is expected to take an initial hidden PyObject* in its + // constructor. Normally this means U is a virtual function + // dispatcher subclass for T. template void check_default_constructible(T*, U*, mpl::bool_c) { @@ -39,7 +49,9 @@ namespace detail sizeof(specify_init_arguments_or_no_init_for_class_(U((::PyObject*)0))) ); } - + + // Handles the "normal" case where T is held directly and + // has_back_reference is not specialized. template void check_default_constructible(T*, T*, mpl::bool_c) { @@ -47,76 +59,76 @@ namespace detail sizeof(specify_init_arguments_or_no_init_for_class_(T())) ); } + + // + // select_value_holder/select_pointer_holder -- + // + // An instantiation of one of these data-free class templates is + // returned by select_holder::execute(), below. Each provides the + // following public interface: + // + // static void assert_default_constructible() -- called when no + // init<...> arguments are specified in class_'s + // constructor; causes a compile-time error when T has no + // corresponding default constructor. + // + // typedef ... type -- the class derived from instance_holder + // which will manage a Held object in Python class instances + // + // static type* get() { return 0; } -- just a way to access the + // computed type at runtime. + // + // static void register_() -- forces registration of any + // to_python converters corresponding to Held. template struct select_value_holder { - BOOST_STATIC_CONSTANT(bool, selector = (!is_same::value) | has_back_reference::value); + BOOST_STATIC_CONSTANT(bool, back_ref = (!is_same::value) | has_back_reference::value); static void assert_default_constructible() { - detail::check_default_constructible((T*)0,(Held*)0,mpl::bool_c()); + detail::check_default_constructible((T*)0,(Held*)0,mpl::bool_c()); } typedef typename mpl::if_c< - selector + back_ref , value_holder_back_reference , value_holder >::type type; - static inline void register_() - { - select_value_holder::register_(mpl::bool_c()); - } + static inline void register_() {} static type* get() { return 0; } - - private: - static inline void register_(mpl::bool_c) - { - python::detail::force_instantiate(instance_finder::registration); - } - - static inline void register_(mpl::bool_c) - { - } }; template struct select_pointer_holder { typedef typename python::pointee::type pointee; - BOOST_STATIC_CONSTANT(bool, selector = (!is_same::value) | has_back_reference::value); + BOOST_STATIC_CONSTANT(bool, back_ref = (!is_same::value) | has_back_reference::value); static void assert_default_constructible() { - detail::check_default_constructible((T*)0,(pointee*)0,mpl::bool_c()); + detail::check_default_constructible((T*)0,(pointee*)0,mpl::bool_c()); } typedef typename mpl::if_c< - selector + back_ref , pointer_holder_back_reference , pointer_holder >::type type; static inline void register_() { - select_pointer_holder::register_(mpl::bool_c()); + select_pointer_holder::register_(mpl::bool_c()); } static type* get() { return 0; } private: - static inline void register_(mpl::bool_c) + static inline void register_(mpl::true_c) { - // not implemented at least until we solve the back - // reference issue mentioned in pointer_holder.hpp. - // - // python::detail::force_instantiate( - // class_wrapper >()); - - python::detail::force_instantiate(instance_finder::registration); - python::detail::force_instantiate(instance_finder::registration); } struct construct_from_pointer @@ -127,37 +139,56 @@ namespace detail } }; - static inline void register_(mpl::bool_c) + static inline void register_(mpl::false_c) { python::detail::force_instantiate( objects::class_value_wrapper >()); - - python::detail::force_instantiate( - instance_finder::registration); } }; } +// select_holder::execute((Held*)0) +// +// implements a compile-time returns an instantiation of +// detail::select_value_holder or detail::select_pointer_holder, as +// appropriate for class_ template struct select_holder { + // Return the additional size to allocate in Python class + // instances to hold the C++ instance data. static inline std::size_t additional_size() { return additional_size_helper(execute((Held*)0)); } - + + // These overloads are an elaborate workaround for deficient + // compilers: + // + // They are meant to be called with a null pointer to the class_'s + // Held template argument. The selected overload will create an + // appropriate instantiation of select_value_holder or + // select_pointer_holder, which is itself an empty class that is + // ultimately used to create the class_'s instance_holder subclass + // object. + + // No Held was specified; T is held directly by-value static inline detail::select_value_holder execute(python::detail::not_specified*) { return detail::select_value_holder(); } + // A type derived from T was specified; it is assumed to be a + // virtual function dispatcher class, and T is held as Held. static inline detail::select_value_holder execute(T*) { return detail::select_value_holder(); } + // Some other type was specified; Held is assumed to be a (smart) + // pointer to T or a class derived from T. static inline detail::select_pointer_holder execute(void*) { diff --git a/include/boost/python/object/value_holder.hpp b/include/boost/python/object/value_holder.hpp index 95b58746..6ae3ae75 100644 --- a/include/boost/python/object/value_holder.hpp +++ b/include/boost/python/object/value_holder.hpp @@ -10,11 +10,13 @@ # define VALUE_HOLDER_DWA20011215_HPP # include + # include # include + # include -# include # include + # include # include diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index 78e95098..c1ad8ce5 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -37,7 +37,9 @@ namespace detail template static result_type execute(T* p) { - // can't use auto_ptr with Intel 5 for some reason + // can't use auto_ptr with Intel 5 and VC6 Dinkum library + // for some reason. We get link errors against the auto_ptr + // copy constructor. # if defined(__ICL) && __ICL < 600 typedef boost::shared_ptr smart_pointer; # else diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 49b362e0..904f66ff 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -7,11 +7,15 @@ #include #include #include + +#include + #include #include #include #include + #include #include @@ -38,18 +42,28 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( PyObject* source , registration const& converters) { - rvalue_from_python_chain const* chain = converters.rvalue_chain; - rvalue_from_python_stage1_data data; - data.convertible = 0; - for (;chain != 0; chain = chain->next) + + // First check to see if it's embedded in an extension class + // instance, as a special case. + data.convertible = objects::find_instance_impl(source, converters.target_type); + if (data.convertible) { - void* r = chain->convertible(source); - if (r != 0) + data.construct = 0; + } + else + { + for (rvalue_from_python_chain const* chain = converters.rvalue_chain; + chain != 0; + chain = chain->next) { - data.convertible = r; - data.construct = chain->construct; - break; + void* r = chain->convertible(source); + if (r != 0) + { + data.convertible = r; + data.construct = chain->construct; + break; + } } } return data; @@ -111,8 +125,12 @@ BOOST_PYTHON_DECL void* get_lvalue_from_python( PyObject* source , registration const& converters) { + // Check to see if it's embedded in a class instance + void* x = objects::find_instance_impl(source, converters.target_type); + if (x) + return x; + lvalue_from_python_chain const* chain = converters.lvalue_chain; - for (;chain != 0; chain = chain->next) { void* r = chain->convert(source); @@ -138,38 +156,45 @@ namespace return true; } - void unvisit(rvalue_from_python_chain const* chain) + // RAII class for managing global visited marks. + struct unvisit { - visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain); - assert(p != visited.end()); - visited.erase(p); - } + unvisit(rvalue_from_python_chain const* chain) + : chain(chain) {} + + ~unvisit() + { + visited_t::iterator const p = std::lower_bound(visited.begin(), visited.end(), chain); + assert(p != visited.end()); + visited.erase(p); + } + private: + rvalue_from_python_chain const* chain; + }; } -BOOST_PYTHON_DECL rvalue_from_python_chain const* implicit_conversion_chain( + +BOOST_PYTHON_DECL bool implicit_rvalue_convertible_from_python( PyObject* source , registration const& converters) { + if (objects::find_instance_impl(source, converters.target_type)) + return true; + rvalue_from_python_chain const* chain = converters.rvalue_chain; if (!visit(chain)) - return 0; + return false; + + unvisit protect(chain); - try + for (;chain != 0; chain = chain->next) { - for (;chain != 0; chain = chain->next) - { - if (chain->convertible(source)) - break; - } + if (chain->convertible(source)) + return true; } - catch(...) - { - unvisit(chain); - throw; - } - unvisit(chain); - return chain; + + return false; } namespace From 0c8aa84f2ffff670ca9bcc17d614982e06d09db2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 20 Dec 2002 18:19:18 +0000 Subject: [PATCH 0966/1042] Enable automatic downcasting to registered classes for pointers, references, and smart pointers [SVN r16673] --- include/boost/python/detail/decref_guard.hpp | 22 +++++++ include/boost/python/object/make_instance.hpp | 51 +++++++--------- .../boost/python/object/make_ptr_instance.hpp | 60 +++++++++++++++++++ include/boost/python/object/select_holder.hpp | 4 +- include/boost/python/to_python_indirect.hpp | 6 +- test/polymorphism.cpp | 41 ++++++++++++- test/polymorphism.py | 24 ++++++-- test/shared_ptr.cpp | 15 +++++ test/shared_ptr.py | 6 ++ 9 files changed, 188 insertions(+), 41 deletions(-) create mode 100644 include/boost/python/detail/decref_guard.hpp create mode 100644 include/boost/python/object/make_ptr_instance.hpp diff --git a/include/boost/python/detail/decref_guard.hpp b/include/boost/python/detail/decref_guard.hpp new file mode 100644 index 00000000..67455706 --- /dev/null +++ b/include/boost/python/detail/decref_guard.hpp @@ -0,0 +1,22 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef DECREF_GUARD_DWA20021220_HPP +# define DECREF_GUARD_DWA20021220_HPP + +namespace boost { namespace python { namespace detail { + +struct decref_guard +{ + decref_guard(PyObject* o) : obj(o) {} + ~decref_guard() { Py_XDECREF(obj); } + void cancel() { obj = 0; } + private: + PyObject* obj; +}; + +}}} // namespace boost::python::detail + +#endif // DECREF_GUARD_DWA20021220_HPP diff --git a/include/boost/python/object/make_instance.hpp b/include/boost/python/object/make_instance.hpp index b9e0c981..eb420d2f 100644 --- a/include/boost/python/object/make_instance.hpp +++ b/include/boost/python/object/make_instance.hpp @@ -8,42 +8,34 @@ # include # include +# include namespace boost { namespace python { namespace objects { -struct decref_guard -{ - decref_guard(PyObject* o) : obj(o) {} - ~decref_guard() { Py_XDECREF(obj); } - void cancel() { obj = 0; } - private: - PyObject* obj; -}; - -template -struct make_instance +template +struct make_instance_impl { typedef objects::instance instance_t; template - static PyObject* execute(Arg& x) + static inline PyObject* execute(Arg& x) { BOOST_STATIC_ASSERT(is_class::value); - - PyTypeObject* type = converter::registered::converters.get_class_object(); + + PyTypeObject* type = Derived::get_class_object(x); PyObject* raw_result = type->tp_alloc( type, objects::additional_instance_size::value); if (raw_result != 0) { - decref_guard protect(raw_result); + python::detail::decref_guard protect(raw_result); instance_t* instance = (instance_t*)raw_result; // construct the new C++ object and install the pointer // in the Python object. - construct(instance, x)->install(raw_result); + Derived::construct(&instance->storage, (PyObject*)instance, x)->install(raw_result); // Note the position of the internally-stored Holder, // for the sake of destruction @@ -54,23 +46,22 @@ struct make_instance } return raw_result; } +}; - private: - // Kind of a hack to support code re-use. The first form is used - // to construct holders around pointers or smart pointers. The - // second form is used to construct holders around by-value - // returns. We have to pass a pointer to the owning Python object - // to the second form in order to make it forward the 2nd argument - // on to the constructor of its embedded T object. - template - static Holder* construct(instance_t* result, Arg& x) - { - return new ((void*)&result->storage) Holder(x); - } - static Holder* construct(instance_t* result, reference_wrapper x) +template +struct make_instance + : make_instance_impl > +{ + template + static inline PyTypeObject* get_class_object(U&) { - return new ((void*)&result->storage) Holder((PyObject*)result, x); + return converter::registered::converters.get_class_object(); + } + + static inline Holder* construct(void* storage, PyObject* instance, reference_wrapper x) + { + return new (storage) Holder(instance, x); } }; diff --git a/include/boost/python/object/make_ptr_instance.hpp b/include/boost/python/object/make_ptr_instance.hpp new file mode 100644 index 00000000..40debeaa --- /dev/null +++ b/include/boost/python/object/make_ptr_instance.hpp @@ -0,0 +1,60 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef MAKE_PTR_INSTANCE_DWA200296_HPP +# define MAKE_PTR_INSTANCE_DWA200296_HPP + +# include +# include +# include +# include +# include + +namespace boost { namespace python { namespace objects { + +template +struct make_ptr_instance + : make_instance_impl > +{ + template + static inline Holder* construct(void* storage, PyObject*, Arg& x) + { + return new (storage) Holder(x); + } + + template + static inline PyTypeObject* get_class_object(Ptr const& x) + { + return get_class_object_impl(get_pointer(x)); + } + + private: + template + static inline PyTypeObject* get_class_object_impl(U const volatile* p) + { + PyTypeObject* derived = get_derived_class_object(is_polymorphic::type(), p); + if (derived) + return derived; + return converter::registered::converters.get_class_object(); + } + + template + static inline PyTypeObject* get_derived_class_object(mpl::true_c, U const volatile* x) + { + converter::registration const* r = converter::registry::query(type_info(typeid(*x))); + return r ? r->m_class_object : 0; + } + + template + static inline PyTypeObject* get_derived_class_object(mpl::false_c, U*) + { + return 0; + } +}; + + +}}} // namespace boost::python::object + +#endif // MAKE_PTR_INSTANCE_DWA200296_HPP diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index 46f3e212..2c032550 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -12,7 +12,7 @@ # include # include # include -# include +# include # include # include # include @@ -142,7 +142,7 @@ namespace detail static inline void register_(mpl::false_c) { python::detail::force_instantiate( - objects::class_value_wrapper >()); + objects::class_value_wrapper >()); } }; } diff --git a/include/boost/python/to_python_indirect.hpp b/include/boost/python/to_python_indirect.hpp index c1ad8ce5..215cb198 100644 --- a/include/boost/python/to_python_indirect.hpp +++ b/include/boost/python/to_python_indirect.hpp @@ -13,7 +13,7 @@ # include # include # include -# include +# include # include namespace boost { namespace python { @@ -48,7 +48,7 @@ namespace detail typedef objects::pointer_holder holder_t; smart_pointer ptr(p); - return objects::make_instance::execute(ptr); + return objects::make_ptr_instance::execute(ptr); } }; @@ -59,7 +59,7 @@ namespace detail static result_type execute(T* p) { typedef objects::pointer_holder holder_t; - return objects::make_instance::execute(p); + return objects::make_ptr_instance::execute(p); } }; diff --git a/test/polymorphism.cpp b/test/polymorphism.cpp index f648448c..02ec7b57 100644 --- a/test/polymorphism.cpp +++ b/test/polymorphism.cpp @@ -3,7 +3,14 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. -#include +#include +#include +#include +#include +#include +#include +#include +#include using namespace boost::python; @@ -40,6 +47,11 @@ struct B : A virtual std::string f() { return "B::f()"; } }; +struct C : A +{ + virtual std::string f() { return "C::f()"; } +}; + A& getBCppObj () { static B b; @@ -48,6 +60,25 @@ A& getBCppObj () std::string call_f(A& a) { return a.f(); } +A* factory(unsigned choice) +{ + switch (choice % 3) + { + case 0: return new A; + break; + case 1: return new B; + break; + default: return new C; + break; + } +} + +C& getCCppObj () +{ + static C c; + return c; +} + BOOST_PYTHON_MODULE_INIT(polymorphism_ext) { class_("A") @@ -56,6 +87,14 @@ BOOST_PYTHON_MODULE_INIT(polymorphism_ext) def("getBCppObj", getBCppObj, return_value_policy()); + class_,boost::noncopyable>("C") + .def("f", &C::f) + ; + + def("getCCppObj", getCCppObj, return_value_policy()); + + def("factory", factory, return_value_policy()); + def("call_f", call_f); } diff --git a/test/polymorphism.py b/test/polymorphism.py index b1836d79..a305bbea 100644 --- a/test/polymorphism.py +++ b/test/polymorphism.py @@ -17,17 +17,31 @@ class PolymorphTest(unittest.TestCase): self.failUnlessEqual ('B::f()', a.f()) self.failUnlessEqual ('B::f()', call_f(a)) self.failUnlessEqual ('A::f()', call_f(A())) + + def test_references(self): + # B is not exposed to Python + a = getBCppObj() + self.failUnlessEqual(type(a), A) + + # C is exposed to Python + c = getCCppObj() + self.failUnlessEqual(type(c), C) + def test_factory(self): + self.failUnlessEqual(type(factory(0)), A) + self.failUnlessEqual(type(factory(1)), A) + self.failUnlessEqual(type(factory(2)), C) + def testReturnPy(self): - class C(A): + class D(A): def f(self): - return 'C.f' + return 'D.f' - c = C() + d = D() - self.failUnlessEqual ('C.f', c.f()) - self.failUnlessEqual ('C.f', call_f(c)) + self.failUnlessEqual ('D.f', d.f()) + self.failUnlessEqual ('D.f', call_f(d)) if __name__ == "__main__": diff --git a/test/shared_ptr.cpp b/test/shared_ptr.cpp index c249547f..5f1b36ce 100644 --- a/test/shared_ptr.cpp +++ b/test/shared_ptr.cpp @@ -82,6 +82,16 @@ struct ZWrap : Z PyObject* m_self; }; +struct YY : Y +{ + YY(int n) : Y(n) {} +}; + +shared_ptr factory(int n) +{ + return shared_ptr(n < 42 ? new Y(n) : new YY(n)); +} + static int stored_v() { return functions::get()->v(); } BOOST_PYTHON_MODULE(shared_ptr_ext) @@ -90,6 +100,8 @@ BOOST_PYTHON_MODULE(shared_ptr_ext) .def("value", &X::value) ; + def("factory", factory); + functions::expose(); def("x_count", &X::count); def("x_release", &functions::release_store); @@ -99,6 +111,9 @@ BOOST_PYTHON_MODULE(shared_ptr_ext) .def("value", &Y::value) ; + class_, boost::noncopyable>("YY", init()) + ; + functions::expose(); def("y_count", &Y::count); def("y_release", &functions::release_store); diff --git a/test/shared_ptr.py b/test/shared_ptr.py index 62e0b4c5..64850097 100644 --- a/test/shared_ptr.py +++ b/test/shared_ptr.py @@ -1,5 +1,11 @@ ''' >>> from shared_ptr_ext import * + +>>> type(factory(3)) + +>>> type(factory(42)) + + >>> class P(Z): ... def v(self): ... return -Z.v(self); From eac0412d18eb4bd64341a44a5ce55b12931093c4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 21 Dec 2002 22:12:31 +0000 Subject: [PATCH 0967/1042] Fixed comment [SVN r16676] --- src/object/function.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/object/function.cpp b/src/object/function.cpp index 259bfb86..2a9f0121 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -267,8 +267,8 @@ void function::add_to_namespace( { // Binary operators need an additional overload which // returns NotImplemented, so that Python will try the - // lxxx functions on the other operand. We add this when - // no overloads for the operator already exist. + // __rxxx__ functions on the other operand. We add this + // when no overloads for the operator already exist. new_func->add_overload(not_implemented_function()); } From aa58e21bdad4e93132e612d7edcecda2428df2a1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 24 Dec 2002 04:49:33 +0000 Subject: [PATCH 0968/1042] Bug fix, thanks to "Daniel Paull" for reporting it. [SVN r16698] --- include/boost/python/signature.hpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/include/boost/python/signature.hpp b/include/boost/python/signature.hpp index 5469fd5a..5b0f6026 100644 --- a/include/boost/python/signature.hpp +++ b/include/boost/python/signature.hpp @@ -52,8 +52,11 @@ namespace boost { namespace python { namespace detail { // return mpl::list(); // } // -// These functions extract the return type, class (for member functions) -// and arguments of the input signature and stuffs them in an mpl::list. +// These functions extract the return type, class (for member +// functions) and arguments of the input signature and stuffs them in +// an mpl::list. Note that cv-qualification is dropped from the +// target class; that is a necessary sacrifice to ensure that an +// lvalue from_python converter is used. // /////////////////////////////////////////////////////////////////////////////// @@ -102,11 +105,11 @@ get_signature(RT(*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T))) template < class RT, class ClassT BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, class T)> inline BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< - RT, ClassT Q& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> + RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T)> get_signature(RT(ClassT::*)(BOOST_PP_ENUM_PARAMS_Z(1, N, T)) Q) { return BOOST_PYTHON_LIST_INC(BOOST_PP_INC(N))< - RT, ClassT Q & BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) + RT, ClassT& BOOST_PP_ENUM_TRAILING_PARAMS_Z(1, N, T) >(); } From 0f95d507c4d61adf3caf61600e943ae0485d9dc3 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Fri, 27 Dec 2002 16:51:53 +0000 Subject: [PATCH 0969/1042] add or update See www.boost.org comments [SVN r16708] --- include/boost/python.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/boost/python.hpp b/include/boost/python.hpp index c608dbfe..db665d8d 100644 --- a/include/boost/python.hpp +++ b/include/boost/python.hpp @@ -3,6 +3,9 @@ // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. + +// See http://www.boost.org/libs/python for documentation. + #ifndef PYTHON_DWA2002810_HPP # define PYTHON_DWA2002810_HPP From 1bb3254d4d3195aeaa050004a89f552195e4c65b Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Dec 2002 16:53:48 +0000 Subject: [PATCH 0970/1042] Check in changes from Brett Calcott [SVN r16716] --- doc/building.html | 61 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/doc/building.html b/doc/building.html index 000aeb3e..45951aa8 100644 --- a/doc/building.html +++ b/doc/building.html @@ -50,6 +50,8 @@
      Building your Extension Module
      Build Variants
      + +
      Building Using the Microsoft Visual Studio IDE

      @@ -308,6 +310,63 @@ bjam -sTOOLS=Python.h, or you will have link incompatibilities.

      + +

      Building Using the Microsoft Visual + Studio IDE

      + +

      For the those of you who feel more comfortable in the IDE + world, a workspace and project file have been included in the libs/python/build/visual_studio + subdirectory. It builds release and debug versions of the + Boost.Python libraries and places them and the same directory as + Jamfile build does, though the intermediate object files are + placed in a different directory. The files have been created using + Microsoft Visual C++ version 6, but they should work for later + versions as well. You will need to tell the IDE where to find the + Python Include/ and Libs/ directories. + Under Tools>Options>Directories, add an entry for the + Python include dir (i.e. c:/Python22/Include), and + one for the Lib (i.e. c:/Python/Libs. Make sure it + is Libs with an "s" and not just + Lib). + +

      Using the IDE for you own projects

      + +

      Building your own projects using the IDE is slightly more + complicated. Firstly, you need to make sure that the project you + create as the right kind. It should be a "Win32 Dynamic-Link + Library". The default one that Visual Studio 6 creates needs + some modifications: turn on RTTI, and change the debug and release + builds to use the respective debug and release Multithreaded DLL + versions. You should probably turn off incremental linking too -- + I believe it a bit flaky. If you do this, then change the "Debug + Info" to "Program Database" to get rid of the Edit and Continue + warning. +

      + +

      You'll need to add the Boost root directory under + Tools>Options>Directories to get your code compiling. To + make it link, add the above boost_python.dsp file to your + workspace, and make your project depend upon it (under + Project>Dependencies). You should be able to build now. +

      + +

      Lastly, go to the Project Settings>Debug Page and add + the Python.exe as the executable for the project. + Set a startup directory, and make sure that your current project's + output dll, the boost_python.dll and the + python22.dll are on the current PATH. + If you have a python script that tests your dll, then add it in + the "Program Arguments". Now, if all went well, you + should be able to hit the Run (F5) button, and debug your code. +

      + +
      +The Visual Studio project files are graciously contributed and +maintained by Brett +Calcott. +
      +

      © Copyright David Abrahams 2002. Permission to copy, use, modify, @@ -316,7 +375,7 @@ bjam -sTOOLS= -

      Updated: O8 October, 2002 (David Abrahams)

      +

      Updated: 29 December, 2002 (David Abrahams)

      From bcf36610e13138273dfd85d012002dba6b9df143 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 29 Dec 2002 17:27:52 +0000 Subject: [PATCH 0971/1042] Check in VisualStudio support from Brett Calcott [SVN r16717] --- build/VisualStudio/boost_python.dsp | 882 ++++++++++++++++++++++++++++ build/VisualStudio/boost_python.dsw | 29 + doc/building.html | 87 ++- doc/news.html | 39 +- doc/v2/acknowledgments.html | 4 + 5 files changed, 979 insertions(+), 62 deletions(-) create mode 100644 build/VisualStudio/boost_python.dsp create mode 100644 build/VisualStudio/boost_python.dsw diff --git a/build/VisualStudio/boost_python.dsp b/build/VisualStudio/boost_python.dsp new file mode 100644 index 00000000..1e4c5358 --- /dev/null +++ b/build/VisualStudio/boost_python.dsp @@ -0,0 +1,882 @@ +# Microsoft Developer Studio Project File - Name="boost_python" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=BOOST_PYTHON - WIN32 RELEASE +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "boost_python.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "boost_python.mak" CFG="BOOST_PYTHON - WIN32 RELEASE" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "boost_python - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "boost_python - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "boost_python - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "../bin-stage" +# PROP Intermediate_Dir "release-obj" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +F90=df.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /c +# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x1409 /d "NDEBUG" +# ADD RSC /l 0x1409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib /nologo /dll /machine:I386 + +!ELSEIF "$(CFG)" == "boost_python - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "../bin-stage" +# PROP Intermediate_Dir "debug-obj" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +F90=df.exe +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /GZ /c +# ADD CPP /nologo /MDd /W3 /GR /GX /Zi /Od /I "../../../../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /Zm800 /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x1409 /d "_DEBUG" +# ADD RSC /l 0x1409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"../bin-stage/boost_python_debug.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "boost_python - Win32 Release" +# Name "boost_python - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\src\aix_init_module.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\converter\arg_to_python_base.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\converter\builtin_converters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\object\class.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\dict.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\object\enum.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\errors.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\converter\from_python.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\object\function.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\object\inheritance.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\object\iterator.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\object\life_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\list.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\long.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\module.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\numeric.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\object_operators.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\object_protocol.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\object\pickle_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\converter\registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\str.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\tuple.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\src\converter\type_id.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Group "detail" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\aix_init_module.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\api_placeholder.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\arg_tuple_size.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\borrowed_ptr.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\call_object.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\caller.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\char_array.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\config.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\construct.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\convertible.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\cv_category.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\decorated_type_id.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\def_helper.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\defaults_def.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\defaults_gen.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\dependent.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\destroy.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\exception_handler.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\force_instantiate.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\if_else.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\indirect_traits.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\make_keyword_range_fn.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\make_tuple.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\map_entry.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\member_function_cast.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\module_base.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\module_init.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\msvc_typeinfo.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\none.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\not_specified.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\operator_id.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\overloads_fwd.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\pointee.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\preprocessor.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\python22_fixed.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\raw_pyobject.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\referent_storage.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\result.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\returning.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\scope.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\string_literal.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\target.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\translate_exception.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\type_list.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\type_list_impl.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\type_list_impl_no_pts.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\type_list_utils.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\unwind_type.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\void_ptr.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\void_return.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\detail\wrap_python.hpp +# End Source File +# End Group +# Begin Group "converter" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\arg_from_python.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\arg_to_python.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\arg_to_python_base.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\builtin_converters.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\constructor_function.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\convertible_function.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\from_python.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\implicit.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\obj_mgr_arg_from_python.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\object_manager.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\pointer_type_id.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\pyobject_traits.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\pyobject_type.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\pytype_arg_from_python.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\pytype_object_mgr_traits.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\registered.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\registered_pointee.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\registrations.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\registry.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\return_from_python.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\rvalue_from_python_data.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\converter\to_python_function_type.hpp +# End Source File +# End Group +# Begin Group "object" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\add_to_namespace.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\class.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\class_converters.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\class_detail.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\class_wrapper.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\construct.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\enum_base.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\find_instance.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\forward.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\function.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\function_handle.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\function_object.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\inheritance.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\instance.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\iterator.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\iterator_core.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\life_support.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\make_holder.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\make_instance.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\pickle_support.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\pointer_holder.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\py_function.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\select_holder.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\value_holder.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object\value_holder_fwd.hpp +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\..\boost\python\arg_from_python.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\args.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\args_fwd.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\back_reference.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\base_type_traits.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\bases.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\borrowed.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\call.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\call_method.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\cast.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\class.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\class_fwd.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\copy_const_reference.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\copy_non_const_reference.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\data_members.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\def.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\default_call_policies.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\dict.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\enum.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\errors.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\exception_translator.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\extract.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\handle.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\handle_fwd.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\has_back_reference.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\implicit.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\init.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\instance_holder.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\iterator.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\list.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\long.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\lvalue_from_pytype.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\make_function.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\manage_new_object.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\module.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\module_init.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\numeric.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object_attributes.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object_call.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object_core.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object_fwd.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object_items.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object_operators.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object_protocol.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object_protocol_core.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\object_slices.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\operators.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\operators2.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\other.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\overloads.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\pointee.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\proxy.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\ptr.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\refcount.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\reference_existing_object.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\return_internal_reference.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\return_value_policy.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\scope.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\self.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\signature.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\slice_nil.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\str.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\tag.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\to_python_converter.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\to_python_indirect.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\to_python_value.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\tuple.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\type_id.hpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\boost\python\with_custodian_and_ward.hpp +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/build/VisualStudio/boost_python.dsw b/build/VisualStudio/boost_python.dsw new file mode 100644 index 00000000..574c3bf8 --- /dev/null +++ b/build/VisualStudio/boost_python.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "boost_python"=".\boost_python.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/doc/building.html b/doc/building.html index 45951aa8..6535e891 100644 --- a/doc/building.html +++ b/doc/building.html @@ -51,7 +51,8 @@
      Build Variants
      -
      Building Using the Microsoft Visual Studio IDE
      +
      Building Using the Microsoft Visual Studio + IDE

      @@ -311,62 +312,54 @@ bjam -sTOOLS=

      -

      Building Using the Microsoft Visual - Studio IDE

      +

      Building Using the Microsoft Visual Studio + IDE

      -

      For the those of you who feel more comfortable in the IDE - world, a workspace and project file have been included in the libs/python/build/visual_studio - subdirectory. It builds release and debug versions of the - Boost.Python libraries and places them and the same directory as - Jamfile build does, though the intermediate object files are - placed in a different directory. The files have been created using - Microsoft Visual C++ version 6, but they should work for later - versions as well. You will need to tell the IDE where to find the - Python Include/ and Libs/ directories. - Under Tools>Options>Directories, add an entry for the - Python include dir (i.e. c:/Python22/Include), and - one for the Lib (i.e. c:/Python/Libs. Make sure it - is Libs with an "s" and not just - Lib). +

      For the those of you who feel more comfortable in the IDE world, a + workspace and project file have been included in the libs/python/build/VisualStudio subdirectory. + It builds release and debug versions of the Boost.Python libraries and + places them and the same directory as Jamfile build does, though the + intermediate object files are placed in a different directory. The files + have been created using Microsoft Visual C++ version 6, but they should + work for later versions as well. You will need to tell the IDE where to + find the Python Include/ and Libs/ directories. + Under Tools>Options>Directories, add an entry for the Python + include dir (i.e. c:/Python22/Include), and one for the Lib + (i.e. c:/Python/Libs. Make sure it is Libs with + an "s" and not just Lib).

      Using the IDE for you own projects

      -

      Building your own projects using the IDE is slightly more - complicated. Firstly, you need to make sure that the project you - create as the right kind. It should be a "Win32 Dynamic-Link - Library". The default one that Visual Studio 6 creates needs - some modifications: turn on RTTI, and change the debug and release - builds to use the respective debug and release Multithreaded DLL - versions. You should probably turn off incremental linking too -- - I believe it a bit flaky. If you do this, then change the "Debug - Info" to "Program Database" to get rid of the Edit and Continue - warning. -

      - +

      Building your own projects using the IDE is slightly more complicated. + Firstly, you need to make sure that the project you create as the right + kind. It should be a "Win32 Dynamic-Link Library". The default one that + Visual Studio 6 creates needs some modifications: turn on RTTI, and + change the debug and release builds to use the respective debug and + release Multithreaded DLL versions. You should probably turn off + incremental linking too -- I believe it a bit flaky. If you do this, then + change the "Debug Info" to "Program Database" to get rid of the Edit and + Continue warning.

      +

      You'll need to add the Boost root directory under Tools>Options>Directories to get your code compiling. To make it link, add the above boost_python.dsp file to your workspace, and make your project depend upon it (under - Project>Dependencies). You should be able to build now. -

      + Project>Dependencies). You should be able to build now.

      -

      Lastly, go to the Project Settings>Debug Page and add - the Python.exe as the executable for the project. - Set a startup directory, and make sure that your current project's - output dll, the boost_python.dll and the - python22.dll are on the current PATH. - If you have a python script that tests your dll, then add it in - the "Program Arguments". Now, if all went well, you - should be able to hit the Run (F5) button, and debug your code. -

      - -
      -The Visual Studio project files are graciously contributed and -maintained by Brett -Calcott. -
      +

      Lastly, go to the Project Settings>Debug Page and add the + Python.exe as the executable for the project. Set a startup + directory, and make sure that your current project's output dll, the + boost_python.dll and the python22.dll are on + the current PATH. If you have a python script that tests + your dll, then add it in the "Program Arguments". Now, if all went well, + you should be able to hit the Run (F5) button, and debug your code.

      +
      + The Visual Studio project files are graciously contributed and + maintained by Brett + Calcott. +

      © Copyright David Abrahams 2002. Permission to copy, use, modify, diff --git a/doc/news.html b/doc/news.html index f63c52cf..b06efbc4 100644 --- a/doc/news.html +++ b/doc/news.html @@ -29,26 +29,35 @@


      +
      29 December 2002
      + +
      Added Visual Studio project file and instructions from Brett + Calcott.
      + +
      20 December 2002
      + +
      Added automatic downcasting for pointers, references, and smart + pointers to polymorphic class types upon conversion to python
      + +
      18 December 2002
      + +
      Optimized from_python conversions for wrapped classes by putting + the conversion logic in the shared library instead of registering + separate converters for each class in each extension module
      +
      19 November 2002
      -
      Removed the need for users to cast base class member - function pointers when used as arguments to add_property
      +
      Removed the need for users to cast base class member function + pointers when used as arguments to add_property
      13 December 2002
      Allow exporting of enum_ values into - enclosing scope. - -
      - Fixed unsigned integer conversions to deal correctly with - numbers that are out-of-range of signed long. - -
      - - + "v2/enum.html#enum_-spec">enum_ values into enclosing + scope.
      + Fixed unsigned integer conversions to deal correctly with numbers that + are out-of-range of signed long.
      14 November 2002
      @@ -71,7 +80,7 @@

      Revised - 13 November, 2002 + 20 December, 2002

      diff --git a/doc/v2/acknowledgments.html b/doc/v2/acknowledgments.html index 3e12f3d0..7b6321f7 100644 --- a/doc/v2/acknowledgments.html +++ b/doc/v2/acknowledgments.html @@ -71,6 +71,10 @@ definition syntax. Pearu Pearson wrote some of the test cases that are in the current test suite.

      +

      Brett Calcott + contributed and maintains the Visual Studio project files and + documentation.

      +

      Martin Casado solved some sticky problems which allow us to build the Boost.Python shared library for AIX's crazy dynamic linking model.

      From 2b1a2ce09c9367a940f47d1bb93458361d3a665a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 7 Jan 2003 17:30:51 +0000 Subject: [PATCH 0972/1042] Build static versions of the library too. [SVN r16785] --- build/Jamfile | 75 +++++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/build/Jamfile b/build/Jamfile index b5f45314..099d40cc 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -23,43 +23,54 @@ if [ check-python-config ] bpl-linkflags = "-e initlibboost_python" ; } + local sources = + numeric.cpp + list.cpp + long.cpp + dict.cpp + tuple.cpp + str.cpp + + aix_init_module.cpp + converter/from_python.cpp + converter/registry.cpp + converter/type_id.cpp + object/enum.cpp + object/class.cpp + object/function.cpp + object/inheritance.cpp + object/life_support.cpp + object/pickle_support.cpp + errors.cpp + module.cpp + converter/builtin_converters.cpp + converter/arg_to_python_base.cpp + object/iterator.cpp + object_protocol.cpp + object_operators.cpp + ; + dll boost_python - : - ../src/numeric.cpp - - ../src/list.cpp - ../src/long.cpp - ../src/dict.cpp - ../src/tuple.cpp - ../src/str.cpp - - ../src/aix_init_module.cpp - ../src/converter/from_python.cpp - ../src/converter/registry.cpp - ../src/converter/type_id.cpp - ../src/object/enum.cpp - ../src/object/class.cpp - ../src/object/function.cpp - ../src/object/inheritance.cpp - ../src/object/life_support.cpp - ../src/object/pickle_support.cpp - ../src/errors.cpp - ../src/module.cpp - ../src/converter/builtin_converters.cpp - ../src/converter/arg_to_python_base.cpp - ../src/object/iterator.cpp - ../src/object_protocol.cpp - ../src/object_operators.cpp - : - $(BOOST_PYTHON_V2_PROPERTIES) + : ../src/$(sources) + : $(BOOST_PYTHON_V2_PROPERTIES) BOOST_PYTHON_SOURCE $(bpl-linkflags) ; - stage bin-stage : boost_python - : - "_debug" - "_pydebug" + lib boost_python + : # sources + ../src/$(sources) + + : # requirements + $(BOOST_PYTHON_V2_PROPERTIES) + BOOST_PYTHON_SOURCE + BOOST_STATIC_LIB + $(bpl-linkflags) + ; + + stage bin-stage : boost_python boost_python + : "_debug" + "_pydebug" : debug release ; From b84a8fd73736f5edabad59a9ed76397dcd454bc6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 7 Jan 2003 17:38:08 +0000 Subject: [PATCH 0973/1042] support for BOOST_PYTHON_STATIC_MODULE [SVN r16786] --- include/boost/python/module_init.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/python/module_init.hpp b/include/boost/python/module_init.hpp index 1d65308a..adc259f3 100644 --- a/include/boost/python/module_init.hpp +++ b/include/boost/python/module_init.hpp @@ -17,7 +17,7 @@ BOOST_PYTHON_DECL void init_module(char const* name, void(*)()); }}} -# if defined(_WIN32) || defined(__CYGWIN__) +# if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(BOOST_PYTHON_STATIC_MODULE) # define BOOST_PYTHON_MODULE_INIT(name) \ void init_module_##name(); \ @@ -28,7 +28,7 @@ extern "C" __declspec(dllexport) void init##name() \ } \ void init_module_##name() -# elif defined(_AIX) +# elif defined(_AIX) && !defined(BOOST_PYTHON_STATIC_MODULE) # include # define BOOST_PYTHON_MODULE_INIT(name) \ From b9ecc931b0a861d99160124b7d9d34dd19e8bbc7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 7 Jan 2003 17:44:06 +0000 Subject: [PATCH 0974/1042] support for BOOST_PYTHON_STATIC_MODULE [SVN r16787] --- doc/v2/configuration.html | 72 +++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/doc/v2/configuration.html b/doc/v2/configuration.html index bed7a263..feee4a05 100644 --- a/doc/v2/configuration.html +++ b/doc/v2/configuration.html @@ -47,22 +47,22 @@

      Application Defined Macros

      These are the macros that may be defined by an application using - Boost.Python. Note that if you extend a strict interpretation of the C++ - standard to cover dynamic libraries, using different values of these - macros when compiling different libraries (including extension modules - and the Boost.Python library itself) is a violation of the ODR. However, we know of no C++ + Boost.Python. Note that if you extend a strict interpretation of + the C++ standard to cover dynamic libraries, using different values of + these macros when compiling different libraries (including extension + modules and the Boost.Python library itself) is a violation of the + ODR. However, we know of no C++ implementations on which this particular violation is detectable or causes any problems.

      - - - @@ -70,15 +70,16 @@ - + "call_method.html#call_method-spec">call_method<R>(... + ). @@ -86,28 +87,39 @@ - + + + + + + + +
      Macro + MacroDefault + DefaultMeaning + Meaning
      15The maximum arity of any - function, member function, or constructor to be wrapped, invocation - of a Boost.Python function wich is specified as taking arguments + The maximum arity of any function, member function, + or constructor to be wrapped, invocation of a Boost.Python + function wich is specified as taking arguments x1, x2,...Xn. This includes, in particular, callback mechanisms such as object::operator()(...) or call_method<R>(... - ).
      10The maximum number of template arguments to the The maximum number of template arguments to the + bases<...> class template, which is used to specify the bases of a wrapped C++ class..
      BOOST_PYTHON_STATIC_MODULEnot definedIf defined, prevents your module initialization + function from being treated as an exported symbol on platforms which + support that distinction in-code

      Library Defined Implementation Macros

      -

      These macros are defined by Boost.Python and are - implementation details of interest only to implementors and those porting - to new platforms.

      +

      These macros are defined by Boost.Python and are implementation + details of interest only to implementors and those porting to new + platforms.

      - - - @@ -115,22 +127,22 @@ - +
      Macro + MacroDefault + DefaultMeaning + Meaning
      not definedIf defined, this indicates that the type_info comparison across - shared library boundaries does not work on this platform. In other - words, if shared-lib-1 passes typeid(T) to a function in - shared-lib-2 which compares it to typeid(T), that - comparison may return false. If this macro is #defined, - Boost.Python uses and compares typeid(T).name() instead - of using and comparing the std::type_info objects - directly.If defined, this indicates that the type_info + comparison across shared library boundaries does not work on this + platform. In other words, if shared-lib-1 passes + typeid(T) to a function in shared-lib-2 which compares + it to typeid(T), that comparison may return + false. If this macro is #defined, Boost.Python uses and + compares typeid(T).name() instead of using and comparing + the std::type_info objects directly.

      Revised - 13 November, 2002 - + 7 January, 2003 +

      © Copyright Date: Tue, 7 Jan 2003 18:03:17 +0000 Subject: [PATCH 0975/1042] support for BOOST_PYTHON_STATIC_MODULE clarification [SVN r16788] --- doc/building.html | 53 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/doc/building.html b/doc/building.html index 6535e891..92fd1694 100644 --- a/doc/building.html +++ b/doc/building.html @@ -49,6 +49,15 @@

      Building your Extension Module
      +
      +
      +
      The Easy Way
      + +
      Building your module outside the Boost + project tree
      +
      +
      +
      Build Variants
      Building Using the Microsoft Visual Studio @@ -65,11 +74,14 @@

      Building Boost.Python

      -

      Every Boost.Python extension module must be linked with the - boost_python shared library. To build - boost_python, use Boost.Build in the usual way from - the libs/python/build subdirectory of your boost +

      Normally, Boost.Python extension modules must be linked with the + boost_python shared library. In special circumstances you + may want to link to a static version of the boost_python + library, but if multiple Boost.Pythone extension modules are used + together, it will prevent sharing of types across extension modules, and + consume extra code space. To build boost_python, use Boost.Build in the usual way + from the libs/python/build subdirectory of your boost installation (if you have already built boost from the top level this may have no effect, since the work is already done).

      @@ -231,13 +243,19 @@ bjam -sTOOLS=Building your Extension Module

      - Though there are other approaches, the easiest way to build an extension - module using Boost.Python is with Boost.Build. Until Boost.Build v2 is - released, cross-project build dependencies are not supported, so it works - most smoothly if you add a new subproject to your boost installation. The - libs/python/example subdirectory of your boost installation - contains a minimal example (along with many extra sources). To copy the - example subproject: + Though there are other approaches, the best way to build an extension + module using Boost.Python is with Boost.Build. If you have to use another + build system, you should use Boost.Build at least once with the + "-n" option so you can see the command-lines it uses, + and replicate them. You are likely to run into compilation or linking + problems otherwise. + +

      The Easy Way

      + Until Boost.Build v2 is released, cross-project build dependencies are + not supported, so it works most smoothly if you add a new subproject to + your boost installation. The libs/python/example + subdirectory of your boost installation contains a minimal example (along + with many extra sources). To copy the example subproject:
      1. Create a new subdirectory in, libs/python, say @@ -251,9 +269,14 @@ bjam -sTOOLS=subproject" rule invocation at the top, and the names of some of the source files and/or targets.
      - If you can't modify or copy your boost installation, the alternative is - to create your own Boost.Build project. A similar example you can use as - a starting point is available in above for testing Boost.Python + apply equally to your new extension modules in this subproject. + +

      Building your module outside the Boost project + tree

      + If you can't (or don't wish to) modify your boost installation, the + alternative is to create your own Boost.Build project. A similar example + you can use as a starting point is available in this archive. You'll need to edit the Jamfile and Jamrules files, depending on the relative location of your Boost installation and the new project. Note that automatic testing of From 50bcf8db343b7d0e1cd3fd65c2bd802710bc511f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 Jan 2003 15:04:05 +0000 Subject: [PATCH 0976/1042] Apply workarounds for msvc-stlport [SVN r16854] --- build/Jamfile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build/Jamfile b/build/Jamfile index 099d40cc..b58c22dc 100644 --- a/build/Jamfile +++ b/build/Jamfile @@ -23,6 +23,11 @@ if [ check-python-config ] bpl-linkflags = "-e initlibboost_python" ; } + # Enabling intrinsics (/0i) or maximize speed (/02) seem to cause + # internal compiler errors with this toolset. + local msvc-stlport-workarounds + = off "-Ogty -O1 -Gs" ; + local sources = numeric.cpp list.cpp @@ -55,6 +60,7 @@ if [ check-python-config ] : $(BOOST_PYTHON_V2_PROPERTIES) BOOST_PYTHON_SOURCE $(bpl-linkflags) + $(msvc-stlport-workarounds) ; lib boost_python @@ -66,6 +72,7 @@ if [ check-python-config ] BOOST_PYTHON_SOURCE BOOST_STATIC_LIB $(bpl-linkflags) + $(msvc-stlport-workarounds) ; stage bin-stage : boost_python boost_python From 5895047e23ed478e15653d5b76d705eb04e293c5 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 Jan 2003 15:11:05 +0000 Subject: [PATCH 0977/1042] Initial Checkin [SVN r16855] --- doc/PyConDC_2003/bpl.txt | 648 +++++++++++++++++++++++++++++++++++ doc/PyConDC_2003/default.css | 188 ++++++++++ 2 files changed, 836 insertions(+) create mode 100644 doc/PyConDC_2003/bpl.txt create mode 100644 doc/PyConDC_2003/default.css diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt new file mode 100644 index 00000000..e4db4933 --- /dev/null +++ b/doc/PyConDC_2003/bpl.txt @@ -0,0 +1,648 @@ +.. This is a comment. Note how any initial comments are moved by + transforms to after the document title, subtitle, and docinfo. + +.. Need intro and conclusion +.. Exposing classes + .. Constructors + .. Overloading + .. Properties and data members + .. Inheritance + .. Operators and Special Functions + .. Virtual Functions +.. Call Policies + +++++++++++++++++++++++++++++++++++++++++++++++ + Introducing Boost.Python (Extended Abstract) +++++++++++++++++++++++++++++++++++++++++++++++ + + +.. bibliographic fields (which also require a transform): + +:Author: David Abrahams +:Address: 45 Walnut Street + Somerville, MA 02143 +:Contact: dave@boost-consulting.com +:organization: `Boost Consulting`_ +:date: $Date$ +:status: This is a "work in progress" +:version: 1 +:copyright: Copyright David Abrahams 2002. All rights reserved + +:Dedication: + + For my girlfriend, wife, and partner Luann + +:abstract: + + This paper describes the Boost.Python library, a system for + C++/Python interoperability. + +.. meta:: + :keywords: Boost,python,Boost.Python,C++ + :description lang=en: C++/Python interoperability with Boost.Python + +.. contents:: Table of Contents +.. section-numbering:: + + +.. _`Boost Consulting`: http://www.boost-consulting.com + +============== + Introduction +============== + +Python and C++ are in many ways as different as two languages could +be: while C++ is usually compiled to machine-code, Python is +interpreted. Python's dynamic type system is often cited as the +foundation of its flexibility, while in C++ static typing is the +cornerstone of its efficiency. C++ has an intricate and difficult +compile-time meta-language, while in Python, practically everything +happens at runtime. + +Yet for many programmers, these very differences mean that Python and +C++ complement one another perfectly. Performance bottlenecks in +Python programs can be rewritten in C++ for maximal speed, and +authors of powerful C++ libraries choose Python as a middleware +language for its flexible system integration capabilities. +Furthermore, the surface differences mask some strong similarities: + +* 'C'-family control structures (if, while, for...) + +* Support for object-orientation, functional programming, and generic + programming (these are both *multi-paradigm* programming languages.) + +* Comprehensive operator overloading facilities, recognizing the + importance of syntactic variability for readability and + expressivity. + +* High-level concepts such as collections and iterators. + +* Strong support for writers of re-usable libraries. + +* C++ idioms in common use, such as handle/body classes and + reference-counted smart pointers mirror Python reference semantics. + +* Exception-handling for effective management of error conditions. + +Given Python's rich 'C' interoperability API, it should in principle +be possible to expose C++ type and function interfaces to Python with +an analogous interface to their C++ counterparts. However, the +facilities provided by Python alone for integration with C++ are +relatively meager. Some of this, such as the need to manage +reference-counting manually and lack of C++ exception-handling +support, comes from the limitations of the 'C' language in which the +API is implemented. Those issues aside,most of the hard problems and +much of the tedium of exposing C++ in Python extension modules can be +handled if the code understands the C++ type system. For example: + +* Every argument of every wrapped function requires some kind of + extraction code to convert it from Python to C++. Likewise, the + function return value has to be converted from C++ to Python. + Appropriate Python exceptions must be raised if the conversion + fails. Argument and return types are part of the function's type, + and much of this tedium can be relieved if the wrapping system can + extract that information through introspection. + +* Passing a wrapped C++ derived class instance to a C++ function + accepting a pointer or reference to a base class requires knowledge + of the inheritance relationship and how to translate the address of + a base class into that of a derived class. + +The Boost.Python Library (BPL) leverages the power of C++ +meta-programming techniques to introspect about the C++ type system, +and presents a simple, IDL-like C++ interface for exposing C++ code in +extension modules. + +=========================== + Boost.Python Design Goals +=========================== + +The primary goal of Boost.Python is to allow users to expose C++ +classes and functions to Python using nothing more than a C++ +compiler. In broad strokes, the user experience should be one of +directly manipulating C++ objects from Python. + +However, it's also important not to translate all interfaces *too* +literally: the idioms of each language must be respected. For +example, though C++ and Python both have an iterator concept, they are +expressed very differently. Boost.Python has to be able to bridge the +interface gap. + +It must be possible to insulate Python users from crashes resulting +from trivial misuses of C++ interfaces, such as accessing +already-deleted objects. By the same token the library should +insulate C++ users from low-level Python 'C' API, replacing +error-prone 'C' interfaces like manual reference-count management and +raw ``PyObject`` pointers with more-robust alternatives. + +Support for component-based development is crucial, so that C++ types +exposed in one extension module can be passed to functions exposed in +another without loss of crucial information like C++ inheritance +relationships. + +Finally, all wrapping must be *non-intrusive*, without modifying or +even seeing the original C++ source code. Existing C++ libraries have +to be wrappable by third parties who only have access to header files +and binaries. + +========================== + Hello Boost.Python World +========================== + +And now for a preview of Boost.Python, and how it improves on the raw +facilities offered by Python. Here's a function we might want to +expose:: + + char const* greet(unsigned x) + { + static char const* const msgs[] = { "hello", "Boost.Python", "world!" }; + + if (x > 2) + throw std::range_error("greet: index out of range"); + + return msgs[x]; + } + +To wrap this function in standard C++ using the Python 'C' API, we'd +need something like this:: + + extern "C" // all Python interactions use 'C' linkage and calling convention + { + // Wrapper to handle argument/result conversion and checking + PyObject* greet_wrap(PyObject* args, PyObject * keywords) + { + int x; + if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments + { + char const* result = greet(x); // invoke wrapped function + return PyString_FromString(result); // convert result to Python + } + return 0; // error occurred + } + + // Table of wrapped functions to be exposed by the module + static PyMethodDef methods[] = { + { "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" } + , { NULL, NULL, 0, NULL } // sentinel + }; + + // module initialization function + DL_EXPORT init_hello() + { + (void) Py_InitModule("hello", methods); // add the methods to the module + } + } + +Now here's the wrapping code we'd use to expose it with Boost.Python:: + + #include + using namespace boost::python; + BOOST_PYTHON_MODULE(hello) + { + def("greet", greet, "return one of 3 parts of a greeting"); + } + +and here it is in action:: + + >>> import hello + >>> for x in range(3): + ... print hello.greet(x) + ... + hello + Boost.Python + world! + +Aside from the fact that the 'C' API version is much more verbose than +the BPL one, it's worth noting that it doesn't handle a few things +correctly: + +* The original function accepts an unsigned integer, and the Python + 'C' API only gives us a way of extracting signed integers. The + Boost.Python version will raise a Python exception if we try to pass + a negative number to ``hello.greet``, but the other one will proceed + to do whatever the C++ implementation does when converting an + negative integer to unsigned (usually wrapping to some very large + number), and pass the incorrect translation on to the wrapped + function. + +* That brings us to the second problem: if the C++ ``greet()`` + function is called with a number greater than 2, it will throw an + exception. Typically, if a C++ exception propagates across the + boundary with code generated by a 'C' compiler, it will cause a + crash. As you can see in the first version, there's no C++ + scaffolding there to prevent this from happening. Functions wrapped + by Boost.Python automatically include an exception-handling layer + which protects Python users by translating unhandled C++ exceptions + into a corresponding Python exception. + +* A slightly more-subtle limitation is that the argument conversion + used in the Python 'C' API case can only get that integer ``x`` in + *one way*. PyArg_ParseTuple can't convert Python ``long`` objects + (arbitrary-precision integers) which happen to fit in an ``unsigned + int`` but not in a ``signed long``, nor will it ever handle a + wrapped C++ class with a user-defined implicit ``operator unsigned + int()`` conversion. The BPL's dynamic type conversion registry + allows users to add arbitrary conversion methods. + +================== + Library Overview +================== + +This section outlines some of the library's major features. Except as +neccessary to avoid confusion, details of library implementation are +omitted. + +------------------ + Exposing Classes +------------------ + +C++ classes and structs are exposed with a similarly-terse interface. +Given:: + + struct World + { + void set(std::string msg) { this->msg = msg; } + std::string greet() { return msg; } + std::string msg; + }; + +The following code will expose it in our extension module:: + + #include + BOOST_PYTHON_MODULE(hello) + { + class_("World") + .def("greet", &World::greet) + .def("set", &World::set) + ; + } + +Although this code has a certain pythonic familiarity, people +sometimes find the syntax bit confusing because it doesn't look like +most of the C++ code they're used to. All the same, this is just +standard C++. Because of their flexible syntax and operator +overloading, C++ and Python are great for defining domain-specific +(sub)languages +(DSLs), and that's what we've done in BPL. To break it down:: + + class_("World") + +constructs an unnamed object of type ``class_`` and passes +``"World"`` to its constructor. This creates a new-style Python class +called ``World`` in the extension module, and associates it with the +C++ type ``World`` in the BPL type conversion registry. We might have +also written:: + + class_ w("World"); + +but that would've been more verbose, since we'd have to name ``w`` +again to invoke its ``def()`` member function:: + + w.def("greet", &World::greet) + +There's nothing special about the location of the dot for member +access in the original example: C++ allows any amount of whitespace on +either side of a token, and placing the dot at the beginning of each +line allows us to chain as many successive calls to member functions +as we like with a uniform syntax. The other key fact that allows +chaining is that ``class_<>`` member functions all return a reference +to ``*this``. + +So the example is equivalent to:: + + class_ w("World"); + w.def("greet", &World::greet); + w.def("set", &World::set); + +It's occasionally useful to be able to break down the components of a +Boost.Python class wrapper in this way, but the rest of this paper +will tend to stick to the terse syntax. + +For completeness, here's the wrapped class in use: + +>>> import hello +>>> planet = hello.World() +>>> planet.set('howdy') +>>> planet.greet() +'howdy' + +Constructors +============ + +Since our ``World`` class is just a plain ``struct``, it has an +implicit no-argument (nullary) constructor. Boost.Python exposes the +nullary constructor by default, which is why we were able to write: + +>>> planet = hello.World() + +However, well-designed classes in any language may require constructor +arguments in order to establish their invariants. Unlike Python, +where ``__init__`` is just a specially-named method, In C++ +constructors cannot be handled like ordinary member functions. In +particular, we can't take their address: ``&World::World`` is an +error. The library provides a different interface for specifying +constructors. Given:: + + struct World + { + World(std::string msg); // added constructor + ... + +we can modify our wrapping code as follows:: + + class_("World", init()) + ... + +of course, a C++ class may have additional constructors, and we can +expose those as well by passing more instances of ``init<...>`` to +``def()``:: + + class_("World", init()) + .def(init()) + ... + +Boost.Python allows wrapped functions, member functions, and +constructors to be overloaded to mirror C++ overloading. + +Data Members and Properties +=========================== + +Any publicly-accessible data members in a C++ class can be easily +exposed as either ``readonly`` or ``readwrite`` attributes:: + + class_("World", init()) + .def_readonly("msg", &World::msg) + ... + +and can be used directly in Python: + +>>> planet = hello.World('howdy') +>>> planet.msg +'howdy' + +This does *not* result in adding attributes to the ``World`` instance +``__dict__``, which can result in substantial memory savings when +wrapping large data structures. In fact, no instance ``__dict__`` +will be created at all unless attributes are explicitly added from +Python. BPL owes this capability to the new Python 2.2 type system, +in particular the descriptor interface and ``property`` type. + +In C++, publicly-accessible data members are considered a sign of poor +design because they break encapsulation, and style guides usually +dictate the use of "getter" and "setter" functions instead. In +Python, however, ``__getattr__``, ``__setattr__``, and since 2.2, +``property`` mean that attribute access is just one more +well-encapsulated syntactic tool at the programmer's disposal. BPL +bridges this idiomatic gap by making Python ``property`` creation +directly available to users. So if ``msg`` were private, we could +still expose it as attribute in Python as follows:: + + class_("World", init()) + .add_property("msg", &World::greet, &World::set) + ... + +The example above mirrors the familiar usage of properties in Python +2.2+: + +>>> class World(object): +... __init__(self, msg): +... self.__msg = msg +... def greet(self): +... return self.__msg +... def set(self, msg): +... self.__msg = msg +... msg = property(greet, set) + +Operators and Special Functions +=============================== + +The ability to write arithmetic operators for user-defined types that +C++ and Python both allow the definition of has been a major factor in +the popularity of both languages for scientific computing. The +success of packages like NumPy attests to the power of exposing +operators in extension modules. In this example we'll wrap a class +representing a position in a large file:: + + class FilePos { /*...*/ }; + + // Linear offset + FilePos operator+(FilePos, int); + FilePos operator+(int, FilePos); + FilePos operator-(FilePos, int); + + // Distance between two FilePos objects + int operator-(FilePos, FilePos); + + // Offset with assignment + FilePos& operator+=(FilePos&, int); + FilePos& operator-=(FilePos&, int); + + // Comparison + bool operator<(FilePos, FilePos); + +The wrapping code looks like this:: + + class_("FilePos") + .def(self + int()) // __add__ + .def(int() + self) // __radd__ + .def(self - int()) // __sub__ + + .def(self - self) // __sub__ + + .def(self += int()) // __iadd__ + .def(self -= int()) // __isub__ + + .def(self < self); // __lt__ + ; + +The magic is performed using a simplified application of "expression +templates" [VELD1995]_, a technique originally developed by for +optimization of high-performance matrix algebra expressions. The +essence is that instead of performing the computation immediately, +operators are overloaded to construct a type *representing* the +computation. In matrix algebra, dramatic optimizations are often +available when the structure of an entire expression can be taken into +account, rather than processing each operation "greedily". +Boost.Python uses the same technique to build an appropriate Python +callable object based on an expression involving ``self``, which is +then added to the class. + +Inheritance +=========== + +C++ inheritance relationships can be represented to Boost.Python by adding +an optional ``bases<...>`` argument to the ``class_<...>`` template +parameter list as follows:: + + class_ >("Derived") + ... + +This has two effects: + +1. When the ``class_<...>`` is created, Python type objects + corresponding to ``Base1`` and ``Base2`` are looked up in the BPL + registry, and are used as bases for the new Python ``Derived`` type + object [#mi]_, so methods exposed for the Python ``Base1`` and + ``Base2`` types are automatically members of the ``Derived`` type. + Because the registry is global, this works correctly even if + ``Derived`` is exposed in a different module from either of its + bases. + +2. C++ conversions from ``Derived`` to its bases are added to the + Boost.Python registry. Thus wrapped C++ methods expecting (a + pointer or reference to) an object of either base type can be + called with an object wrapping a ``Derived`` instance. Wrapped + member functions of class ``T`` are treated as though they have an + implicit first argument of ``T&``, so these conversions are + neccessary to allow the base class methods to be called for derived + objects. + +Of course it's possible to derive new Python classes from wrapped C++ +class instances. Because Boost.Python uses the new-style class +system, that works very much as for the Python built-in types. There +is one significant detail in which it differs: the built-in types +generally establish their invariants in their ``__new__`` function, so +that derived classes do not need to call ``__init__`` on the base +class before invoking its methods : + +>>> class L(list): +... def __init__(self): +... pass +... +>>> L().reverse() +>>> + +Because C++ object construction is a one-step operation, C++ instance +data cannot be constructed until the arguments are available, in the +``__init__`` function: + +>>> class D(SomeBPLClass): +... def __init__(self): +... pass +... +>>> D().some_bpl_method() +Traceback (most recent call last): + File "", line 1, in ? +TypeError: bad argument type for built-in operation + +This happened because Boost.Python couldn't find instance data of type +``SomeBPLClass`` within the ``D`` instance; ``D``'s ``__init__`` +function masked construction of the base class. It could be corrected +by either removing ``D``'s ``__init__`` function or having it call +``SomeBPLClass.__init__(...)`` explicitly. + +Virtual Functions +================= + +Deriving new types in Python from extension classes is not very +interesting unless they can be used polymorphically from C++. In +other words, Python method implementations should appear to override +the implementation of C++ virtual functions when called *through base +class pointers/references from C++*. Since the only way to alter the +behavior of a virtual function is to override it in a derived class, +the user must build a special derived class to dispatch a polymorphic +class' virtual functions:: + + // + // interface to wrap: + // + class Base + { + public: + virtual int f(std::string x) { return 42; } + virtual ~Base(); + }; + + int calls_f(Base const& b, std::string x) { return b.f(x); } + + // + // Wrapping Code + // + + // Dispatcher class + struct BaseWrap : Base + { + // Store a pointer to the Python object + BaseWrap(PyObject* self_) : self(self_) {} + PyObject* self; + + // Default implementation, for when f is not overridden + int f_default(std::string x) { return this->Base::f(x); } + // Dispatch implementation + int f(std::string x) { return call_method(self, "f", x); } + }; + + ... + def("calls_f", calls_f); + class_("Base") + .def("f", &Base::f, &BaseWrap::f_default) + ; + +Now here's some Python code which demonstrates: + +>>> class Derived(Base): +... def f(self, s): +... return len(s) +... +>>> calls_f(Base(), 'foo') +42 +>>> calls_f(Derived(), 'forty-two') +9 + +Things to notice about the dispatcher class: + +* The key element which allows overriding in Python is the + ``call_method`` invocation, which uses the same global type + conversion registry as the C++ function wrapping does to convert its + arguments from C++ to Python and its return type from Python to C++. + +* Any constructor signatures you wish to wrap must be replicated with + an initial ``PyObject*`` argument + +* The dispatcher must store this argument so that it can be used to + invoke ``call_method`` + +* The ``f_default`` member function is needed when the function being + exposed is not pure virtual; there's no other way ``Base::f`` can be + called on an object of type ``BaseWrap``, since it overrides ``f``. + +Admittedly, this formula is tedious to repeat, especially on a project +with many polymorphic classes; that it is neccessary reflects +limitations in C++'s compile-time reflection capabilities. Several +efforts are underway to write front-ends for Boost.Python which can +generate these dispatchers (and other wrapping code) automatically. +If these are successful it will mark a move away from wrapping +everything directly in pure C++ for many of our users. + +============= + Conclusions +============= + +Perhaps one day we'll have a language with the simplicity and +expressive power of Python and the compile-time muscle of C++. Being +able to take advantage of all of these facilities without paying the +mental and development-time penalties of crossing a language barrier +would bring enormous benefits. Until then, interoperability tools +like Boost.Python can help lower the barrier and make the benefits of +both languages more accessible to both communities. + +=========== + Footnotes +=========== + +.. [#mi] For hard-core new-style class/extension module writers it is + worth noting that the normal requirement that all extension classes + with data form a layout-compatible single-inheritance chain is + lifted for Boost.Python extension classes. Clearly, either + ``Base1`` or ``Base2`` has to occupy a different offset in the + ``Derived`` class instance. This is possible because the wrapped + part of BPL extension class instances is never assumed to have a + fixed offset within the wrapper. + +=========== + Citations +=========== + +.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report, + Vol. 7 No. 5 June 1995, pp. 26-31. + http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html diff --git a/doc/PyConDC_2003/default.css b/doc/PyConDC_2003/default.css new file mode 100644 index 00000000..2e1fddb9 --- /dev/null +++ b/doc/PyConDC_2003/default.css @@ -0,0 +1,188 @@ +/* +:Author: David Goodger +:Contact: goodger@users.sourceforge.net +:date: $Date$ +:version: $Revision$ +:copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the HTML output of Docutils. +*/ + +.first { + margin-top: 0 } + +.last { + margin-bottom: 0 } + +a.toc-backref { + text-decoration: none ; + color: black } + +dd { + margin-bottom: 0.5em } + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.attention, div.caution, div.danger, div.error, div.hint, +div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +div.hint p.admonition-title, div.important p.admonition-title, +div.note p.admonition-title, div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em } + +div.footer, div.header { + font-size: smaller } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1.title { + text-align: center } + +h2.subtitle { + text-align: center } + +hr { + width: 75% } + +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.line-block { + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option-argument { + font-style: italic } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +table { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.citation { + border-left: solid thin gray ; + padding-left: 0.5ex } + +table.docinfo { + margin: 2em 4em } + +table.footnote { + border-left: solid thin black ; + padding-left: 0.5ex } + +td, th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +th.docinfo-name, th.field-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap } + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + font-size: 100% } + +tt { + background-color: #eeeeee } + +ul.auto-toc { + list-style-type: none } From 4f5272cab9a0f263ae0637dfb6017db8d27ca9c3 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 10 Jan 2003 15:17:46 +0000 Subject: [PATCH 0978/1042] Folded in Ralf's first set of edits [SVN r16856] --- doc/PyConDC_2003/bpl.txt | 154 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 7 deletions(-) diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt index e4db4933..09a8b464 100644 --- a/doc/PyConDC_2003/bpl.txt +++ b/doc/PyConDC_2003/bpl.txt @@ -614,17 +614,157 @@ generate these dispatchers (and other wrapping code) automatically. If these are successful it will mark a move away from wrapping everything directly in pure C++ for many of our users. +Serialization +============= + +*Serialization* is the process of converting objects in memory to a +form that can be stored on disk or sent over a network connection. The +serialized object (most often a plain string) can be retrieved and +converted back to the original object. A good serialization system will +automatically convert entire object hierarchies. Python's standard +``pickle`` module is such a system. It leverages the language's +virtually unlimited runtime introspection facilities for serializing +practically arbitrary user-defined objects. With a few simple and +unintrusive provisions this powerful machinery can be extended to work +for wrapped C++ objects. Here is a simple example:: + + #include + + struct World + { + World(std::string a_msg) : msg(a_msg) {} + std::string greet() const { return msg; } + std::string msg; + }; + + #include + using namespace boost::python; + + struct World_picklers : pickle_suite + { + static tuple + getinitargs(World const& w) { return make_tuple(w.greet()); } + }; + + BOOST_PYTHON_MODULE(hello) + { + class_("World", init()) + .def("greet", &World::greet) + .def_pickle(World_picklers()) + ; + } + +Now let's create a ``World`` object and put it to rest on disk:: + + >>> import hello + >>> import pickle + >>> a_world = hello.World("howdy") + >>> pickle.dump(a_world, open("my_world", "w")) + +Resurrecting the ``World`` object in a different process is equally easy:: + + >>> import pickle + >>> resurrected_world = pickle.load(open("my_world", "r")) + >>> resurrected_world.greet() + 'howdy' + +Boost.Python's ``pickle_suite`` fully supports the documented +``pickle`` protocols. Of course ``cPickle`` can also be used for faster +processing. Enabling serialization of more complex C++ objects requires +a little more work than is shown in this example, but the ``object`` +interface (see next section) greatly helps in keeping the code +manageable. + +================== + Object interface +================== + +Experienced extension module authors will be familiar with the 'C' view +of Python objects, the ubiquitous ``PyObject*``. Most if not all Python +'C' API functions involve ``PyObject*`` as arguments or return type. A +major complication is the raw reference counting interface presented to +the 'C' programmer. E.g. some API functions return *new references* and +others return *borrowed references*. It is up to the extension module +writer to properly increment and decrement reference counts. This +quickly becomes cumbersome and error prone, especially if there are +multiple execution paths. + +Boost.Python provides a type ``object`` which is essentially a high +level wrapper around ``PyObject*``. ``object`` automates reference +counting as much as possible. It also provides the facilities for +converting arbitrary C++ types to Python objects and vice versa. +This should significantly reduce the learning effort for prospective +extension module writers. + +To illustrate, this Python code snippet:: + + def f(x, y): + if (y == 'foo'): + x[3:7] = 'bar' + else: + x.items += y(3, x) + return x + +Can be rewritten in C++ using Boost.Python facilities:: + + object f(object x, object y) { + if (y == "foo") + x.slice(3,7) = "bar"; + else + x.attr("items") += y(3, x); + return x; + } + +The ``extract`` class template can be used to convert Python objects +to C++ types:: + + object o(3); + double x = extract(o); + +If the C++ type cannot be extracted an appropriate exception is thrown +(``extract`` provides facilities for avoiding exceptions if this is +desired). + +All registered user-defined conversions are automatically accessible +through the ``object`` interface. With reference to the ``World`` class +defined in previous examples:: + + object as_python_object(World("howdy")); + World back_as_c_plus_plus_object = extract(as_python_object); + +The ``object`` type is accompanied by a set of derived types +that mirror the Python built-in types such as ``list``, ``dict``, +``tuple``, etc. as much as possible. This enables convenient +manipulation of these high-level types from C++:: + + dict d; + d["some"] = "thing"; + d["lucky_number"] = 13; + list l = d.keys(); + ============= Conclusions ============= -Perhaps one day we'll have a language with the simplicity and -expressive power of Python and the compile-time muscle of C++. Being -able to take advantage of all of these facilities without paying the -mental and development-time penalties of crossing a language barrier -would bring enormous benefits. Until then, interoperability tools -like Boost.Python can help lower the barrier and make the benefits of -both languages more accessible to both communities. +The examples in this paper illustrate that Boost.Python enables +seamless interoperability between C++ and Python. Importantly, this is +achieved without introducing a third syntax: the Python/C++ interface +definitions are written in pure C++. This avoids any problems with +parsing the C++ code to be interfaced to Python, yet the interface +definitions are concise and maintainable. Freed from much of the +intricacies of crossing a language boundary, software designers can +take full advantage of two rich and complimentary language +environments. + +.. I'm not ready to give up on all of this quite yet + +.. Perhaps one day we'll have a language with the simplicity and + expressive power of Python and the compile-time muscle of C++. Being + able to take advantage of all of these facilities without paying the + mental and development-time penalties of crossing a language barrier + would bring enormous benefits. Until then, interoperability tools + like Boost.Python can help lower the barrier and make the benefits of + both languages more accessible to both communities. =========== Footnotes From 84a8fb71b86dbdf99fefce7c612d72cf0c83e16c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 10 Jan 2003 19:00:05 +0000 Subject: [PATCH 0979/1042] meager result after a real hard try [SVN r16863] --- doc/PyConDC_2003/bpl.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt index 09a8b464..43aa812e 100644 --- a/doc/PyConDC_2003/bpl.txt +++ b/doc/PyConDC_2003/bpl.txt @@ -751,10 +751,10 @@ seamless interoperability between C++ and Python. Importantly, this is achieved without introducing a third syntax: the Python/C++ interface definitions are written in pure C++. This avoids any problems with parsing the C++ code to be interfaced to Python, yet the interface -definitions are concise and maintainable. Freed from much of the -intricacies of crossing a language boundary, software designers can -take full advantage of two rich and complimentary language -environments. +definitions are concise and maintainable. Freed from most of the +development-time penalties of crossing a language boundary, software +designers can take full advantage of two rich and complimentary +language environments. .. I'm not ready to give up on all of this quite yet From 72b214b8db25e60e7b9f802fbbc695b5fc2f2251 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 10 Jan 2003 19:22:13 +0000 Subject: [PATCH 0980/1042] details from the introduction moved to design goals section [SVN r16864] --- doc/PyConDC_2003/bpl.txt | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt index 43aa812e..25d50621 100644 --- a/doc/PyConDC_2003/bpl.txt +++ b/doc/PyConDC_2003/bpl.txt @@ -91,24 +91,11 @@ facilities provided by Python alone for integration with C++ are relatively meager. Some of this, such as the need to manage reference-counting manually and lack of C++ exception-handling support, comes from the limitations of the 'C' language in which the -API is implemented. Those issues aside,most of the hard problems and -much of the tedium of exposing C++ in Python extension modules can be -handled if the code understands the C++ type system. For example: +API is implemented. -* Every argument of every wrapped function requires some kind of - extraction code to convert it from Python to C++. Likewise, the - function return value has to be converted from C++ to Python. - Appropriate Python exceptions must be raised if the conversion - fails. Argument and return types are part of the function's type, - and much of this tedium can be relieved if the wrapping system can - extract that information through introspection. - -* Passing a wrapped C++ derived class instance to a C++ function - accepting a pointer or reference to a base class requires knowledge - of the inheritance relationship and how to translate the address of - a base class into that of a derived class. - -The Boost.Python Library (BPL) leverages the power of C++ +Most of the hard problems and much of the tedium of exposing C++ in +Python extension modules can be handled if the code understands the C++ +type system. The Boost.Python Library (BPL) leverages the power of C++ meta-programming techniques to introspect about the C++ type system, and presents a simple, IDL-like C++ interface for exposing C++ code in extension modules. @@ -128,6 +115,17 @@ example, though C++ and Python both have an iterator concept, they are expressed very differently. Boost.Python has to be able to bridge the interface gap. +Every argument of every wrapped function must be converted +automatically from Python to C++. Likewise, the function return value +must be converted automatically from C++ to Python. Appropriate +Python exceptions must be raised if the conversion fails. + +It must be possible to pass a wrapped C++ derived class instance to a +C++ function accepting a pointer or reference to a base class. For +this Boost.Python has to maintain a graph of the inheritance +relationships including information on how to translate the address of +a base class into that of a derived class. + It must be possible to insulate Python users from crashes resulting from trivial misuses of C++ interfaces, such as accessing already-deleted objects. By the same token the library should From e13a11eb7ff9da28e7fcd67949b7b20fa6c63bd9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 11 Jan 2003 00:18:59 +0000 Subject: [PATCH 0981/1042] Fix dict bug [SVN r16866] --- src/dict.cpp | 4 ++-- test/dict.cpp | 1 + test/dict.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dict.cpp b/src/dict.cpp index 847d2182..f1b8df84 100644 --- a/src/dict.cpp +++ b/src/dict.cpp @@ -65,8 +65,8 @@ object dict_base::get(object_cref k) const { if (check_exact(this)) { - return object(detail::borrowed_reference( - PyDict_GetItem(this->ptr(),k.ptr()))); + PyObject* result = PyDict_GetItem(this->ptr(),k.ptr()); + return object(detail::borrowed_reference(result ? result : Py_None)); } else { diff --git a/test/dict.cpp b/test/dict.cpp index 538c7930..de6d4a86 100644 --- a/test/dict.cpp +++ b/test/dict.cpp @@ -61,6 +61,7 @@ void test_templates(object print) //print(tmp[1]); tmp[1.5] = 13; print(tmp.get(1.5)); + print(tmp.get(44)); print(tmp); print(tmp.get(2,"default")); print(tmp.has_key(key)); diff --git a/test/dict.py b/test/dict.py index fdabf2c9..c99d2e9b 100644 --- a/test/dict.py +++ b/test/dict.py @@ -20,6 +20,7 @@ >>> test_templates(printer) a test string 13 +None {1.5: 13, 1: 'a test string'} default 0 From ba4906d05ca39a3130ef1a85d30ecde779128ce6 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Mon, 13 Jan 2003 10:05:01 +0000 Subject: [PATCH 0982/1042] Update V2 Jamfile for Boost. [SVN r16882] --- build/Jamfile.v2 | 24 ++++++++++++++++-------- example/Jamfile.v2 | 2 ++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 62f3b344..f2912fa7 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -13,15 +13,23 @@ else if [ GLOB /usr/include/python2.2 : * ] PYTHON_PATH = /usr ; } -PYTHON_LIB = python2.2 ; - if [ os.name ] in CYGWIN NT { - lib_condition = true: ; + lib_condition = shared: ; defines = USE_DL_IMPORT ; - PYTHON_LIB = python2.2.dll ; + + # Declare a target for the python interpreter library + lib python : : python2.2.dll ; + PYTHON_LIB = python ; +} +else +{ + lib python : : python2.2 ; + PYTHON_LIB = python ; } + + if $(PYTHON_PATH) { @@ -29,7 +37,7 @@ project boost/python : source-location ../src : requirements $(PYTHON_PATH)/include/python2.2 $(lib_condition)$(PYTHON_PATH)/lib/python2.2/config - true:$(PYTHON_LIB) + shared:$(PYTHON_LIB) $(defines) : use-requirements # requirement that will be propageted to *users* of this library $(PYTHON_PATH)/include/python2.2 @@ -40,7 +48,7 @@ project boost/python # true:$(PYTHON_LIB) $(PYTHON_PATH)/lib/python2.2/config - $(PYTHON_LIB) + $(PYTHON_LIB) ; lib boost_python @@ -70,8 +78,8 @@ lib boost_python object/iterator.cpp object_protocol.cpp object_operators.cpp - : false:BOOST_PYTHON_STATIC_LIB + : static:BOOST_PYTHON_STATIC_LIB BOOST_PYTHON_SOURCE - : true + : shared ; } diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index f80168e2..cf7a2972 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -7,4 +7,6 @@ project python-extension getting_started1 : getting_started1.cpp : true ; python-extension getting_started2 : getting_started2.cpp : true ; + +exe embedding_test : embedding_test.cpp : BOOST_PYTHON_DYNAMIC_LIB true ; From 9d26167ec1f1dd094483da128a4107f53a67a0d9 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Mon, 13 Jan 2003 12:31:12 +0000 Subject: [PATCH 0983/1042] Change use-requirements to usage-requirements in some library Jamfiles. [SVN r16884] --- build/Jamfile.v2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index f2912fa7..7b9e21f1 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -39,7 +39,7 @@ project boost/python $(lib_condition)$(PYTHON_PATH)/lib/python2.2/config shared:$(PYTHON_LIB) $(defines) - : use-requirements # requirement that will be propageted to *users* of this library + : usage-requirements # requirement that will be propageted to *users* of this library $(PYTHON_PATH)/include/python2.2 # We have a bug which causes us to conclude that conditionalized From 21f3c7c8c251b87a0c9a4b7982b098033fdac216 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 15 Jan 2003 06:19:23 +0000 Subject: [PATCH 0984/1042] Mac OS X status [SVN r16904] --- doc/v2/faq.html | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/doc/v2/faq.html b/doc/v2/faq.html index c21007ab..06087038 100644 --- a/doc/v2/faq.html +++ b/doc/v2/faq.html @@ -41,6 +41,8 @@
      How do I debug my Python extensions?
      Why doesn't my *= operator work?
      + +
      Does Boost.Python work with Mac OS X?
      @@ -326,16 +328,38 @@ To cure this problem, all you need to do is upgrade your Python to version 2.2.1 or later. + +

      Does Boost.Python work with Mac OS X?

      + +
      +

      The short answer: as of January 2003, unfortunately not. +

      +The longer answer: using Mac OS 10.2.3 with the December Developer's Kit, +Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles fine, +including the examples. However, there are problems at runtime +(see http://mail.python.org/pipermail/c++-sig/2003-January/003267.html). +Solutions are currently unknown. +

      +It is known that under certain circumstances objects are double-destructed. +See http://mail.python.org/pipermail/c++-sig/2003-January/003278.html" +for details. It is not clear however if this problem is related to +the Boost.Python runtime issues. +

      +

      Revised - 24 November, 2002 + 14 January, 2003

      © Copyright Dave Abrahams 2002. All Rights + "../../../../people/dave_abrahams.htm">Dave Abrahams 2002-2003. All Rights Reserved.

      From 571790097a5d73e9be73db28ecb2102f7bfa5078 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Sat, 18 Jan 2003 01:44:48 +0000 Subject: [PATCH 0985/1042] minor error fixed PodBayDoorException const& x [SVN r16926] --- doc/tutorial/doc/exception_translation.html | 14 +++++++------- doc/tutorial/doc/quickstart.txt | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/tutorial/doc/exception_translation.html b/doc/tutorial/doc/exception_translation.html index 9ec6bc86..aaab2ec7 100644 --- a/doc/tutorial/doc/exception_translation.html +++ b/doc/tutorial/doc/exception_translation.html @@ -33,16 +33,16 @@ then gives up:

      Users may provide custom translation. Here's an example:

      -
      -    struct PodBayDoorException;
      -    void translator(PodBayDoorException& x) {
      +
      +    struct PodBayDoorException;
      +    void translator(PodBayDoorException const& x) {
               PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave...");
      -    }
      -    BOOST_PYTHON_MODULE(kubrick) {
      +    }
      +    BOOST_PYTHON_MODULE(kubrick) {
                register_exception_translator<
                     PodBayDoorException>(translator);
      -         ...
      -
      + ... +
      diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt index 73da42c7..a67e196e 100644 --- a/doc/tutorial/doc/quickstart.txt +++ b/doc/tutorial/doc/quickstart.txt @@ -1245,7 +1245,7 @@ then gives up: Users may provide custom translation. Here's an example: struct PodBayDoorException; - void translator(PodBayDoorException& x) { + void translator(PodBayDoorException const& x) { PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave..."); } BOOST_PYTHON_MODULE(kubrick) { From 399cf70b92480913b7f76a296f4ae7d08d53fc94 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 19 Jan 2003 19:12:30 +0000 Subject: [PATCH 0986/1042] Add staticmethod support from Nikolay Mladenov [SVN r16946] --- doc/news.html | 8 ++- doc/v2/acknowledgments.html | 3 + doc/v2/class.html | 97 +++++++++++++++++---------- include/boost/python/class.hpp | 5 ++ include/boost/python/object/class.hpp | 12 +++- src/object/class.cpp | 31 +++++++++ src/object/function.cpp | 16 +++++ test/Jamfile | 1 + test/staticmethod.cpp | 46 +++++++++++++ test/staticmethod.py | 52 ++++++++++++++ 10 files changed, 233 insertions(+), 38 deletions(-) create mode 100644 test/staticmethod.cpp create mode 100644 test/staticmethod.py diff --git a/doc/news.html b/doc/news.html index b06efbc4..ac0fb176 100644 --- a/doc/news.html +++ b/doc/news.html @@ -29,10 +29,16 @@
      +
      19 January 2003
      + +
      Integrated staticmethod support from Nikolay Mladenov. Thanks, + Nikolay!
      +
      29 December 2002
      Added Visual Studio project file and instructions from Brett - Calcott.
      + Calcott. Thanks, Brett!
      20 December 2002
      diff --git a/doc/v2/acknowledgments.html b/doc/v2/acknowledgments.html index 7b6321f7..82cea6a2 100644 --- a/doc/v2/acknowledgments.html +++ b/doc/v2/acknowledgments.html @@ -75,6 +75,9 @@ contributed and maintains the Visual Studio project files and documentation.

      +

      Nikolay Mladenov contributed + staticmethod support.

      +

      Martin Casado solved some sticky problems which allow us to build the Boost.Python shared library for AIX's crazy dynamic linking model.

      diff --git a/doc/v2/class.html b/doc/v2/class.html index 6e63f0a4..85eda64e 100644 --- a/doc/v2/class.html +++ b/doc/v2/class.html @@ -212,7 +212,7 @@ namespace boost { namespace python { template <class T - , class Bases = bases<> + , class Bases = bases<> , class HeldType = T , class NonCopyable = unspecified > @@ -242,6 +242,9 @@ namespace boost { namespace python template <class Fn, class A1, class A2, class A3> class_& def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&); + // declaring method as static + class_& staticmethod(char const* name); + // exposing operators template <unspecified> class_& def(HeldType according to the semantics described above, using a copy of init_expr's call policies. - If the longest valid prefix of Init contains N - types and init_expr holds M keywords, an initial - sequence of the keywords are used for all but the first - N - M arguments of each overload. + If the longest valid prefix of + Init contains N types and init_expr + holds M keywords, an initial sequence of the keywords are used + for all but the first N - M arguments of + each overload.
      Returns: *this
      @@ -378,20 +382,20 @@ class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3
    • If a1 is the result of an overload-dispatch-expression, - only the second form is allowed and fn must be a pointer - to function or pointer to member function whose arity is the same as A1's maximum arity. + only the second form is allowed and fn must be a pointer to + function or pointer to member function whose arity is the same as A1's maximum + arity.
      Effects: For each prefix P of - Fn's sequence of argument types, beginning - with the one whose length is A1's minimum - arity, adds a - name(...) method - overload to the extension class. Each overload generated - invokes + Fn's sequence of argument types, beginning with + the one whose length is A1's minimum + arity, adds a + name(...) method overload to + the extension class. Each overload generated invokes a1's call-expression with P, using a copy of a1's call policies. If the longest valid prefix of A1 @@ -477,6 +481,37 @@ class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3
      Returns: *this
      +class_& staticmethod(char const* name);
      +
      + +
      +
      Requires: name is an ntbs which conforms to Python's identifier + naming rules, and corresponds to a method whose overloads have all + been defined.
      + +
      Effects: Replaces the existing named attribute x with + the result of invoking staticmethod(x) + in Python. Specifies that the corresponding method is static and + therefore no object instance will be passed to it. This is equivalent + to the Python statement:
      + +
      +
      +setattr(self, name, staticmethod(getattr(self, name)))
      +
      +
      + +
      Note: Attempting to invoke def(name,...) after + invoking staticmethod(name) will raise a RuntimeError.
      + +
      Returns: *this
      +
      +
      + +
       template <unspecified>
       class_& def(detail::operator_<unspecified>);
      @@ -597,27 +632,21 @@ class_& def_pickle(PickleSuite const&);
       
      -
      Requires: PickleSuite must be publically derived from - pickle_suite.
      +
      Requires: PickleSuite must be publically derived from pickle_suite.
      Effects: Defines a legal combination of the special - attributes and methods: - __getinitargs__, - __getstate__, - __setstate__, - __getstate_manages_dict__, - __safe_for_unpickling__, - __reduce__ -
      + attributes and methods: __getinitargs__, + __getstate__, __setstate__, + __getstate_manages_dict__, + __safe_for_unpickling__, __reduce__
      Returns: *this
      -
      Rationale: Provides an - easy to use high-level interface - for establishing complete pickle support for the wrapped class. - The user is protected by compile-time consistency checks.
      +
      Rationale: Provides an easy to use + high-level interface for establishing complete pickle support for + the wrapped class. The user is protected by compile-time consistency + checks.

      @@ -685,8 +714,8 @@ class_<Derived, bases<Base> >("Derived"); Revised - 13 November, 2002 - + 13 November, 2002 +

      © Copyright make_method_static(name); + return *this; + } private: // helper functions inline void register_() const; diff --git a/include/boost/python/object/class.hpp b/include/boost/python/object/class.hpp index f551c29c..78cf06b5 100644 --- a/include/boost/python/object/class.hpp +++ b/include/boost/python/object/class.hpp @@ -31,6 +31,12 @@ struct BOOST_PYTHON_DECL class_base : python::api::object , char const* doc = 0 // Docstring, if any. ); + + // Implementation detail. Hiding this in the private section would + // require use of template friend declarations. + void enable_pickling(bool getstate_manages_dict); + + protected: // Retrieve the underlying object void add_property(char const* name, object const& fget); void add_property(char const* name, object const& fget, object const& fset); @@ -45,9 +51,9 @@ struct BOOST_PYTHON_DECL class_base : python::api::object // for abstract classes. void def_no_init(); - // Implementation detail. Hiding this in the private section would - // require use of template friend declarations. - void enable_pickling(bool getstate_manages_dict); + // Effects: + // setattr(self, staticmethod(getattr(self, method_name))) + void make_method_static(const char *method_name); }; }}} // namespace boost::python::objects diff --git a/src/object/class.cpp b/src/object/class.cpp index 3c261026..dc560fef 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -440,6 +440,37 @@ namespace objects } } + namespace + { + PyObject* callable_check(PyObject* callable) + { + if (PyCallable_Check(expect_non_null(callable))) + return callable; + + ::PyErr_Format( + PyExc_TypeError + , "staticmethod expects callable object; got an object of type %s, which is not callable" + , callable->ob_type->tp_name + ); + + throw_error_already_set(); + return 0; + } + } + + void class_base::make_method_static(const char * method_name) + { + PyTypeObject* self = downcast(this->ptr()); + dict d((handle<>(borrowed(self->tp_dict)))); + + object method(d[method_name]); + + this->attr(method_name) = object( + handle<>( + PyStaticMethod_New((callable_check)(method.ptr()) ) + )); + } + BOOST_PYTHON_DECL type_handle registered_class_object(class_id id) { return query_class(id); diff --git a/src/object/function.cpp b/src/object/function.cpp index 2a9f0121..bf6e8665 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -261,7 +262,22 @@ void function::add_to_namespace( if (existing) { if (existing->ob_type == &function_type) + { new_func->add_overload(existing); + } + else if (existing->ob_type == &PyStaticMethod_Type) + { + char const* name_space_name = extract(name_space.attr("__name__")); + + ::PyErr_Format( + PyExc_RuntimeError + , "Boost.Python - All overloads must be exported " + "before calling \'class_<...>(\"%s\").staticmethod(\"%s\")\'" + , name_space_name + , name_ + ); + throw_error_already_set(); + } } else if (is_binary_operator(name_)) { diff --git a/test/Jamfile b/test/Jamfile index 67c2c118..eb767745 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -63,6 +63,7 @@ run ../test/embedding.cpp ../build/boost_python $(PYTHON_LIB_PATH) $(PYTHON_EMBEDDED_LIBRARY) ; +bpl-test staticmethod ; bpl-test shared_ptr ; bpl-test polymorphism ; bpl-test auto_ptr ; diff --git a/test/staticmethod.cpp b/test/staticmethod.cpp new file mode 100644 index 00000000..a62f6275 --- /dev/null +++ b/test/staticmethod.cpp @@ -0,0 +1,46 @@ +// Copyright David Abrahams 2002. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#include +#include +#include +#include +#include +#include + +using namespace boost::python; + +struct X +{ + explicit X(int x) : x(x), magic(7654321) { ++counter; } + X(X const& rhs) : x(rhs.x), magic(7654321) { ++counter; } + virtual ~X() { assert(magic == 7654321); magic = 6666666; x = 9999; --counter; } + + void set(int x) { assert(magic == 7654321); this->x = x; } + int value() const { assert(magic == 7654321); return x; } + static int count() { return counter; } + private: + void operator=(X const&); + private: + int x; + long magic; + static int counter; +}; +int X::counter; +int getXmagic(){return 7654321;} + +BOOST_PYTHON_MODULE(staticmethod_ext) +{ + class_("X", init()) + .def("value", &X::value) + .def("set", &X::set) + .def("count", &X::count) + .staticmethod("count") + .def("magic", &getXmagic) + .staticmethod("magic") + ; +} + +#include "module_tail.cpp" diff --git a/test/staticmethod.py b/test/staticmethod.py new file mode 100644 index 00000000..7fcaae60 --- /dev/null +++ b/test/staticmethod.py @@ -0,0 +1,52 @@ +''' +>>> from staticmethod_ext import * + +>>> class X1(X): +... pass + + +>>> x = X(16) +>>> x1 = X1(17) + + + +>>> x1.count() +2 + +>>> x.count() +2 + +>>> X1.count() +2 + +>>> X.count() +2 + + +>>> x1.magic() +7654321 + +>>> x.magic() +7654321 + +>>> X1.magic() +7654321 + +>>> X.magic() +7654321 + + +''' + +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0]) From 9dfe98abb0ff14f3da2b16d149a41e17aae4c697 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 23 Jan 2003 04:32:10 +0000 Subject: [PATCH 0987/1042] bug fix + regression test [SVN r17002] --- .../python/converter/return_from_python.hpp | 14 ++--- src/converter/from_python.cpp | 3 -- test/Jamfile | 2 + test/ben_scott1.cpp | 51 +++++++++++++++++++ test/ben_scott1.py | 14 +++++ 5 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 test/ben_scott1.cpp create mode 100644 test/ben_scott1.py diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 18c2d227..72527b0b 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -40,13 +40,7 @@ namespace detail template struct return_rvalue_from_python { - typedef typename mpl::if_< - mpl::logical_and< - has_trivial_copy, mpl::bool_c<(sizeof(T) <= 2 * sizeof(double))> - > - , T - , T& - >::type result_type; + typedef T result_type; return_rvalue_from_python(); result_type operator()(PyObject*); @@ -127,6 +121,12 @@ namespace detail inline typename return_rvalue_from_python::result_type return_rvalue_from_python::operator()(PyObject* obj) { + // Take possession of the source object here. If the result is in + // fact going to be a copy of an lvalue embedded in the object, + // and we take possession inside rvalue_result_from_python, it + // will be destroyed too early. + handle<> holder(obj); + return *(T*) (rvalue_result_from_python)(obj, m_data.stage1); } diff --git a/src/converter/from_python.cpp b/src/converter/from_python.cpp index 904f66ff..e633debf 100644 --- a/src/converter/from_python.cpp +++ b/src/converter/from_python.cpp @@ -83,9 +83,6 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1( BOOST_PYTHON_DECL void* rvalue_result_from_python( PyObject* src, rvalue_from_python_stage1_data& data) { - // Take possession of the source object. - handle<> holder(src); - // Retrieve the registration // Cast in two steps for less-capable compilers void const* converters_ = data.convertible; diff --git a/test/Jamfile b/test/Jamfile index eb767745..f667159b 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -95,6 +95,8 @@ bpl-test back_reference ; bpl-test implicit ; bpl-test data_members ; +bpl-test ben_scott1 ; + bpl-test bienstman1 ; bpl-test bienstman2 ; bpl-test bienstman3 ; diff --git a/test/ben_scott1.cpp b/test/ben_scott1.cpp new file mode 100644 index 00000000..3c0d5522 --- /dev/null +++ b/test/ben_scott1.cpp @@ -0,0 +1,51 @@ +#include +#include +using namespace boost::python; +using namespace boost; + +struct Product {}; +typedef shared_ptr ProductPtr; + + +struct Creator +{ + virtual ~Creator() {} + virtual ProductPtr create() = 0; +}; + + +struct Factory +{ + void reg(Creator* c) { mC = c; } + ProductPtr create() + { + std::cout << "Name: " << (typeid(*mC)).name() << std::endl; + return mC->create(); + } + +private: + Creator* mC; +}; + +struct CreatorWrap : public Creator +{ + CreatorWrap(PyObject* self) : mSelf(self) {} + ProductPtr create() { return call_method(mSelf, "create"); } + PyObject* mSelf; +}; + +BOOST_PYTHON_MODULE(ben_scott1_ext) +{ + class_("Product"); + + class_("Creator") + .def("create", &CreatorWrap::create) + ; + + class_("Factory") + .def("reg", &Factory::reg, with_custodian_and_ward<1,2>()) + .def("create", &Factory::create) + ; +} + +#include "../test/module_tail.cpp" diff --git a/test/ben_scott1.py b/test/ben_scott1.py new file mode 100644 index 00000000..1475e3d0 --- /dev/null +++ b/test/ben_scott1.py @@ -0,0 +1,14 @@ +# This regression test checks that call_method(...) where T is a +# non-reference, non-pointer type that happens to be held inside the +# result object (and thus is found as an lvalue) works. +from ben_scott1_ext import * + +class CreatorImpl(Creator): + def create(self): + return Product() + +factory = Factory() +c = CreatorImpl() +factory.reg(c) + +a = factory.create() From 6f687ee402ff640b2360318b53f46f846789286a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 23 Jan 2003 17:38:57 +0000 Subject: [PATCH 0988/1042] Added a FAQ [SVN r17010] --- doc/v2/faq.html | 247 +++++++++++++++++++++++++++++------------------- 1 file changed, 150 insertions(+), 97 deletions(-) diff --git a/doc/v2/faq.html b/doc/v2/faq.html index 06087038..1b600072 100644 --- a/doc/v2/faq.html +++ b/doc/v2/faq.html @@ -29,10 +29,10 @@


      -
      Is return_internal reference +
      Is return_internal_reference efficient?
      -
      How can I wrap containers which take C++ +
      How can I wrap functions which take C++ containers as arguments?
      fatal error C1204:Compiler limit:internal @@ -40,13 +40,18 @@
      How do I debug my Python extensions?
      -
      Why doesn't my *= operator work?
      +
      Why doesn't my *= operator + work?
      Does Boost.Python work with Mac OS X?
      + +
      How can I find the existing PyObject that holds a + C++ object?
      +
      -

      Is return_internal reference efficient?

      +

      Is return_internal_reference efficient?

      Q: I have an object composed of 12 doubles. A const& to @@ -70,6 +75,7 @@ cycles.

      +

      How can I wrap functions which take C++ containers as arguments?

      @@ -161,7 +167,7 @@ cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx - +

      fatal error C1204:Compiler limit:internal structure overflow

      @@ -203,9 +209,9 @@ void more_of_my_module() can always pass a reference to the class_ object to a function in another source file, and call some of its member functions (e.g. .def(...)) in the auxilliary source - file: + file: -

      more_of_my_class.cpp: +

      more_of_my_class.cpp:

       void more_of_my_class(class<my_class>& x)
       {
      @@ -221,28 +227,25 @@ void more_of_my_class(class<my_class>& x)
             
           
       
      +

      How do I debug my Python extensions?

      -

      Greg Burley gives the following answer for Unix GCC users: +

      Greg Burley gives the following answer for Unix GCC users:

      -Once you have created a boost python extension for your c++ library or -class, you may need to debug the code. Afterall this is one of the -reasons for wrapping the library in python. An expected side-effect or -benefit of using BPL is that debugging should be isolated to the c++ -library that is under test, given that python code is minimal and -boost::python either works or it doesn't. (ie. While errors can occur -when the wrapping method is invalid, most errors are caught by the -compiler ;-). - -

      - -The basic steps required to initiate a gdb session to debug a c++ -library via python are shown here. Note, however that you should start -the gdb session in the directory that contains your BPL my_ext.so -module. - + Once you have created a boost python extension for your c++ library or + class, you may need to debug the code. Afterall this is one of the + reasons for wrapping the library in python. An expected side-effect or + benefit of using BPL is that debugging should be isolated to the c++ + library that is under test, given that python code is minimal and + boost::python either works or it doesn't. (ie. While errors can occur + when the wrapping method is invalid, most errors are caught by the + compiler ;-). +

      The basic steps required to initiate a gdb session to debug a c++ + library via python are shown here. Note, however that you should start + the gdb session in the directory that contains your BPL my_ext.so + module.

       (gdb) target exec python
       (gdb) run
      @@ -258,63 +261,54 @@ Current language:  auto; currently c++
       
      -

      +

      Greg's approach works even better using Emacs' "gdb" + command, since it will show you each line of source as you step through + it.

      -Greg's approach works even better using Emacs' -"gdb" command, since it will show you each line -of source as you step through it. +

      On Windows, my favorite debugging solution is the debugger that + comes with Microsoft Visual C++ 7. This debugger seems to work with code + generated by all versions of Microsoft and Metrowerks toolsets; it's rock + solid and "just works" without requiring any special tricks from the + user.

      -

      - -On Windows, my favorite debugging solution is the debugger that comes -with Microsoft Visual C++ 7. This debugger seems to work with code -generated by all versions of Microsoft and Metrowerks toolsets; it's -rock solid and "just works" without requiring any special -tricks from the user. - -

      - -Unfortunately for Cygwin and MinGW users, as of this writing gdb on -Windows has a very hard time dealing with shared libraries, which -could make Greg's approach next to useless for you. My best advice for -you is to use Metrowerks C++ for compiler conformance and Microsoft -Visual Studio as a debugger when you need one. - -

      Debugging extensions through Boost.Build

      - -If you are launching your extension module tests with Boost.Build using the -boost-python-runtest rule, you can ask it to launch your -debugger for you by adding "-sPYTHON_LAUNCH=debugger" -to your bjam command-line: +

      Unfortunately for Cygwin and MinGW users, as of this writing gdb on + Windows has a very hard time dealing with shared libraries, which could + make Greg's approach next to useless for you. My best advice for you is + to use Metrowerks C++ for compiler conformance and Microsoft Visual + Studio as a debugger when you need one.

      +

      Debugging extensions through Boost.Build

      + If you are launching your extension module tests with Boost.Build using the + boost-python-runtest rule, you can ask it to launch your + debugger for you by adding "-sPYTHON_LAUNCH=debugger" to your bjam + command-line:
      -bjam -sTOOLS=metrowerks "-sPYTHON_LAUNCH=devenv /debugexe" test
      +bjam -sTOOLS=metrowerks "-sPYTHON_LAUNCH=devenv /debugexe" test
       bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
       
      + It can also be extremely useful to add the -d+2 option when + you run your test, because Boost.Build will then show you the exact + commands it uses to invoke it. This will invariably involve setting up + PYTHONPATH and other important environment variables such as + LD_LIBRARY_PATH which may be needed by your debugger in order to get + things to work right. -It can also be extremely useful to add the -d+2 option -when you run your test, because Boost.Build will then show you the -exact commands it uses to invoke it. This will invariably involve -setting up PYTHONPATH and other important environment variables such -as LD_LIBRARY_PATH which may be needed by your debugger in order to -get things to work right. - +

      Why doesn't my *= operator work?

      -
      -Q: I have exported my class to python, with many overloaded operators. it -works fine for me except the *= operator. It always tells -me "can't multiply sequence with non int type". If I use -p1.__imul__(p2) instead of p1 *= -p2, it successfully executes my code. What's wrong with -me? - -

      A: There's nothing wrong with you. This is a bug in Python -2.2. You can see the same effect in Pure Python (you can learn a lot -about what's happening in Boost.Python by playing with new-style -classes in Pure Python). +

      + Q: I have exported my class to python, with many overloaded + operators. it works fine for me except the *= + operator. It always tells me "can't multiply sequence with non int + type". If I use p1.__imul__(p2) instead of + p1 *= p2, it successfully executes my code. What's + wrong with me? +

      A: There's nothing wrong with you. This is a bug in Python + 2.2. You can see the same effect in Pure Python (you can learn a lot + about what's happening in Boost.Python by playing with new-style + classes in Pure Python).

       >>> class X(object):
       ...     def __imul__(self, x):
      @@ -323,44 +317,103 @@ classes in Pure Python).
       >>> x = X()
       >>> x *= 1
       
      + To cure this problem, all you need to do is upgrade your Python to + version 2.2.1 or later. +
      -To cure this problem, all you need to do is upgrade your Python to -version 2.2.1 or later. - -
      - +

      Does Boost.Python work with Mac OS X?

      -
      -

      The short answer: as of January 2003, unfortunately not. -

      -The longer answer: using Mac OS 10.2.3 with the December Developer's Kit, -Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles fine, -including the examples. However, there are problems at runtime -(see http://mail.python.org/pipermail/c++-sig/2003-January/003267.html). -Solutions are currently unknown. -

      -It is known that under certain circumstances objects are double-destructed. -See http://mail.python.org/pipermail/c++-sig/2003-January/003278.html" -for details. It is not clear however if this problem is related to -the Boost.Python runtime issues. -

      +
      +

      The short answer: as of January 2003, unfortunately not.

      +

      The longer answer: using Mac OS 10.2.3 with the December Developer's + Kit, Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles + fine, including the examples. However, there are problems at runtime + (see http://mail.python.org/pipermail/c++-sig/2003-January/003267.html). + Solutions are currently unknown.

      + +

      It is known that under certain circumstances objects are + double-destructed. See http://mail.python.org/pipermail/c++-sig/2003-January/003278.html" + for details. It is not clear however if this problem is related to the + Boost.Python runtime issues.

      +
      + +
      +

      How can I find the existing PyObject that holds a C++ + object?

      + +
      + "I am wrapping a function that always returns a pointer to an + already-held C++ object." +
      + One way to do that is to hijack the mechanisms used for wrapping a class + with virtual functions. If you make a wrapper class with an initial + PyObject* constructor argument and store that PyObject* as "self", you + can get back to it by casting down to that wrapper type in a thin wrapper + function. For example: +
      +class X { X(int); virtual ~X(); ... };
      +X* f();  // known to return Xs that are managed by Python objects
      +
      +
      +// wrapping code
      +
      +struct X_wrap : X
      +{
      +    X_wrap(PyObject* self, int v) : self(self), X(v) {}
      +    PyObject* self;
      +};
      +
      +handle<> f_wrap()
      +{
      +    X_wrap* xw = dynamic_cast<X_wrap*>(f());
      +    assert(xw != 0);
      +    return handle<>(borrowed(xw->self));
      +}
      +
      +...
      +
      +def("f", f_wrap());
      +class_<X,X_wrap>("X", init<int>())
      +   ...
      +   ;
      +
      + Of course, if X has no virtual functions you'll have to use + static_cast instead of dynamic_cast with no + runtime check that it's valid. This approach also only works if the + X object was constructed from Python, because + Xs constructed from C++ are of course never + X_wrap objects. + +

      Another approach to this requires some work on Boost.Python, but it's + work we've been meaning to get to anyway. Currently, when a + shared_ptr<X> is converted from Python, the shared_ptr + actually manages a reference to the containing Python object. I plan to + make it so that when a shared_ptr<X> is converted back to Python, + the library checks to see if it's one of those "Python object managers" + and if so just returns the original Python object. To exploit this you'd + have to be able to change the C++ code you're wrapping so that it deals + with shared_ptr instead of raw pointers.

      + +

      There are other approaches too. The functions that receive the Python + object that you eventually want to return could be wrapped with a thin + wrapper that records the correspondence between the object address and + its containing Python object, and you could have your f_wrap function + look in that mapping to get the Python object out.


      Revised - 14 January, 2003 + 23 January, 2003

      © Copyright Dave Abrahams 2002-2003. All Rights - Reserved.

      + "../../../../people/dave_abrahams.htm">Dave Abrahams 2002-2003. All + Rights Reserved.

      From 8f12fdea4a595f942abc76fd4f0ba9d5283e2c6f Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 31 Jan 2003 18:37:11 +0000 Subject: [PATCH 0989/1042] Remove workaround patches [SVN r17128] --- include/boost/python/detail/indirect_traits.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index 92748982..d53e396c 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -18,7 +18,7 @@ # include # include # include -# include +# include # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # include @@ -86,7 +86,7 @@ template struct is_reference_to_member_function_pointer : is_reference_to_member_function_pointer_impl { - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) }; template @@ -192,7 +192,7 @@ struct is_reference_to_class >::value) ); typedef mpl::bool_c type; - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) }; template @@ -285,7 +285,7 @@ template struct is_pointer_to_function : mpl::if_, is_pointer_to_function_aux, mpl::bool_c >::type { - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_pointer_to_function,(T)) + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_function,(T)) }; struct false_helper1 @@ -422,7 +422,7 @@ struct is_reference_to_function_pointer , mpl::bool_c >::type { - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) }; @@ -453,7 +453,7 @@ struct is_reference_to_member_function_pointer , mpl::bool_c >::type { - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) }; template @@ -470,7 +470,7 @@ struct is_reference_to_class & (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type))) ); typedef mpl::bool_c type; - BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) }; template From 5bcf90766f32496ae029ea7cb05f003e6d062dc3 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 5 Feb 2003 19:58:43 +0000 Subject: [PATCH 0990/1042] draft thinking hybrid section added [SVN r17242] --- doc/PyConDC_2003/bpl.txt | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt index 25d50621..48ef5994 100644 --- a/doc/PyConDC_2003/bpl.txt +++ b/doc/PyConDC_2003/bpl.txt @@ -740,6 +740,60 @@ manipulation of these high-level types from C++:: d["lucky_number"] = 13; list l = d.keys(); +================= + Thinking hybrid +================= + +For many applications runtime performance considerations are very +important. This is particularly true for most scientific applications. +Often the performance considerations dictate the use of a compiled +language for the core algorithms. Traditionally the decision to use a +particular programming language is an exclusive one. Because of the +practical and mental difficulties of combining different languages many +systems are written in just one language. This is quite unfortunate +because the price payed for runtime performance is typically a +significant overhead due to static typing. For example, our experience +shows that developing maintainable C++ code is typically much more +time-consuming and requires much more hard-earned working experience +than developing useful Python code. A related observation is that many +compiled packages are augmented by some type of rudimentary scripting +layer. These ad hoc solutions clearly show that many times a compiled +language alone does not get the job done. On the other hand it is also +clear that a pure Python implementation is too slow for numerically +intensive production code. + +Boost.Python enables us to *think hybrid* when developing new +applications. For example, Python can be used for rapidly prototyping a +new application. Python's ease of use and the large pool of standard +libraries give us a head start on the way to a first working system. If +necessary, the working procedure can be used to discover the +rate-limiting algorithms. To maximize performance these can be +reimplemented in C++, together with the Boost.Python bindings needed to +tie them back into the existing higher-level procedure. + +Of course, this *top-down* approach is less attractive if it is clear +from the start that many algorithms will eventually have to be +implemented in a compiled language. Fortunately Boost.Python also +enables us to pursue a *bottom-up* approach. We have used this approach +very successfully in the development of a toolbox for scientific +applications (scitbx) that we will describe elsewhere. The toolbox +started out mainly as a library of C++ classes with Boost.Python +bindings, and for a while the growth was mainly concentrated on the C++ +parts. However, as the toolbox is becoming more complete, more and more +newly added functionality can be implemented in Python. We expect this +trend to continue, as illustrated qualitatively in this figure: + +.. image:: python_cpp_mix.png + +This figure shows the ratio of newly added C++ and Python code over +time as new algorithms are implemented. We expect this ratio to level +out near 70% Python. The increasing ability to solve new problems +mostly with the easy-to-use Python language rather than a necessarily +more arcane statically typed language is the return on the investment +of learning how to use Boost.Python. The ability to solve some problems +entirely using only Python will enable a larger group of people to +participate in the rapid development of new applications. + ============= Conclusions ============= From ac55c5ccf7b602e3f9b780fd05503a416fb098ad Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 6 Feb 2003 13:50:31 +0000 Subject: [PATCH 0991/1042] Add FAQ reference [SVN r17249] --- doc/v2/with_custodian_and_ward.html | 522 ++++++++++++++++------------ 1 file changed, 299 insertions(+), 223 deletions(-) diff --git a/doc/v2/with_custodian_and_ward.html b/doc/v2/with_custodian_and_ward.html index 89ecb42c..e6fc15df 100644 --- a/doc/v2/with_custodian_and_ward.html +++ b/doc/v2/with_custodian_and_ward.html @@ -1,149 +1,199 @@ - - + + + + - - Boost.Python - <boost/python/with_custodian_and_ward.hpp> - -
    • + + Boost.Python - <boost/python/with_custodian_and_ward.hpp> + + + +
      +
      -

      -

      - +

      + C++ Boost + +

      +
      -

      Boost.Python

      - -

      Header <boost/python/with_custodian_and_ward.hpp>

      +

      + Boost.Python +

      +

      + Header <boost/python/with_custodian_and_ward.hpp> +

      +

      - -

      Contents

      - +

      + Contents +

      -
      Introduction - - -
      Classes +
      + Introduction +
      +
      + Classes +
      -
      - -
      Class Template with_custodian_and_ward +
      + Class Template + with_custodian_and_ward +
      - -
      Class Template - with_custodian_and_ward synopsis - -
      Class - with_custodian_and_ward static functions +
      + Class + Template with_custodian_and_ward synopsis +
      +
      + Class + with_custodian_and_ward static functions +
      - -
      Class Template with_custodian_and_ward_postcall +
      +
      + Class Template + with_custodian_and_ward_postcall +
      - -
      Class Template - with_custodian_and_ward_postcall synopsis - -
      Class - with_custodian_and_ward_postcall static functions +
      + Class + Template with_custodian_and_ward_postcall + synopsis +
      +
      + Class + with_custodian_and_ward_postcall static + functions +
      +
      - - -
      Example + +
      + Example +

      - -

      Introduction

      - - This header provides faciliites for establishing a lifetime - dependency between two of a function's Python argument or result - objects. The ward object will not be destroyed until after - the custodian as long as the custodian object supports weak +

      + Introduction +

      This header provides faciliites for establishing a lifetime + dependency between two of a function's Python argument or result objects. + The ward object will not be destroyed until after the custodian as + long as the custodian object supports weak references (Boost.Python extension classes all support weak references). If the custodian object does not support weak - references and is not None, an appropriate exception - will be thrown. The two class templates - with_custodian_and_ward and - with_custodian_and_ward_postcall differ in the point - at which they take effect. - -

      In order to reduce the chance of inadvertently - creating dangling pointers, the default is to do lifetime binding - before the underlying C++ object is invoked. However, - before invocation the result object is not available, so - with_custodian_and_ward_postcall is provided to bind - lifetimes after invocation. Also, if a C++ exception is thrown - after with_custodian_and_ward<>::precall but - before the underlying C++ object actually stores a pointer, the - lifetime of the custodian and ward objects will be artificially - bound together, so one might choose - with_custodian_and_ward_postcall instead, depending - on the semantics of the function being wrapped. - -

      Classes

      - -

      Class template with_custodian_and_ward

      - - + references and is not None, an appropriate exception will be + thrown. The two class templates with_custodian_and_ward and + with_custodian_and_ward_postcall differ in the point at + which they take effect. +

      + In order to reduce the chance of inadvertently creating dangling + pointers, the default is to do lifetime binding before the + underlying C++ object is invoked. However, before invocation the result + object is not available, so + with_custodian_and_ward_postcall is provided to bind + lifetimes after invocation. Also, if a C++ exception is thrown after + with_custodian_and_ward<>::precall but before the + underlying C++ object actually stores a pointer, the lifetime of the + custodian and ward objects will be artificially bound together, so one + might choose with_custodian_and_ward_postcall instead, + depending on the semantics of the function being wrapped. +

      +

      + Please note that this is not the appropriate tool to use when + wrapping functions which transfer ownership of a raw pointer + across the function-call boundary. Please see the FAQ if you want to do that. +

      +

      + Classes +

      +

      + Class template + with_custodian_and_ward +

      - + + + + - + + + - + + + - + + + +
      with_custodian_and_ward template parameters
      Parameter - - Requirements - - Description - - Default - + + Parameter + + Requirements + + Description + + Default +
      custodian - - A positive compile-time constant of type - std::size_t. - - The 1-based index of the parameter which is the dependency in the - lifetime relationship to be established. If used to - wrap a member function, parameter 1 is the target object - (*this). Note that if the target Python object - type doesn't support weak references, a Python - TypeError exception will be raised when the - C++ object being wrapped is called. - - + + custodian + + A positive compile-time constant of type std::size_t. + + The 1-based index of the parameter which is the dependency in the + lifetime relationship to be established. If used to wrap a member + function, parameter 1 is the target object (*this). + Note that if the target Python object type doesn't support weak + references, a Python TypeError exception will be + raised when the C++ object being wrapped is called. +
      ward - - A positive compile-time constant of type - std::size_t. - - The 1-based index of the parameter which is the dependent in the - lifetime relationship to be established. If used to - wrap a member function, parameter 1 is the target object - (*this). - - + + ward + + A positive compile-time constant of type std::size_t. + + The 1-based index of the parameter which is the dependent in the + lifetime relationship to be established. If used to wrap a member + function, parameter 1 is the target object (*this). +
      Base - - A model of CallPolicies - - Used for policy composition. - - default_call_policies - + + Base + + A model of CallPolicies + + Used for policy + composition. + + default_call_policies +
      - -

      Class template with_custodian_and_ward synopsis

      -
      +    

      + Class template + with_custodian_and_ward synopsis +

      +
       namespace boost { namespace python
       {
          template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
      @@ -153,85 +203,107 @@ namespace boost { namespace python
          };
       }}
       
      - -

      Class - with_custodian_and_ward static functions

      - -
      +    

      + Class + with_custodian_and_ward static functions +

      +
       bool precall(PyObject* args);
       
      -
      -
      Requires: PyTuple_Check(args) != 0 -
      Effects: Makes the lifetime of the argument indicated - by ward dependent on the lifetime of the argument - indicated by custodian. - -
      Returns: false and PyErr_Occurred() != 0 - upon failure, true otherwise. -
      - - - - -

      Class template with_custodian_and_ward_postcall

      - - - +
      + Requires: PyTuple_Check(args) + != 0 +
      +
      + Effects: Makes the lifetime of the argument indicated by + ward dependent on the lifetime of the argument indicated + by custodian. +
      +
      + Returns: false and PyErr_Occurred() != 0 + upon failure, true otherwise. +
      + +

      + Class template + with_custodian_and_ward_postcall +

      +
      - + + + + - + + + - + + + - + + + +
      - with_custodian_and_ward_postcall template parameters + with_custodian_and_ward_postcall template + parameters
      Parameter - - Requirements - - Description - - Default - + + Parameter + + Requirements + + Description + + Default +
      custodian - - A compile-time constant of type - std::size_t. - - The index of the parameter which is the dependency in the - lifetime relationship to be established. Zero indicates the - result object; 1 indicates the first argument. If used to wrap - a member function, parameter 1 is the target object - (*this). Note that if the target Python object - type doesn't support weak references, a Python - TypeError exception will be raised when the - C++ object being wrapped is called. - - + + custodian + + A compile-time constant of type std::size_t. + + The index of the parameter which is the dependency in the lifetime + relationship to be established. Zero indicates the result object; 1 + indicates the first argument. If used to wrap a member function, + parameter 1 is the target object (*this). Note that if + the target Python object type doesn't support weak references, a + Python TypeError exception will be raised when the C++ + object being wrapped is called. +
      ward - - A compile-time constant of type std::size_t. - - The index of the parameter which is the dependent in the - lifetime relationship to be established. Zero indicates the - result object; 1 indicates the first argument. If used to wrap - a member function, parameter 1 is the target object - (*this). - + + ward + + A compile-time constant of type std::size_t. + + The index of the parameter which is the dependent in the lifetime + relationship to be established. Zero indicates the result object; 1 + indicates the first argument. If used to wrap a member function, + parameter 1 is the target object (*this). +
      Base - - A model of CallPolicies - - Used for policy - composition. - - default_call_policies - + + Base + + A model of CallPolicies + + Used for policy + composition. + + default_call_policies +
      - -

      Class template with_custodian_and_ward_postcall synopsis

      -
      +    

      + Class + template with_custodian_and_ward_postcall synopsis +

      +
       namespace boost { namespace python
       {
          template <std::size_t custodian, std::size_t ward, class Base = default_call_policies>
      @@ -241,51 +313,55 @@ namespace boost { namespace python
          };
       }}
       
      - -

      Class - with_custodian_and_ward_postcall static functions

      - -
      +    

      + Class + with_custodian_and_ward_postcall static functions +

      +
       PyObject* postcall(PyObject* args, PyObject* result);
       
      -
      -
      Requires: PyTuple_Check(args) - != 0, result != 0. - -
      Effects: Makes the lifetime of the object indicated - by ward dependent on the lifetime of the object - indicated by custodian. - -
      Returns: 0 and PyErr_Occurred() != 0 - upon failure, true otherwise. +
      + Requires: PyTuple_Check(args) + != 0, result != 0. +
      +
      + Effects: Makes the lifetime of the object indicated by + ward dependent on the lifetime of the object indicated + by custodian. +
      +
      + Returns: 0 and PyErr_Occurred() != 0 + upon failure, true otherwise. +
      - - - -

      Example

      - -The following example shows how -with_custodian_and_ward_postcall is used by the library -to implement return_internal_reference - -
      +    

      + Example +

      The following example shows how + with_custodian_and_ward_postcall is used by the library to + implement return_internal_reference + +
       template <std::size_t owner_arg = 1, class Base = default_call_policies>
       struct return_internal_reference
           : with_custodian_and_ward_postcall<0, owner_arg, Base>
       {
      -   typedef reference_existing_object result_converter;
      +   typedef reference_existing_object result_converter;
       };
       
      - -

      Revised - - 13 November, 2002 - - -

      © Copyright Dave - Abrahams 2002. All Rights Reserved. - +

      + Revised + + 13 November, 2002 + +

      +

      + © Copyright Dave + Abrahams 2002. All Rights Reserved. +

      + + From 55cb918c51e343c0350fd1b3cd54b8c36ebf2309 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 6 Feb 2003 13:50:53 +0000 Subject: [PATCH 0992/1042] Add ownership question [SVN r17250] --- doc/v2/faq.html | 552 +++++++++++++++++++++++++++--------------------- 1 file changed, 306 insertions(+), 246 deletions(-) diff --git a/doc/v2/faq.html b/doc/v2/faq.html index 1b600072..244d16f4 100644 --- a/doc/v2/faq.html +++ b/doc/v2/faq.html @@ -1,58 +1,70 @@ - - + "HTML Tidy for Cygwin (vers 1st February 2003), see www.w3.org"> + - - Boost.Python - FAQ + + Boost.Python - FAQ + - - +
      -
      -

      C++ Boost

      +

      + C++ Boost +

      -

      Boost.Python

      - -

      Frequently Asked Questions (FAQs)

      +

      + Boost.Python +

      +

      + Frequently Asked Questions (FAQs) +


      -
      -
      Is return_internal_reference - efficient?
      - -
      How can I wrap functions which take C++ - containers as arguments?
      - -
      fatal error C1204:Compiler limit:internal - structure overflow
      - -
      How do I debug my Python extensions?
      - -
      Why doesn't my *= operator - work?
      - -
      Does Boost.Python work with Mac OS X?
      - -
      How can I find the existing PyObject that holds a - C++ object?
      +
      + Is return_internal_reference efficient? +
      +
      + How can I wrap functions which take C++ + containers as arguments? +
      +
      + fatal error C1204:Compiler limit:internal structure + overflow +
      +
      + How do I debug my Python extensions? +
      +
      + Why doesn't my *= operator work? +
      +
      + Does Boost.Python work with Mac OS X? +
      +
      + How can I find the existing PyObject that holds a C++ + object? +
      +
      + How can I wrap a function which needs to take + ownership of a raw pointer? +
      - -
      - -

      Is return_internal_reference efficient?

      - +
      +

      + Is return_internal_reference efficient? +

      Q: I have an object composed of 12 doubles. A const& to this object is returned by a member function of another class. From the @@ -62,129 +74,126 @@ return_internal_reference. Are there considerations that would lead me to prefer one over the other, such as size of generated code or memory overhead? - -

      A: copy_const_reference will make an instance with storage - for one of your objects, size = base_size + 12 * sizeof(double). - return_internal_reference will make an instance with storage for a - pointer to one of your objects, size = base_size + sizeof(void*). - However, it will also create a weak reference object which goes in the - source object's weakreflist and a special callback object to manage the - lifetime of the internally-referenced object. My guess? - copy_const_reference is your friend here, resulting in less overall - memory use and less fragmentation, also probably fewer total - cycles.

      +

      + A: copy_const_reference will make an instance with storage for + one of your objects, size = base_size + 12 * sizeof(double). + return_internal_reference will make an instance with storage for a + pointer to one of your objects, size = base_size + sizeof(void*). + However, it will also create a weak reference object which goes in + the source object's weakreflist and a special callback object to + manage the lifetime of the internally-referenced object. My guess? + copy_const_reference is your friend here, resulting in less overall + memory use and less fragmentation, also probably fewer total cycles. +

      - -
      -

      How can I wrap functions which take C++ - containers as arguments?

      - -

      Ralf W. Grosse-Kunstleve provides these notes:

      - +
      +

      + How can I wrap functions which take C++ + containers as arguments? +

      +

      + Ralf W. Grosse-Kunstleve provides these notes: +

      1. Using the regular class_<> wrapper: -
        +        
         class_<std::vector<double> >("std_vector_double")
           .def(...)
           ...
           ;
        -
        - This can be moved to a template so that several types (double, int, - long, etc.) can be wrapped with the same code. This technique is used - in the file - +
        This can be moved to a template so that several types (double, int, +long, etc.) can be wrapped with the same code. This technique is used in the +file
        scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h -
        - in the "scitbx" package. The file could easily be modified for - wrapping std::vector<> instantiations. - -

        This type of C++/Python binding is most suitable for containers - that may contain a large number of elements (>10000).

        + in the "scitbx" package. The file could easily be + modified for wrapping std::vector<> instantiations. +

        + This type of C++/Python binding is most suitable for containers + that may contain a large number of elements (>10000). +

      2. -
      3. Using custom rvalue converters. Boost.Python "rvalue converters" match function signatures such as: -
        +        
         void foo(std::vector<double> const& array); // pass by const-reference
         void foo(std::vector<double> array); // pass by value
        -
        - Some custom rvalue converters are implemented in the file - +
        Some custom rvalue converters are implemented in the file
        scitbx/include/scitbx/boost_python/container_conversions.h -
        - This code can be used to convert from C++ container types such as - std::vector<> or std::list<> to Python tuples and vice - versa. A few simple examples can be found in the file - + This code can be used to convert from C++ container + types such as std::vector<> or std::list<> to Python + tuples and vice versa. A few simple examples can be found in the file +
        scitbx/array_family/boost_python/regression_test_module.cpp -
        - Automatic C++ container <-> Python tuple conversions are most - suitable for containers of moderate size. These converters generate - significantly less object code compared to alternative 1 above. + Automatic C++ container <-> Python tuple + conversions are most suitable for containers of moderate size. These + converters generate significantly less object code compared to + alternative 1 above.
      4. -
      - A disadvantage of using alternative 2 is that operators such as + A disadvantage of using alternative 2 is that operators such as arithmetic +,-,*,/,% are not available. It would be useful to have custom rvalue converters that convert to a "math_array" type instead of tuples. This is currently not implemented but is possible within the framework of Boost.Python V2 as it will be released in the next couple of weeks. [ed.: this was posted on 2002/03/10] - -

      It would also be useful to also have "custom lvalue converters" such - as std::vector<> <-> Python list. These converters would - support the modification of the Python list from C++. For example:

      - -

      C++:

      -
      +    

      + It would also be useful to also have "custom lvalue converters" such as + std::vector<> <-> Python list. These converters would + support the modification of the Python list from C++. For example: +

      +

      + C++: +

      +
       void foo(std::vector<double>& array)
       {
         for(std::size_t i=0;i<array.size();i++) {
           array[i] *= 2;
         }
       }
      -
      - Python: -
      +
      Python: +
       >>> l = [1, 2, 3]
       >>> foo(l)
       >>> print l
       [2, 4, 6]
      -
      - Custom lvalue converters require changes to the Boost.Python core library - and are currently not available. - -

      P.S.:

      - -

      The "scitbx" files referenced above are available via anonymous - CVS:

      -
      +
      Custom lvalue converters require changes to the Boost.Python core +library and are currently not available. +

      + P.S.: +

      +

      + The "scitbx" files referenced above are available via anonymous CVS: +

      +
       cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login
       cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
       
      - -
      -

      fatal error C1204:Compiler limit:internal - structure overflow

      - +
      +

      + fatal error C1204:Compiler limit:internal structure + overflow +

      Q: I get this error message when compiling a large source file. What can I do? - -

      A: You have two choices:

      - +

      + A: You have two choices: +

        -
      1. Upgrade your compiler (preferred)
      2. - +
      3. + Upgrade your compiler (preferred) +
      4. Break your source file up into multiple translation units. - -

        my_module.cpp:

        -
        +          

        + my_module.cpp: +

        +
         ...
         void more_of_my_module();
         BOOST_PYTHON_MODULE(my_module)
        @@ -194,25 +203,23 @@ BOOST_PYTHON_MODULE(my_module)
            ...
            more_of_my_module();
         }
        -
        - more_of_my_module.cpp: -
        +
        more_of_my_module.cpp: +
         void more_of_my_module()
         {
            def("baz", baz);
            ...
         }
        -
        - If you find that a class_<...> declaration - can't fit in a single source file without triggering the error, you - can always pass a reference to the class_ object to a - function in another source file, and call some of its member - functions (e.g. .def(...)) in the auxilliary source - file: - -

        more_of_my_class.cpp:

        -
        +
        If you find that a class_<...> declaration can't fit +in a single source file without triggering the error, you can always pass a +reference to the class_ object to a function in another source +file, and call some of its member functions (e.g. .def(...)) in +the auxilliary source file: +

        + more_of_my_class.cpp: +

        +
         void more_of_my_class(class<my_class>& x)
         {
            x
        @@ -226,12 +233,13 @@ void more_of_my_class(class<my_class>& x)
                 
      - -
      -

      How do I debug my Python extensions?

      - -

      Greg Burley gives the following answer for Unix GCC users:

      - +
      +

      + How do I debug my Python extensions? +

      +

      + Greg Burley gives the following answer for Unix GCC users: +

      Once you have created a boost python extension for your c++ library or class, you may need to debug the code. Afterall this is one of the @@ -241,12 +249,13 @@ void more_of_my_class(class<my_class>& x) boost::python either works or it doesn't. (ie. While errors can occur when the wrapping method is invalid, most errors are caught by the compiler ;-). - -

      The basic steps required to initiate a gdb session to debug a c++ - library via python are shown here. Note, however that you should start - the gdb session in the directory that contains your BPL my_ext.so - module.

      -
      +      

      + The basic steps required to initiate a gdb session to debug a c++ + library via python are shown here. Note, however that you should + start the gdb session in the directory that contains your BPL + my_ext.so module. +

      +
       (gdb) target exec python
       (gdb) run
        >>> from my_ext import *
      @@ -260,43 +269,44 @@ Current language:  auto; currently c++
       (gdb) do debugging stuff
       
      - -

      Greg's approach works even better using Emacs' "gdb" - command, since it will show you each line of source as you step through - it.

      - -

      On Windows, my favorite debugging solution is the debugger that - comes with Microsoft Visual C++ 7. This debugger seems to work with code - generated by all versions of Microsoft and Metrowerks toolsets; it's rock - solid and "just works" without requiring any special tricks from the - user.

      - -

      Unfortunately for Cygwin and MinGW users, as of this writing gdb on - Windows has a very hard time dealing with shared libraries, which could - make Greg's approach next to useless for you. My best advice for you is - to use Metrowerks C++ for compiler conformance and Microsoft Visual - Studio as a debugger when you need one.

      - -

      Debugging extensions through Boost.Build

      - If you are launching your extension module tests with + Greg's approach works even better using Emacs' "gdb" + command, since it will show you each line of source as you step through + it. +

      +

      + On Windows, my favorite debugging solution is the debugger that + comes with Microsoft Visual C++ 7. This debugger seems to work with + code generated by all versions of Microsoft and Metrowerks toolsets; + it's rock solid and "just works" without requiring any special tricks + from the user. +

      +

      + Unfortunately for Cygwin and MinGW users, as of this writing gdb on + Windows has a very hard time dealing with shared libraries, which could + make Greg's approach next to useless for you. My best advice for you is + to use Metrowerks C++ for compiler conformance and Microsoft Visual + Studio as a debugger when you need one. +

      +

      + Debugging extensions through Boost.Build +

      If you are launching your extension module tests with
      Boost.Build using the boost-python-runtest rule, you can ask it to launch your debugger for you by adding "-sPYTHON_LAUNCH=debugger" to your bjam command-line: -
      +    
       bjam -sTOOLS=metrowerks "-sPYTHON_LAUNCH=devenv /debugexe" test
       bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
      -
      - It can also be extremely useful to add the -d+2 option when - you run your test, because Boost.Build will then show you the exact - commands it uses to invoke it. This will invariably involve setting up - PYTHONPATH and other important environment variables such as - LD_LIBRARY_PATH which may be needed by your debugger in order to get - things to work right. - -
      -

      Why doesn't my *= operator work?

      - +
      It can also be extremely useful to add the -d+2 option +when you run your test, because Boost.Build will then show you the exact +commands it uses to invoke it. This will invariably involve setting up +PYTHONPATH and other important environment variables such as LD_LIBRARY_PATH +which may be needed by your debugger in order to get things to work right. +
      +

      + Why doesn't my *= operator work? +

      Q: I have exported my class to python, with many overloaded operators. it works fine for me except the *= @@ -304,57 +314,60 @@ bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test type". If I use p1.__imul__(p2) instead of p1 *= p2, it successfully executes my code. What's wrong with me? - -

      A: There's nothing wrong with you. This is a bug in Python - 2.2. You can see the same effect in Pure Python (you can learn a lot - about what's happening in Boost.Python by playing with new-style - classes in Pure Python).

      -
      +      

      + A: There's nothing wrong with you. This is a bug in Python + 2.2. You can see the same effect in Pure Python (you can learn a lot + about what's happening in Boost.Python by playing with new-style + classes in Pure Python). +

      +
       >>> class X(object):
       ...     def __imul__(self, x):
       ...         print 'imul'
       ...
       >>> x = X()
       >>> x *= 1
      -
      - To cure this problem, all you need to do is upgrade your Python to - version 2.2.1 or later. +
      To cure this problem, all you need to do is upgrade your Python to +version 2.2.1 or later.
      - -
      -

      Does Boost.Python work with Mac OS X?

      - +
      +

      + Does Boost.Python work with Mac OS X? +

      -

      The short answer: as of January 2003, unfortunately not.

      - -

      The longer answer: using Mac OS 10.2.3 with the December Developer's - Kit, Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles - fine, including the examples. However, there are problems at runtime - (see http://mail.python.org/pipermail/c++-sig/2003-January/003267.html). - Solutions are currently unknown.

      - -

      It is known that under certain circumstances objects are - double-destructed. See http://mail.python.org/pipermail/c++-sig/2003-January/003278.html" - for details. It is not clear however if this problem is related to the - Boost.Python runtime issues.

      +

      + The short answer: as of January 2003, unfortunately not. +

      +

      + The longer answer: using Mac OS 10.2.3 with the December Developer's + Kit, Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles + fine, including the examples. However, there are problems at runtime + (see http://mail.python.org/pipermail/c++-sig/2003-January/003267.html). + Solutions are currently unknown. +

      +

      + It is known that under certain circumstances objects are + double-destructed. See http://mail.python.org/pipermail/c++-sig/2003-January/003278.html + for details. It is not clear however if this problem is related to + the Boost.Python runtime issues. +

      - -
      -

      How can I find the existing PyObject that holds a C++ - object?

      - +
      +

      + How can I find the existing PyObject that holds a C++ + object? +

      "I am wrapping a function that always returns a pointer to an already-held C++ object." -
      - One way to do that is to hijack the mechanisms used for wrapping a class - with virtual functions. If you make a wrapper class with an initial - PyObject* constructor argument and store that PyObject* as "self", you - can get back to it by casting down to that wrapper type in a thin wrapper - function. For example: -
      +    One way to do that is to hijack the mechanisms used for
      +    wrapping a class with virtual functions. If you make a wrapper class with
      +    an initial PyObject* constructor argument and store that PyObject* as
      +    "self", you can get back to it by casting down to that wrapper type in a
      +    thin wrapper function. For example: 
      +    
       class X { X(int); virtual ~X(); ... };
       X* f();  // known to return Xs that are managed by Python objects
       
      @@ -380,40 +393,87 @@ def("f", f_wrap());
       class_<X,X_wrap>("X", init<int>())
          ...
          ;
      -
      - Of course, if X has no virtual functions you'll have to use - static_cast instead of dynamic_cast with no - runtime check that it's valid. This approach also only works if the - X object was constructed from Python, because - Xs constructed from C++ are of course never - X_wrap objects. - -

      Another approach to this requires some work on Boost.Python, but it's - work we've been meaning to get to anyway. Currently, when a - shared_ptr<X> is converted from Python, the shared_ptr - actually manages a reference to the containing Python object. I plan to - make it so that when a shared_ptr<X> is converted back to Python, - the library checks to see if it's one of those "Python object managers" - and if so just returns the original Python object. To exploit this you'd - have to be able to change the C++ code you're wrapping so that it deals - with shared_ptr instead of raw pointers.

      - -

      There are other approaches too. The functions that receive the Python - object that you eventually want to return could be wrapped with a thin - wrapper that records the correspondence between the object address and - its containing Python object, and you could have your f_wrap function - look in that mapping to get the Python object out.

      -
      - -

      Revised - - 23 January, 2003 - +

      Of course, if X has no virtual functions you'll have to use +static_cast instead of dynamic_cast with no runtime +check that it's valid. This approach also only works if the X +object was constructed from Python, because Xs constructed from +C++ are of course never X_wrap objects. +

      + Another approach to this requires some work on Boost.Python, but it's + work we've been meaning to get to anyway. Currently, when a + shared_ptr<X> is converted from Python, the + shared_ptr actually manages a reference to the containing Python + object. I plan to make it so that when a shared_ptr<X> is + converted back to Python, the library checks to see if it's one of + those "Python object managers" and if so just returns the original + Python object. To exploit this you'd have to be able to change the C++ + code you're wrapping so that it deals with shared_ptr instead of raw + pointers. +

      +

      + There are other approaches too. The functions that receive the Python + object that you eventually want to return could be wrapped with a thin + wrapper that records the correspondence between the object address and + its containing Python object, and you could have your f_wrap function + look in that mapping to get the Python object out. +

      +

      + How can I wrap a function which needs to take + ownership of a raw pointer? +

      +
      + Part of an API that I'm wrapping goes something like this: +
      +struct A {}; struct B { void add( A* ); }
      +where B::add() takes ownership of the pointer passed to it.
      +
      +

      + However: +

      +
      +a = mod.A()
      +b = mod.B()
      +b.add( a )
      +del a         
      +del b
      +# python interpreter crashes 
      +# later due to memory corruption.
      +
      +

      + Even binding the lifetime of a to b via + with_custodian_and_ward doesn't prevent the python object a from + ultimately trying to delete the object it's pointing to. Is there a + way to accomplish a 'transfer-of-ownership' of a wrapped C++ object? +

      +

      + --Bruce Lowery +

      +
      Yes: Make sure the C++ object is held by auto_ptr: +
      +class_<A, std::auto_ptr<A> >("A")
      +    ...
      +    ;
      +
      Then make a thin wrapper function which takes an auto_ptr parameter: +
      +void b_insert(B& b, std::auto_ptr<A> a)
      +{
      +    b.insert(a.get());
      +    a.release();
      +}
      +
      Wrap that as B.add. Note that pointers returned via + manage_new_object + will also be held by auto_ptr, so this + transfer-of-ownership will also work correctly. +
      +

      + Revised + + 23 January, 2003 + +

      +

      + © Copyright Dave + Abrahams 2002-2003. All Rights Reserved.

      - -

      © Copyright Dave Abrahams 2002-2003. All - Rights Reserved.

      - From ad8da7166bb4aa115726e4e003d3b59cb839c743 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 6 Feb 2003 20:56:26 +0000 Subject: [PATCH 0993/1042] edits [SVN r17257] --- doc/PyConDC_2003/bpl.txt | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt index 48ef5994..62f471d0 100644 --- a/doc/PyConDC_2003/bpl.txt +++ b/doc/PyConDC_2003/bpl.txt @@ -91,11 +91,23 @@ facilities provided by Python alone for integration with C++ are relatively meager. Some of this, such as the need to manage reference-counting manually and lack of C++ exception-handling support, comes from the limitations of the 'C' language in which the -API is implemented. +API is implemented. Most of the remaining issues can be handled if +the code understands the C++ type system. For example: -Most of the hard problems and much of the tedium of exposing C++ in -Python extension modules can be handled if the code understands the C++ -type system. The Boost.Python Library (BPL) leverages the power of C++ +* Every argument of every wrapped function requires some kind of + extraction code to convert it from Python to C++. Likewise, the + function return value has to be converted from C++ to Python. + Appropriate Python exceptions must be raised if the conversion + fails. Argument and return types are part of the function's type, + and much of this tedium can be relieved if the wrapping system can + extract that information through introspection. + +* Passing a wrapped C++ derived class instance to a C++ function + accepting a pointer or reference to a base class requires knowledge + of the inheritance relationship and how to translate the address of + a base class into that of a derived class. + +The Boost.Python Library (BPL) leverages the power of C++ meta-programming techniques to introspect about the C++ type system, and presents a simple, IDL-like C++ interface for exposing C++ code in extension modules. @@ -115,17 +127,6 @@ example, though C++ and Python both have an iterator concept, they are expressed very differently. Boost.Python has to be able to bridge the interface gap. -Every argument of every wrapped function must be converted -automatically from Python to C++. Likewise, the function return value -must be converted automatically from C++ to Python. Appropriate -Python exceptions must be raised if the conversion fails. - -It must be possible to pass a wrapped C++ derived class instance to a -C++ function accepting a pointer or reference to a base class. For -this Boost.Python has to maintain a graph of the inheritance -relationships including information on how to translate the address of -a base class into that of a derived class. - It must be possible to insulate Python users from crashes resulting from trivial misuses of C++ interfaces, such as accessing already-deleted objects. By the same token the library should @@ -612,8 +613,9 @@ generate these dispatchers (and other wrapping code) automatically. If these are successful it will mark a move away from wrapping everything directly in pure C++ for many of our users. -Serialization -============= +--------------- + Serialization +--------------- *Serialization* is the process of converting objects in memory to a form that can be stored on disk or sent over a network connection. The @@ -673,9 +675,9 @@ a little more work than is shown in this example, but the ``object`` interface (see next section) greatly helps in keeping the code manageable. -================== +------------------ Object interface -================== +------------------ Experienced extension module authors will be familiar with the 'C' view of Python objects, the ubiquitous ``PyObject*``. Most if not all Python From 80488e2f23ed1730dbb093948c39cb2b70b15b62 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 6 Feb 2003 22:42:36 +0000 Subject: [PATCH 0994/1042] improved serialization and object interface sections; some sentences added to the end of the conclusion [SVN r17258] --- doc/PyConDC_2003/bpl.txt | 94 +++++++++++++++++----------- doc/PyConDC_2003/python_cpp_mix.png | Bin 0 -> 6293 bytes 2 files changed, 58 insertions(+), 36 deletions(-) create mode 100755 doc/PyConDC_2003/python_cpp_mix.png diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt index 62f471d0..fe0f686b 100644 --- a/doc/PyConDC_2003/bpl.txt +++ b/doc/PyConDC_2003/bpl.txt @@ -622,11 +622,11 @@ form that can be stored on disk or sent over a network connection. The serialized object (most often a plain string) can be retrieved and converted back to the original object. A good serialization system will automatically convert entire object hierarchies. Python's standard -``pickle`` module is such a system. It leverages the language's -virtually unlimited runtime introspection facilities for serializing -practically arbitrary user-defined objects. With a few simple and -unintrusive provisions this powerful machinery can be extended to work -for wrapped C++ objects. Here is a simple example:: +``pickle`` module is such a system. It leverages the language's strong +runtime introspection facilities for serializing practically arbitrary +user-defined objects. With a few simple and unintrusive provisions this +powerful machinery can be extended to also work for wrapped C++ objects. +Here is an example:: #include @@ -661,19 +661,33 @@ Now let's create a ``World`` object and put it to rest on disk:: >>> a_world = hello.World("howdy") >>> pickle.dump(a_world, open("my_world", "w")) -Resurrecting the ``World`` object in a different process is equally easy:: +In a potentially *different script* on a potentially *different +computer* with a potentially *different operating system*:: >>> import pickle >>> resurrected_world = pickle.load(open("my_world", "r")) >>> resurrected_world.greet() 'howdy' -Boost.Python's ``pickle_suite`` fully supports the documented -``pickle`` protocols. Of course ``cPickle`` can also be used for faster -processing. Enabling serialization of more complex C++ objects requires -a little more work than is shown in this example, but the ``object`` -interface (see next section) greatly helps in keeping the code -manageable. +Of course the ``cPickle`` module can also be used for faster +processing. + +Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol +defined in the standard Python documentation. There is a one-to-one +correspondence between the standard pickling methods (``__getinitargs__``, +``__getstate__``, ``__setstate__``) and the functions defined by the +user in the class derived from ``pickle_suite`` (``getinitargs``, +``getstate``, ``setstate``). The ``class_::def_pickle()`` member function +is used to establish the Python bindings for all user-defined functions +simultaneously. Correct signatures for these functions are enforced at +compile time. Non-sensical combinations of the three pickle functions +are also rejected at compile time. These measures are designed to +help the user in avoiding obvious errors. + +Enabling serialization of more complex C++ objects requires a little +more work than is shown in the example above. Fortunately the +``object`` interface (see next section) greatly helps in keeping the +code manageable. ------------------ Object interface @@ -693,38 +707,22 @@ Boost.Python provides a type ``object`` which is essentially a high level wrapper around ``PyObject*``. ``object`` automates reference counting as much as possible. It also provides the facilities for converting arbitrary C++ types to Python objects and vice versa. -This should significantly reduce the learning effort for prospective +This significantly reduces the learning effort for prospective extension module writers. -To illustrate, this Python code snippet:: +Creating an ``object`` from any other type is extremely simple:: - def f(x, y): - if (y == 'foo'): - x[3:7] = 'bar' - else: - x.items += y(3, x) - return x + object o(3); -Can be rewritten in C++ using Boost.Python facilities:: - - object f(object x, object y) { - if (y == "foo") - x.slice(3,7) = "bar"; - else - x.attr("items") += y(3, x); - return x; - } +``object`` has templated interactions with all other types, with +automatic to-python conversions. It happens so naturally that it's +easily overlooked. The ``extract`` class template can be used to convert Python objects to C++ types:: - object o(3); double x = extract(o); -If the C++ type cannot be extracted an appropriate exception is thrown -(``extract`` provides facilities for avoiding exceptions if this is -desired). - All registered user-defined conversions are automatically accessible through the ``object`` interface. With reference to the ``World`` class defined in previous examples:: @@ -732,6 +730,22 @@ defined in previous examples:: object as_python_object(World("howdy")); World back_as_c_plus_plus_object = extract(as_python_object); +If a C++ type cannot be converted to a Python object an appropriate +exception is thrown at runtime. Similarly, an appropriate exception is +thrown if a C++ type cannot be extracted from a Python object. +``extract`` provides facilities for avoiding exceptions if this is +desired. + +The ``object::attr()`` member function is available for accessing +and manipulating attributes of Python objects. For example:: + + object planet(World()); + planet.attr("set")("howdy"); + +``planet.attr("set")`` returns a callable ``object``. ``"howdy"`` is +converted to a Python string object which is then passed as an argument +to the ``set`` method. + The ``object`` type is accompanied by a set of derived types that mirror the Python built-in types such as ``list``, ``dict``, ``tuple``, etc. as much as possible. This enables convenient @@ -742,6 +756,8 @@ manipulation of these high-level types from C++:: d["lucky_number"] = 13; list l = d.keys(); +This almost looks and works like regular Python code, but it is pure C++. + ================= Thinking hybrid ================= @@ -765,7 +781,7 @@ clear that a pure Python implementation is too slow for numerically intensive production code. Boost.Python enables us to *think hybrid* when developing new -applications. For example, Python can be used for rapidly prototyping a +applications. Python can be used for rapidly prototyping a new application. Python's ease of use and the large pool of standard libraries give us a head start on the way to a first working system. If necessary, the working procedure can be used to discover the @@ -808,7 +824,13 @@ parsing the C++ code to be interfaced to Python, yet the interface definitions are concise and maintainable. Freed from most of the development-time penalties of crossing a language boundary, software designers can take full advantage of two rich and complimentary -language environments. +language environments. In practice it turns out that some things are +very difficult to do with pure Python/C (e.g. an efficient array +library with an intuitive interface in the compiled language) and +others are very difficult to do with pure C++ (e.g. serialization). +If one has the luxury of being able to design a software system as a +hybrid system from the ground up there are many new ways of avoiding +road blocks in one language or the other. .. I'm not ready to give up on all of this quite yet diff --git a/doc/PyConDC_2003/python_cpp_mix.png b/doc/PyConDC_2003/python_cpp_mix.png new file mode 100755 index 0000000000000000000000000000000000000000..fd74cbb2247835aa8b49e91642f29713e366195b GIT binary patch literal 6293 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 Y!@fNJ(%=4NW}qnoPgg&ebxsLQ00Quv$N&HU literal 0 HcmV?d00001 From 9c50496d937e554c13c1d0092ae4684ff7026df4 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 7 Feb 2003 01:07:39 +0000 Subject: [PATCH 0995/1042] second half of introduction rewritten; SWIG, SIP, CXX acknowledged as suggested by the PyConDC reviewers; technical points moved to Library Overview section [SVN r17259] --- doc/PyConDC_2003/bpl_mods.txt | 908 ++++++++++++++++++++++++++++++++++ 1 file changed, 908 insertions(+) create mode 100644 doc/PyConDC_2003/bpl_mods.txt diff --git a/doc/PyConDC_2003/bpl_mods.txt b/doc/PyConDC_2003/bpl_mods.txt new file mode 100644 index 00000000..e243cda9 --- /dev/null +++ b/doc/PyConDC_2003/bpl_mods.txt @@ -0,0 +1,908 @@ +.. This is a comment. Note how any initial comments are moved by + transforms to after the document title, subtitle, and docinfo. + +.. Need intro and conclusion +.. Exposing classes + .. Constructors + .. Overloading + .. Properties and data members + .. Inheritance + .. Operators and Special Functions + .. Virtual Functions +.. Call Policies + +++++++++++++++++++++++++++++++++++++++++++++++ + Introducing Boost.Python (Extended Abstract) +++++++++++++++++++++++++++++++++++++++++++++++ + + +.. bibliographic fields (which also require a transform): + +:Author: David Abrahams +:Address: 45 Walnut Street + Somerville, MA 02143 +:Contact: dave@boost-consulting.com +:organization: `Boost Consulting`_ +:date: $Date$ +:status: This is a "work in progress" +:version: 1 +:copyright: Copyright David Abrahams 2002. All rights reserved + +:Dedication: + + For my girlfriend, wife, and partner Luann + +:abstract: + + This paper describes the Boost.Python library, a system for + C++/Python interoperability. + +.. meta:: + :keywords: Boost,python,Boost.Python,C++ + :description lang=en: C++/Python interoperability with Boost.Python + +.. contents:: Table of Contents +.. section-numbering:: + + +.. _`Boost Consulting`: http://www.boost-consulting.com + +============== + Introduction +============== + +Python and C++ are in many ways as different as two languages could +be: while C++ is usually compiled to machine-code, Python is +interpreted. Python's dynamic type system is often cited as the +foundation of its flexibility, while in C++ static typing is the +cornerstone of its efficiency. C++ has an intricate and difficult +meta-language to support compile-time polymorphism, while Python is +a uniform language with convenient runtime polymorphism. + +Yet for many programmers, these very differences mean that Python and +C++ complement one another perfectly. Performance bottlenecks in +Python programs can be rewritten in C++ for maximal speed, and +authors of powerful C++ libraries choose Python as a middleware +language for its flexible system integration capabilities. +Furthermore, the surface differences mask some strong similarities: + +* 'C'-family control structures (if, while, for...) + +* Support for object-orientation, functional programming, and generic + programming (these are both *multi-paradigm* programming languages.) + +* Comprehensive operator overloading facilities, recognizing the + importance of syntactic variability for readability and + expressivity. + +* High-level concepts such as collections and iterators. + +* High-level encapsulation facilities (C++: namespaces, Python: modules) + to support the design of re-usable libraries. + +* Exception-handling for effective management of error conditions. + +* C++ idioms in common use, such as handle/body classes and + reference-counted smart pointers mirror Python reference semantics. + +Python provides a rich 'C' API for writers of 'C' extension modules. +Unfortunately, using this API directly for exposing C++ type and +function interfaces to Python is much more tedious than it should be. +This is mainly due to the limitations of the 'C' language. Compared to +C++ and Python, 'C' has only very rudimentary abstraction facilities. +Support for exception-handling is completely missing. One important +undesirable consequence is that 'C' extension module writers are +required to manually manage Python reference counts. Another unpleasant +consequence is a very high degree of repetition of similar code in 'C' +extension modules. Of course highly redundant code does not only cause +frustration for the module writer, but is also very difficult to +maintain. + +The limitations of the 'C' API have lead to the development of a +variety of wrapping systems. SWIG_ is probably the most popular package +for the integration of C/C++ and Python. A more recent development is +the SIP_ package, which is specifically designed for interfacing Python +with the Qt_ graphical user interface library. Both SWIG and SIP +introduce a new specialized language for defining the inter-language +bindings. Of course being able to use a specialized language has +advantages, but having to deal with three different languages (Python, +C/C++ and the interface language) also introduces practical and mental +difficulties. The CXX_ package demonstrates an interesting alternative. +It shows that at least some parts of Python's 'C' API can be wrapped +and presented through a much more user-friendly C++ interface. However, +unlike SWIG and SIP, CXX does not include support for wrapping C++ +classes as new Python types. CXX is also no longer actively developed. + +In some respects Boost.Python combines ideas from SWIG and SIP with +ideas from CXX. Like SWIG and SIP, Boost.Python is a system for +wrapping C++ classes as new Python "built-in" types, and C/C++ +functions as Python functions. Like CXX, Boost.Python presents Python's +'C' API through a C++ interface. Boost.Python goes beyond the scope of +other systems with the unique support for C++ virtual functions that +are overrideable in Python, support for organizing extensions as Python +packages with a central registry for inter-language type conversions, +and a convenient mechanism for tying into Python's serialization engine +(pickle). Importantly, all this is achieved without introducing a new +syntax. Boost.Python leverages the power of C++ meta-programming +techniques to introspect about the C++ type system, and presents a +simple, IDL-like C++ interface for exposing C/C++ code in extension +modules. Boost.Python is a pure C++ library, the inter-language +bindings are defined in pure C++, and other than a C++ compiler only +Python itself is required to get started with Boost.Python. Last but +not least, Boost.Python is an unrestricted open source library. There +are no strings attached even for commercial applications. + +.. _SWIG: http://www.swig.org/ +.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php +.. _Qt: http://www.trolltech.com/ +.. _CXX: http://cxx.sourceforge.net/ + +=========================== + Boost.Python Design Goals +=========================== + +The primary goal of Boost.Python is to allow users to expose C++ +classes and functions to Python using nothing more than a C++ +compiler. In broad strokes, the user experience should be one of +directly manipulating C++ objects from Python. + +However, it's also important not to translate all interfaces *too* +literally: the idioms of each language must be respected. For +example, though C++ and Python both have an iterator concept, they are +expressed very differently. Boost.Python has to be able to bridge the +interface gap. + +It must be possible to insulate Python users from crashes resulting +from trivial misuses of C++ interfaces, such as accessing +already-deleted objects. By the same token the library should +insulate C++ users from low-level Python 'C' API, replacing +error-prone 'C' interfaces like manual reference-count management and +raw ``PyObject`` pointers with more-robust alternatives. + +Support for component-based development is crucial, so that C++ types +exposed in one extension module can be passed to functions exposed in +another without loss of crucial information like C++ inheritance +relationships. + +Finally, all wrapping must be *non-intrusive*, without modifying or +even seeing the original C++ source code. Existing C++ libraries have +to be wrappable by third parties who only have access to header files +and binaries. + +========================== + Hello Boost.Python World +========================== + +And now for a preview of Boost.Python, and how it improves on the raw +facilities offered by Python. Here's a function we might want to +expose:: + + char const* greet(unsigned x) + { + static char const* const msgs[] = { "hello", "Boost.Python", "world!" }; + + if (x > 2) + throw std::range_error("greet: index out of range"); + + return msgs[x]; + } + +To wrap this function in standard C++ using the Python 'C' API, we'd +need something like this:: + + extern "C" // all Python interactions use 'C' linkage and calling convention + { + // Wrapper to handle argument/result conversion and checking + PyObject* greet_wrap(PyObject* args, PyObject * keywords) + { + int x; + if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments + { + char const* result = greet(x); // invoke wrapped function + return PyString_FromString(result); // convert result to Python + } + return 0; // error occurred + } + + // Table of wrapped functions to be exposed by the module + static PyMethodDef methods[] = { + { "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" } + , { NULL, NULL, 0, NULL } // sentinel + }; + + // module initialization function + DL_EXPORT init_hello() + { + (void) Py_InitModule("hello", methods); // add the methods to the module + } + } + +Now here's the wrapping code we'd use to expose it with Boost.Python:: + + #include + using namespace boost::python; + BOOST_PYTHON_MODULE(hello) + { + def("greet", greet, "return one of 3 parts of a greeting"); + } + +and here it is in action:: + + >>> import hello + >>> for x in range(3): + ... print hello.greet(x) + ... + hello + Boost.Python + world! + +Aside from the fact that the 'C' API version is much more verbose than +the BPL one, it's worth noting that it doesn't handle a few things +correctly: + +* The original function accepts an unsigned integer, and the Python + 'C' API only gives us a way of extracting signed integers. The + Boost.Python version will raise a Python exception if we try to pass + a negative number to ``hello.greet``, but the other one will proceed + to do whatever the C++ implementation does when converting an + negative integer to unsigned (usually wrapping to some very large + number), and pass the incorrect translation on to the wrapped + function. + +* That brings us to the second problem: if the C++ ``greet()`` + function is called with a number greater than 2, it will throw an + exception. Typically, if a C++ exception propagates across the + boundary with code generated by a 'C' compiler, it will cause a + crash. As you can see in the first version, there's no C++ + scaffolding there to prevent this from happening. Functions wrapped + by Boost.Python automatically include an exception-handling layer + which protects Python users by translating unhandled C++ exceptions + into a corresponding Python exception. + +* A slightly more-subtle limitation is that the argument conversion + used in the Python 'C' API case can only get that integer ``x`` in + *one way*. PyArg_ParseTuple can't convert Python ``long`` objects + (arbitrary-precision integers) which happen to fit in an ``unsigned + int`` but not in a ``signed long``, nor will it ever handle a + wrapped C++ class with a user-defined implicit ``operator unsigned + int()`` conversion. The BPL's dynamic type conversion registry + allows users to add arbitrary conversion methods. + +================== + Library Overview +================== + +This section outlines some of the library's major features. Except as +neccessary to avoid confusion, details of library implementation are +omitted. + +------------------------------------------- + The fundamental type-conversion mechanism +------------------------------------------- + +XXX This needs to be rewritten. + +Every argument of every wrapped function requires some kind of +extraction code to convert it from Python to C++. Likewise, the +function return value has to be converted from C++ to Python. +Appropriate Python exceptions must be raised if the conversion fails. +Argument and return types are part of the function's type, and much of +this tedium can be relieved if the wrapping system can extract that +information through introspection. + +Passing a wrapped C++ derived class instance to a C++ function +accepting a pointer or reference to a base class requires knowledge of +the inheritance relationship and how to translate the address of a base +class into that of a derived class. + +------------------ + Exposing Classes +------------------ + +C++ classes and structs are exposed with a similarly-terse interface. +Given:: + + struct World + { + void set(std::string msg) { this->msg = msg; } + std::string greet() { return msg; } + std::string msg; + }; + +The following code will expose it in our extension module:: + + #include + BOOST_PYTHON_MODULE(hello) + { + class_("World") + .def("greet", &World::greet) + .def("set", &World::set) + ; + } + +Although this code has a certain pythonic familiarity, people +sometimes find the syntax bit confusing because it doesn't look like +most of the C++ code they're used to. All the same, this is just +standard C++. Because of their flexible syntax and operator +overloading, C++ and Python are great for defining domain-specific +(sub)languages +(DSLs), and that's what we've done in BPL. To break it down:: + + class_("World") + +constructs an unnamed object of type ``class_`` and passes +``"World"`` to its constructor. This creates a new-style Python class +called ``World`` in the extension module, and associates it with the +C++ type ``World`` in the BPL type conversion registry. We might have +also written:: + + class_ w("World"); + +but that would've been more verbose, since we'd have to name ``w`` +again to invoke its ``def()`` member function:: + + w.def("greet", &World::greet) + +There's nothing special about the location of the dot for member +access in the original example: C++ allows any amount of whitespace on +either side of a token, and placing the dot at the beginning of each +line allows us to chain as many successive calls to member functions +as we like with a uniform syntax. The other key fact that allows +chaining is that ``class_<>`` member functions all return a reference +to ``*this``. + +So the example is equivalent to:: + + class_ w("World"); + w.def("greet", &World::greet); + w.def("set", &World::set); + +It's occasionally useful to be able to break down the components of a +Boost.Python class wrapper in this way, but the rest of this paper +will tend to stick to the terse syntax. + +For completeness, here's the wrapped class in use: + +>>> import hello +>>> planet = hello.World() +>>> planet.set('howdy') +>>> planet.greet() +'howdy' + +Constructors +============ + +Since our ``World`` class is just a plain ``struct``, it has an +implicit no-argument (nullary) constructor. Boost.Python exposes the +nullary constructor by default, which is why we were able to write: + +>>> planet = hello.World() + +However, well-designed classes in any language may require constructor +arguments in order to establish their invariants. Unlike Python, +where ``__init__`` is just a specially-named method, In C++ +constructors cannot be handled like ordinary member functions. In +particular, we can't take their address: ``&World::World`` is an +error. The library provides a different interface for specifying +constructors. Given:: + + struct World + { + World(std::string msg); // added constructor + ... + +we can modify our wrapping code as follows:: + + class_("World", init()) + ... + +of course, a C++ class may have additional constructors, and we can +expose those as well by passing more instances of ``init<...>`` to +``def()``:: + + class_("World", init()) + .def(init()) + ... + +Boost.Python allows wrapped functions, member functions, and +constructors to be overloaded to mirror C++ overloading. + +Data Members and Properties +=========================== + +Any publicly-accessible data members in a C++ class can be easily +exposed as either ``readonly`` or ``readwrite`` attributes:: + + class_("World", init()) + .def_readonly("msg", &World::msg) + ... + +and can be used directly in Python: + +>>> planet = hello.World('howdy') +>>> planet.msg +'howdy' + +This does *not* result in adding attributes to the ``World`` instance +``__dict__``, which can result in substantial memory savings when +wrapping large data structures. In fact, no instance ``__dict__`` +will be created at all unless attributes are explicitly added from +Python. BPL owes this capability to the new Python 2.2 type system, +in particular the descriptor interface and ``property`` type. + +In C++, publicly-accessible data members are considered a sign of poor +design because they break encapsulation, and style guides usually +dictate the use of "getter" and "setter" functions instead. In +Python, however, ``__getattr__``, ``__setattr__``, and since 2.2, +``property`` mean that attribute access is just one more +well-encapsulated syntactic tool at the programmer's disposal. BPL +bridges this idiomatic gap by making Python ``property`` creation +directly available to users. So if ``msg`` were private, we could +still expose it as attribute in Python as follows:: + + class_("World", init()) + .add_property("msg", &World::greet, &World::set) + ... + +The example above mirrors the familiar usage of properties in Python +2.2+: + +>>> class World(object): +... __init__(self, msg): +... self.__msg = msg +... def greet(self): +... return self.__msg +... def set(self, msg): +... self.__msg = msg +... msg = property(greet, set) + +Operators and Special Functions +=============================== + +The ability to write arithmetic operators for user-defined types that +C++ and Python both allow the definition of has been a major factor in +the popularity of both languages for scientific computing. The +success of packages like NumPy attests to the power of exposing +operators in extension modules. In this example we'll wrap a class +representing a position in a large file:: + + class FilePos { /*...*/ }; + + // Linear offset + FilePos operator+(FilePos, int); + FilePos operator+(int, FilePos); + FilePos operator-(FilePos, int); + + // Distance between two FilePos objects + int operator-(FilePos, FilePos); + + // Offset with assignment + FilePos& operator+=(FilePos&, int); + FilePos& operator-=(FilePos&, int); + + // Comparison + bool operator<(FilePos, FilePos); + +The wrapping code looks like this:: + + class_("FilePos") + .def(self + int()) // __add__ + .def(int() + self) // __radd__ + .def(self - int()) // __sub__ + + .def(self - self) // __sub__ + + .def(self += int()) // __iadd__ + .def(self -= int()) // __isub__ + + .def(self < self); // __lt__ + ; + +The magic is performed using a simplified application of "expression +templates" [VELD1995]_, a technique originally developed by for +optimization of high-performance matrix algebra expressions. The +essence is that instead of performing the computation immediately, +operators are overloaded to construct a type *representing* the +computation. In matrix algebra, dramatic optimizations are often +available when the structure of an entire expression can be taken into +account, rather than processing each operation "greedily". +Boost.Python uses the same technique to build an appropriate Python +callable object based on an expression involving ``self``, which is +then added to the class. + +Inheritance +=========== + +C++ inheritance relationships can be represented to Boost.Python by adding +an optional ``bases<...>`` argument to the ``class_<...>`` template +parameter list as follows:: + + class_ >("Derived") + ... + +This has two effects: + +1. When the ``class_<...>`` is created, Python type objects + corresponding to ``Base1`` and ``Base2`` are looked up in the BPL + registry, and are used as bases for the new Python ``Derived`` type + object [#mi]_, so methods exposed for the Python ``Base1`` and + ``Base2`` types are automatically members of the ``Derived`` type. + Because the registry is global, this works correctly even if + ``Derived`` is exposed in a different module from either of its + bases. + +2. C++ conversions from ``Derived`` to its bases are added to the + Boost.Python registry. Thus wrapped C++ methods expecting (a + pointer or reference to) an object of either base type can be + called with an object wrapping a ``Derived`` instance. Wrapped + member functions of class ``T`` are treated as though they have an + implicit first argument of ``T&``, so these conversions are + neccessary to allow the base class methods to be called for derived + objects. + +Of course it's possible to derive new Python classes from wrapped C++ +class instances. Because Boost.Python uses the new-style class +system, that works very much as for the Python built-in types. There +is one significant detail in which it differs: the built-in types +generally establish their invariants in their ``__new__`` function, so +that derived classes do not need to call ``__init__`` on the base +class before invoking its methods : + +>>> class L(list): +... def __init__(self): +... pass +... +>>> L().reverse() +>>> + +Because C++ object construction is a one-step operation, C++ instance +data cannot be constructed until the arguments are available, in the +``__init__`` function: + +>>> class D(SomeBPLClass): +... def __init__(self): +... pass +... +>>> D().some_bpl_method() +Traceback (most recent call last): + File "", line 1, in ? +TypeError: bad argument type for built-in operation + +This happened because Boost.Python couldn't find instance data of type +``SomeBPLClass`` within the ``D`` instance; ``D``'s ``__init__`` +function masked construction of the base class. It could be corrected +by either removing ``D``'s ``__init__`` function or having it call +``SomeBPLClass.__init__(...)`` explicitly. + +Virtual Functions +================= + +Deriving new types in Python from extension classes is not very +interesting unless they can be used polymorphically from C++. In +other words, Python method implementations should appear to override +the implementation of C++ virtual functions when called *through base +class pointers/references from C++*. Since the only way to alter the +behavior of a virtual function is to override it in a derived class, +the user must build a special derived class to dispatch a polymorphic +class' virtual functions:: + + // + // interface to wrap: + // + class Base + { + public: + virtual int f(std::string x) { return 42; } + virtual ~Base(); + }; + + int calls_f(Base const& b, std::string x) { return b.f(x); } + + // + // Wrapping Code + // + + // Dispatcher class + struct BaseWrap : Base + { + // Store a pointer to the Python object + BaseWrap(PyObject* self_) : self(self_) {} + PyObject* self; + + // Default implementation, for when f is not overridden + int f_default(std::string x) { return this->Base::f(x); } + // Dispatch implementation + int f(std::string x) { return call_method(self, "f", x); } + }; + + ... + def("calls_f", calls_f); + class_("Base") + .def("f", &Base::f, &BaseWrap::f_default) + ; + +Now here's some Python code which demonstrates: + +>>> class Derived(Base): +... def f(self, s): +... return len(s) +... +>>> calls_f(Base(), 'foo') +42 +>>> calls_f(Derived(), 'forty-two') +9 + +Things to notice about the dispatcher class: + +* The key element which allows overriding in Python is the + ``call_method`` invocation, which uses the same global type + conversion registry as the C++ function wrapping does to convert its + arguments from C++ to Python and its return type from Python to C++. + +* Any constructor signatures you wish to wrap must be replicated with + an initial ``PyObject*`` argument + +* The dispatcher must store this argument so that it can be used to + invoke ``call_method`` + +* The ``f_default`` member function is needed when the function being + exposed is not pure virtual; there's no other way ``Base::f`` can be + called on an object of type ``BaseWrap``, since it overrides ``f``. + +Admittedly, this formula is tedious to repeat, especially on a project +with many polymorphic classes; that it is neccessary reflects +limitations in C++'s compile-time reflection capabilities. Several +efforts are underway to write front-ends for Boost.Python which can +generate these dispatchers (and other wrapping code) automatically. +If these are successful it will mark a move away from wrapping +everything directly in pure C++ for many of our users. + +--------------- + Serialization +--------------- + +*Serialization* is the process of converting objects in memory to a +form that can be stored on disk or sent over a network connection. The +serialized object (most often a plain string) can be retrieved and +converted back to the original object. A good serialization system will +automatically convert entire object hierarchies. Python's standard +``pickle`` module is such a system. It leverages the language's strong +runtime introspection facilities for serializing practically arbitrary +user-defined objects. With a few simple and unintrusive provisions this +powerful machinery can be extended to also work for wrapped C++ objects. +Here is an example:: + + #include + + struct World + { + World(std::string a_msg) : msg(a_msg) {} + std::string greet() const { return msg; } + std::string msg; + }; + + #include + using namespace boost::python; + + struct World_picklers : pickle_suite + { + static tuple + getinitargs(World const& w) { return make_tuple(w.greet()); } + }; + + BOOST_PYTHON_MODULE(hello) + { + class_("World", init()) + .def("greet", &World::greet) + .def_pickle(World_picklers()) + ; + } + +Now let's create a ``World`` object and put it to rest on disk:: + + >>> import hello + >>> import pickle + >>> a_world = hello.World("howdy") + >>> pickle.dump(a_world, open("my_world", "w")) + +In a potentially *different script* on a potentially *different +computer* with a potentially *different operating system*:: + + >>> import pickle + >>> resurrected_world = pickle.load(open("my_world", "r")) + >>> resurrected_world.greet() + 'howdy' + +Of course the ``cPickle`` module can also be used for faster +processing. + +Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol +defined in the standard Python documentation. There is a one-to-one +correspondence between the standard pickling methods (``__getinitargs__``, +``__getstate__``, ``__setstate__``) and the functions defined by the +user in the class derived from ``pickle_suite`` (``getinitargs``, +``getstate``, ``setstate``). The ``class_::def_pickle()`` member function +is used to establish the Python bindings for all user-defined functions +simultaneously. Correct signatures for these functions are enforced at +compile time. Non-sensical combinations of the three pickle functions +are also rejected at compile time. These measures are designed to +help the user in avoiding obvious errors. + +Enabling serialization of more complex C++ objects requires a little +more work than is shown in the example above. Fortunately the +``object`` interface (see next section) greatly helps in keeping the +code manageable. + +------------------ + Object interface +------------------ + +Experienced extension module authors will be familiar with the 'C' view +of Python objects, the ubiquitous ``PyObject*``. Most if not all Python +'C' API functions involve ``PyObject*`` as arguments or return type. A +major complication is the raw reference counting interface presented to +the 'C' programmer. E.g. some API functions return *new references* and +others return *borrowed references*. It is up to the extension module +writer to properly increment and decrement reference counts. This +quickly becomes cumbersome and error prone, especially if there are +multiple execution paths. + +Boost.Python provides a type ``object`` which is essentially a high +level wrapper around ``PyObject*``. ``object`` automates reference +counting as much as possible. It also provides the facilities for +converting arbitrary C++ types to Python objects and vice versa. +This significantly reduces the learning effort for prospective +extension module writers. + +Creating an ``object`` from any other type is extremely simple:: + + object o(3); + +``object`` has templated interactions with all other types, with +automatic to-python conversions. It happens so naturally that it's +easily overlooked. + +The ``extract`` class template can be used to convert Python objects +to C++ types:: + + double x = extract(o); + +All registered user-defined conversions are automatically accessible +through the ``object`` interface. With reference to the ``World`` class +defined in previous examples:: + + object as_python_object(World("howdy")); + World back_as_c_plus_plus_object = extract(as_python_object); + +If a C++ type cannot be converted to a Python object an appropriate +exception is thrown at runtime. Similarly, an appropriate exception is +thrown if a C++ type cannot be extracted from a Python object. +``extract`` provides facilities for avoiding exceptions if this is +desired. + +The ``object::attr()`` member function is available for accessing +and manipulating attributes of Python objects. For example:: + + object planet(World()); + planet.attr("set")("howdy"); + +``planet.attr("set")`` returns a callable ``object``. ``"howdy"`` is +converted to a Python string object which is then passed as an argument +to the ``set`` method. + +The ``object`` type is accompanied by a set of derived types +that mirror the Python built-in types such as ``list``, ``dict``, +``tuple``, etc. as much as possible. This enables convenient +manipulation of these high-level types from C++:: + + dict d; + d["some"] = "thing"; + d["lucky_number"] = 13; + list l = d.keys(); + +This almost looks and works like regular Python code, but it is pure C++. + +================= + Thinking hybrid +================= + +For many applications runtime performance considerations are very +important. This is particularly true for most scientific applications. +Often the performance considerations dictate the use of a compiled +language for the core algorithms. Traditionally the decision to use a +particular programming language is an exclusive one. Because of the +practical and mental difficulties of combining different languages many +systems are written in just one language. This is quite unfortunate +because the price payed for runtime performance is typically a +significant overhead due to static typing. For example, our experience +shows that developing maintainable C++ code is typically much more +time-consuming and requires much more hard-earned working experience +than developing useful Python code. A related observation is that many +compiled packages are augmented by some type of rudimentary scripting +layer. These ad hoc solutions clearly show that many times a compiled +language alone does not get the job done. On the other hand it is also +clear that a pure Python implementation is too slow for numerically +intensive production code. + +Boost.Python enables us to *think hybrid* when developing new +applications. Python can be used for rapidly prototyping a +new application. Python's ease of use and the large pool of standard +libraries give us a head start on the way to a first working system. If +necessary, the working procedure can be used to discover the +rate-limiting algorithms. To maximize performance these can be +reimplemented in C++, together with the Boost.Python bindings needed to +tie them back into the existing higher-level procedure. + +Of course, this *top-down* approach is less attractive if it is clear +from the start that many algorithms will eventually have to be +implemented in a compiled language. Fortunately Boost.Python also +enables us to pursue a *bottom-up* approach. We have used this approach +very successfully in the development of a toolbox for scientific +applications (scitbx) that we will describe elsewhere. The toolbox +started out mainly as a library of C++ classes with Boost.Python +bindings, and for a while the growth was mainly concentrated on the C++ +parts. However, as the toolbox is becoming more complete, more and more +newly added functionality can be implemented in Python. We expect this +trend to continue, as illustrated qualitatively in this figure: + +.. image:: python_cpp_mix.png + +This figure shows the ratio of newly added C++ and Python code over +time as new algorithms are implemented. We expect this ratio to level +out near 70% Python. The increasing ability to solve new problems +mostly with the easy-to-use Python language rather than a necessarily +more arcane statically typed language is the return on the investment +of learning how to use Boost.Python. The ability to solve some problems +entirely using only Python will enable a larger group of people to +participate in the rapid development of new applications. + +============= + Conclusions +============= + +The examples in this paper illustrate that Boost.Python enables +seamless interoperability between C++ and Python. Importantly, this is +achieved without introducing a third syntax: the Python/C++ interface +definitions are written in pure C++. This avoids any problems with +parsing the C++ code to be interfaced to Python, yet the interface +definitions are concise and maintainable. Freed from most of the +development-time penalties of crossing a language boundary, software +designers can take full advantage of two rich and complimentary +language environments. In practice it turns out that some things are +very difficult to do with pure Python/C (e.g. an efficient array +library with an intuitive interface in the compiled language) and +others are very difficult to do with pure C++ (e.g. serialization). +If one has the luxury of being able to design a software system as a +hybrid system from the ground up there are many new ways of avoiding +road blocks in one language or the other. + +.. I'm not ready to give up on all of this quite yet + +.. Perhaps one day we'll have a language with the simplicity and + expressive power of Python and the compile-time muscle of C++. Being + able to take advantage of all of these facilities without paying the + mental and development-time penalties of crossing a language barrier + would bring enormous benefits. Until then, interoperability tools + like Boost.Python can help lower the barrier and make the benefits of + both languages more accessible to both communities. + +=========== + Footnotes +=========== + +.. [#mi] For hard-core new-style class/extension module writers it is + worth noting that the normal requirement that all extension classes + with data form a layout-compatible single-inheritance chain is + lifted for Boost.Python extension classes. Clearly, either + ``Base1`` or ``Base2`` has to occupy a different offset in the + ``Derived`` class instance. This is possible because the wrapped + part of BPL extension class instances is never assumed to have a + fixed offset within the wrapper. + +=========== + Citations +=========== + +.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report, + Vol. 7 No. 5 June 1995, pp. 26-31. + http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html From 2b5ef3c572416eb3c4848b7db884083b191ba232 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 7 Feb 2003 18:56:16 +0000 Subject: [PATCH 0996/1042] Python 2.3 compatibility [SVN r17271] --- src/object/class.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/object/class.cpp b/src/object/class.cpp index dc560fef..ff14c9b7 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -277,16 +277,11 @@ namespace objects object module_prefix() { - object result( + return object( PyObject_IsInstance(scope().ptr(), upcast(&PyModule_Type)) ? object(scope().attr("__name__")) : api::getattr(scope(), "__module__", str()) ); - - if (result) - result += '.'; - - return result; } namespace @@ -348,11 +343,14 @@ namespace objects // Call the class metatype to create a new class dict d; - + + object m = module_prefix(); + if (m) d["__module__"] = m; + if (doc != 0) d["__doc__"] = doc; - object result = object(class_metatype())(module_prefix() + name, bases, d); + object result = object(class_metatype())(name, bases, d); assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type)); if (scope().ptr() != Py_None) From 47291f68b2ab0e1968c324bd166fd2d40e8f2c66 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Tue, 11 Feb 2003 12:18:47 +0000 Subject: [PATCH 0997/1042] removed unnecessary file [SVN r17318] --- .../doc/building_an_extension_module.html | 186 ------------------ 1 file changed, 186 deletions(-) delete mode 100644 doc/tutorial/doc/building_an_extension_module.html diff --git a/doc/tutorial/doc/building_an_extension_module.html b/doc/tutorial/doc/building_an_extension_module.html deleted file mode 100644 index ffa176b7..00000000 --- a/doc/tutorial/doc/building_an_extension_module.html +++ /dev/null @@ -1,186 +0,0 @@ - - - -Building an Extension Module - - - - - - - - - - -
      - Building - an Extension Module
      -
      - - - - - - -
      -

      Building Boost.Python

      -

      Every Boost.Python extension module must be linked with the boost_python shared - library. To build boost_python, use Boost.Build - in the usual way from the libs/python/build subdirectory of your boost - installation (if you have already built boost from the top level this may have - no effect, since the work is already done).

      -

      Configuration

      -

      You may need to configure the following variables to point Boost.Build at your - Python installation:

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Variable NameSemanticsDefaultNotes
      PYTHON_ROOT The root directory of your Python installationWindows:
      - c:/tools/python
      - Unix: /usr/local
      On Unix, this is the --with-prefix= directory used to configure - Python
      PYTHON_VERSION The The 2-part python Major.Minor version numberWindows: 2.1 Unix: 1.5Be sure not to include a third number, e.g. not "2.2.1", even - if that's the version you have.
      PYTHON_INCLUDES path to Python #include directoriesAutoconfigured from
      - PYTHON_ROOT
       
      PYTHON_LIB_PATHpath to Python library object.Autoconfigured from
      - PYTHON_ROOT
       
      PYTHON_STDLIB_PATHpath to Python standard library modulesAutoconfigured from
      - PYTHON_ROOT
       
      CYGWIN_ROOT path to the user's Cygwin installationAutoconfigured from
      - PYTHON_ROOT
      Cygwin only. This and the following - two settings are useful when building with multiple toolsets on Windows, - since Cygwin requires a different build of Python.
      GCC_PYTHON_ROOTpath to the user's Cygwin Python installation$(CYGWIN_ROOT)
      - /usr/local
      Cygwin only
      GCC_DEBUG_PYTHON_ROOT path to the user's Cygwin pydebug - build$(CYGWIN_ROOT)
      - /usr/local/pydebug
      Cygwin only
      -

      Results

      -

      The build process will create a libs/python/build/bin-stage subdirectory - of the boost root (or of $(ALL_LOCATE_TARGET), if you have set that - variable), containing the built libraries. The libraries are actually built - to unique directories for each toolset and variant elsewhere in the filesystem, - and copied to the bin-stage directory as a convenience, so if you build with - multiple toolsets at once, the product of later toolsets will overwrite that - of earlier toolsets in bin-stage.

      -

      Testing

      -

      To build and test Boost.Python from within the libs/python/build directory, - invoke

      -
          bjam -sTOOLS=toolset test
      -

      This will update all of the Boost.Python v1 test and example targets. The tests - are relatively quiet by default. To get more-verbose output, you might try

      -
          bjam -sTOOLS=toolset -sPYTHON_TEST_ARGS=-v test
      -

      which will print each test's Python code with the expected output as it passes.

      -

      Building your Extension Module

      -

      Though there are other approaches, the easiest way to build an extension module - using Boost.Python is with Boost.Build. Until Boost.Build v2 is released, cross-project - build dependencies are not supported, so it works most smoothly if you add a - new subproject to your boost installation. The libs/python/example - subdirectory of your boost installation contains a minimal example (along with - many extra sources). To copy the example subproject:

      -
        -
      1. Create a new subdirectory in, libs/python, say libs/python/my_project.
      2. -
      3. Copy libs/python/example/Jamfile - to your new directory.
      4. -
      5. Edit the Jamfile as appropriate for your project. You'll want to change - the subproject rule invocation at the top, and the names of some - of the source files and/or targets.
      6. -
      -

      If you can't modify or copy your boost installation, the alternative is to - create your own Boost.Build project. A similar example you can use as a starting - point is available in this archive. You'll - need to edit the Jamfile and Jamrules files, depending on the relative location - of your Boost installation and the new project. Note that automatic testing - of extension modules is not available in this configuration.

      -

      Build Variants

      -

      Three variant configurations of all python-related targets are supported, and - can be selected by setting the BUILD variable:

      -

      * release (optimization, -DNDEBUG)
      - * debug (no optimization -D_DEBUG)
      - * debug-python (no optimization, -D_DEBUG -DBOOST_DEBUG_PYTHON)

      -

      The first two variants of the boost_python library are built by default, and - are compatible with the default Python distribution. The debug-python variant - corresponds to a specially-built debugging version of Python. On Unix platforms, - this python is built by adding --with-pydebug when configuring the - Python build. On Windows, the debugging version of Python is generated by the - "Win32 Debug" target of the PCBuild.dsw Visual C++ 6.0 project in - the PCBuild subdirectory of your Python distribution. Extension modules built - with Python debugging enabled are not link-compatible with a non-debug build - of Python. Since few people actually have a debug build of Python (it doesn't - come with the standard distribution), the normal debug variant builds modules - which are compatible with ordinary Python.

      -

      On many windows compilers, when extension modules are built with -D_DEBUG, - Python defaults to force linking with a special debugging version of the Python - DLL. Since this debug DLL isn't supplied with the default Python installation - for Windows, Boost.Python uses boost/python/detail/wrap_python.hpp - to temporarily undefine _DEBUG when Python.h is #included - - unless BOOST_DEBUG_PYTHON is defined.

      -

      If you want the extra runtime checks available with the debugging version of - the library, #define BOOST_DEBUG_PYTHON - to re-enable python debuggin, and link with the debug-python variant of boost_python.

      -

      If you do not #define BOOST_DEBUG_PYTHON, - be sure that any source files in your extension module #include - <boost/python/detail/wrap_python.hpp> instead of the usual Python.h, - or you will have link incompatibilities.

      - - - - - - - -
      -
      -
      - - From 6f91b9351956c56ad901a7e1b5a7a7c0449b244e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 11 Feb 2003 17:29:27 +0000 Subject: [PATCH 0998/1042] removed to make binary [SVN r17319] --- doc/PyConDC_2003/python_cpp_mix.png | Bin 6293 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 doc/PyConDC_2003/python_cpp_mix.png diff --git a/doc/PyConDC_2003/python_cpp_mix.png b/doc/PyConDC_2003/python_cpp_mix.png deleted file mode 100755 index fd74cbb2247835aa8b49e91642f29713e366195b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6293 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 Y!@fNJ(%=4NW}qnoPgg&ebxsLQ00Quv$N&HU From 472dc3bd41af8f17fe65610b0c152c2115708ebb Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 11 Feb 2003 17:30:23 +0000 Subject: [PATCH 0999/1042] made binary [SVN r17320] --- doc/PyConDC_2003/python_cpp_mix.png | Bin 0 -> 6293 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 doc/PyConDC_2003/python_cpp_mix.png diff --git a/doc/PyConDC_2003/python_cpp_mix.png b/doc/PyConDC_2003/python_cpp_mix.png new file mode 100755 index 0000000000000000000000000000000000000000..fd74cbb2247835aa8b49e91642f29713e366195b GIT binary patch literal 6293 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 Y!@fNJ(%=4NW}qnoPgg&ebxsLQ00Quv$N&HU literal 0 HcmV?d00001 From ff9f262fac190f7fd31f6476e756ed4b88976368 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Tue, 18 Feb 2003 18:44:16 +0000 Subject: [PATCH 1000/1042] tutorial update [SVN r17512] --- doc/tutorial/doc/basic_interface.html | 16 +- doc/tutorial/doc/building_hello_world.html | 2 +- doc/tutorial/doc/call_policies.html | 32 ++-- doc/tutorial/doc/class_data_members.html | 17 +- .../class_operators_special_functions.html | 26 +-- doc/tutorial/doc/class_properties.html | 22 ++- doc/tutorial/doc/class_virtual_functions.html | 83 +++++---- doc/tutorial/doc/constructors.html | 28 +-- doc/tutorial/doc/default_arguments.html | 86 +++++++--- doc/tutorial/doc/derived_object_types.html | 30 ++-- doc/tutorial/doc/enums.html | 24 +-- doc/tutorial/doc/exception_translation.html | 10 +- doc/tutorial/doc/exposing_classes.html | 22 +-- doc/tutorial/doc/extracting_c___objects.html | 10 +- doc/tutorial/doc/functions.html | 2 +- doc/tutorial/doc/inheritance.html | 16 +- doc/tutorial/doc/iterators.html | 18 +- doc/tutorial/doc/object_interface.html | 8 +- doc/tutorial/doc/overloading.html | 152 +++++++++++++++++ doc/tutorial/doc/quickstart.html | 10 +- doc/tutorial/doc/quickstart.txt | 161 +++++++++++++++++- doc/tutorial/index.html | 7 +- 22 files changed, 561 insertions(+), 221 deletions(-) create mode 100644 doc/tutorial/doc/overloading.html diff --git a/doc/tutorial/doc/basic_interface.html b/doc/tutorial/doc/basic_interface.html index a9326c80..8165b121 100644 --- a/doc/tutorial/doc/basic_interface.html +++ b/doc/tutorial/doc/basic_interface.html @@ -34,7 +34,7 @@ To illustrate, this Python code snippet:

           def f(x, y):
                if (y == 'foo'):
      -             x[3:7] = 'bar'
      +             x[3:7] = 'bar'
                else:
                    x.items += y(3, x)
                return x
      @@ -45,16 +45,16 @@ To illustrate, this Python code snippet:

      Can be rewritten in C++ using Boost.Python facilities this way:

      -    object f(object x, object y) {
      +    object f(object x, object y) {
                if (y == "foo")
      -             x.slice(3,7) = "bar";
      +             x.slice(3,7) = "bar";
                else
      -             x.attr("items") += y(3, x);
      +             x.attr("items") += y(3, x);
                return x;
      -    }
      -    object getfunc() {
      +    }
      +    object getfunc() {
               return object(f);
      -    }
      +    }
       

      Apart from cosmetic differences due to the fact that we are writing the @@ -68,7 +68,7 @@ coder.


      -


      -

      -    >>> x = f(y, z) #x refers to some C++ X
      +    >>> x = f(y, z) ##x refers to some C++ X
           >>> del y
      -    >>> x.some_method() #CRASH!
      +    >>> x.some_method() ##CRASH!
       

      What's the problem?

      @@ -53,10 +53,10 @@ What's the problem?

      Well, what if f() was implemented as shown below:

           X& f(Y& y, Z* z)
      -    {
      +    {
               y.z = z;
               return y.x;
      -    }
      +    }
       

      The problem is that the lifetime of result X& is tied to the lifetime @@ -70,8 +70,8 @@ Here's what's happening:

      1. f is called passing in a reference to y and a pointer to z
      2. A reference to y.x is returned
      3. y is deleted. x is a dangling reference
      4. x.some_method() is called
      5. BOOM!

      We could copy result into a new object:

      -    >>> f(y, z).set(42) #Result disappears
      -    >>> y.x.get()       #No crash, but still bad
      +    >>> f(y, z).set(42) ##Result disappears
      +    >>> y.x.get()       ##No crash, but still bad
           3.14
       

      @@ -84,25 +84,25 @@ Our problems do not end there. Suppose Y is implemented as follows:

      struct Y { X x; Z* z; - int z_value() { return z->value(); } - }; + int z_value() { return z->value(); } + };

      Notice that the data member z is held by class Y using a raw pointer. Now we have a potential dangling pointer problem inside Y:

      -    >>> x = f(y, z) #y refers to z
      -    >>> del z       #Kill the z object
      -    >>> y.z_value() #CRASH!
      +    >>> x = f(y, z) ##y refers to z
      +    >>> del z       ##Kill the z object
      +    >>> y.z_value() ##CRASH!
       

      For reference, here's the implementation of f again:

           X& f(Y& y, Z* z)
      -    {
      +    {
               y.z = z;
               return y.x;
      -    }
      +    }
       

      Here's what's happening:

      @@ -113,7 +113,7 @@ are our friends:

           def("f", f,
               return_internal_reference<1,
      -            with_custodian_and_ward<1, 2> >());
      +            with_custodian_and_ward<1, 2> >());
       

      What are the 1 and 2 parameters, you ask?

      @@ -138,7 +138,7 @@ or more policies can be composed by chaining. Here's the general syntax:

           policy1<args...,
               policy2<args...,
      -            policy3<args...> > >
      +            policy3<args...> > >
       

      Here is the list of predefined call policies. A complete reference detailing @@ -160,7 +160,7 @@ here.


      -

           struct Var
           {
      -        Var(std::string name) : name(name), value() {}
      +        Var(std::string name) : name(name), value() {}
               std::string const name;
               float value;
      -    };
      +    };
       

      Our C++ Var class and its data members can be exposed to Python:

           class_<Var>("Var", init<std::string>())
      -        .def_readonly("name", &Var::name)
      -        .def_readwrite("value", &Var::value);
      +        .def_readonly("name", &Var::name)
      +        .def_readwrite("value", &Var::value);
       

      -Then, in Python:

      +Then, in Python, assuming we have placed our Var class inside the namespace +hello as we did before:

      -    >>> x = Var('pi')
      -    >>> x.value = 3.14
      +    >>> x = hello.Var('pi')
      +    >>> x.value = 3.14
           >>> print x.name, 'is around', x.value
           pi is around 3.14
       
      @@ -68,7 +69,7 @@ as read-write.


      -

      Consider a file position class FilePos and a set of operators that take on FilePos instances:

      -    class FilePos { /*...*/ };
      +    class FilePos { /*...*/ };
       
           FilePos     operator+(FilePos, int);
           FilePos     operator+(int, FilePos);
      @@ -47,13 +47,13 @@ The class and the various operators can be mapped to Python rather easily
       and intuitively:

           class_<FilePos>("FilePos")
      -        .def(self + int())          // __add__
      -        .def(int() + self)          // __radd__
      -        .def(self - self)           // __sub__
      -        .def(self - int())          // __sub__
      -        .def(self += int())         // __iadd__
      +        .def(self + int())          // __add__
      +        .def(int() + self)          // __radd__
      +        .def(self - self)           // __sub__
      +        .def(self - int())          // __sub__
      +        .def(self += int())         // __iadd__
               .def(self -= other<int>())
      -        .def(self < self);          // __lt__
      +        .def(self < self);          // __lt__
       

      The code snippet above is very clear and needs almost no explanation at @@ -69,17 +69,17 @@ similar set of intuitive interfaces can also be used to wrap C++ functions that correspond to these Python special functions. Example:

           class Rational
      -    { operator double() const; };
      +    { operator double() const; };
       
           Rational pow(Rational, Rational);
           Rational abs(Rational);
           ostream& operator<<(ostream&,Rational);
       
           class_<Rational>()
      -        .def(float_(self))                  // __float__
      -        .def(pow(self, other<Rational>))    // __pow__
      -        .def(abs(self))                     // __abs__
      -        .def(str(self))                     // __str__
      +        .def(float_(self))                  // __float__
      +        .def(pow(self, other<Rational>))    // __pow__
      +        .def(abs(self))                     // __abs__
      +        .def(str(self))                     // __str__
               ;
       

      @@ -100,7 +100,7 @@ Well, the method str requires the operator<< to do its w
      -



      Num(); float get() const; void set(float value); - ... - }; + ... + };

      However, in Python attribute access is fine; it doesn't neccessarily break encapsulation to let users handle attributes directly, because the attributes can just be a different syntax for a method call. Wrapping our Num class using Boost.Python:

      - -
      +
           class_<Num>("Num")
      -        .add_property("rovalue", &Num::get)
      -        .add_property("value", &Num::get, &Var::set);
      -
      -
      + .add_property("rovalue", &Num::get) + .add_property("value", &Num::get, &Num::set); +

      And at last, in Python:

           >>> x = Num()
      -    >>> x.value = 3.14
      +    >>> x.value = 3.14
           >>> x.value, x.rovalue
           (3.14, 3.14)
      -    >>> x.rovalue = 2.17 #error!
      +    >>> x.rovalue = 2.17 ##error!
       

      Take note that the class property rovalue is exposed as read-only since the rovalue setter member function is not passed in:

      -    .add_property("rovalue", &Var::get)
      +    .add_property("rovalue", &Num::get)
       
      @@ -74,7 +72,7 @@ since the rovalue setter member function is not passed in:


      -

           struct Base
           {
      -        virtual int f() = 0;
      -    };
      +        virtual int f() = 0;
      +    };
       

      Since f is a pure virtual function, Base is now an abstract @@ -40,7 +40,7 @@ class. Given an instance of our class, the free function call_f calls some implementation of this virtual function in a concrete derived class:

      -    int call_f(Base& b) { return b.f(); }
      +    int call_f(Base& b) { return b.f(); }
       

      To allow this function to be implemented in a Python derived class, we @@ -49,10 +49,10 @@ need to create a class wrapper:

      struct BaseWrap : Base { BaseWrap(PyObject* self_) - : self(self_) {} - int f() { return call_method<int>(self, "f"); } + : self(self_) {} + int f() { return call_method<int>(self, "f"); } PyObject* self; - }; + };
      @@ -93,7 +93,7 @@ polymorphically fromC++. Wrapping Base and the free function call_f:

           class_<Base, BaseWrap, boost::noncopyable>("Base", no_init)
      -        ;
      +        ;
           def("call_f", call_f);
       

      @@ -104,31 +104,31 @@ Python. To do that, it needs Base's copy constructor... which isn't available, since Base is an abstract class.

      In Python, let us try to instantiate our Base class:

      - -
      +
           >>> base = Base()
      -    RuntimeError: This class cannot be instantiated from Python
      -
      + RuntimeError: This class cannot be instantiated from Python +

      Why is it an error? Base is an abstract class. As such it is advisable to define the Python wrapper with no_init as we have done above. Doing so will disallow abstract base classes such as Base to be instantiated.

      -

      Deriving a Python class

      -

      Now, at last, we can even derive from our base class Base in Python. - Before we can do that, we have to set up our class_ wrapper as:

      -
          class_<Base, BaseWrap, boost::noncopyable>("Base")
      -        ;
      -

      Otherwise, we have to suppress the Base class' no_init by adding an - __init__() method to all our derived classes. no_init actually - adds an __init__ method that raises a Python RuntimeError exception.

      - -
      +

      Deriving a Python class

      +Now, at last, we can even derive from our base class Base in Python. Before +we can do that, we have to set up our class_ wrapper as:

      +
      +    class_<Base, BaseWrap, boost::noncopyable>("Base")
      +        ;
      +
      +

      +Otherwise, we have to suppress the Base class' no_init by adding an +__init__() method to all our derived classes. no_init actually adds +an __init__ method that raises a Python RuntimeError exception.

      +
           >>> class Derived(Base):
      -    ...     def f(self):
      -    ...         return 42
      +    ...     def f(self):
      +    ...         return 42
           ...
      -
      -
      +

      Cool eh? A Python class deriving from a C++ class!

      @@ -159,8 +159,8 @@ declared as pure virtual:

           struct Base
           {
      -        virtual int f() { return 0; }
      -    };
      +        virtual int f() { return 0; }
      +    };
       

      And instead is implemented to return 0, as shown above.

      @@ -168,20 +168,19 @@ And instead is implemented to return 0, as shown above.

      struct BaseWrap : Base { BaseWrap(PyObject* self_) - : self(self_) {} - int f() { return call_method<int>(self, "f"); } - static int default_f(Base* b) { return b->Base::f(); } // <<=== added + : self(self_) {} + int f() { return call_method<int>(self, "f"); } + static int default_f(Base* b) { return b->Base::f(); } // <<=== added PyObject* self; - }; + };

      then, our Boost.Python wrapper:

      - -
          class_<Base, BaseWrap, boost::non_copyable>("Base")
      -        .def("f", &BaseWrap::default_f)
      -        ;
      -
      -
      +
      +    class_<Base, BaseWrap>("Base")
      +        .def("f", &BaseWrap::default_f)
      +        ;
      +

      Note that we are allowing Base objects to be instantiated this time, unlike before where we specifically defined the class_<Base> with @@ -190,11 +189,11 @@ unlike before where we specifically defined the class_<Base> with In Python, the results would be as expected:

           >>> base = Base()
      -    >>> class Derived(Base):
      -    ...     def f(self):
      -    ...         return 42
      +    >>> class Derived(Base):
      +    ...     def f(self):
      +    ...         return 42
           ...
      -    >>> derived = Derived()
      +    >>> derived = Derived()
       

      Calling base.f():

      @@ -228,7 +227,7 @@ Calling call_f, passing in a derived object:


      -

           struct World
           {
      -        World(std::string msg): msg(msg) {} // added constructor
      -        void set(std::string msg) { this->msg = msg; }
      -        std::string greet() { return msg; }
      +        World(std::string msg): msg(msg) {} // added constructor
      +        void set(std::string msg) { this->msg = msg; }
      +        std::string greet() { return msg; }
               std::string msg;
      -    };
      +    };
       

      This time World has no default constructor; our previous @@ -54,12 +54,12 @@ expose instead.

      using namespace boost::python; BOOST_PYTHON_MODULE(hello) - { + { class_<World>("World", init<std::string>()) - .def("greet", &World::greet) - .def("set", &World::set) - ; - } + .def("greet", &World::greet) + .def("set", &World::set) + ; + }

      init<std::string>() exposes the constructor taking in a @@ -71,10 +71,10 @@ the def() member function. Say for example we have another World constructor taking in two doubles:

           class_<World>("World", init<std::string>())
      -        .def(init<double, double>())
      -        .def("greet", &World::greet)
      -        .def("set", &World::set)
      -    ;
      +        .def(init<double, double>())
      +        .def("greet", &World::greet)
      +        .def("set", &World::set)
      +    ;
       

      On the other hand, if we do not wish to expose any constructors at @@ -93,7 +93,7 @@ Python RuntimeError exception.


      -

      @@ -29,43 +29,44 @@ Boost.Python wraps (member) function pointers. Unfortunately, C++ function pointers carry no default argument info. Take a function f with default arguments:

      -    int f(int, double = 3.14, char const* = "hello");
      +    int f(int, double = 3.14, char const* = "hello");
       

      But the type of a pointer to the function f has no information about its default arguments:

      -    int(*g)(int,double,char const*) = f;    // defaults lost!
      +    int(*g)(int,double,char const*) = f;    // defaults lost!
       

      When we pass this function pointer to the def function, there is no way to retrieve the default arguments:

      -    def("f", f);                            // defaults lost!
      +    def("f", f);                            // defaults lost!
       

      Because of this, when wrapping C++ code in earlier versions of Boost.Python, we had to resort to writing thin wrappers:

           // write "thin wrappers"
      -    int f1(int x) { f(x); }
      -    int f2(int x, double y) { f(x,y); }
      +    int f1(int x) { f(x); }
      +    int f2(int x, double y) { f(x,y); }
       
      -    /*...*/
      +    /*...*/
       
      -        // in module init
      -        def("f", f);  // all arguments
      -        def("f", f2); // two arguments
      -        def("f", f1); // one argument
      +        // in module init
      +        def("f", f);  // all arguments
      +        def("f", f2); // two arguments
      +        def("f", f1); // one argument
       

      When you want to wrap functions (or member functions) that either:

      -
      • have default arguments, or
      • are overloaded with a common sequence of initial arguments

      -Boost.Python now has a way to make it easier.

      -

      -For instance, given a function:

      +
      • have default arguments, or
      • are overloaded with a common sequence of initial arguments

      BOOST_PYTHON_FUNCTION_OVERLOADS

      +Boost.Python now has a way to make it easier. For instance, given a function:

      -    int foo(int a, char b = 1, unsigned c = 2, double d = 3);
      +    int foo(int a, char b = 1, unsigned c = 2, double d = 3)
      +    {
      +        /*...*/
      +    }
       

      The macro invocation:

      @@ -73,7 +74,7 @@ The macro invocation:

      BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4)

      -Will automatically create the thin wrappers for us. This macro will create +will automatically create the thin wrappers for us. This macro will create a class foo_overloads that can be passed on to def(...). The third and fourth macro argument are the minimum arguments and maximum arguments, respectively. In our foo function the minimum number of arguments is 1 @@ -82,21 +83,58 @@ automatically add all the foo variants for us:

           .def("foo", foo, foo_overloads());
       
      +

      BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS

      +Objects here, objects there, objects here there everywhere. More frequently +than anything else, we need to expose member functions of our classes to +Python. Then again, we have the same inconveniences as before when default +arguments or overloads with a common sequence of initial arguments come +into play. Another macro is provided to make this a breeze.

      +Like BOOST_PYTHON_FUNCTION_OVERLOADS, +BOOST_PYTHON_FUNCTION_OVERLOADS may be used to automatically create +the thin wrappers for wrapping member functions. Let's have an example:

      +
      +    struct george
      +    {
      +        void
      +        wack_em(int a, int b = 0, char c = 'x')
      +        {
      +            /*...*/
      +        }
      +    };
      +
      +

      +The macro invocation:

      +
      +    BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3)
      +
      +

      +will generate a set of thin wrappers for george's wack_em member function +accepting a minimum of 1 and a maximum of 3 arguments (i.e. the third and +fourth macro argument). The thin wrappers are all enclosed in a class named +george_overloads that can then be used as an argument to def(...):

      +
      +    .def("wack_em", &george::wack_em, george_overloads());
      +
      +

      +See the +overloads reference +for details.

      +

      init and optional

      A similar facility is provided for class constructors, again, with -default arguments or a sequence of overloads. Remember init<...>? For example, +default arguments or a sequence of overloads. Remember init<...>? For example, given a class X with a constructor:

           struct X
           {
               X(int a, char b = 'D', std::string c = "constructor", double d = 0.0);
      -        /*...*/
      -    }
      +        /*...*/
      +    }
       

      You can easily add this constructor to Boost.Python in one shot:

      -    .def(init<int, optional<char, std::string, double> >())
      +    .def(init<int, optional<char, std::string, double> >())
       

      Notice the use of init<...> and optional<...> to signify the default @@ -105,11 +143,11 @@ Notice the use of init<...> and optional<...> to s - +
      -



      • list
      • dict
      • tuple
      • str
      • long_
      • enum

      These derived object types act like real Python types. For instance:

      -    str(1) ==> "1"
      +    str(1) ==> "1"
       

      Wherever appropriate, a particular derived object has corresponding @@ -50,11 +50,11 @@ declared below, is wrapped, it will only accept instances of Python's str type and subtypes.

           void f(str name)
      -    {
      -        object n2 = name.attr("upper")();   // NAME = name.upper()
      -        str NAME = name.upper();            // better
      +    {
      +        object n2 = name.attr("upper")();   // NAME = name.upper()
      +        str NAME = name.upper();            // better
               object msg = "%s is bigger than %s" % make_tuple(NAME,name);
      -    }
      +    }
       

      In finer detail:

      @@ -76,14 +76,14 @@ of most of Python's mutable types make copies, just as in Python.

      Python:

      -    >>> d = dict(x.__dict__)     #copies x.__dict__
      -    >>> d['whatever']            #modifies the copy
      +    >>> d = dict(x.__dict__)     ##copies x.__dict__
      +    >>> d['whatever']            ##modifies the copy
       

      C++:

      -    dict d(x.attr("__dict__"));  #copies x.__dict__
      -    d['whatever'] = 3;           #modifies the copy
      +    dict d(x.attr("__dict__"));  ##copies x.__dict__
      +    d['whatever'] = 3;           ##modifies the copy
       

      class_<T> as objects

      Due to the dynamic nature of Boost.Python objects, any class_<T> may @@ -92,13 +92,13 @@ also be one of these types! The following code snippet wraps the class

      We can use this to create wrapped instances. Example:

      -    object vec345 = (
      +    object vec345 = (
               class_<Vec2>("Vec2", init<double, double>())
      -            .def_readonly("length", &Point::length)
      -            .def_readonly("angle", &Point::angle)
      -        )(3.0, 4.0);
      +            .def_readonly("length", &Point::length)
      +            .def_readonly("angle", &Point::angle)
      +        )(3.0, 4.0);
       
      -    assert(vec345.attr("length") == 5.0);
      +    assert(vec345.attr("length") == 5.0);
       
      @@ -108,7 +108,7 @@ We can use this to create wrapped instances. Example:


      -

      the construct:

           enum_<choice>("choice")
      -        .value("red", red)
      -        .value("blue", blue)
      -        ;
      +        .value("red", red)
      +        .value("blue", blue)
      +        ;
       

      can be used to expose to Python. The new enum type is created in the @@ -67,16 +67,16 @@ You can access those values in Python as

      where my_module is the module where the enum is declared. You can also create a new scope around a class:

      -    scope in_X = class_<X>("X")
      -                    .def( ... )
      -                    .def( ... )
      -                ;
      +    scope in_X = class_<X>("X")
      +                    .def( ... )
      +                    .def( ... )
      +                ;
       
      -    // Expose X::nested as X.nested
      +    // Expose X::nested as X.nested
           enum_<X::nested>("nested")
      -        .value("red", red)
      -        .value("blue", blue)
      -        ;
      +        .value("red", red)
      +        .value("blue", blue)
      +        ;
       
      @@ -86,7 +86,7 @@ create a new scope around a class:


      -

      Users may provide custom translation. Here's an example:

      -
      -    struct PodBayDoorException;
      -    void translator(PodBayDoorException const& x) {
      +
      +    struct PodBayDoorException;
      +    void translator(PodBayDoorException const& x) {
               PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave...");
           }
           BOOST_PYTHON_MODULE(kubrick) {
                register_exception_translator<
                     PodBayDoorException>(translator);
                ...
      -
      +
      @@ -51,7 +51,7 @@ Users may provide custom translation. Here's an example:


      -

           struct World
           {
      -        void set(std::string msg) { this->msg = msg; }
      -        std::string greet() { return msg; }
      +        void set(std::string msg) { this->msg = msg; }
      +        std::string greet() { return msg; }
               std::string msg;
      -    };
      +    };
       

      We can expose this to Python by writing a corresponding Boost.Python @@ -44,12 +44,12 @@ C++ Wrapper:

      using namespace boost::python; BOOST_PYTHON_MODULE(hello) - { + { class_<World>("World") - .def("greet", &World::greet) - .def("set", &World::set) - ; - } + .def("greet", &World::greet) + .def("set", &World::set) + ; + }

      Here, we wrote a C++ class wrapper that exposes the member functions @@ -58,8 +58,8 @@ may use our class World in Python. Here's a sample Python session:

           >>> import hello
           >>> planet = hello.World()
      -    >>> planet.set('howdy')
      -    >>> planet.greet()
      +    >>> planet.set('howdy')
      +    >>> planet.greet()
           'howdy'
       
      @@ -70,7 +70,7 @@ may use our class World in Python. Here's a sample Python session:


      -

      -    double x = o.attr("length"); // compile error
      +    double x = o.attr("length"); // compile error
       

      In the code above, we got a compiler error because Boost.Python @@ -52,15 +52,15 @@ appropriate exception is thrown. To avoid an exception, we need to test for extractibility:

           extract<Vec2&> x(o);
      -    if (x.check()) {
      -        Vec2& v = x(); ...
      +    if (x.check()) {
      +        Vec2& v = x(); ...
       

      The astute reader might have noticed that the extract<T> facility in fact solves the mutable copying problem:

           dict d = extract<dict>(x.attr("__dict__"));
      -    d['whatever'] = 3;          #modifies x.__dict__ !
      +    d['whatever'] = 3;          ##modifies x.__dict__ !
       
      @@ -70,7 +70,7 @@ facility in fact solves the mutable copying problem:


      -



      Consider this trivial inheritance structure:

      -    struct Base { virtual ~Base(); };
      +    struct Base { virtual ~Base(); };
           struct Derived : Base {};
       

      @@ -42,22 +42,22 @@ instances:

           void b(Base*);
           void d(Derived*);
      -    Base* factory() { return new Derived; }
      +    Base* factory() { return new Derived; }
       

      We've seen how we can wrap the base class Base:

           class_<Base>("Base")
      -        /*...*/
      -        ;
      +        /*...*/
      +        ;
       

      Now we can inform Boost.Python of the inheritance relationship between Derived and its base class Base. Thus:

      -    class_<Derived, bases<Base> >("Derived")
      -        /*...*/
      -        ;
      +    class_<Derived, bases<Base> >("Derived")
      +        /*...*/
      +        ;
       

      Doing so, we get some things for free:

      @@ -89,7 +89,7 @@ call policies later.


      -

      • 1 category (forward)
      • 1 operation category (next())
      • Raises StopIteration exception at end

      The typical Python iteration protocol: for y in x... is as follows:

      -    iter = x.__iter__()         #get iterator
      +    iter = x.__iter__()         ##get iterator
           try:
               while 1:
      -        y = iter.next()         #get each item
      -        ...                     #process y
      -    except StopIteration: pass  #iterator exhausted
      +        y = iter.next()         ##get each item
      +        ...                     ##process y
      +    except StopIteration: pass  ##iterator exhausted
       

      Boost.Python provides some mechanisms to make C++ iterators play along @@ -47,14 +47,14 @@ nicely as Python iterators. What we need to do is to produce appropriate __iter__ function from C++ iterators that is compatible with the Python iteration protocol. For example:

      -    object get_iterator = iterator<vector<int> >();
      +    object get_iterator = iterator<vector<int> >();
           object iter = get_iterator(v);
           object first = iter.next();
       

      Or for use in class_<>:

      -    .def("__iter__", iterator<vector<int> >())
      +    .def("__iter__", iterator<vector<int> >())
       

      range

      @@ -81,8 +81,8 @@ bogon Particle accelerator code:

      Now, our C++ Wrapper:

           class_<F>("Field")
      -        .property("pions", range(&F::p_begin, &F::p_end))
      -        .property("bogons", range(&F::b_begin, &F::b_end));
      +        .property("pions", range(&F::p_begin, &F::p_end))
      +        .property("bogons", range(&F::b_begin, &F::b_end));
       
      @@ -92,7 +92,7 @@ Now, our C++ Wrapper:


      -

      - +

      -

      +It was mentioned in passing in the previous section that +BOOST_PYTHON_FUNCTION_OVERLOADS and BOOST_PYTHON_FUNCTION_OVERLOADS +can also be used for overloaded functions and member functions with a +common sequence of initial arguments. Here is an example:

      +
      +     void foo()
      +     {
      +        /*...*/
      +     }
      +
      +     void foo(bool a)
      +     {
      +        /*...*/
      +     }
      +
      +     void foo(bool a, int b)
      +     {
      +        /*...*/
      +     }
      +
      +     void foo(bool a, int b, char c)
      +     {
      +        /*...*/
      +     }
      +
      +

      +Like in the previous section, we can generate thin wrappers for these +overloaded functions in one-shot:

      +
      +    BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3)
      +
      +

      +Then...

      +
      +    .def("foo", foo, foo_overloads());
      +
      +

      +Notice though that we have a situation now where we have a minimum of zero +(0) arguments and a maximum of 3 arguments.

      +

      Manual Wrapping

      +It is important to emphasize however that the overloaded functions must +have a common sequence of initial arguments. Otherwise, our scheme above +will not work.

      +

      +The following illustrates an alternate scheme for manually wrapping an +overloaded member function instead of +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS. Obviously, the same technique +can be applied to wrapping overloaded non- member functions.

      +

      +We have here our C++ classes:

      +
      +    struct X
      +    {
      +        bool f(int a, double b = 0, char c = 'x')
      +        {
      +            return true;
      +        }
      +
      +        int f(int a, int b, int c)
      +        {
      +            return a + b + c;
      +        };
      +    };
      +
      +

      +Notice that class X has two overloaded functions with different signatures. +The types of the arguments, and the return are totally different, unlike +above where we have a common sequence of initial arguments.

      +

      +We shall start by introducing some member function pointer variables:

      +
      +    bool    (X::*fx1)(int)              = &X::f;
      +    bool    (X::*fx2)(int, double)      = &X::f;
      +    bool    (X::*fx3)(int, double, char)= &X::f;
      +    int     (X::*fx4)(int, int, int)    = &X::f;
      +
      +

      +The first three member function pointers take care of the first X::f +overload. The one with default arguments. The last member function pointer +takes care of the second X::f overload.

      +

      +With these in hand, we can proceed to define and wrap this for Python:

      +
      +    .def("f", fx1)
      +    .def("f", fx2)
      +    .def("f", fx3)
      +    .def("f", fx4)
      +
      +

      +Actually, we can mix and match manual wrapping of overloaded functions and +automatic wrapping through BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS and +its sister, BOOST_PYTHON_FUNCTION_OVERLOADS. Since the first overload +has default arguments, we can use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS +to automatically wrap the first three of the defs above and manually +wrap just the last. Here's how we'll do this:

      +
      +    BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)
      +
      +

      +Create a member function pointers as above for both X::f overloads:

      +
      +    bool    (X::*fx1)(int, double, char)    = &X::f;
      +    int     (X::*fx2)(int, int, int)        = &X::f;
      +
      +

      +Then...

      +
      +    .def("f", fx1, xf_overloads());
      +    .def("f", fx2)
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/quickstart.html b/doc/tutorial/doc/quickstart.html index ec1a89ac..02ba7a1a 100644 --- a/doc/tutorial/doc/quickstart.html +++ b/doc/tutorial/doc/quickstart.html @@ -39,9 +39,9 @@ Following C/C++ tradition, let's start with the "hello, world". A C++ Function:

           char const* greet()
      -    {
      +    {
              return "hello, world";
      -    }
      +    }
       

      can be exposed to Python by writing a Boost.Python wrapper:

      @@ -50,9 +50,9 @@ can be exposed to Python by writing a Boost.Python wrapper:

      using namespace boost::python; BOOST_PYTHON_MODULE(hello) - { + { def("greet", greet); - } + }

      That's it. We're done. We can now build this as a shared library. The @@ -70,7 +70,7 @@ resulting DLL is now visible to Python. Here's a sample Python session:


      -



      +It was mentioned in passing in the previous section that +BOOST_PYTHON_FUNCTION_OVERLOADS and BOOST_PYTHON_FUNCTION_OVERLOADS +can also be used for overloaded functions and member functions with a +common sequence of initial arguments. Here is an example:

      +
      +     void foo()
      +     {
      +        /*...*/
      +     }
      +
      +     void foo(bool a)
      +     {
      +        /*...*/
      +     }
      +
      +     void foo(bool a, int b)
      +     {
      +        /*...*/
      +     }
      +
      +     void foo(bool a, int b, char c)
      +     {
      +        /*...*/
      +     }
      +
      +

      +Like in the previous section, we can generate thin wrappers for these +overloaded functions in one-shot:

      +
      +    BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3)
      +
      +

      +Then...

      +
      +    .def("foo", foo, foo_overloads());
      +
      +

      +Notice though that we have a situation now where we have a minimum of zero +(0) arguments and a maximum of 3 arguments.

      +

      Manual Wrapping

      +It is important to emphasize however that the overloaded functions must +have a common sequence of initial arguments. Otherwise, our scheme above +will not work. If this is not the case, we have to wrap our functions + +manually.

      +

      +Actually, we can mix and match manual wrapping of overloaded functions and +automatic wrapping through BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS and +its sister, BOOST_PYTHON_FUNCTION_OVERLOADS. Following up on our example +presented in the section +on overloading, since the +first overload has default arguments, we can use +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS to automatically wrap the first +three of the defs above and manually wrap just the last. Here's how +we'll do this:

      +
      +    BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)
      +
      +

      +Create a member function pointers as above for both X::f overloads:

      +
      +    bool    (X::*fx1)(int, double, char)    = &X::f;
      +    int     (X::*fx2)(int, int, int)        = &X::f;
      +
      +

      +Then...

      +
      +    .def("f", fx1, xf_overloads());
      +    .def("f", fx2)
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/call_policies.html b/doc/tutorial/doc/call_policies.html index 47871700..dc94ea5b 100644 --- a/doc/tutorial/doc/call_policies.html +++ b/doc/tutorial/doc/call_policies.html @@ -4,7 +4,7 @@ Call Policies - + @@ -21,7 +21,7 @@ - +

      @@ -156,7 +156,7 @@ here.

      - +
      diff --git a/doc/tutorial/doc/class_operators_special_functions.html b/doc/tutorial/doc/class_operators_special_functions.html index e22bd2ff..ce7aab66 100644 --- a/doc/tutorial/doc/class_operators_special_functions.html +++ b/doc/tutorial/doc/class_operators_special_functions.html @@ -3,7 +3,7 @@ Class Operators/Special Functions - + @@ -20,7 +20,7 @@ - +
      @@ -95,7 +95,7 @@ Well, the method str requires the operator<< to do its w - +
      diff --git a/doc/tutorial/doc/class_virtual_functions.html b/doc/tutorial/doc/class_virtual_functions.html index 46cb7837..37ce60ce 100644 --- a/doc/tutorial/doc/class_virtual_functions.html +++ b/doc/tutorial/doc/class_virtual_functions.html @@ -4,7 +4,7 @@ Class Virtual Functions - + @@ -21,7 +21,7 @@ - +

      @@ -112,118 +112,11 @@ In Python, let us try to instantiate our Base class:

      Why is it an error? Base is an abstract class. As such it is advisable to define the Python wrapper with no_init as we have done above. Doing so will disallow abstract base classes such as Base to be instantiated.

      -

      Deriving a Python class

      -Now, at last, we can even derive from our base class Base in Python. Before -we can do that, we have to set up our class_ wrapper as:

      -
      -    class_<Base, BaseWrap, boost::noncopyable>("Base")
      -        ;
      -
      -

      -Otherwise, we have to suppress the Base class' no_init by adding an -__init__() method to all our derived classes. no_init actually adds -an __init__ method that raises a Python RuntimeError exception.

      -
      -    >>> class Derived(Base):
      -    ...     def f(self):
      -    ...         return 42
      -    ...
      -
      -

      -Cool eh? A Python class deriving from a C++ class!

      -

      -Let's now make an instance of our Python class Derived:

      -
      -    >>> derived = Derived()
      -
      -

      -Calling derived.f():

      -
      -    >>> derived.f()
      -    42
      -
      -

      -Will yield the expected result. Finally, calling calling the free function -call_f with derived as argument:

      -
      -    >>> call_f(derived)
      -    42
      -
      -

      -Will also yield the expected result.

      -

      -Here's what's happening:

      -
      1. call_f(derived) is called in Python
      2. This corresponds to def("call_f", call_f);. Boost.Python dispatches this call.
      3. int call_f(Base& b) { return b.f(); } accepts the call.
      4. The overridden virtual function f of BaseWrap is called.
      5. call_method<int>(self, "f"); dispatches the call back to Python.
      6. def f(self): return 42 is finally called.

      -Rewind back to our Base class, if its member function f was not -declared as pure virtual:

      -
      -    struct Base
      -    {
      -        virtual int f() { return 0; }
      -    };
      -
      -

      -And instead is implemented to return 0, as shown above.

      -
      -    struct BaseWrap : Base
      -    {
      -        BaseWrap(PyObject* self_)
      -            : self(self_) {}
      -        int f() { return call_method<int>(self, "f"); }
      -        static int default_f(Base* b) { return b->Base::f(); } // <<=== added
      -        PyObject* self;
      -    };
      -
      -

      -then, our Boost.Python wrapper:

      -
      -    class_<Base, BaseWrap>("Base")
      -        .def("f", &BaseWrap::default_f)
      -        ;
      -
      -

      -Note that we are allowing Base objects to be instantiated this time, -unlike before where we specifically defined the class_<Base> with -no_init.

      -

      -In Python, the results would be as expected:

      -
      -    >>> base = Base()
      -    >>> class Derived(Base):
      -    ...     def f(self):
      -    ...         return 42
      -    ...
      -    >>> derived = Derived()
      -
      -

      -Calling base.f():

      -
      -    >>> base.f()
      -    0
      -
      -

      -Calling derived.f():

      -
      -    >>> derived.f()
      -    42
      -
      -

      -Calling call_f, passing in a base object:

      -
      -    >>> call_f(base)
      -    0
      -
      -

      -Calling call_f, passing in a derived object:

      -
      -    >>> call_f(derived)
      -    42
      -
      - +

      diff --git a/doc/tutorial/doc/default_arguments.html b/doc/tutorial/doc/default_arguments.html index 8eaf8476..d0c1f426 100644 --- a/doc/tutorial/doc/default_arguments.html +++ b/doc/tutorial/doc/default_arguments.html @@ -3,8 +3,8 @@ Default Arguments - - + + @@ -20,8 +20,8 @@
      - - + +

      @@ -44,8 +44,10 @@ to retrieve the default arguments:

      def("f", f); // defaults lost!

      -Because of this, when wrapping C++ code in earlier versions of -Boost.Python, we had to resort to writing thin wrappers:

      +Because of this, when wrapping C++ code, we had to resort to manual +wrapping as outlined in the +previous section, or +writing thin wrappers:

           // write "thin wrappers"
           int f1(int x) { f(x); }
      @@ -142,8 +144,8 @@ Notice the use of init<...> and optional<...> to s
       
      -    
      -    
      +    
      +    

      diff --git a/doc/tutorial/doc/deriving_a_python_class.html b/doc/tutorial/doc/deriving_a_python_class.html new file mode 100644 index 00000000..d5a8034e --- /dev/null +++ b/doc/tutorial/doc/deriving_a_python_class.html @@ -0,0 +1,82 @@ + + + +Deriving a Python Class + + + + + + + + + + +
      + + Deriving a Python Class +
      +
      + + + + + + +
      +

      +Continuing, now, at last, we can even derive from our base class Base in +Python. Before we can do that, we have to set up our class_ wrapper as:

      +
      +    class_<Base, BaseWrap, boost::noncopyable>("Base")
      +        ;
      +
      +

      +Otherwise, we have to suppress the Base class' no_init by adding an +__init__() method to all our derived classes. no_init actually adds +an __init__ method that raises a Python RuntimeError exception.

      +
      +    >>> class Derived(Base):
      +    ...     def f(self):
      +    ...         return 42
      +    ...
      +
      +

      +Cool eh? A Python class deriving from a C++ class!

      +

      +Let's now make an instance of our Python class Derived:

      +
      +    >>> derived = Derived()
      +
      +

      +Calling derived.f():

      +
      +    >>> derived.f()
      +    42
      +
      +

      +Will yield the expected result. Finally, calling calling the free function +call_f with derived as argument:

      +
      +    >>> call_f(derived)
      +    42
      +
      +

      +Will also yield the expected result.

      +

      +Here's what's happening:

      +
      1. call_f(derived) is called in Python
      2. This corresponds to def("call_f", call_f);. Boost.Python dispatches this call.
      3. int call_f(Base& b) { return b.f(); } accepts the call.
      4. The overridden virtual function f of BaseWrap is called.
      5. call_method<int>(self, "f"); dispatches the call back to Python.
      6. def f(self): return 42 is finally called.
      + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/object_interface.html b/doc/tutorial/doc/object_interface.html index 1fd3a04d..1988dcd7 100644 --- a/doc/tutorial/doc/object_interface.html +++ b/doc/tutorial/doc/object_interface.html @@ -3,7 +3,7 @@ Object Interface - + @@ -20,7 +20,7 @@ - +
      @@ -40,7 +40,7 @@ should minimize the learning curve significantly.

      - +
      diff --git a/doc/tutorial/doc/overloading.html b/doc/tutorial/doc/overloading.html index da0ad8ac..06baaa3a 100644 --- a/doc/tutorial/doc/overloading.html +++ b/doc/tutorial/doc/overloading.html @@ -3,8 +3,8 @@ Overloading - - + + @@ -20,59 +20,16 @@
      - - + +

      -It was mentioned in passing in the previous section that -BOOST_PYTHON_FUNCTION_OVERLOADS and BOOST_PYTHON_FUNCTION_OVERLOADS -can also be used for overloaded functions and member functions with a -common sequence of initial arguments. Here is an example:

      -
      -     void foo()
      -     {
      -        /*...*/
      -     }
      -
      -     void foo(bool a)
      -     {
      -        /*...*/
      -     }
      -
      -     void foo(bool a, int b)
      -     {
      -        /*...*/
      -     }
      -
      -     void foo(bool a, int b, char c)
      -     {
      -        /*...*/
      -     }
      -
      -

      -Like in the previous section, we can generate thin wrappers for these -overloaded functions in one-shot:

      -
      -    BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3)
      -
      -

      -Then...

      -
      -    .def("foo", foo, foo_overloads());
      -
      -

      -Notice though that we have a situation now where we have a minimum of zero -(0) arguments and a maximum of 3 arguments.

      -

      Manual Wrapping

      -It is important to emphasize however that the overloaded functions must -have a common sequence of initial arguments. Otherwise, our scheme above -will not work.

      -

      -The following illustrates an alternate scheme for manually wrapping an -overloaded member function instead of -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS. Obviously, the same technique -can be applied to wrapping overloaded non- member functions.

      +The following illustrates a scheme for manually wrapping an overloaded +member function or. Obviously, the same technique can be applied to +wrapping overloaded non- member functions. Take note that this scheme +applies to actual overloaded (member, non-member) functions as well as +(member, non-member) functions with default arguments.

      We have here our C++ classes:

      @@ -113,33 +70,11 @@ With these in hand, we can proceed to define and wrap this for Python:

      .def("f", fx3) .def("f", fx4)
      -

      -Actually, we can mix and match manual wrapping of overloaded functions and -automatic wrapping through BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS and -its sister, BOOST_PYTHON_FUNCTION_OVERLOADS. Since the first overload -has default arguments, we can use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS -to automatically wrap the first three of the defs above and manually -wrap just the last. Here's how we'll do this:

      -
      -    BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)
      -
      -

      -Create a member function pointers as above for both X::f overloads:

      -
      -    bool    (X::*fx1)(int, double, char)    = &X::f;
      -    int     (X::*fx2)(int, int, int)        = &X::f;
      -
      -

      -Then...

      -
      -    .def("f", fx1, xf_overloads());
      -    .def("f", fx2)
      -
      - - + +

      diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt index 3d4eb7ec..a071949a 100644 --- a/doc/tutorial/doc/quickstart.txt +++ b/doc/tutorial/doc/quickstart.txt @@ -527,10 +527,10 @@ Why is it an error? [^Base] is an abstract class. As such it is advisable to define the Python wrapper with [^no_init] as we have done above. Doing so will disallow abstract base classes such as [^Base] to be instantiated. -[h2 Deriving a Python class] +[page:1 Deriving a Python Class] -Now, at last, we can even derive from our base class Base in Python. Before -we can do that, we have to set up our class_ wrapper as: +Continuing, now, at last, we can even derive from our base class Base in +Python. Before we can do that, we have to set up our [^class_] wrapper as: class_("Base") ; @@ -572,30 +572,45 @@ Here's what's happening: # [^call_method(self, "f");] dispatches the call back to Python. # [^def f(self): return 42] is finally called. -Rewind back to our [^Base] class, if its member function [^f] was not -declared as pure virtual: +[page:1 Virtual Functions with Default Implementations] + +Recall that in the [@class_virtual_functions.html previous section], we +wrapped a class with a pure virtual function that we then implemented in +C++ or Python classes derived from it. Our base class: + + struct Base + { + virtual int f() = 0; + }; + +had a pure virtual function [^f]. If, however, its member function [^f] was +not declared as pure virtual: struct Base { virtual int f() { return 0; } }; -And instead is implemented to return [^0], as shown above. +and instead had a default implementation that returns [^0], as shown above, +we need to add a forwarding function that calls the [^Base] default virtual +function [^f] implementation: struct BaseWrap : Base { BaseWrap(PyObject* self_) : self(self_) {} int f() { return call_method(self, "f"); } - static int default_f(Base* b) { return b->Base::f(); } // <<=== added + int default_f() { return Base::f(); } // <<=== ***ADDED*** PyObject* self; }; -then, our Boost.Python wrapper: +Then, Boost.Python needs to keep track of 1) the dispatch function [^f] and +2) the forwarding function to its default implementation [^default_f]. +There's a special [^def] function for this purpose. Here's how it is +applied to our example above: class_("Base") - .def("f", &BaseWrap::default_f) - ; + .def("f", &Base::f, &BaseWrap::default_f) Note that we are allowing [^Base] objects to be instantiated this time, unlike before where we specifically defined the [^class_] with @@ -874,6 +889,51 @@ these can be found [@../../v2/reference.html#models_of_call_policies here]. "Explicit is better than implicit"[br] "In the face of ambiguity, refuse the temptation to guess"[br]] +[page:1 Overloading] + +The following illustrates a scheme for manually wrapping an overloaded +member function or. Obviously, the same technique can be applied to +wrapping overloaded non- member functions. Take note that this scheme +applies to actual overloaded (member, non-member) functions as well as +(member, non-member) functions with default arguments. + +We have here our C++ classes: + + struct X + { + bool f(int a, double b = 0, char c = 'x') + { + return true; + } + + int f(int a, int b, int c) + { + return a + b + c; + }; + }; + +Notice that class X has two overloaded functions with different signatures. +The types of the arguments, and the return are totally different, unlike +above where we have a common sequence of initial arguments. + +We shall start by introducing some member function pointer variables: + + bool (X::*fx1)(int) = &X::f; + bool (X::*fx2)(int, double) = &X::f; + bool (X::*fx3)(int, double, char)= &X::f; + int (X::*fx4)(int, int, int) = &X::f; + +The first three member function pointers take care of the first X::f +overload. The one with default arguments. The last member function pointer +takes care of the second X::f overload. + +With these in hand, we can proceed to define and wrap this for Python: + + .def("f", fx1) + .def("f", fx2) + .def("f", fx3) + .def("f", fx4) + [page:1 Default Arguments] Boost.Python wraps (member) function pointers. Unfortunately, C++ function @@ -892,8 +952,9 @@ to retrieve the default arguments: def("f", f); // defaults lost! -Because of this, when wrapping C++ code in earlier versions of -Boost.Python, we had to resort to writing thin wrappers: +Because of this, when wrapping C++ code, we had to resort to manual +wrapping as outlined in the [@overloading.html previous section], or +writing thin wrappers: // write "thin wrappers" int f1(int x) { f(x); } @@ -987,7 +1048,7 @@ You can easily add this constructor to Boost.Python in one shot: Notice the use of [^init<...>] and [^optional<...>] to signify the default (optional arguments). -[page:1 Overloading] +[page:1 Auto-Overloading] It was mentioned in passing in the previous section that [^BOOST_PYTHON_FUNCTION_OVERLOADS] and [^BOOST_PYTHON_FUNCTION_OVERLOADS] @@ -1030,56 +1091,17 @@ Notice though that we have a situation now where we have a minimum of zero It is important to emphasize however that [*the overloaded functions must have a common sequence of initial arguments]. Otherwise, our scheme above -will not work. - -The following illustrates an alternate scheme for manually wrapping an -overloaded member function instead of -[^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS]. Obviously, the same technique -can be applied to wrapping overloaded non- member functions. - -We have here our C++ classes: - - struct X - { - bool f(int a, double b = 0, char c = 'x') - { - return true; - } - - int f(int a, int b, int c) - { - return a + b + c; - }; - }; - -Notice that class X has two overloaded functions with different signatures. -The types of the arguments, and the return are totally different, unlike -above where we have a common sequence of initial arguments. - -We shall start by introducing some member function pointer variables: - - bool (X::*fx1)(int) = &X::f; - bool (X::*fx2)(int, double) = &X::f; - bool (X::*fx3)(int, double, char)= &X::f; - int (X::*fx4)(int, int, int) = &X::f; - -The first three member function pointers take care of the first X::f -overload. The one with default arguments. The last member function pointer -takes care of the second X::f overload. - -With these in hand, we can proceed to define and wrap this for Python: - - .def("f", fx1) - .def("f", fx2) - .def("f", fx3) - .def("f", fx4) +will not work. If this is not the case, we have to wrap our functions +[@overloading.html manually]. Actually, we can mix and match manual wrapping of overloaded functions and automatic wrapping through [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] and -its sister, [^BOOST_PYTHON_FUNCTION_OVERLOADS]. Since the first overload -has default arguments, we can use [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] -to automatically wrap the first three of the [^def]s above and manually -wrap just the last. Here's how we'll do this: +its sister, [^BOOST_PYTHON_FUNCTION_OVERLOADS]. Following up on our example +presented in the section [@overloading.html on overloading], since the +first overload has default arguments, we can use +[^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] to automatically wrap the first +three of the [^def]s above and manually wrap just the last. Here's how +we'll do this: BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4) diff --git a/doc/tutorial/doc/virtual_functions_with_default_implementations.html b/doc/tutorial/doc/virtual_functions_with_default_implementations.html new file mode 100644 index 00000000..f7b15115 --- /dev/null +++ b/doc/tutorial/doc/virtual_functions_with_default_implementations.html @@ -0,0 +1,122 @@ + + + +Virtual Functions with Default Implementations + + + + + + + + + + +
      + + Virtual Functions with Default Implementations +
      +
      + + + + + + +
      +

      +Recall that in the +previous section, we +wrapped a class with a pure virtual function that we then implemented in +C++ or Python classes derived from it. Our base class:

      +
      +    struct Base
      +    {
      +        virtual int f() = 0;
      +    };
      +
      +

      +had a pure virtual function f. If, however, its member function f was +not declared as pure virtual:

      +
      +    struct Base
      +    {
      +        virtual int f() { return 0; }
      +    };
      +
      +

      +and instead had a default implementation that returns 0, as shown above, +we need to add a forwarding function that calls the Base default virtual +function f implementation:

      +
      +    struct BaseWrap : Base
      +    {
      +        BaseWrap(PyObject* self_)
      +            : self(self_) {}
      +        int f() { return call_method<int>(self, "f"); }
      +        int default_f() { return Base::f(); } // <<=== ***ADDED***
      +        PyObject* self;
      +    };
      +
      +

      +Then, Boost.Python needs to keep track of 1) the dispatch function f and +2) the forwarding function to its default implementation default_f. +There's a special def function for this purpose. Here's how it is +applied to our example above:

      +
      +    class_<Base, BaseWrap>("Base")
      +        .def("f", &Base::f, &BaseWrap::default_f)
      +
      +

      +Note that we are allowing Base objects to be instantiated this time, +unlike before where we specifically defined the class_<Base> with +no_init.

      +

      +In Python, the results would be as expected:

      +
      +    >>> base = Base()
      +    >>> class Derived(Base):
      +    ...     def f(self):
      +    ...         return 42
      +    ...
      +    >>> derived = Derived()
      +
      +

      +Calling base.f():

      +
      +    >>> base.f()
      +    0
      +
      +

      +Calling derived.f():

      +
      +    >>> derived.f()
      +    42
      +
      +

      +Calling call_f, passing in a base object:

      +
      +    >>> call_f(base)
      +    0
      +
      +

      +Calling call_f, passing in a derived object:

      +
      +    >>> call_f(derived)
      +    42
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/index.html b/doc/tutorial/index.html index 108d25f6..9439b300 100644 --- a/doc/tutorial/index.html +++ b/doc/tutorial/index.html @@ -60,6 +60,16 @@ Class Virtual Functions + + + Deriving a Python Class + + + + + Virtual Functions with Default Implementations + + Class Operators/Special Functions @@ -75,6 +85,11 @@ Call Policies + + + Overloading + + Default Arguments @@ -82,7 +97,7 @@ - Overloading + Auto-Overloading From 600602f9dc65718081dfff5b8e71cd510ae86e5b Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Sun, 23 Feb 2003 03:53:36 +0000 Subject: [PATCH 1010/1042] Tutorial updates [SVN r17598] --- doc/tutorial/doc/auto_overloading.html | 8 ++-- doc/tutorial/doc/deriving_a_python_class.html | 5 ++- doc/tutorial/doc/overloading.html | 31 ++++++------- doc/tutorial/doc/quickstart.txt | 44 ++++++++++--------- 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/doc/tutorial/doc/auto_overloading.html b/doc/tutorial/doc/auto_overloading.html index 7f1208d4..d478eeae 100644 --- a/doc/tutorial/doc/auto_overloading.html +++ b/doc/tutorial/doc/auto_overloading.html @@ -76,10 +76,10 @@ automatic wrapping through BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS and its sister, BOOST_PYTHON_FUNCTION_OVERLOADS. Following up on our example presented in the section on overloading, since the -first overload has default arguments, we can use -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS to automatically wrap the first -three of the defs above and manually wrap just the last. Here's how -we'll do this:

      +first 4 overload functins have a common sequence of initial arguments, we +can use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS to automatically wrap the +first three of the defs and manually wrap just the last. Here's +how we'll do this:

           BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)
       
      diff --git a/doc/tutorial/doc/deriving_a_python_class.html b/doc/tutorial/doc/deriving_a_python_class.html index d5a8034e..5c268371 100644 --- a/doc/tutorial/doc/deriving_a_python_class.html +++ b/doc/tutorial/doc/deriving_a_python_class.html @@ -25,8 +25,9 @@

      -Continuing, now, at last, we can even derive from our base class Base in -Python. Before we can do that, we have to set up our class_ wrapper as:

      +Continuing, we can derive from our base class Base in Python and override +the virtual function in Python. Before we can do that, we have to set up +our class_ wrapper as:

           class_<Base, BaseWrap, boost::noncopyable>("Base")
               ;
      diff --git a/doc/tutorial/doc/overloading.html b/doc/tutorial/doc/overloading.html
      index 06baaa3a..f93edcac 100644
      --- a/doc/tutorial/doc/overloading.html
      +++ b/doc/tutorial/doc/overloading.html
      @@ -26,16 +26,24 @@
       
       

      The following illustrates a scheme for manually wrapping an overloaded -member function or. Obviously, the same technique can be applied to -wrapping overloaded non- member functions. Take note that this scheme -applies to actual overloaded (member, non-member) functions as well as -(member, non-member) functions with default arguments.

      +member functions. Of course, the same technique can be applied to wrapping +overloaded non-member functions.

      -We have here our C++ classes:

      +We have here our C++ class:

           struct X
           {
      -        bool f(int a, double b = 0, char c = 'x')
      +        bool f(int a)
      +        {
      +            return true;
      +        }
      +
      +        bool f(int a, double b)
      +        {
      +            return true;
      +        }
      +
      +        bool f(int a, double b, char c)
               {
                   return true;
               }
      @@ -47,11 +55,8 @@ We have here our C++ classes:

      };

      -Notice that class X has two overloaded functions with different signatures. -The types of the arguments, and the return are totally different, unlike -above where we have a common sequence of initial arguments.

      -

      -We shall start by introducing some member function pointer variables:

      +Class X has 4 overloaded functions. We shall start by introducing some +member function pointer variables:

           bool    (X::*fx1)(int)              = &X::f;
           bool    (X::*fx2)(int, double)      = &X::f;
      @@ -59,10 +64,6 @@ We shall start by introducing some member function pointer variables:

      int (X::*fx4)(int, int, int) = &X::f;

      -The first three member function pointers take care of the first X::f -overload. The one with default arguments. The last member function pointer -takes care of the second X::f overload.

      -

      With these in hand, we can proceed to define and wrap this for Python:

           .def("f", fx1)
      diff --git a/doc/tutorial/doc/quickstart.txt b/doc/tutorial/doc/quickstart.txt
      index a071949a..7efc63bf 100644
      --- a/doc/tutorial/doc/quickstart.txt
      +++ b/doc/tutorial/doc/quickstart.txt
      @@ -529,8 +529,9 @@ so will disallow abstract base classes such as [^Base] to be instantiated.
       
       [page:1 Deriving a Python Class]
       
      -Continuing, now, at last, we can even derive from our base class Base in
      -Python. Before we can do that, we have to set up our [^class_] wrapper as:
      +Continuing, we can derive from our base class Base in Python and override
      +the virtual function in Python. Before we can do that, we have to set up
      +our [^class_] wrapper as:
       
           class_("Base")
               ;
      @@ -892,16 +893,24 @@ these can be found [@../../v2/reference.html#models_of_call_policies here].
       [page:1 Overloading]
       
       The following illustrates a scheme for manually wrapping an overloaded
      -member function or. Obviously, the same technique can be applied to
      -wrapping overloaded non- member functions. Take note that this scheme
      -applies to actual overloaded (member, non-member) functions as well as
      -(member, non-member) functions with default arguments.
      +member functions. Of course, the same technique can be applied to wrapping
      +overloaded non-member functions.
       
      -We have here our C++ classes:
      +We have here our C++ class:
       
           struct X
           {
      -        bool f(int a, double b = 0, char c = 'x')
      +        bool f(int a)
      +        {
      +            return true;
      +        }
      +
      +        bool f(int a, double b)
      +        {
      +            return true;
      +        }
      +
      +        bool f(int a, double b, char c)
               {
                   return true;
               }
      @@ -912,21 +921,14 @@ We have here our C++ classes:
               };
           };
       
      -Notice that class X has two overloaded functions with different signatures.
      -The types of the arguments, and the return are totally different, unlike
      -above where we have a common sequence of initial arguments.
      -
      -We shall start by introducing some member function pointer variables:
      +Class X has 4 overloaded functions. We shall start by introducing some
      +member function pointer variables:
       
           bool    (X::*fx1)(int)              = &X::f;
           bool    (X::*fx2)(int, double)      = &X::f;
           bool    (X::*fx3)(int, double, char)= &X::f;
           int     (X::*fx4)(int, int, int)    = &X::f;
       
      -The first three member function pointers take care of the first X::f
      -overload. The one with default arguments. The last member function pointer
      -takes care of the second X::f overload.
      -
       With these in hand, we can proceed to define and wrap this for Python:
       
           .def("f", fx1)
      @@ -1098,10 +1100,10 @@ Actually, we can mix and match manual wrapping of overloaded functions and
       automatic wrapping through [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] and
       its sister, [^BOOST_PYTHON_FUNCTION_OVERLOADS]. Following up on our example
       presented in the section [@overloading.html on overloading], since the
      -first overload has default arguments, we can use
      -[^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] to automatically wrap the first
      -three of the [^def]s above and manually wrap just the last. Here's how
      -we'll do this:
      +first 4 overload functins have a common sequence of initial arguments, we
      +can use [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] to automatically wrap the
      +first three of the [^def]s and manually wrap just the last. Here's
      +how we'll do this:
       
           BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)
       
      
      From 5cdebaf896f71966f3736fe099b8b772817dd3ba Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Tue, 25 Feb 2003 00:56:55 +0000
      Subject: [PATCH 1011/1042] gcc-2.95 workaround
      
      [SVN r17620]
      ---
       include/boost/python/init.hpp | 4 ++--
       1 file changed, 2 insertions(+), 2 deletions(-)
      
      diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp
      index f9de81c5..76aa9b33 100644
      --- a/include/boost/python/init.hpp
      +++ b/include/boost/python/init.hpp
      @@ -315,7 +315,7 @@ namespace detail
                 , mpl::push_front<>
                 >::type args;
       
      -      typedef typename ClassT::holder_selector holder_selector_t;
      +      typedef typename ClassT::holder_selector::type selector_t;
             typedef typename ClassT::held_type held_type_t;
       
             cl.def(
      @@ -327,7 +327,7 @@ namespace detail
                       // Using runtime type selection works around a CWPro7 bug.
                       , holder_selector_t::execute((held_type_t*)0).get()
       #    else
      -                , holder_selector_t::type::get()
      +                , selector_t::get()
       #    endif 
                       )
                   , doc
      
      From 1c346b253133d06afa0be9d46e4ce82caa91207a Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Tue, 25 Feb 2003 00:57:33 +0000
      Subject: [PATCH 1012/1042] fix metafunctions for MPL
      
      [SVN r17621]
      ---
       include/boost/python/ptr.hpp | 10 +++++-----
       1 file changed, 5 insertions(+), 5 deletions(-)
      
      diff --git a/include/boost/python/ptr.hpp b/include/boost/python/ptr.hpp
      index 5f8ad2d0..3fdef0f4 100644
      --- a/include/boost/python/ptr.hpp
      +++ b/include/boost/python/ptr.hpp
      @@ -15,6 +15,7 @@
       # endif
       
       # include 
      +# include 
       
       namespace boost { namespace python {
       
      @@ -39,16 +40,14 @@ inline pointer_wrapper ptr(T t)
       # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
       template
       class is_pointer_wrapper
      +    : public mpl::false_c
       {
      - public:
      -    BOOST_STATIC_CONSTANT(bool, value = false); 
       };
       
       template
       class is_pointer_wrapper >
      +    : public mpl::true_c
       {
      - public:
      -    BOOST_STATIC_CONSTANT(bool, value = true);
       };
       
       template
      @@ -109,8 +108,9 @@ class is_pointer_wrapper
        public:
           BOOST_STATIC_CONSTANT(
               bool, value = (
      -            sizeof(detail::is_pointer_wrapper_test(boost::type()))
      +        sizeof(detail::is_pointer_wrapper_test(boost::type()))
                   == sizeof(detail::yes_pointer_wrapper_t)));
      +    typedef mpl::bool_c type;
       };
       
       template 
      
      From 479d8fc0f68fad006001f74b8eac5d186cb12a61 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Tue, 25 Feb 2003 01:03:40 +0000
      Subject: [PATCH 1013/1042] shared_ptr deleter introspection support
       miscellaneous cleanups and MPL idiom-izing
      
      [SVN r17622]
      ---
       .../boost/python/converter/arg_to_python.hpp  | 129 ++++++++++--------
       .../boost/python/converter/from_python.hpp    |   2 +-
       .../boost/python/converter/object_manager.hpp |  23 ++--
       .../python/converter/shared_ptr_deleter.hpp   |   8 +-
       .../python/detail/copy_ctor_mutates_rhs.hpp   |  48 +------
       include/boost/python/detail/mpl_lambda.hpp    |  53 +------
       .../boost/python/detail/string_literal.hpp    |  14 +-
       include/boost/python/to_python_value.hpp      |  55 ++++++--
       src/converter/builtin_converters.cpp          |  27 +++-
       test/copy_ctor_mutates_rhs.cpp                |   1 +
       test/shared_ptr.cpp                           |   2 +
       test/shared_ptr.py                            |   1 +
       12 files changed, 171 insertions(+), 192 deletions(-)
      
      diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp
      index 192639ed..4d654eb3 100755
      --- a/include/boost/python/converter/arg_to_python.hpp
      +++ b/include/boost/python/converter/arg_to_python.hpp
      @@ -7,21 +7,31 @@
       # define ARG_TO_PYTHON_DWA200265_HPP
       
       # include 
      +# include 
      +# include 
      +
       # include 
       # include 
       # include 
      -# include 
      -# include 
      -# include 
      -# include 
      +# include 
      +// Bring in specializations
      +# include 
      +
      +# include 
      +
      +# include 
      +
       # include 
       # include 
       # include 
      -# include 
      -// Bring in specializations
      -# include 
      -# include 
      -# include 
      +# include 
      +
      +# include 
      +# include 
      +# include 
      +
      +
      +# include 
       
       namespace boost { namespace python { namespace converter { 
       
      @@ -43,6 +53,14 @@ namespace detail
             static PyObject* get_object(T& x);
         };
       
      +  template 
      +  struct shared_ptr_arg_to_python : handle<>
      +  {
      +      shared_ptr_arg_to_python(T const& x);
      +   private:
      +      static PyObject* get_object(T& x);
      +  };
      +
         template 
         struct value_arg_to_python : arg_to_python_base
         {
      @@ -84,54 +102,51 @@ namespace detail
         template 
         struct select_arg_to_python
         {
      -      // Special handling for char const[N]; interpret them as char
      -      // const* for the sake of conversion
      -      BOOST_STATIC_CONSTANT(
      -          bool, is_string = python::detail::is_string_literal::value);
      -      
      -      BOOST_STATIC_CONSTANT(
      -          bool, function = is_function::value | python::detail::is_pointer_to_function::value | is_member_function_pointer::value);
      -      
      -      BOOST_STATIC_CONSTANT(
      -          bool, manager = is_object_manager::value);
      -      
      -      BOOST_STATIC_CONSTANT(
      -          bool, ptr = is_pointer::value);
      -      
      -      BOOST_STATIC_CONSTANT(
      -          bool, ref_wrapper = is_reference_wrapper::value);
      -
      -      BOOST_STATIC_CONSTANT(
      -          bool, ptr_wrapper = is_pointer_wrapper::value);
      -
             typedef typename unwrap_reference::type unwrapped_referent;
             typedef typename unwrap_pointer::type unwrapped_ptr;
       
      -      typedef typename mpl::if_c<
      -          is_string
      -          , arg_to_python
      -          , typename mpl::if_c<
      -              function
      -              , function_arg_to_python
      -              , typename mpl::if_c<
      -                  manager
      -                  , object_manager_arg_to_python
      -                  , typename mpl::if_c<
      -                      ptr
      -                      , pointer_deep_arg_to_python
      -                      , typename mpl::if_c<
      -                          ptr_wrapper
      -                          , pointer_shallow_arg_to_python
      -                          , typename mpl::if_c<
      -                              ref_wrapper
      -                              , reference_arg_to_python
      -                              , value_arg_to_python
      -                            >::type
      -                        >::type
      -                    >::type
      -                >::type
      -            >::type
      -        >::type
      +      typedef typename mpl::if_<
      +          // Special handling for char const[N]; interpret them as char
      +          // const* for the sake of conversion
      +          python::detail::is_string_literal
      +        , arg_to_python
      +
      +        , typename mpl::if_<
      +              python::detail::value_is_shared_ptr
      +            , shared_ptr_arg_to_python
      +      
      +            , typename mpl::if_<
      +                mpl::logical_or<
      +                    is_function
      +                  , python::detail::is_pointer_to_function
      +                  , is_member_function_pointer
      +                >
      +                , function_arg_to_python
      +
      +                , typename mpl::if_<
      +                      is_object_manager
      +                    , object_manager_arg_to_python
      +
      +                    , typename mpl::if_<
      +                          is_pointer
      +                        , pointer_deep_arg_to_python
      +
      +                        , typename mpl::if_<
      +                              is_pointer_wrapper
      +                            , pointer_shallow_arg_to_python
      +
      +                            , typename mpl::if_<
      +                                  is_reference_wrapper
      +                                , reference_arg_to_python
      +                                , value_arg_to_python
      +                              >::type
      +                          >::type
      +                      >::type
      +                  >::type
      +              >::type
      +          >::type
      +      >::type
      +      
             type;
         };
       }
      @@ -216,6 +231,12 @@ namespace detail
         {
         }
       
      +  template 
      +  inline shared_ptr_arg_to_python::shared_ptr_arg_to_python(T const& x)
      +      : handle<>(shared_ptr_to_python(x))
      +  {
      +  }
      +
         template 
         inline pointer_shallow_arg_to_python::pointer_shallow_arg_to_python(Ptr x)
             : handle<>(pointer_shallow_arg_to_python::get_object(x))
      diff --git a/include/boost/python/converter/from_python.hpp b/include/boost/python/converter/from_python.hpp
      index 0822e563..32a7431e 100644
      --- a/include/boost/python/converter/from_python.hpp
      +++ b/include/boost/python/converter/from_python.hpp
      @@ -13,7 +13,7 @@
       namespace boost { namespace python { namespace converter { 
       
       struct registration;
      -struct rvalue_from_python_chain;
      +
       
       BOOST_PYTHON_DECL void* get_lvalue_from_python(
           PyObject* source, registration const&);
      diff --git a/include/boost/python/converter/object_manager.hpp b/include/boost/python/converter/object_manager.hpp
      index 974c149b..f93dd3fd 100755
      --- a/include/boost/python/converter/object_manager.hpp
      +++ b/include/boost/python/converter/object_manager.hpp
      @@ -12,6 +12,7 @@
       # include 
       # include 
       # include 
      +# include 
       
       // Facilities for dealing with types which always manage Python
       // objects. Some examples are object, list, str, et. al. Different
      @@ -117,16 +118,15 @@ struct object_manager_traits
       
       template 
       struct is_object_manager
      +    : mpl::bool_c::is_specialized>
       {
      -    BOOST_STATIC_CONSTANT(
      -        bool, value = object_manager_traits::is_specialized);
       };
       
       # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
       template 
       struct is_reference_to_object_manager
      +    : mpl::false_c
       {
      -    BOOST_STATIC_CONSTANT(bool, value = false);
       };
       
       template 
      @@ -164,8 +164,8 @@ namespace detail
         template 
         struct is_object_manager_help
         {
      -      typedef typename mpl::if_c<
      -          is_object_manager::value
      +      typedef typename mpl::if_<
      +          is_object_manager
                 , yes_reference_to_object_manager
                 , no_reference_to_object_manager
                 >::type type;
      @@ -197,8 +197,8 @@ namespace detail
         
         template 
         struct is_reference_to_object_manager_nonref
      +      : mpl::false_c
         {
      -      BOOST_STATIC_CONSTANT(bool, value = false);
         };
       
         template 
      @@ -211,19 +211,18 @@ namespace detail
                   == sizeof(detail::yes_reference_to_object_manager)
                 )
               );
      +      typedef mpl::bool_c type;
         };
       }
       
       template 
       struct is_reference_to_object_manager
      -{
      -    typedef typename mpl::if_c<
      -        is_reference::value
      +    : mpl::if_<
      +        is_reference
               , detail::is_reference_to_object_manager_ref
               , detail::is_reference_to_object_manager_nonref
      -    > chooser;
      -
      -    BOOST_STATIC_CONSTANT(bool, value = chooser::type::value);
      +    >::type
      +{
       };
       # endif 
       
      diff --git a/include/boost/python/converter/shared_ptr_deleter.hpp b/include/boost/python/converter/shared_ptr_deleter.hpp
      index eb02e18a..f2ebfc40 100644
      --- a/include/boost/python/converter/shared_ptr_deleter.hpp
      +++ b/include/boost/python/converter/shared_ptr_deleter.hpp
      @@ -8,12 +8,12 @@
       
       namespace boost { namespace python { namespace converter { 
       
      -struct shared_ptr_deleter
      +struct BOOST_PYTHON_DECL shared_ptr_deleter
       {
      -    shared_ptr_deleter(handle<> owner)
      -        : owner(owner) {}
      +    shared_ptr_deleter(handle<> owner);
      +    ~shared_ptr_deleter();
       
      -    void operator()(void const*) { owner.reset(); }
      +    void operator()(void const*);
               
           handle<> owner;
       };
      diff --git a/include/boost/python/detail/copy_ctor_mutates_rhs.hpp b/include/boost/python/detail/copy_ctor_mutates_rhs.hpp
      index 57c3d403..434df76c 100755
      --- a/include/boost/python/detail/copy_ctor_mutates_rhs.hpp
      +++ b/include/boost/python/detail/copy_ctor_mutates_rhs.hpp
      @@ -3,56 +3,14 @@
       // copyright notice appears in all copies. This software is provided
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
      -#include 
      -#ifndef BOOST_NO_AUTO_PTR
      -# include 
      -#endif 
      -
       #ifndef COPY_CTOR_MUTATES_RHS_DWA2003219_HPP
       # define COPY_CTOR_MUTATES_RHS_DWA2003219_HPP
       
      +#include 
      +#include 
      +
       namespace boost { namespace python { namespace detail { 
       
      -# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_AUTO_PTR)
      -
      -template 
      -struct is_auto_ptr
      -{
      -    typedef char yes;
      -    typedef char (&no)[2];
      -
      -    static
      -    T& f();
      -
      -    template 
      -    static yes test(std::auto_ptr&, int);
      -
      -    template 
      -    static no test(U&, ...);
      -    
      -    BOOST_STATIC_CONSTANT(
      -        bool, value = sizeof(test(f(), 0)) == sizeof(yes));
      -
      -    typedef mpl::bool_c type;
      -                              
      -};
      -
      -# else
      -
      -template 
      -struct is_auto_ptr : mpl::false_c
      -{
      -};
      -
      -#  if !defined(BOOST_NO_AUTO_PTR)
      -template 
      -struct is_auto_ptr > : mpl::true_c
      -{
      -};
      -
      -#  endif
      -# endif
      -
       template 
       struct copy_ctor_mutates_rhs
           : is_auto_ptr
      diff --git a/include/boost/python/detail/mpl_lambda.hpp b/include/boost/python/detail/mpl_lambda.hpp
      index edbea72a..953bca63 100644
      --- a/include/boost/python/detail/mpl_lambda.hpp
      +++ b/include/boost/python/detail/mpl_lambda.hpp
      @@ -6,57 +6,8 @@
       #ifndef MPL_LAMBDA_DWA2002122_HPP
       # define MPL_LAMBDA_DWA2002122_HPP
       
      +// this header should go away soon
       # include 
      -
      -# if 0 // defined(BOOST_MSVC) && BOOST_MSVC <= 1300
      -   // This approach fails, unfortunately
      -
      -#  include 
      -#  include 
      -
      -#   define BOOST_PYTHON_LAMBDA_SUPPORT_FORMAL_ARG(R,class_,i,param)     \
      -    BOOST_PP_COMMA_IF(i) class_ param                                   \
      -    /**/
      -
      -#   define BOOST_PYTHON_LAMBDA_SUPPORT_ACTUAL_ARG(R,_,i,param)          \
      -    BOOST_PP_COMMA_IF(i) param                                          \
      -    /**/
      -
      -#   define BOOST_PYTHON_MPL_LAMBDA_SUPPORT(i,name,params)               \
      -            struct rebind;                                              \
      -        };                                                              \
      -    template <                                                          \
      -        BOOST_PP_LIST_FOR_EACH_I_R(                                     \
      -              1                                                         \
      -            , BOOST_PYTHON_LAMBDA_SUPPORT_FORMAL_ARG                    \
      -            , class                                                     \
      -            , BOOST_PP_TUPLE_TO_LIST(i,params)                          \
      -            )                                                           \
      -        >                                                               \
      -    struct name <                                                       \
      -        BOOST_PP_LIST_FOR_EACH_I_R(                                     \
      -              1                                                         \
      -            , BOOST_PYTHON_LAMBDA_SUPPORT_ACTUAL_ARG                    \
      -            , class                                                     \
      -            , BOOST_PP_TUPLE_TO_LIST(i,params)                          \
      -            )                                                           \
      -    >::rebind                                                           \
      -    {                                                                   \
      -        BOOST_STATIC_CONSTANT(int, arity = i);                          \
      -        BOOST_PP_LIST_FOR_EACH_I_R(                                     \
      -              1                                                         \
      -            , BOOST_MPL_AUX_LAMBDA_SUPPORT_ARG_TYPEDEF_FUNC             \
      -            , typedef                                                   \
      -            , BOOST_PP_TUPLE_TO_LIST(i,params)                          \
      -            )                                                           \
      -                                                                        \
      -        template< BOOST_MPL_PP_PARAMS(i,typename U) > struct apply      \
      -                : name< BOOST_MPL_PP_PARAMS(i,U) >                      \
      -        {                                                               \
      -        };                                                              \
      -    /**/
      -#  else
      -#   define BOOST_PYTHON_MPL_LAMBDA_SUPPORT BOOST_MPL_AUX_LAMBDA_SUPPORT
      -#  endif 
      +# define BOOST_PYTHON_MPL_LAMBDA_SUPPORT BOOST_MPL_AUX_LAMBDA_SUPPORT
       
       #endif // MPL_LAMBDA_DWA2002122_HPP
      diff --git a/include/boost/python/detail/string_literal.hpp b/include/boost/python/detail/string_literal.hpp
      index 3b3c4bd9..0236a14f 100644
      --- a/include/boost/python/detail/string_literal.hpp
      +++ b/include/boost/python/detail/string_literal.hpp
      @@ -10,21 +10,20 @@
       # include 
       # include 
       # include 
      +# include 
       
       namespace boost { namespace python { namespace detail { 
       
       # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
       template 
      -struct is_string_literal
      +struct is_string_literal : mpl::false_c
       {
      -    BOOST_STATIC_CONSTANT(bool, value = false);
       };
       
       #  if !defined(__MWERKS__) || __MWERKS__ > 0x2407
       template 
      -struct is_string_literal
      +struct is_string_literal : mpl::true_c
       {
      -    BOOST_STATIC_CONSTANT(bool, value = true);
       };
       
       #   if (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031) \
      @@ -32,9 +31,8 @@ struct is_string_literal
       // This compiler mistakenly gets the type of string literals as char*
       // instead of char[NN].
       template <>
      -struct is_string_literal
      +struct is_string_literal : mpl::true_c
       {
      -    BOOST_STATIC_CONSTANT(bool, value = true);
       };
       #   endif
       
      @@ -65,6 +63,7 @@ struct string_literal_helper
               
               BOOST_STATIC_CONSTANT(
                   bool, value = sizeof(self::check(x)) == sizeof(yes_string_literal));
      +        typedef mpl::bool_c type;
           };
       };
       
      @@ -72,9 +71,8 @@ template <>
       struct string_literal_helper
       {
           template 
      -    struct apply
      +    struct apply : mpl::false_c
           {
      -        BOOST_STATIC_CONSTANT(bool, value = false);
           };
       };
       
      diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp
      index 17f6b174..ee49849d 100644
      --- a/include/boost/python/to_python_value.hpp
      +++ b/include/boost/python/to_python_value.hpp
      @@ -6,15 +6,22 @@
       #ifndef TO_PYTHON_VALUE_DWA200221_HPP
       # define TO_PYTHON_VALUE_DWA200221_HPP
       
      -# include 
      +# include 
      +# include 
      +
       # include 
       # include 
       # include 
       # include 
      +# include 
      +# include 
      +
      +# include 
      +
      +# include 
      +
       # include 
      -# include 
      -# include 
      -# include 
      +# include 
       
       namespace boost { namespace python { 
       
      @@ -50,18 +57,36 @@ namespace detail
             // but it will have to serve for now.
             BOOST_STATIC_CONSTANT(bool, uses_registry = true);
         };
      +
      +  template 
      +  struct shared_ptr_to_python_value
      +  {
      +      typedef typename add_reference<
      +          typename add_const::type
      +      >::type argument_type;
      +    
      +      PyObject* operator()(argument_type) const;
      +
      +      // This information helps make_getter() decide whether to try to
      +      // return an internal reference or not. I don't like it much,
      +      // but it will have to serve for now.
      +      BOOST_STATIC_CONSTANT(bool, uses_registry = false);
      +  };
       }
       
       template 
       struct to_python_value
      -    : mpl::if_c<
      -          boost::type_traits::ice_or<
      -              converter::is_object_manager::value
      -            , converter::is_reference_to_object_manager::value
      -            >::value
      -
      -        , detail::object_manager_to_python_value
      -        , detail::registry_to_python_value
      +    : mpl::if_<
      +          detail::value_is_shared_ptr
      +        , detail::shared_ptr_to_python_value
      +        , typename mpl::if_<
      +              mpl::logical_or<
      +                  converter::is_object_manager
      +                , converter::is_reference_to_object_manager
      +              >
      +            , detail::object_manager_to_python_value
      +            , detail::registry_to_python_value
      +          >::type
             >::type
       {
       };
      @@ -85,6 +110,12 @@ namespace detail
                     get_managed_object(x, tag))
                 );
         }
      +
      +  template 
      +  inline PyObject* shared_ptr_to_python_value::operator()(argument_type x) const
      +  {
      +      return converter::shared_ptr_to_python(x);
      +  }
       }
       
       }} // namespace boost::python
      diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp
      index 5c08c945..af6fada9 100644
      --- a/src/converter/builtin_converters.cpp
      +++ b/src/converter/builtin_converters.cpp
      @@ -4,20 +4,37 @@
       // "as is" without express or implied warranty, and with no claim as
       // to its suitability for any purpose.
       
      -#include 
      -#include 
      -#include 
      -#include 
      -#include 
       #include 
       #include 
       #include 
      +#include 
      +
      +#include 
      +#include 
      +
      +#include 
      +#include 
      +#include 
      +#include 
      +#include 
      +
       #include 
       #include 
       #include 
       
       namespace boost { namespace python { namespace converter {
       
      +shared_ptr_deleter::shared_ptr_deleter(handle<> owner)
      +    : owner(owner)
      +{}
      +
      +shared_ptr_deleter::~shared_ptr_deleter() {}
      +
      +void shared_ptr_deleter::operator()(void const*)
      +{
      +    owner.reset();
      +}
      +
       namespace
       {
         // An lvalue conversion function which extracts a char const* from a
      diff --git a/test/copy_ctor_mutates_rhs.cpp b/test/copy_ctor_mutates_rhs.cpp
      index 473b7a66..7244ab0e 100755
      --- a/test/copy_ctor_mutates_rhs.cpp
      +++ b/test/copy_ctor_mutates_rhs.cpp
      @@ -20,4 +20,5 @@ int main()
           BOOST_STATIC_ASSERT(copy_ctor_mutates_rhs >::value);
           BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs::value);
           BOOST_STATIC_ASSERT(!copy_ctor_mutates_rhs::value);
      +    return 0;
       }
      diff --git a/test/shared_ptr.cpp b/test/shared_ptr.cpp
      index 5f1b36ce..39da8652 100644
      --- a/test/shared_ptr.cpp
      +++ b/test/shared_ptr.cpp
      @@ -93,6 +93,7 @@ shared_ptr factory(int n)
       }
       
       static int stored_v() { return functions::get()->v(); }
      +static shared_ptr stored_z() { return functions::get(); }
       
       BOOST_PYTHON_MODULE(shared_ptr_ext)
       {
      @@ -128,6 +129,7 @@ BOOST_PYTHON_MODULE(shared_ptr_ext)
           def("z_count", &Z::count);
           def("z_release", &functions::release_store);
           def("z_look_store", &functions::look_store);
      +    def("stored_z", &stored_z);
           def("stored_v", &stored_v);
       }
       
      diff --git a/test/shared_ptr.py b/test/shared_ptr.py
      index 64850097..e86da6df 100644
      --- a/test/shared_ptr.py
      +++ b/test/shared_ptr.py
      @@ -46,6 +46,7 @@ bye
       ... except TypeError: pass
       ... else: 'print expected a TypeError'
       >>> store(z)
      +>>> assert stored_z() is z  # show that deleter introspection works
       >>> del z
       >>> stored_v()
       13
      
      From 4874a1801b214c13fdb71a766f306f416cb0c486 Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Tue, 25 Feb 2003 02:15:55 +0000
      Subject: [PATCH 1014/1042] Improved Boost.Python build reliability and
       documentation.
      
      [SVN r17623]
      ---
       doc/building.html | 33 ++++++++++++++-------------------
       1 file changed, 14 insertions(+), 19 deletions(-)
      
      diff --git a/doc/building.html b/doc/building.html
      index e285f765..2a65a6db 100644
      --- a/doc/building.html
      +++ b/doc/building.html
      @@ -140,21 +140,12 @@
             
       
             
      -        PYTHON_STDLIB_PATH
      +        CYGWIN_PYTHON_[DEBUG_]VERSION
       
      -        path to Python standard library modules
      +        The version of python being used under Cygwin. 
       
      -        Autoconfigured from PYTHON_ROOT
      -      
      +        $(PYTHON_VERSION)
       
      -      
      -        CYGWIN_PYTHON_ROOT
      -
      -        unix-style path containing the include/
      -        directory containing
      -        python$(PYTHON_VERSION)/python.h. 
      -
      -        
               
       
               Use only when building with  
       
             
      -        CYGWIN_PYTHON_ROOT
      +        CYGWIN_PYTHON_[DEBUG_]ROOT
       
      -        path to the user's Cygwin Python installation
      +        unix-style path containing the include/
      +        directory containing
      +        python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h. 
       
      -        /usr
      +        $(PYTHON_ROOT)
      +
      +        
       
               Use only when building with Cygwin GCC. 
       
             
      -        CYGWIN_PYTHON_LIB_PATH
      +        CYGWIN_PYTHON_[DEBUG_]LIB_PATH
       
               path containing the user's Cygwin Python import lib
      -        libpython$(PYTHON_VERSION).dll.a
      +        libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll.a
       
               Autoconfigured from CYGWIN_PYTHON_ROOT
       
      @@ -185,10 +180,10 @@
               "http://www.cygwin.com">Cygwin GCC. 
       
             
      -        CYGWIN_PYTHON_DLL_PATH
      +        CYGWIN_PYTHON_[DEBUG_]DLL_PATH
       
               path containing the user's Cygwin Python dll
      -        (libpython$(PYTHON_VERSION).dll)
      +        (libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll)
       
               /bin
       
      
      From 6d7d2ea5fe823f830ff135c14bc8c41f93d8b47a Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Tue, 25 Feb 2003 03:31:36 +0000
      Subject: [PATCH 1015/1042] initial checkin
      
      [SVN r17626]
      ---
       .../python/converter/shared_ptr_to_python.hpp | 26 ++++++++
       include/boost/python/detail/is_auto_ptr.hpp   | 31 +++++++++
       include/boost/python/detail/is_xxx.hpp        | 59 +++++++++++++++++
       .../python/detail/value_is_shared_ptr.hpp     | 18 ++++++
       include/boost/python/detail/value_is_xxx.hpp  | 63 +++++++++++++++++++
       5 files changed, 197 insertions(+)
       create mode 100644 include/boost/python/converter/shared_ptr_to_python.hpp
       create mode 100644 include/boost/python/detail/is_auto_ptr.hpp
       create mode 100644 include/boost/python/detail/is_xxx.hpp
       create mode 100644 include/boost/python/detail/value_is_shared_ptr.hpp
       create mode 100644 include/boost/python/detail/value_is_xxx.hpp
      
      diff --git a/include/boost/python/converter/shared_ptr_to_python.hpp b/include/boost/python/converter/shared_ptr_to_python.hpp
      new file mode 100644
      index 00000000..0002fa91
      --- /dev/null
      +++ b/include/boost/python/converter/shared_ptr_to_python.hpp
      @@ -0,0 +1,26 @@
      +// Copyright David Abrahams 2003. Permission to copy, use,
      +// modify, sell and distribute this software is granted provided this
      +// copyright notice appears in all copies. This software is provided
      +// "as is" without express or implied warranty, and with no claim as
      +// to its suitability for any purpose.
      +#ifndef SHARED_PTR_TO_PYTHON_DWA2003224_HPP
      +# define SHARED_PTR_TO_PYTHON_DWA2003224_HPP
      +
      +# include 
      +# include 
      +# include 
      +
      +namespace boost { namespace python { namespace converter { 
      +
      +template 
      +PyObject* shared_ptr_to_python(shared_ptr const& x)
      +{
      +    if (shared_ptr_deleter* d = boost::get_deleter(x))
      +        return incref(d->owner.get());
      +    else
      +        return converter::registered const&>::converters.to_python(&x);
      +}
      +
      +}}} // namespace boost::python::converter
      +
      +#endif // SHARED_PTR_TO_PYTHON_DWA2003224_HPP
      diff --git a/include/boost/python/detail/is_auto_ptr.hpp b/include/boost/python/detail/is_auto_ptr.hpp
      new file mode 100644
      index 00000000..9602a8d4
      --- /dev/null
      +++ b/include/boost/python/detail/is_auto_ptr.hpp
      @@ -0,0 +1,31 @@
      +// Copyright David Abrahams 2003. Permission to copy, use,
      +// modify, sell and distribute this software is granted provided this
      +// copyright notice appears in all copies. This software is provided
      +// "as is" without express or implied warranty, and with no claim as
      +// to its suitability for any purpose.
      +#ifndef IS_AUTO_PTR_DWA2003224_HPP
      +# define IS_AUTO_PTR_DWA2003224_HPP
      +
      +# ifndef BOOST_NO_AUTO_PTR
      +#  include 
      +#  include 
      +# endif
      +
      +namespace boost { namespace python { namespace detail { 
      +
      +# if !defined(BOOST_NO_AUTO_PTR)
      +
      +BOOST_PYTHON_IS_XXX_DEF(auto_ptr, std::auto_ptr, 1)
      +
      +# else
      +
      +template 
      +struct is_auto_ptr : mpl::false_c
      +{
      +};
      +
      +# endif
      +    
      +}}} // namespace boost::python::detail
      +
      +#endif // IS_AUTO_PTR_DWA2003224_HPP
      diff --git a/include/boost/python/detail/is_xxx.hpp b/include/boost/python/detail/is_xxx.hpp
      new file mode 100644
      index 00000000..6510adc8
      --- /dev/null
      +++ b/include/boost/python/detail/is_xxx.hpp
      @@ -0,0 +1,59 @@
      +// Copyright David Abrahams 2003. Permission to copy, use,
      +// modify, sell and distribute this software is granted provided this
      +// copyright notice appears in all copies. This software is provided
      +// "as is" without express or implied warranty, and with no claim as
      +// to its suitability for any purpose.
      +#ifndef IS_XXX_DWA2003224_HPP
      +# define IS_XXX_DWA2003224_HPP
      +
      +# include 
      +# include 
      +# include 
      +
      +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
      +# include 
      +
      +#  define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs)      \
      +template                                                  \
      +struct is_##name                                                    \
      +{                                                                   \
      +    typedef char yes;                                               \
      +    typedef char (&no)[2];                                          \
      +                                                                    \
      +    static X_ dummy;                                                \
      +                                                                    \
      +    template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) >          \
      +    static yes test(                                                \
      +       qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) >&, int  \
      +    );                                                              \
      +                                                                    \
      +    template                                               \
      +    static no test(U&, ...);                                        \
      +                                                                    \
      +    BOOST_STATIC_CONSTANT(                                          \
      +        bool, value                                                 \
      +        = !is_reference::value                                  \
      +        & (sizeof(test(dummy, 0)) == sizeof(yes)));                 \
      +                                                                    \
      +    typedef mpl::bool_c type;                                \
      +};
      +
      +# else
      +
      +#  define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs)  \
      +template                                               \
      +struct is_##name : mpl::false_c                                 \
      +{                                                               \
      +};                                                              \
      +                                                                \
      +template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class T) >          \
      +struct is_##name<                                               \
      +   qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, T) >        \
      +>                                                               \
      +   : mpl::true_c                                                \
      +{                                                               \
      +};
      +
      +# endif
      +
      +#endif // IS_XXX_DWA2003224_HPP
      diff --git a/include/boost/python/detail/value_is_shared_ptr.hpp b/include/boost/python/detail/value_is_shared_ptr.hpp
      new file mode 100644
      index 00000000..5d2c8abe
      --- /dev/null
      +++ b/include/boost/python/detail/value_is_shared_ptr.hpp
      @@ -0,0 +1,18 @@
      +// Copyright David Abrahams 2003. Permission to copy, use,
      +// modify, sell and distribute this software is granted provided this
      +// copyright notice appears in all copies. This software is provided
      +// "as is" without express or implied warranty, and with no claim as
      +// to its suitability for any purpose.
      +#ifndef VALUE_IS_SHARED_PTR_DWA2003224_HPP
      +# define VALUE_IS_SHARED_PTR_DWA2003224_HPP
      +
      +# include 
      +# include 
      +
      +namespace boost { namespace python { namespace detail { 
      +
      +BOOST_PYTHON_VALUE_IS_XXX_DEF(shared_ptr, shared_ptr, 1)
      +    
      +}}} // namespace boost::python::detail
      +
      +#endif // VALUE_IS_SHARED_PTR_DWA2003224_HPP
      diff --git a/include/boost/python/detail/value_is_xxx.hpp b/include/boost/python/detail/value_is_xxx.hpp
      new file mode 100644
      index 00000000..5621ad55
      --- /dev/null
      +++ b/include/boost/python/detail/value_is_xxx.hpp
      @@ -0,0 +1,63 @@
      +// Copyright David Abrahams 2003. Permission to copy, use,
      +// modify, sell and distribute this software is granted provided this
      +// copyright notice appears in all copies. This software is provided
      +// "as is" without express or implied warranty, and with no claim as
      +// to its suitability for any purpose.
      +#ifndef VALUE_IS_XXX_DWA2003224_HPP
      +# define VALUE_IS_XXX_DWA2003224_HPP
      +
      +# include 
      +# include 
      +# include 
      +
      +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
      +# include 
      +# include 
      +
      +#  define BOOST_PYTHON_VALUE_IS_XXX_DEF(name, qualified_name, nargs)    \
      +template                                                      \
      +struct value_is_##name                                                  \
      +{                                                                       \
      +    typedef char yes;                                                   \
      +    typedef char (&no)[2];                                              \
      +                                                                        \
      +    static typename add_reference::type dummy;                      \
      +                                                                        \
      +    template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) >              \
      +    static yes test(                                                    \
      +       qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) > const&, int \
      +    );                                                                  \
      +                                                                        \
      +    template                                                   \
      +    static no test(U&, ...);                                            \
      +                                                                        \
      +    BOOST_STATIC_CONSTANT(                                              \
      +        bool, value                                                     \
      +        = (sizeof(test(dummy, 0)) == sizeof(yes)));                     \
      +                                                                        \
      +    typedef mpl::bool_c type;                                    \
      +};
      +
      +# else
      +
      +#  include 
      +#  include 
      +#  include 
      +
      +#  define BOOST_PYTHON_VALUE_IS_XXX_DEF(name, qualified_name, nargs)    \
      +template                                                      \
      +struct value_is_##name                                                  \
      +{                                                                       \
      +    BOOST_PYTHON_IS_XXX_DEF(name,qualified_name,nargs)                  \
      +    BOOST_STATIC_CONSTANT(bool, value = is_##name<                      \
      +                               typename remove_cv<                      \
      +                                  typename remove_reference::type   \
      +                               >::type                                  \
      +                           >::value);                                   \
      +    typedef mpl::bool_c type;                                    \
      +                                                                        \
      +};                                                              
      +
      +# endif
      +
      +#endif // VALUE_IS_XXX_DWA2003224_HPP
      
      From 923feda9f712be49b6945395aed3e71fe91e153c Mon Sep 17 00:00:00 2001
      From: Dave Abrahams 
      Date: Tue, 25 Feb 2003 03:54:38 +0000
      Subject: [PATCH 1016/1042] update
      
      [SVN r17627]
      ---
       doc/news.html | 12 ++++++++++++
       1 file changed, 12 insertions(+)
      
      diff --git a/doc/news.html b/doc/news.html
      index ac0fb176..8ab97245 100644
      --- a/doc/news.html
      +++ b/doc/news.html
      @@ -29,6 +29,18 @@
           
      +
      24 February 2003
      + +
      Finished improved support + for boost::shared_ptr. Now any wrapped object of + C++ class X can be converted automatically + to shared_ptr<X>, regardless of how it was + wrapped. The shared_ptr will manage the lifetime + of the Python object which supplied the X, rather + than just the X object itself, and when such + a shared_ptr is converted back to Python, the + original Python object will be returned.
      +
      19 January 2003
      Integrated staticmethod support from Date: Tue, 25 Feb 2003 23:11:41 +0000 Subject: [PATCH 1017/1042] MPL names/directory structure refactoring [SVN r17651] --- include/boost/python/args.hpp | 6 ++-- include/boost/python/bases.hpp | 8 +++--- include/boost/python/class.hpp | 26 ++++++++--------- .../boost/python/converter/arg_to_python.hpp | 4 +-- .../boost/python/converter/object_manager.hpp | 10 +++---- .../python/converter/return_from_python.hpp | 4 +-- .../python/detail/copy_ctor_mutates_rhs.hpp | 2 +- include/boost/python/detail/def_helper.hpp | 16 +++++------ include/boost/python/detail/defaults_def.hpp | 2 +- .../boost/python/detail/indirect_traits.hpp | 28 +++++++++---------- include/boost/python/detail/is_auto_ptr.hpp | 2 +- include/boost/python/detail/is_xxx.hpp | 8 +++--- .../python/detail/make_keyword_range_fn.hpp | 2 +- .../boost/python/detail/string_literal.hpp | 12 ++++---- include/boost/python/detail/value_is_xxx.hpp | 6 ++-- include/boost/python/init.hpp | 8 +++--- include/boost/python/make_function.hpp | 6 ++-- .../boost/python/object/make_ptr_instance.hpp | 4 +-- include/boost/python/object/select_holder.hpp | 20 ++++++------- include/boost/python/ptr.hpp | 8 +++--- include/boost/python/to_python_value.hpp | 4 +-- 21 files changed, 93 insertions(+), 93 deletions(-) diff --git a/include/boost/python/args.hpp b/include/boost/python/args.hpp index eaf5818f..b2b76c87 100644 --- a/include/boost/python/args.hpp +++ b/include/boost/python/args.hpp @@ -21,7 +21,7 @@ # include # include -# include +# include # include # include @@ -65,7 +65,7 @@ namespace detail BOOST_STATIC_CONSTANT(bool, is_key = is_keywords::value); BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key)); - typedef mpl::bool_c type; + typedef mpl::bool_ type; BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) }; # else @@ -89,7 +89,7 @@ namespace detail sizeof(detail::is_keywords_test( (void (*)(T))0 )) == sizeof(detail::yes_keywords_t))); - typedef mpl::bool_c type; + typedef mpl::bool_ type; BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T)) }; # endif diff --git a/include/boost/python/bases.hpp b/include/boost/python/bases.hpp index 356f120a..5b6ea8c3 100644 --- a/include/boost/python/bases.hpp +++ b/include/boost/python/bases.hpp @@ -8,7 +8,7 @@ # include # include # include -# include +# include # include # include @@ -25,13 +25,13 @@ namespace boost { namespace python { { # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template struct specifies_bases - : mpl::false_c + : mpl::false_ { }; template < BOOST_PP_ENUM_PARAMS_Z(1, BOOST_PYTHON_MAX_BASES, class Base) > struct specifies_bases< bases< BOOST_PYTHON_BASE_PARAMS > > - : mpl::true_c + : mpl::true_ { }; # else @@ -48,7 +48,7 @@ namespace boost { namespace python { BOOST_STATIC_CONSTANT(bool, non_ref = !is_reference::value); public: BOOST_STATIC_CONSTANT(bool, value = non_ref & (sizeof(is_bases_helper(make())) == 1)); - typedef mpl::bool_c type; + typedef mpl::bool_ type; }; # endif template > diff --git a/include/boost/python/class.hpp b/include/boost/python/class.hpp index 3be45854..a56af61c 100644 --- a/include/boost/python/class.hpp +++ b/include/boost/python/class.hpp @@ -25,9 +25,9 @@ # include # include -# include -# include -# include +# include +# include +# include # include # include @@ -79,12 +79,12 @@ namespace detail struct operator_; // Register to_python converters for a class T. The first argument - // will be mpl::true_c unless noncopyable was specified as a + // will be mpl::true_ unless noncopyable was specified as a // class_<...> template parameter. The 2nd argument is a pointer to // the type of holder that must be created. The 3rd argument is a // reference to the Python type object to be created. template - inline void register_class_to_python(mpl::true_c copyable, SelectHolder selector, T* = 0) + inline void register_class_to_python(mpl::true_ copyable, SelectHolder selector, T* = 0) { typedef typename SelectHolder::type holder; force_instantiate(objects::class_cref_wrapper >()); @@ -92,7 +92,7 @@ namespace detail } template - inline void register_class_to_python(mpl::false_c copyable, SelectHolder selector, T* = 0) + inline void register_class_to_python(mpl::false_ copyable, SelectHolder selector, T* = 0) { SelectHolder::register_(); } @@ -131,7 +131,7 @@ namespace detail static void must_be_derived_class_member(Default const&) { - typedef typename assertion > >::failed test0; + typedef typename assertion > >::failed test0; typedef typename assertion >::failed test1; typedef typename assertion >::failed test2; not_a_derived_class_member(Fn()); @@ -398,7 +398,7 @@ class class_ : public objects::class_base , helper.policies(), helper.keywords()) , helper.doc()); - this->def_default(name, fn, helper, mpl::bool_c()); + this->def_default(name, fn, helper, mpl::bool_()); } // @@ -411,7 +411,7 @@ class class_ : public objects::class_base char const* name , Fn fn , Helper const& helper - , mpl::bool_c) + , mpl::bool_) { detail::error::virtual_function_default::must_be_derived_class_member( helper.default_implementation()); @@ -424,7 +424,7 @@ class class_ : public objects::class_base } template - inline void def_default(char const*, Fn, Helper const&, mpl::bool_c) + inline void def_default(char const*, Fn, Helper const&, mpl::bool_) { } // @@ -474,7 +474,7 @@ inline void class_::register_() const objects::register_class_from_python(); detail::register_class_to_python( - mpl::bool_c() + mpl::bool_() # if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) , holder_selector::execute((held_type*)0) # elif BOOST_WORKAROUND(BOOST_MSVC, <= 1300) @@ -519,7 +519,7 @@ namespace detail { template struct has_noncopyable - : mpl::logical_or< + : mpl::or_< is_same , is_same , is_same @@ -530,7 +530,7 @@ namespace detail template struct select_held_type : mpl::if_< - mpl::logical_or< + mpl::or_< specifies_bases , is_same > diff --git a/include/boost/python/converter/arg_to_python.hpp b/include/boost/python/converter/arg_to_python.hpp index 4d654eb3..3d62eccd 100755 --- a/include/boost/python/converter/arg_to_python.hpp +++ b/include/boost/python/converter/arg_to_python.hpp @@ -31,7 +31,7 @@ # include -# include +# include namespace boost { namespace python { namespace converter { @@ -116,7 +116,7 @@ namespace detail , shared_ptr_arg_to_python , typename mpl::if_< - mpl::logical_or< + mpl::or_< is_function , python::detail::is_pointer_to_function , is_member_function_pointer diff --git a/include/boost/python/converter/object_manager.hpp b/include/boost/python/converter/object_manager.hpp index f93dd3fd..7c8c9084 100755 --- a/include/boost/python/converter/object_manager.hpp +++ b/include/boost/python/converter/object_manager.hpp @@ -12,7 +12,7 @@ # include # include # include -# include +# include // Facilities for dealing with types which always manage Python // objects. Some examples are object, list, str, et. al. Different @@ -118,14 +118,14 @@ struct object_manager_traits template struct is_object_manager - : mpl::bool_c::is_specialized> + : mpl::bool_::is_specialized> { }; # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template struct is_reference_to_object_manager - : mpl::false_c + : mpl::false_ { }; @@ -197,7 +197,7 @@ namespace detail template struct is_reference_to_object_manager_nonref - : mpl::false_c + : mpl::false_ { }; @@ -211,7 +211,7 @@ namespace detail == sizeof(detail::yes_reference_to_object_manager) ) ); - typedef mpl::bool_c type; + typedef mpl::bool_ type; }; } diff --git a/include/boost/python/converter/return_from_python.hpp b/include/boost/python/converter/return_from_python.hpp index 72527b0b..69c7a71b 100755 --- a/include/boost/python/converter/return_from_python.hpp +++ b/include/boost/python/converter/return_from_python.hpp @@ -14,8 +14,8 @@ # include # include # include -# include -# include +# include +# include namespace boost { namespace python { namespace converter { diff --git a/include/boost/python/detail/copy_ctor_mutates_rhs.hpp b/include/boost/python/detail/copy_ctor_mutates_rhs.hpp index 434df76c..b1613924 100755 --- a/include/boost/python/detail/copy_ctor_mutates_rhs.hpp +++ b/include/boost/python/detail/copy_ctor_mutates_rhs.hpp @@ -7,7 +7,7 @@ # define COPY_CTOR_MUTATES_RHS_DWA2003219_HPP #include -#include +#include namespace boost { namespace python { namespace detail { diff --git a/include/boost/python/detail/def_helper.hpp b/include/boost/python/detail/def_helper.hpp index d78ddb81..98933bd4 100644 --- a/include/boost/python/detail/def_helper.hpp +++ b/include/boost/python/detail/def_helper.hpp @@ -10,9 +10,9 @@ # include # include # include -# include -# include -# include +# include +# include +# include # include # include # include @@ -98,8 +98,8 @@ namespace detail struct doc_extract : tuple_extract< Tuple - , mpl::logical_not< - mpl::logical_or< + , mpl::not_< + mpl::or_< is_reference_to_class , is_reference_to_member_function_pointer > @@ -118,10 +118,10 @@ namespace detail struct policy_extract : tuple_extract< Tuple - , mpl::logical_and< - mpl::logical_not > + , mpl::and_< + mpl::not_ > , is_reference_to_class - , mpl::logical_not > + , mpl::not_ > > > { diff --git a/include/boost/python/detail/defaults_def.hpp b/include/boost/python/detail/defaults_def.hpp index efb1c395..ac963cb6 100644 --- a/include/boost/python/detail/defaults_def.hpp +++ b/include/boost/python/detail/defaults_def.hpp @@ -102,7 +102,7 @@ namespace detail // template // inline void // define_stub_function( - // char const* name, OverloadsT s, NameSpaceT& name_space, mpl::int_c) + // char const* name, OverloadsT s, NameSpaceT& name_space, mpl::int_) // { // name_space.def(name, &OverloadsT::func_N); // } diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index d53e396c..3f6a0098 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -17,7 +17,7 @@ # include # include # include -# include +# include # include # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -48,7 +48,7 @@ struct is_reference_to_const # endif template -struct is_reference_to_function : mpl::bool_c +struct is_reference_to_function : mpl::bool_ { }; @@ -58,7 +58,7 @@ struct is_reference_to_function : is_function }; template -struct is_pointer_to_function : mpl::bool_c +struct is_pointer_to_function : mpl::bool_ { BOOST_STATIC_CONSTANT(bool, value = false); }; @@ -71,7 +71,7 @@ struct is_pointer_to_function : is_function }; template -struct is_reference_to_member_function_pointer_impl : mpl::bool_c +struct is_reference_to_member_function_pointer_impl : mpl::bool_ { }; @@ -100,14 +100,14 @@ struct is_reference_to_function_pointer_aux typename remove_reference::type >::type >::value)); - typedef mpl::bool_c type; + typedef mpl::bool_ type; }; template struct is_reference_to_function_pointer : mpl::if_c< is_reference_to_function::value - , mpl::bool_c + , mpl::bool_ , is_reference_to_function_pointer_aux >::type { @@ -191,7 +191,7 @@ struct is_reference_to_class >::value >::value) ); - typedef mpl::bool_c type; + typedef mpl::bool_ type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) }; @@ -267,7 +267,7 @@ struct is_reference_to_function_aux template struct is_reference_to_function - : mpl::if_, is_reference_to_function_aux, mpl::bool_c >::type + : mpl::if_, is_reference_to_function_aux, mpl::bool_ >::type { }; @@ -278,12 +278,12 @@ struct is_pointer_to_function_aux BOOST_STATIC_CONSTANT( bool, value = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)); - typedef mpl::bool_c type; + typedef mpl::bool_ type; }; template struct is_pointer_to_function - : mpl::if_, is_pointer_to_function_aux, mpl::bool_c >::type + : mpl::if_, is_pointer_to_function_aux, mpl::bool_ >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_function,(T)) }; @@ -419,7 +419,7 @@ struct is_reference_to_function_pointer : mpl::if_< is_reference , is_pointer_to_function_aux - , mpl::bool_c + , mpl::bool_ >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) @@ -442,7 +442,7 @@ struct is_pointer_to_member_function_aux BOOST_STATIC_CONSTANT( bool, value = sizeof((member_function_pointer_helper)(t)) == sizeof(inner_yes_type)); - typedef mpl::bool_c type; + typedef mpl::bool_ type; }; template @@ -450,7 +450,7 @@ struct is_reference_to_member_function_pointer : mpl::if_< is_reference , is_pointer_to_member_function_aux - , mpl::bool_c + , mpl::bool_ >::type { BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) @@ -469,7 +469,7 @@ struct is_reference_to_class = (is_reference::value & (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type))) ); - typedef mpl::bool_c type; + typedef mpl::bool_ type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) }; diff --git a/include/boost/python/detail/is_auto_ptr.hpp b/include/boost/python/detail/is_auto_ptr.hpp index 9602a8d4..986a6309 100644 --- a/include/boost/python/detail/is_auto_ptr.hpp +++ b/include/boost/python/detail/is_auto_ptr.hpp @@ -20,7 +20,7 @@ BOOST_PYTHON_IS_XXX_DEF(auto_ptr, std::auto_ptr, 1) # else template -struct is_auto_ptr : mpl::false_c +struct is_auto_ptr : mpl::false_ { }; diff --git a/include/boost/python/detail/is_xxx.hpp b/include/boost/python/detail/is_xxx.hpp index 6510adc8..ad888b84 100644 --- a/include/boost/python/detail/is_xxx.hpp +++ b/include/boost/python/detail/is_xxx.hpp @@ -7,7 +7,7 @@ # define IS_XXX_DWA2003224_HPP # include -# include +# include # include # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) @@ -35,14 +35,14 @@ struct is_##name \ = !is_reference::value \ & (sizeof(test(dummy, 0)) == sizeof(yes))); \ \ - typedef mpl::bool_c type; \ + typedef mpl::bool_ type; \ }; # else # define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs) \ template \ -struct is_##name : mpl::false_c \ +struct is_##name : mpl::false_ \ { \ }; \ \ @@ -50,7 +50,7 @@ template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class T) > \ struct is_##name< \ qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, T) > \ > \ - : mpl::true_c \ + : mpl::true_ \ { \ }; diff --git a/include/boost/python/detail/make_keyword_range_fn.hpp b/include/boost/python/detail/make_keyword_range_fn.hpp index b7d78fdd..9c749292 100644 --- a/include/boost/python/detail/make_keyword_range_fn.hpp +++ b/include/boost/python/detail/make_keyword_range_fn.hpp @@ -25,7 +25,7 @@ template object make_keyword_range_function(F f, Policies const& policies, keyword_range const& kw) { return detail::make_function_aux( - f, policies, args_from_python(), detail::get_signature(f), kw, mpl::int_c<0>()); + f, policies, args_from_python(), detail::get_signature(f), kw, mpl::int_<0>()); } // Builds an '__init__' function which inserts the given Holder type diff --git a/include/boost/python/detail/string_literal.hpp b/include/boost/python/detail/string_literal.hpp index 0236a14f..ee8cc0b6 100644 --- a/include/boost/python/detail/string_literal.hpp +++ b/include/boost/python/detail/string_literal.hpp @@ -10,19 +10,19 @@ # include # include # include -# include +# include namespace boost { namespace python { namespace detail { # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template -struct is_string_literal : mpl::false_c +struct is_string_literal : mpl::false_ { }; # if !defined(__MWERKS__) || __MWERKS__ > 0x2407 template -struct is_string_literal : mpl::true_c +struct is_string_literal : mpl::true_ { }; @@ -31,7 +31,7 @@ struct is_string_literal : mpl::true_c // This compiler mistakenly gets the type of string literals as char* // instead of char[NN]. template <> -struct is_string_literal : mpl::true_c +struct is_string_literal : mpl::true_ { }; # endif @@ -63,7 +63,7 @@ struct string_literal_helper BOOST_STATIC_CONSTANT( bool, value = sizeof(self::check(x)) == sizeof(yes_string_literal)); - typedef mpl::bool_c type; + typedef mpl::bool_ type; }; }; @@ -71,7 +71,7 @@ template <> struct string_literal_helper { template - struct apply : mpl::false_c + struct apply : mpl::false_ { }; }; diff --git a/include/boost/python/detail/value_is_xxx.hpp b/include/boost/python/detail/value_is_xxx.hpp index 5621ad55..f0a9a11c 100644 --- a/include/boost/python/detail/value_is_xxx.hpp +++ b/include/boost/python/detail/value_is_xxx.hpp @@ -7,7 +7,7 @@ # define VALUE_IS_XXX_DWA2003224_HPP # include -# include +# include # include # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) @@ -35,7 +35,7 @@ struct value_is_##name \ bool, value \ = (sizeof(test(dummy, 0)) == sizeof(yes))); \ \ - typedef mpl::bool_c type; \ + typedef mpl::bool_ type; \ }; # else @@ -54,7 +54,7 @@ struct value_is_##name \ typename remove_reference::type \ >::type \ >::value); \ - typedef mpl::bool_c type; \ + typedef mpl::bool_ type; \ \ }; diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index 76aa9b33..bfc398d6 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include # include @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include @@ -104,7 +104,7 @@ namespace detail BOOST_STATIC_CONSTANT( bool, value = sizeof(f(t())) == sizeof(::boost::type_traits::yes_type)); - typedef mpl::bool_c type; + typedef mpl::bool_ type; BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T)) }; @@ -127,7 +127,7 @@ namespace detail template struct is_optional : is_optional_impl { - typedef mpl::bool_c::value> type; + typedef mpl::bool_::value> type; BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_optional,(T)) }; #endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) diff --git a/include/boost/python/make_function.hpp b/include/boost/python/make_function.hpp index 99bc0253..9632bbd5 100644 --- a/include/boost/python/make_function.hpp +++ b/include/boost/python/make_function.hpp @@ -13,7 +13,7 @@ # include # include -# include +# include namespace boost { namespace python { @@ -41,7 +41,7 @@ namespace detail // As above, except that it accepts argument keywords. NumKeywords // is used only for a compile-time assertion to make sure the user // doesn't pass more keywords than the function can accept. To - // disable all checking, pass mpl::int_c<0> for NumKeywords. + // disable all checking, pass mpl::int_<0> for NumKeywords. template object make_function_aux( F f @@ -93,7 +93,7 @@ object make_function(F f, CallPolicies const& policies, Keywords const& keywords , detail::args_from_python() , detail::get_signature(f) , keywords.range() - , mpl::int_c() + , mpl::int_() ); } diff --git a/include/boost/python/object/make_ptr_instance.hpp b/include/boost/python/object/make_ptr_instance.hpp index 40debeaa..0b07ae26 100644 --- a/include/boost/python/object/make_ptr_instance.hpp +++ b/include/boost/python/object/make_ptr_instance.hpp @@ -41,14 +41,14 @@ struct make_ptr_instance } template - static inline PyTypeObject* get_derived_class_object(mpl::true_c, U const volatile* x) + static inline PyTypeObject* get_derived_class_object(mpl::true_, U const volatile* x) { converter::registration const* r = converter::registry::query(type_info(typeid(*x))); return r ? r->m_class_object : 0; } template - static inline PyTypeObject* get_derived_class_object(mpl::false_c, U*) + static inline PyTypeObject* get_derived_class_object(mpl::false_, U*) { return 0; } diff --git a/include/boost/python/object/select_holder.hpp b/include/boost/python/object/select_holder.hpp index ca2eeaa8..87bc06da 100644 --- a/include/boost/python/object/select_holder.hpp +++ b/include/boost/python/object/select_holder.hpp @@ -18,9 +18,9 @@ # include -# include +# include # include -# include +# include # include # include @@ -49,7 +49,7 @@ namespace detail // constructor. Normally this means U is a virtual function // dispatcher subclass for T. template - void check_default_constructible(T*, U*, mpl::bool_c) + void check_default_constructible(T*, U*, mpl::bool_) { python::detail::force_instantiate( sizeof(specify_init_arguments_or_no_init_for_class_(U((::PyObject*)0))) @@ -59,7 +59,7 @@ namespace detail // Handles the "normal" case where T is held directly and // has_back_reference is not specialized. template - void check_default_constructible(T*, T*, mpl::bool_c) + void check_default_constructible(T*, T*, mpl::bool_) { python::detail::force_instantiate( sizeof(specify_init_arguments_or_no_init_for_class_(T())) @@ -94,7 +94,7 @@ namespace detail static void assert_default_constructible() { - detail::check_default_constructible((T*)0,(Held*)0,mpl::bool_c()); + detail::check_default_constructible((T*)0,(Held*)0,mpl::bool_()); } typedef typename mpl::if_c< @@ -116,7 +116,7 @@ namespace detail static void assert_default_constructible() { - detail::check_default_constructible((T*)0,(pointee*)0,mpl::bool_c()); + detail::check_default_constructible((T*)0,(pointee*)0,mpl::bool_()); } typedef typename mpl::if_c< @@ -127,13 +127,13 @@ namespace detail static inline void register_() { - select_pointer_holder::register_(mpl::bool_c()); + select_pointer_holder::register_(mpl::bool_()); } static type* get() { return 0; } private: - static inline void register_(mpl::true_c) + static inline void register_(mpl::true_) { } @@ -145,7 +145,7 @@ namespace detail } }; - static inline void register_(mpl::false_c) + static inline void register_(mpl::false_) { python::detail::force_instantiate( objects::class_value_wrapper >()); @@ -212,7 +212,7 @@ struct select_holder is_same , detail::select_value_holder , typename mpl::if_< - mpl::logical_or< + mpl::or_< is_same , is_base_and_derived > diff --git a/include/boost/python/ptr.hpp b/include/boost/python/ptr.hpp index 3fdef0f4..dd37f58b 100644 --- a/include/boost/python/ptr.hpp +++ b/include/boost/python/ptr.hpp @@ -15,7 +15,7 @@ # endif # include -# include +# include namespace boost { namespace python { @@ -40,13 +40,13 @@ inline pointer_wrapper ptr(T t) # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template class is_pointer_wrapper - : public mpl::false_c + : public mpl::false_ { }; template class is_pointer_wrapper > - : public mpl::true_c + : public mpl::true_ { }; @@ -110,7 +110,7 @@ class is_pointer_wrapper bool, value = ( sizeof(detail::is_pointer_wrapper_test(boost::type())) == sizeof(detail::yes_pointer_wrapper_t))); - typedef mpl::bool_c type; + typedef mpl::bool_ type; }; template diff --git a/include/boost/python/to_python_value.hpp b/include/boost/python/to_python_value.hpp index ee49849d..4af5c6f8 100644 --- a/include/boost/python/to_python_value.hpp +++ b/include/boost/python/to_python_value.hpp @@ -21,7 +21,7 @@ # include # include -# include +# include namespace boost { namespace python { @@ -80,7 +80,7 @@ struct to_python_value detail::value_is_shared_ptr , detail::shared_ptr_to_python_value , typename mpl::if_< - mpl::logical_or< + mpl::or_< converter::is_object_manager , converter::is_reference_to_object_manager > From 2c4fa48f46dedea7d1fe0a32fc555b21216139f9 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 26 Feb 2003 13:48:16 +0000 Subject: [PATCH 1018/1042] Fixes for Intel5 [SVN r17658] --- test/auto_ptr.cpp | 6 ++++-- test/auto_ptr.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/auto_ptr.cpp b/test/auto_ptr.cpp index 1de51f23..22e2df73 100644 --- a/test/auto_ptr.cpp +++ b/test/auto_ptr.cpp @@ -9,8 +9,10 @@ #include #include #include -#include "test_class.hpp" +#include + +#include "test_class.hpp" #include using namespace boost::python; @@ -70,7 +72,7 @@ BOOST_PYTHON_MODULE(auto_ptr_ext) ; // VC6 auto_ptrs do not have converting constructors -#if defined(BOOST_MSVC_STD_ITERATOR) +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 306) scope().attr("broken_auto_ptr") = 1; #else scope().attr("broken_auto_ptr") = 0; diff --git a/test/auto_ptr.py b/test/auto_ptr.py index 426a5d84..cd83208f 100644 --- a/test/auto_ptr.py +++ b/test/auto_ptr.py @@ -22,7 +22,7 @@ >>> broken_auto_ptr and -1 or look(x) -1 ->>> if not '--broken-auto-ptr' in sys.argv: +>>> if not broken_auto_ptr: ... try: x.value() ... except TypeError: pass ... else: print 'expected a TypeError exception' From ee44c90e859c109caeb6c797c40dd972f052772a Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 27 Feb 2003 02:20:01 +0000 Subject: [PATCH 1019/1042] Fixes for Python and Cygwin testing [SVN r17667] --- test/Jamfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/Jamfile b/test/Jamfile index d71c02fa..4a5b14d9 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -61,7 +61,9 @@ run ../test/embedding.cpp ../build/boost_python : # requirements $(PYTHON_PROPERTIES) $(PYTHON_LIB_PATH) - $(PYTHON_EMBEDDED_LIBRARY) ; + <$(gcc-compilers)>$(CYGWIN_PYTHON_DEBUG_DLL_PATH) + <$(gcc-compilers)><*>$(CYGWIN_PYTHON_DLL_PATH) + $(PYTHON_EMBEDDED_LIBRARY) ; bpl-test staticmethod ; bpl-test shared_ptr ; From 99f45b474e3983425605327a099ef13188828847 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Thu, 27 Feb 2003 13:07:41 +0000 Subject: [PATCH 1020/1042] Fix broken links [SVN r17671] --- doc/v2/CallPolicies.html | 2 +- doc/v2/Dereferenceable.html | 2 +- doc/v2/Extractor.html | 2 +- doc/v2/HolderGenerator.html | 2 +- doc/v2/ResultConverter.html | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/v2/CallPolicies.html b/doc/v2/CallPolicies.html index b1fec484..09877c5d 100644 --- a/doc/v2/CallPolicies.html +++ b/doc/v2/CallPolicies.html @@ -5,7 +5,7 @@ - + Boost.Python - CallPolicies Concept diff --git a/doc/v2/Dereferenceable.html b/doc/v2/Dereferenceable.html index 965e4043..fdea0fc0 100644 --- a/doc/v2/Dereferenceable.html +++ b/doc/v2/Dereferenceable.html @@ -1,7 +1,7 @@ - + Boost.Python - Dereferenceable Concept diff --git a/doc/v2/Extractor.html b/doc/v2/Extractor.html index f70b39d4..c28f5f58 100755 --- a/doc/v2/Extractor.html +++ b/doc/v2/Extractor.html @@ -1,7 +1,7 @@ - + Boost.Python - Extractor Concept diff --git a/doc/v2/HolderGenerator.html b/doc/v2/HolderGenerator.html index 281d5c4a..34634798 100755 --- a/doc/v2/HolderGenerator.html +++ b/doc/v2/HolderGenerator.html @@ -1,7 +1,7 @@ - + Boost.Python - Holder Concept diff --git a/doc/v2/ResultConverter.html b/doc/v2/ResultConverter.html index d107b62e..63187c3a 100644 --- a/doc/v2/ResultConverter.html +++ b/doc/v2/ResultConverter.html @@ -1,7 +1,7 @@ - + Boost.Python - ResultConverter Concept From c6ca85b52582fc7a18804d586a81569a47c5bb89 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 1 Mar 2003 18:19:38 +0000 Subject: [PATCH 1021/1042] Added embedding tutorial from Dirk Gerrits. Thanks, Dirk! [SVN r17690] --- doc/tutorial/doc/embedding.html | 97 ++++++++ doc/tutorial/doc/enums.html | 6 +- doc/tutorial/doc/iterators.html | 6 +- doc/tutorial/doc/using_the_interpreter.html | 236 ++++++++++++++++++++ doc/tutorial/index.html | 10 + 5 files changed, 349 insertions(+), 6 deletions(-) create mode 100644 doc/tutorial/doc/embedding.html create mode 100644 doc/tutorial/doc/using_the_interpreter.html diff --git a/doc/tutorial/doc/embedding.html b/doc/tutorial/doc/embedding.html new file mode 100644 index 00000000..ef64b088 --- /dev/null +++ b/doc/tutorial/doc/embedding.html @@ -0,0 +1,97 @@ + + + +Embedding + + + + + + + + + + +
      + + Embedding +
      +
      + + + + + + +
      +

      +By now you should know how to use Boost.Python to call your C++ code from +Python. However, sometimes you may need to do the reverse: call Python code +from the C++-side. This requires you to embed the Python interpreter +into your C++ program.

      +

      +Currently, Boost.Python does not directly support everything you'll need +when embedding. Therefore you'll need to use the + +Python/C API to fill in +the gaps. However, Boost.Python already makes embedding a lot easier and, +in a future version, it may become unnecessary to touch the Python/C API at +all. So stay tuned...

      +

      Building embedded programs

      +To be able to use embedding in your programs, they have to be linked to +both Boost.Python's and Python's static link library.

      +

      +Boost.Python's static link library comes in two variants. Both are located +in Boost's /libs/python/build/bin-stage subdirectory. On Windows, the +variants are called boost_python.lib (for release builds) and +boost_python_debug.lib (for debugging). If you can't find the libraries, +you probably haven't built Boost.Python yet. See +and Testing on how to do this.

      +

      +Python's static link library can be found in the /libs subdirectory of +your Python directory. On Windows it is called pythonXY.lib where X.Y is +your major Python version number.

      +

      +Additionally, Python's /include subdirectory has to be added to your +include path.

      +

      +In a Jamfile, all the above boils down to:

      +
      +    projectroot c:\projects\embedded_program ; # location of the program
      +
      +    # bring in the rules for python
      +    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
      +    include python.jam ;
      +
      +    exe embedded_program # name of the executable
      +      : #sources
      +         embedded_program.cpp
      +      : # requirements
      +         <find-library>boost_python <library-path>c:\boost\libs\python
      +      $(PYTHON_PROPERTIES)
      +        <library-path>$(PYTHON_LIB_PATH)
      +        <find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
      +

      Getting started

      +Being able to build is nice, but there is nothing to build yet. Embedding +the Python interpreter into one of your C++ programs requires these 4 +steps:

      +
      1. #include <boost/python.hpp>

      2. Call +Py_Initialize() to start the interpreter and create the __main__ module.

      3. Call other Python C API routines to use the interpreter.

      4. Call +Py_Finalize() to stop the interpreter and release its resources.

      +(Of course, there can be other C++ code between all of these steps.)

      +

      Now that we can embed the interpreter in our programs, lets see how to put it to use...

      + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/doc/enums.html b/doc/tutorial/doc/enums.html index f9bc1272..09632e31 100644 --- a/doc/tutorial/doc/enums.html +++ b/doc/tutorial/doc/enums.html @@ -4,7 +4,7 @@ Enums - + @@ -21,7 +21,7 @@ - +

      @@ -82,7 +82,7 @@ create a new scope around a class:

      - +
      diff --git a/doc/tutorial/doc/iterators.html b/doc/tutorial/doc/iterators.html index c0234efc..585f89b1 100644 --- a/doc/tutorial/doc/iterators.html +++ b/doc/tutorial/doc/iterators.html @@ -3,7 +3,7 @@ Iterators - + @@ -20,7 +20,7 @@ - +
      @@ -87,7 +87,7 @@ Now, our C++ Wrapper:

      - +
      diff --git a/doc/tutorial/doc/using_the_interpreter.html b/doc/tutorial/doc/using_the_interpreter.html new file mode 100644 index 00000000..4c0e4de9 --- /dev/null +++ b/doc/tutorial/doc/using_the_interpreter.html @@ -0,0 +1,236 @@ + + + +Using the interpreter + + + + + + + + + + +
      + + Using the interpreter +
      +
      + + + + + + +
      +

      +As you probably already know, objects in Python are reference-counted. +Naturally, the PyObjects of the Python/C API are also reference-counted. +There is a difference however. While the reference-counting is fully +automatic in Python, the Python/C API requires you to do it + +by hand. This is +messy and especially hard to get right in the presence of C++ exceptions. +Fortunately Boost.Python provides the +handle class +template to automate the process.

      +

      Reference-counting handles

      +There are two ways in which a function in the Python/C API can return a +PyObject*: as a borrowed reference or as a new reference. Which of +these a function uses, is listed in that function's documentation. The two +require slightely different approaches to reference-counting but both can +be 'handled' by Boost.Python.

      +

      +For a function returning a borrowed reference we'll have to tell the +handle that the PyObject* is borrowed with the aptly named + +borrowed function. Two functions +returning borrowed references are +PyImport_AddModule and +PyModule_GetDict. +The former returns a reference to an already imported module, the latter +retrieves a module's namespace dictionary. Let's use them to retrieve the +namespace of the __main__ module:

      +
      +    handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
      +    handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
      +
      +

      +Because the Python/C API doesn't know anything about handles, we used +the +get member function to +retrieve the PyObject* from which the handle was constructed.

      +

      +For a function returning a new reference we can just create a handle +out of the raw PyObject* without wrapping it in a call to borrowed. One +such function that returns a new reference is +PyRun_String which we'll +discuss in the next section.

      + + + + +
      + Handle is a class template, so why haven't we been using any template parameters?
      +
      +handle has a single template parameter specifying the type of the managed object. This type is PyObject 99% of the time, so the parameter was defaulted to PyObject for convenience. Therefore we can use the shorthand handle<> instead of the longer, but equivalent, handle<PyObject>. +
      +

      Running Python code

      +To run Python code from C++ there is a family of functions in the API +starting with the PyRun prefix. You can find the full list of these +functions +here. They +all work similarly so we will look at only one of them, namely:

      +
      +    PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
      +
      +

      + +PyRun_String takes the code to execute as a null-terminated (C-style) +string in its str parameter. The function returns a new reference to a +Python object. Which object is returned depends on the start paramater.

      +

      +The start parameter is the start symbol from the Python grammar to use +for interpreting the code. The possible values are:

      + + + +
      +Start symbols
      +Py_eval_inputfor interpreting isolated expressions
      +Py_file_inputfor interpreting sequences of statements
      +Py_single_inputfor interpreting a single statement
      +

      +When using +Py_eval_input, the input string must contain a single expression +and its result is returned. When using +Py_file_input, the string can +contain an abitrary number of statements and None is returned. + +Py_single_input works in the same way as +Py_file_input but only accepts a +single statement.

      +

      +Lastly, the globals and locals parameters are Python dictionaries +containing the globals and locals of the context in which to run the code. +For most intents and purposes you can use the namespace dictionary of the +__main__ module for both parameters.

      +

      +We have already seen how to get the __main__ module's namespace so let's +run some Python code in it:

      +
      +    handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
      +    handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
      +    handle<>( PyRun_String("hello = file('hello.txt', 'w')\n"
      +                           "hello.write('Hello world!')\n"
      +                           "hello.close()", Py_file_input,
      +                           main_namespace.get(), main_namespace.get()) );
      +
      +

      +This should create a file called 'hello.txt' in the current directory +containing a phrase that is well-known in programming circles.

      +

      + Note that we wrap the return value of +PyRun_String in a +(nameless) handle even though we are not interested in it. If we didn't +do this, the the returned object would be kept alive unnecessarily. Unless +you want to be a Dr. Frankenstein, always wrap PyObject*s in handles.

      +

      Beyond handles

      +It's nice that handle manages the reference counting details for us, but +other than that it doesn't do much. Often we'd like to have a more useful +class to manipulate Python objects. But we have already seen such a class +in the +previous section: the aptly named object +class and it's derivatives. What we haven't seen, is that they can be +constructed from a handle. The following examples should illustrate this +fact:

      +
      +    handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
      +    main_namespace dict(handle<>(borrowed( PyModule_GetDict(main_module.get()) )));
      +    handle<>( PyRun_String("result = 5 ** 2", Py_file_input,
      +                           main_namespace.ptr(), main_namespace.ptr()) );
      +    int five_squared = extract<int>( main_namespace["result"] );
      +
      +

      +Here we create a dictionary object for the __main__ module's namespace. +Then we assign 5 squared to the result variable and read this variable from +the dictionary. Another way to achieve the same result is to let + +PyRun_String return the result directly with +Py_eval_input:

      +
      +    object result(handle<>( PyRun_String("5 ** 2", Py_eval_input,
      +                                         main_namespace.ptr(), main_namespace.ptr()) ));
      +    int five_squared = extract<int>(result);
      +
      +

      + Note that object's member function to return the wrapped +PyObject* is called ptr instead of get. This makes sense if you +take into account the different functions that object and handle +perform.

      +

      Exception handling

      +If an exception occurs in the execution of some Python code, the +PyRun_String function returns a null pointer. Constructing a handle out of this null pointer throws +error_already_set, so basically, the Python exception is automatically translated into a C++ exception when using handle:

      +
      +    try
      +    {
      +        object result(handle<>( PyRun_String("5/0", Py_eval_input,
      +                                             main_namespace.ptr(), main_namespace.ptr()) ));
      +        // execution will never get here:
      +        int five_divided_by_zero = extract<int>(result);
      +    }
      +    catch(error_already_set)
      +    {
      +        // handle the exception in some way
      +    }
      +
      +

      +The error_already_set exception class doesn't carry any information in itself. To find out more about the Python exception that occurred, you need to use the +exception handling functions of the Python/C API in your catch-statement. This can be as simple as calling +PyErr_Print() to print the exception's traceback to the console, or comparing the type of the exception with those of the +standard exceptions:

      +
      +    catch(error_already_set)
      +    {
      +        if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
      +        {
      +            // handle ZeroDivisionError specially
      +        }
      +        else
      +        {
      +            // print all other errors to stderr
      +            PyErr_Print();
      +        }
      +    }
      +
      +

      +(To retrieve even more information from the exception you can use some of the other exception handling functions listed +here.)

      +

      +If you'd rather not have handle throw a C++ exception when it is constructed, you can use the +allow_null function in the same way you'd use borrowed:

      +
      +    handle<> result(allow_null( PyRun_String("5/0", Py_eval_input,
      +                                             main_namespace.ptr(), main_namespace.ptr()) ));
      +    if (!result)
      +        // Python exception occurred
      +    else
      +        // everything went okay, it's safe to use the result
      +
      + + + + + + +
      +
      +
      + + diff --git a/doc/tutorial/index.html b/doc/tutorial/index.html index 9439b300..eaeffa03 100644 --- a/doc/tutorial/index.html +++ b/doc/tutorial/index.html @@ -125,6 +125,16 @@ Enums + + + Embedding + + + + + Using the interpreter + + Iterators From 4c7cff6e8eb6486bfa6003b2338fec44977725fd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 1 Mar 2003 18:25:41 +0000 Subject: [PATCH 1022/1042] fix bad link [SVN r17691] --- doc/tutorial/doc/embedding.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/tutorial/doc/embedding.html b/doc/tutorial/doc/embedding.html index ef64b088..8cd1c725 100644 --- a/doc/tutorial/doc/embedding.html +++ b/doc/tutorial/doc/embedding.html @@ -44,10 +44,10 @@ both Boost.Python's and Python's static link library.

      Boost.Python's static link library comes in two variants. Both are located in Boost's /libs/python/build/bin-stage subdirectory. On Windows, the variants are called boost_python.lib (for release builds) and -boost_python_debug.lib (for debugging). If you can't find the libraries, -you probably haven't built Boost.Python yet. See -and Testing on how to do this.

      +boost_python_debug.lib (for debugging). If you can't find the +libraries, you probably haven't built Boost.Python yet. See Building and Testing on how to do +this.

      Python's static link library can be found in the /libs subdirectory of your Python directory. On Windows it is called pythonXY.lib where X.Y is From 5ac7741ca9e37a0594703e2e2e834ea15fcf07b7 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 2 Mar 2003 00:55:07 +0000 Subject: [PATCH 1023/1042] Updates for ACCU [SVN r17695] --- doc/PyConDC_2003/bpl.txt | 519 +++++++++++++++++++-------------------- 1 file changed, 254 insertions(+), 265 deletions(-) diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt index fe0f686b..3332373f 100644 --- a/doc/PyConDC_2003/bpl.txt +++ b/doc/PyConDC_2003/bpl.txt @@ -1,52 +1,37 @@ -.. This is a comment. Note how any initial comments are moved by - transforms to after the document title, subtitle, and docinfo. - -.. Need intro and conclusion -.. Exposing classes - .. Constructors - .. Overloading - .. Properties and data members - .. Inheritance - .. Operators and Special Functions - .. Virtual Functions -.. Call Policies - -++++++++++++++++++++++++++++++++++++++++++++++ - Introducing Boost.Python (Extended Abstract) -++++++++++++++++++++++++++++++++++++++++++++++ - - -.. bibliographic fields (which also require a transform): ++++++++++++++++++++++++++++++++++++++++++++ + Building Hybrid Systems with Boost.Python ++++++++++++++++++++++++++++++++++++++++++++ :Author: David Abrahams -:Address: 45 Walnut Street - Somerville, MA 02143 :Contact: dave@boost-consulting.com :organization: `Boost Consulting`_ :date: $Date$ -:status: This is a "work in progress" -:version: 1 -:copyright: Copyright David Abrahams 2002. All rights reserved -:Dedication: +:Author: Ralf W. Grosse-Kunstleve - For my girlfriend, wife, and partner Luann - -:abstract: - - This paper describes the Boost.Python library, a system for - C++/Python interoperability. - -.. meta:: - :keywords: Boost,python,Boost.Python,C++ - :description lang=en: C++/Python interoperability with Boost.Python +:status: Draft +:copyright: Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved .. contents:: Table of Contents -.. section-numbering:: .. _`Boost Consulting`: http://www.boost-consulting.com +========== + Abstract +========== + +Boost.Python is an open source C++ library which provides a concise +IDL-like interface for binding C++ classes and functions to +Python. Leveraging the full power of C++ compile-time introspection +and of recently developed metaprogramming techniques, this is achieved +entirely in pure C++, without introducing a new syntax. +Boost.Python's rich set of features and high-level interface make it +possible to engineer hybrid software systems from the ground up, +giving programmers easy and coherent access to both the efficient +compile-time polymorphism of C++ and the extremely convenient run-time +polymorphism of Python. + ============== Introduction ============== @@ -77,40 +62,90 @@ Furthermore, the surface differences mask some strong similarities: * High-level concepts such as collections and iterators. -* Strong support for writers of re-usable libraries. +* High-level encapsulation facilities (C++: namespaces, Python: modules) + to support the design of re-usable libraries. + +* Exception-handling for effective management of error conditions. * C++ idioms in common use, such as handle/body classes and reference-counted smart pointers mirror Python reference semantics. -* Exception-handling for effective management of error conditions. - Given Python's rich 'C' interoperability API, it should in principle be possible to expose C++ type and function interfaces to Python with an analogous interface to their C++ counterparts. However, the facilities provided by Python alone for integration with C++ are -relatively meager. Some of this, such as the need to manage -reference-counting manually and lack of C++ exception-handling -support, comes from the limitations of the 'C' language in which the -API is implemented. Most of the remaining issues can be handled if -the code understands the C++ type system. For example: +relatively meager. Compared to C++ and Python, 'C' has only very +rudimentary abstraction facilities, and support for exception-handling +is completely missing. 'C' extension module writers are required to +manually manage Python reference counts, which is both annoyingly +tedious and extremely error-prone. Traditional extension modules also +tend to contain a great deal of boilerplate code repetition which +makes them difficult to maintain, especially when wrapping an evolving +API. -* Every argument of every wrapped function requires some kind of - extraction code to convert it from Python to C++. Likewise, the - function return value has to be converted from C++ to Python. - Appropriate Python exceptions must be raised if the conversion - fails. Argument and return types are part of the function's type, - and much of this tedium can be relieved if the wrapping system can - extract that information through introspection. +These limitations have lead to the development of a variety of wrapping +systems. SWIG_ is probably the most popular package for the +integration of C/C++ and Python. A more recent development is SIP_, +which was specifically designed for interfacing Python with the Qt_ +graphical user interface library. Both SWIG and SIP introduce their +own specialized languages for customizing inter-language bindings. +This has certain advantages, but having to deal with three different +languages (Python, C/C++ and the interface language) also introduces +practical and mental difficulties. The CXX_ package demonstrates an +interesting alternative. It shows that at least some parts of +Python's 'C' API can be wrapped and presented through a much more +user-friendly C++ interface. However, unlike SWIG and SIP, CXX does +not include support for wrapping C++ classes as new Python types. -* Passing a wrapped C++ derived class instance to a C++ function - accepting a pointer or reference to a base class requires knowledge - of the inheritance relationship and how to translate the address of - a base class into that of a derived class. +The features and goals of Boost.Python_ overlap significantly with +many of these other systems. That said, Boost.Python attempts to +maximize convenience and flexibility without introducing a separate +wrapping language. Instead, it presents the user with a high-level +C++ interface for wrapping C++ classes and functions, managing much of +the complexity behind-the-scense with static metaprogramming. +Boost.Python also goes beyond the scope of earlier systems by +providing: -The Boost.Python Library (BPL) leverages the power of C++ -meta-programming techniques to introspect about the C++ type system, -and presents a simple, IDL-like C++ interface for exposing C++ code in -extension modules. +* Support for C++ virtual functions that can be overridden in Python. + +* Comprehensive lifetime management facilities for low-level C++ + pointers and references. + +* Support for organizing extensions as Python packages, + with a central registry for inter-language type conversions. + +* A safe and convenient mechanism for tying into Python's powerful + serialization engine (pickle). + +* Coherence with the rules for handling C++ lvalues and rvalues that + can only come from a deep understanding of both the Python and C++ + type systems. + +The key insight that sparked the development of Boost.Python is that +much of the boilerplate code in traditional extension modules could be +eliminated using C++ compile-time introspection. Each argument of a +wrapped C++ function must be extracted from a Python object using a +procedure that depends on the argument type. Similarly the function's +return type determines how the return value will be converted from C++ +to Python. Of course argument and return types are part of each +function's type, and this is exactly the source from which +Boost.Python deduces most of the information required. + +This approach leads to *user guided wrapping*: as much information is +extracted directly from the source code to be wrapped as is possible +within the framework of pure C++, and some additional information is +supplied explicitly by the user. Mostly the guidance is mechanical +and little real intervention is required. Because there the interface +specification is written in the same full-featured language as the +code being exposed, the user has unprecedented power available when +she does need to take control. + +.. _Python: http://www.python.org/ +.. _SWIG: http://www.swig.org/ +.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php +.. _Qt: http://www.trolltech.com/ +.. _CXX: http://cxx.sourceforge.net/ +.. _Boost.Python: http://www.boost.org/libs/python/doc =========================== Boost.Python Design Goals @@ -211,9 +246,8 @@ and here it is in action:: Boost.Python world! -Aside from the fact that the 'C' API version is much more verbose than -the BPL one, it's worth noting that it doesn't handle a few things -correctly: +Aside from the fact that the 'C' API version is much more verbose, +it's worth noting a few things that it doesn't handle correctly: * The original function accepts an unsigned integer, and the Python 'C' API only gives us a way of extracting signed integers. The @@ -240,8 +274,8 @@ correctly: (arbitrary-precision integers) which happen to fit in an ``unsigned int`` but not in a ``signed long``, nor will it ever handle a wrapped C++ class with a user-defined implicit ``operator unsigned - int()`` conversion. The BPL's dynamic type conversion registry - allows users to add arbitrary conversion methods. + int()`` conversion. Boost.Python's dynamic type conversion + registry allows users to add arbitrary conversion methods. ================== Library Overview @@ -282,15 +316,15 @@ most of the C++ code they're used to. All the same, this is just standard C++. Because of their flexible syntax and operator overloading, C++ and Python are great for defining domain-specific (sub)languages -(DSLs), and that's what we've done in BPL. To break it down:: +(DSLs), and that's what we've done in Boost.Python. To break it down:: class_("World") constructs an unnamed object of type ``class_`` and passes ``"World"`` to its constructor. This creates a new-style Python class called ``World`` in the extension module, and associates it with the -C++ type ``World`` in the BPL type conversion registry. We might have -also written:: +C++ type ``World`` in the Boost.Python type conversion registry. We +might have also written:: class_ w("World"); @@ -314,8 +348,8 @@ So the example is equivalent to:: w.def("set", &World::set); It's occasionally useful to be able to break down the components of a -Boost.Python class wrapper in this way, but the rest of this paper -will tend to stick to the terse syntax. +Boost.Python class wrapper in this way, but the rest of this article +will stick to the terse syntax. For completeness, here's the wrapped class in use: @@ -330,9 +364,9 @@ Constructors Since our ``World`` class is just a plain ``struct``, it has an implicit no-argument (nullary) constructor. Boost.Python exposes the -nullary constructor by default, which is why we were able to write: +nullary constructor by default, which is why we were able to write: :: ->>> planet = hello.World() + >>> planet = hello.World() However, well-designed classes in any language may require constructor arguments in order to establish their invariants. Unlike Python, @@ -383,18 +417,18 @@ This does *not* result in adding attributes to the ``World`` instance ``__dict__``, which can result in substantial memory savings when wrapping large data structures. In fact, no instance ``__dict__`` will be created at all unless attributes are explicitly added from -Python. BPL owes this capability to the new Python 2.2 type system, -in particular the descriptor interface and ``property`` type. +Python. Boost.Python owes this capability to the new Python 2.2 type +system, in particular the descriptor interface and ``property`` type. In C++, publicly-accessible data members are considered a sign of poor design because they break encapsulation, and style guides usually dictate the use of "getter" and "setter" functions instead. In Python, however, ``__getattr__``, ``__setattr__``, and since 2.2, ``property`` mean that attribute access is just one more -well-encapsulated syntactic tool at the programmer's disposal. BPL -bridges this idiomatic gap by making Python ``property`` creation -directly available to users. So if ``msg`` were private, we could -still expose it as attribute in Python as follows:: +well-encapsulated syntactic tool at the programmer's disposal. +Boost.Python bridges this idiomatic gap by making Python ``property`` +creation directly available to users. If ``msg`` were private, we +could still expose it as attribute in Python as follows:: class_("World", init()) .add_property("msg", &World::greet, &World::set) @@ -412,59 +446,40 @@ The example above mirrors the familiar usage of properties in Python ... self.__msg = msg ... msg = property(greet, set) -Operators and Special Functions -=============================== +Operator Overloading +==================== -The ability to write arithmetic operators for user-defined types that -C++ and Python both allow the definition of has been a major factor in -the popularity of both languages for scientific computing. The -success of packages like NumPy attests to the power of exposing -operators in extension modules. In this example we'll wrap a class -representing a position in a large file:: +The ability to write arithmetic operators for user-defined types has +been a major factor in the success of both languages for numerical +computation, and the success of packages like NumPy_ attests to the +power of exposing operators in extension modules. Boost.Python +provides a concise mechanism for wrapping operator overloads. The +example below shows a fragment from a wrapper for the Boost rational +number library:: - class FilePos { /*...*/ }; - - // Linear offset - FilePos operator+(FilePos, int); - FilePos operator+(int, FilePos); - FilePos operator-(FilePos, int); - - // Distance between two FilePos objects - int operator-(FilePos, FilePos); - - // Offset with assignment - FilePos& operator+=(FilePos&, int); - FilePos& operator-=(FilePos&, int); - - // Comparison - bool operator<(FilePos, FilePos); - -The wrapping code looks like this:: - - class_("FilePos") - .def(self + int()) // __add__ - .def(int() + self) // __radd__ - .def(self - int()) // __sub__ - - .def(self - self) // __sub__ - - .def(self += int()) // __iadd__ - .def(self -= int()) // __isub__ - - .def(self < self); // __lt__ - ; + class_ >("rational_int") + .def(init()) // constructor, e.g. rational_int(3,4) + .def("numerator", &rational::numerator) + .def("denominator", &rational::denominator) + .def(-self) // __neg__ (unary minus) + .def(self + self) // __add__ (homogeneous) + .def(self * self) // __mul__ + .def(self + int()) // __add__ (heterogenous) + .def(int() + self) // __radd__ + ... The magic is performed using a simplified application of "expression -templates" [VELD1995]_, a technique originally developed by for +templates" [VELD1995]_, a technique originally developed for optimization of high-performance matrix algebra expressions. The essence is that instead of performing the computation immediately, operators are overloaded to construct a type *representing* the computation. In matrix algebra, dramatic optimizations are often available when the structure of an entire expression can be taken into -account, rather than processing each operation "greedily". +account, rather than evaluating each operation "greedily". Boost.Python uses the same technique to build an appropriate Python -callable object based on an expression involving ``self``, which is -then added to the class. +method object based on expressions involving ``self``. + +.. _NumPy: http://www.pfdubois.com/numpy/ Inheritance =========== @@ -479,11 +494,11 @@ parameter list as follows:: This has two effects: 1. When the ``class_<...>`` is created, Python type objects - corresponding to ``Base1`` and ``Base2`` are looked up in the BPL - registry, and are used as bases for the new Python ``Derived`` type - object [#mi]_, so methods exposed for the Python ``Base1`` and - ``Base2`` types are automatically members of the ``Derived`` type. - Because the registry is global, this works correctly even if + corresponding to ``Base1`` and ``Base2`` are looked up in + Boost.Python's registry, and are used as bases for the new Python + ``Derived`` type object, so methods exposed for the Python ``Base1`` + and ``Base2`` types are automatically members of the ``Derived`` + type. Because the registry is global, this works correctly even if ``Derived`` is exposed in a different module from either of its bases. @@ -515,20 +530,20 @@ Because C++ object construction is a one-step operation, C++ instance data cannot be constructed until the arguments are available, in the ``__init__`` function: ->>> class D(SomeBPLClass): +>>> class D(SomeBoostPythonClass): ... def __init__(self): ... pass ... ->>> D().some_bpl_method() +>>> D().some_boost_python_method() Traceback (most recent call last): File "", line 1, in ? TypeError: bad argument type for built-in operation This happened because Boost.Python couldn't find instance data of type -``SomeBPLClass`` within the ``D`` instance; ``D``'s ``__init__`` +``SomeBoostPythonClass`` within the ``D`` instance; ``D``'s ``__init__`` function masked construction of the base class. It could be corrected by either removing ``D``'s ``__init__`` function or having it call -``SomeBPLClass.__init__(...)`` explicitly. +``SomeBoostPythonClass.__init__(...)`` explicitly. Virtual Functions ================= @@ -605,13 +620,30 @@ Things to notice about the dispatcher class: exposed is not pure virtual; there's no other way ``Base::f`` can be called on an object of type ``BaseWrap``, since it overrides ``f``. +Deeper Reflection on the Horizon? +================================= + Admittedly, this formula is tedious to repeat, especially on a project -with many polymorphic classes; that it is neccessary reflects -limitations in C++'s compile-time reflection capabilities. Several -efforts are underway to write front-ends for Boost.Python which can -generate these dispatchers (and other wrapping code) automatically. -If these are successful it will mark a move away from wrapping -everything directly in pure C++ for many of our users. +with many polymorphic classes. That it is neccessary reflects some +limitations in C++'s compile-time introspection capabilities: there's +no way to enumerate the members of a class and find out which are +virtual functions. At least one very promising project has been +started to write a front-end which can generate these dispatchers (and +other wrapping code) automatically from C++ headers. + +Pyste builds on GCC_XML_, which generates an XML version of GCC's +internal program representation. Since GCC is a highly-conformant C++ +compiler, this ensures correct handling of the most-sophisticated +template code and full access to the underlying type system. In +keeping with the Boost.Python philosophy, a Pyste interface +description is neither intrusive on the code being wrapped, nor +expressed in some unfamiliar language: instead it is a 100% pure +Python script. If Pyste is successful it will mark a move away from +wrapping everything directly in C++ for many of our users. We expect +that soon, not only our users but the Boost.Python developers +themselves will be "thinking hybrid" about their own code. + +.. _`GCC_XML`: http://www.gccxml.org/HTML/Index.html --------------- Serialization @@ -622,7 +654,7 @@ form that can be stored on disk or sent over a network connection. The serialized object (most often a plain string) can be retrieved and converted back to the original object. A good serialization system will automatically convert entire object hierarchies. Python's standard -``pickle`` module is such a system. It leverages the language's strong +``pickle`` module is just such a system. It leverages the language's strong runtime introspection facilities for serializing practically arbitrary user-defined objects. With a few simple and unintrusive provisions this powerful machinery can be extended to also work for wrapped C++ objects. @@ -673,16 +705,14 @@ Of course the ``cPickle`` module can also be used for faster processing. Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol -defined in the standard Python documentation. There is a one-to-one -correspondence between the standard pickling methods (``__getinitargs__``, -``__getstate__``, ``__setstate__``) and the functions defined by the -user in the class derived from ``pickle_suite`` (``getinitargs``, -``getstate``, ``setstate``). The ``class_::def_pickle()`` member function -is used to establish the Python bindings for all user-defined functions -simultaneously. Correct signatures for these functions are enforced at -compile time. Non-sensical combinations of the three pickle functions -are also rejected at compile time. These measures are designed to -help the user in avoiding obvious errors. +defined in the standard Python documentation. Like a __getinitargs__ +function in Python, the pickle_suite's getinitargs() is responsible for +creating the argument tuple that will be use to reconstruct the pickled +object. The other elements of the Python pickling protocol, +__getstate__ and __setstate__ can be optionally provided via C++ +getstate and setstate functions. C++'s static type system allows the +library to ensure at compile-time that nonsensical combinations of +functions (e.g. getstate without setstate) are not used. Enabling serialization of more complex C++ objects requires a little more work than is shown in the example above. Fortunately the @@ -693,58 +723,38 @@ code manageable. Object interface ------------------ -Experienced extension module authors will be familiar with the 'C' view -of Python objects, the ubiquitous ``PyObject*``. Most if not all Python -'C' API functions involve ``PyObject*`` as arguments or return type. A -major complication is the raw reference counting interface presented to -the 'C' programmer. E.g. some API functions return *new references* and -others return *borrowed references*. It is up to the extension module -writer to properly increment and decrement reference counts. This -quickly becomes cumbersome and error prone, especially if there are -multiple execution paths. +Experienced 'C' language extension module authors will be familiar +with the ubiquitous ``PyObject*``, manual reference-counting, and the +need to remember which API calls return "new" (owned) references or +"borrowed" (raw) references. These constraints are not just +cumbersome but also a major source of errors, especially in the +presence of exceptions. -Boost.Python provides a type ``object`` which is essentially a high -level wrapper around ``PyObject*``. ``object`` automates reference -counting as much as possible. It also provides the facilities for -converting arbitrary C++ types to Python objects and vice versa. -This significantly reduces the learning effort for prospective -extension module writers. +Boost.Python provides a class ``object`` which automates reference +counting and provides conversion to Python from C++ objects of +arbitrary type. This significantly reduces the learning effort for +prospective extension module writers. Creating an ``object`` from any other type is extremely simple:: - object o(3); + object s("hello, world"); // s manages a Python string ``object`` has templated interactions with all other types, with automatic to-python conversions. It happens so naturally that it's -easily overlooked. +easily overlooked:: + + object ten_Os = 10 * s[4]; // -> "oooooooooo" + +In the example above, ``4`` and ``10`` are converted to Python objects +before the indexing and multiplication operations are invoked. The ``extract`` class template can be used to convert Python objects to C++ types:: double x = extract(o); -All registered user-defined conversions are automatically accessible -through the ``object`` interface. With reference to the ``World`` class -defined in previous examples:: - - object as_python_object(World("howdy")); - World back_as_c_plus_plus_object = extract(as_python_object); - -If a C++ type cannot be converted to a Python object an appropriate -exception is thrown at runtime. Similarly, an appropriate exception is -thrown if a C++ type cannot be extracted from a Python object. -``extract`` provides facilities for avoiding exceptions if this is -desired. - -The ``object::attr()`` member function is available for accessing -and manipulating attributes of Python objects. For example:: - - object planet(World()); - planet.attr("set")("howdy"); - -``planet.attr("set")`` returns a callable ``object``. ``"howdy"`` is -converted to a Python string object which is then passed as an argument -to the ``set`` method. +If a conversion in either direction cannot be performed, an +appropriate exception is thrown at runtime. The ``object`` type is accompanied by a set of derived types that mirror the Python built-in types such as ``list``, ``dict``, @@ -756,104 +766,83 @@ manipulation of these high-level types from C++:: d["lucky_number"] = 13; list l = d.keys(); -This almost looks and works like regular Python code, but it is pure C++. +This almost looks and works like regular Python code, but it is pure +C++. Of course we can wrap C++ functions which accept or return +``object`` instances. + +.. ===================== + Development history + ===================== + + XXX Outline of development history to illustrate that the + library is mature. XXX + + This can be postponed for the PyConDC paper ================= Thinking hybrid ================= -For many applications runtime performance considerations are very -important. This is particularly true for most scientific applications. -Often the performance considerations dictate the use of a compiled -language for the core algorithms. Traditionally the decision to use a -particular programming language is an exclusive one. Because of the -practical and mental difficulties of combining different languages many -systems are written in just one language. This is quite unfortunate -because the price payed for runtime performance is typically a -significant overhead due to static typing. For example, our experience -shows that developing maintainable C++ code is typically much more -time-consuming and requires much more hard-earned working experience -than developing useful Python code. A related observation is that many -compiled packages are augmented by some type of rudimentary scripting -layer. These ad hoc solutions clearly show that many times a compiled -language alone does not get the job done. On the other hand it is also -clear that a pure Python implementation is too slow for numerically -intensive production code. +Because of the practical and mental difficulties of combining +programming languages, it is common to settle a single language at the +outset of any development effort. For many applications, performance +considerations dictate the use of a compiled language for the core +algorithms. Unfortunately, due to the complexity of the static type +system, the price we pay for runtime performance is often a +significant increase in development time. Experience shows that +writing maintainable C++ code usually takes longer and requires *far* +more hard-earned working experience than developing comparable Python +code. Even when developers are comfortable working exclusively in +compiled languages, they often augment their systems by some type of +ad hoc scripting layer for the benefit of their users without ever +availing themselves of the same advantages. -Boost.Python enables us to *think hybrid* when developing new -applications. Python can be used for rapidly prototyping a -new application. Python's ease of use and the large pool of standard -libraries give us a head start on the way to a first working system. If -necessary, the working procedure can be used to discover the -rate-limiting algorithms. To maximize performance these can be -reimplemented in C++, together with the Boost.Python bindings needed to -tie them back into the existing higher-level procedure. +Boost.Python enables us to *think hybrid*. Python can be used for +rapidly prototyping a new application; its ease of use and the large +pool of standard libraries give us a head start on the way to a +working system. If necessary, the working code can be used to +discover rate-limiting hotspots. To maximize performance these can +be reimplemented in C++, together with the Boost.Python bindings +needed to tie them back into the existing higher-level procedure. Of course, this *top-down* approach is less attractive if it is clear from the start that many algorithms will eventually have to be -implemented in a compiled language. Fortunately Boost.Python also -enables us to pursue a *bottom-up* approach. We have used this approach -very successfully in the development of a toolbox for scientific -applications (scitbx) that we will describe elsewhere. The toolbox -started out mainly as a library of C++ classes with Boost.Python -bindings, and for a while the growth was mainly concentrated on the C++ -parts. However, as the toolbox is becoming more complete, more and more -newly added functionality can be implemented in Python. We expect this -trend to continue, as illustrated qualitatively in this figure: +implemented in C++. Fortunately Boost.Python also enables us to +pursue a *bottom-up* approach. We have used this approach very +successfully in the development of a toolbox for scientific +applications. The toolbox started out mainly as a library of C++ +classes with Boost.Python bindings, and for a while the growth was +mainly concentrated on the C++ parts. However, as the toolbox is +becoming more complete, more and more newly added functionality can be +implemented in Python. .. image:: python_cpp_mix.png -This figure shows the ratio of newly added C++ and Python code over -time as new algorithms are implemented. We expect this ratio to level -out near 70% Python. The increasing ability to solve new problems -mostly with the easy-to-use Python language rather than a necessarily -more arcane statically typed language is the return on the investment -of learning how to use Boost.Python. The ability to solve some problems -entirely using only Python will enable a larger group of people to -participate in the rapid development of new applications. +This figure shows the estimated ratio of newly added C++ and Python +code over time as new algorithms are implemented. We expect this +ratio to level out near 70% Python. Being able to solve new problems +mostly in Python rather than a more difficult statically typed +language is the return on our investment in Boost.Python. The ability +to access all of our code from Python allows a broader group of +developers to use it in the rapid development of new applications. ============= Conclusions ============= -The examples in this paper illustrate that Boost.Python enables -seamless interoperability between C++ and Python. Importantly, this is -achieved without introducing a third syntax: the Python/C++ interface -definitions are written in pure C++. This avoids any problems with -parsing the C++ code to be interfaced to Python, yet the interface -definitions are concise and maintainable. Freed from most of the -development-time penalties of crossing a language boundary, software -designers can take full advantage of two rich and complimentary -language environments. In practice it turns out that some things are -very difficult to do with pure Python/C (e.g. an efficient array -library with an intuitive interface in the compiled language) and -others are very difficult to do with pure C++ (e.g. serialization). -If one has the luxury of being able to design a software system as a -hybrid system from the ground up there are many new ways of avoiding -road blocks in one language or the other. +Boost.Python achieves seamless interoperability between two rich and +complimentary language environments. Because it leverages template +metaprogramming to introspect about types and functions, the user +never has to learn a third syntax: the interface definitions are +written in concise and maintainable C++. Also, the wrapping system +doesn't have to parse C++ headers or represent the type system: the +compiler does that work for us. -.. I'm not ready to give up on all of this quite yet - -.. Perhaps one day we'll have a language with the simplicity and - expressive power of Python and the compile-time muscle of C++. Being - able to take advantage of all of these facilities without paying the - mental and development-time penalties of crossing a language barrier - would bring enormous benefits. Until then, interoperability tools - like Boost.Python can help lower the barrier and make the benefits of - both languages more accessible to both communities. - -=========== - Footnotes -=========== - -.. [#mi] For hard-core new-style class/extension module writers it is - worth noting that the normal requirement that all extension classes - with data form a layout-compatible single-inheritance chain is - lifted for Boost.Python extension classes. Clearly, either - ``Base1`` or ``Base2`` has to occupy a different offset in the - ``Derived`` class instance. This is possible because the wrapped - part of BPL extension class instances is never assumed to have a - fixed offset within the wrapper. +Computationally intensive tasks play to the strengths of C++ and are +often impossible to implement efficiently in pure Python, while jobs +like serialization that are trivial in Python can be very difficult in +pure C++. Given the luxury of building a hybrid software system from +the ground up, we can approach design with new confidence and power. =========== Citations From 15a148ab108b8c2f74b61164153f410608d90a7a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 2 Mar 2003 02:50:49 +0000 Subject: [PATCH 1024/1042] minor polishing, corrections [SVN r17696] --- doc/PyConDC_2003/bpl.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt index 3332373f..9241acb9 100644 --- a/doc/PyConDC_2003/bpl.txt +++ b/doc/PyConDC_2003/bpl.txt @@ -27,7 +27,7 @@ Python. Leveraging the full power of C++ compile-time introspection and of recently developed metaprogramming techniques, this is achieved entirely in pure C++, without introducing a new syntax. Boost.Python's rich set of features and high-level interface make it -possible to engineer hybrid software systems from the ground up, +possible to engineer packages from the ground up as hybrid systems, giving programmers easy and coherent access to both the efficient compile-time polymorphism of C++ and the extremely convenient run-time polymorphism of Python. @@ -102,7 +102,7 @@ many of these other systems. That said, Boost.Python attempts to maximize convenience and flexibility without introducing a separate wrapping language. Instead, it presents the user with a high-level C++ interface for wrapping C++ classes and functions, managing much of -the complexity behind-the-scense with static metaprogramming. +the complexity behind-the-scenes with static metaprogramming. Boost.Python also goes beyond the scope of earlier systems by providing: @@ -135,7 +135,7 @@ This approach leads to *user guided wrapping*: as much information is extracted directly from the source code to be wrapped as is possible within the framework of pure C++, and some additional information is supplied explicitly by the user. Mostly the guidance is mechanical -and little real intervention is required. Because there the interface +and little real intervention is required. Because the interface specification is written in the same full-featured language as the code being exposed, the user has unprecedented power available when she does need to take control. From 4b97e191b8edb3e3724d5aca161b4a6081575e37 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 2 Mar 2003 15:25:35 +0000 Subject: [PATCH 1025/1042] Fix formatting errors [SVN r17697] --- doc/PyConDC_2003/bpl.txt | 88 ++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/doc/PyConDC_2003/bpl.txt b/doc/PyConDC_2003/bpl.txt index 9241acb9..8113f50e 100644 --- a/doc/PyConDC_2003/bpl.txt +++ b/doc/PyConDC_2003/bpl.txt @@ -351,13 +351,13 @@ It's occasionally useful to be able to break down the components of a Boost.Python class wrapper in this way, but the rest of this article will stick to the terse syntax. -For completeness, here's the wrapped class in use: +For completeness, here's the wrapped class in use: :: ->>> import hello ->>> planet = hello.World() ->>> planet.set('howdy') ->>> planet.greet() -'howdy' + >>> import hello + >>> planet = hello.World() + >>> planet.set('howdy') + >>> planet.greet() + 'howdy' Constructors ============ @@ -407,11 +407,11 @@ exposed as either ``readonly`` or ``readwrite`` attributes:: .def_readonly("msg", &World::msg) ... -and can be used directly in Python: +and can be used directly in Python: :: ->>> planet = hello.World('howdy') ->>> planet.msg -'howdy' + >>> planet = hello.World('howdy') + >>> planet.msg + 'howdy' This does *not* result in adding attributes to the ``World`` instance ``__dict__``, which can result in substantial memory savings when @@ -435,16 +435,16 @@ could still expose it as attribute in Python as follows:: ... The example above mirrors the familiar usage of properties in Python -2.2+: +2.2+: :: ->>> class World(object): -... __init__(self, msg): -... self.__msg = msg -... def greet(self): -... return self.__msg -... def set(self, msg): -... self.__msg = msg -... msg = property(greet, set) + >>> class World(object): + ... __init__(self, msg): + ... self.__msg = msg + ... def greet(self): + ... return self.__msg + ... def set(self, msg): + ... self.__msg = msg + ... msg = property(greet, set) Operator Overloading ==================== @@ -517,27 +517,27 @@ system, that works very much as for the Python built-in types. There is one significant detail in which it differs: the built-in types generally establish their invariants in their ``__new__`` function, so that derived classes do not need to call ``__init__`` on the base -class before invoking its methods : +class before invoking its methods : :: ->>> class L(list): -... def __init__(self): -... pass -... ->>> L().reverse() ->>> + >>> class L(list): + ... def __init__(self): + ... pass + ... + >>> L().reverse() + >>> Because C++ object construction is a one-step operation, C++ instance data cannot be constructed until the arguments are available, in the -``__init__`` function: +``__init__`` function: :: ->>> class D(SomeBoostPythonClass): -... def __init__(self): -... pass -... ->>> D().some_boost_python_method() -Traceback (most recent call last): - File "", line 1, in ? -TypeError: bad argument type for built-in operation + >>> class D(SomeBoostPythonClass): + ... def __init__(self): + ... pass + ... + >>> D().some_boost_python_method() + Traceback (most recent call last): + File "", line 1, in ? + TypeError: bad argument type for built-in operation This happened because Boost.Python couldn't find instance data of type ``SomeBoostPythonClass`` within the ``D`` instance; ``D``'s ``__init__`` @@ -592,16 +592,16 @@ class' virtual functions:: .def("f", &Base::f, &BaseWrap::f_default) ; -Now here's some Python code which demonstrates: +Now here's some Python code which demonstrates: :: ->>> class Derived(Base): -... def f(self, s): -... return len(s) -... ->>> calls_f(Base(), 'foo') -42 ->>> calls_f(Derived(), 'forty-two') -9 + >>> class Derived(Base): + ... def f(self, s): + ... return len(s) + ... + >>> calls_f(Base(), 'foo') + 42 + >>> calls_f(Derived(), 'forty-two') + 9 Things to notice about the dispatcher class: From 577f58149c1e7053a4e84cae89a0bf8b5c7c2ce0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sun, 2 Mar 2003 22:11:20 +0000 Subject: [PATCH 1026/1042] tests for operators returning const objects [SVN r17700] --- test/operators.cpp | 15 +++++++++++---- test/operators.py | 3 +++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/test/operators.cpp b/test/operators.cpp index e4ac1e07..9e7a1e5a 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -21,7 +21,13 @@ using namespace boost::python; -typedef test_class<> X; +struct X : test_class<> +{ + typedef test_class<> base_t; + + X(int x) : base_t(x) {} + X const operator+(X const& r) { return X(value() + r.value()); } +}; X operator-(X const& l, X const& r) { return X(l.value() - r.value()); } X operator-(int l, X const& r) { return X(l - r.value()); } @@ -39,17 +45,17 @@ X abs(X x) { return X(x.value() < 0 ? -x.value() : x.value()); } X pow(X x, int y) { - return X(int(pow(double(x.value()), y))); + return X(int(pow(double(x.value()), double(y)))); } X pow(X x, X y) { - return X(int(pow(double(x.value()), y.value()))); + return X(int(pow(double(x.value()), double(y.value())))); } int pow(int x, X y) { - return int(pow(double(x), y.value())); + return int(pow(double(x), double(y.value()))); } std::ostream& operator<<(std::ostream& s, X const& x) @@ -61,6 +67,7 @@ BOOST_PYTHON_MODULE(operators_ext) { class_("X", init()) .def("value", &X::value) + .def(self + self) .def(self - self) .def(self - int()) .def(other() - self) diff --git a/test/operators.py b/test/operators.py index 58ffb5eb..b18d4d2d 100644 --- a/test/operators.py +++ b/test/operators.py @@ -15,6 +15,9 @@ >>> (-y).value() 39 +>>> (x + y).value() +3 + >>> abs(y).value() 39 From d028a60cc2158ac7c4614f73959ea5a31ae335dd Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 3 Mar 2003 17:21:30 +0000 Subject: [PATCH 1027/1042] Workaround for vc7 bug (and regression test) [SVN r17708] --- include/boost/python/detail/is_xxx.hpp | 3 ++- test/implicit.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/boost/python/detail/is_xxx.hpp b/include/boost/python/detail/is_xxx.hpp index ad888b84..0faea999 100644 --- a/include/boost/python/detail/is_xxx.hpp +++ b/include/boost/python/detail/is_xxx.hpp @@ -12,6 +12,7 @@ # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) # include +# include # define BOOST_PYTHON_IS_XXX_DEF(name, qualified_name, nargs) \ template \ @@ -20,7 +21,7 @@ struct is_##name \ typedef char yes; \ typedef char (&no)[2]; \ \ - static X_ dummy; \ + static typename add_reference::type dummy; \ \ template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \ static yes test( \ diff --git a/test/implicit.cpp b/test/implicit.cpp index b56e6b10..c4728548 100644 --- a/test/implicit.cpp +++ b/test/implicit.cpp @@ -20,8 +20,18 @@ int x_value(X const& x) X make_x(int n) { return X(n); } + +// foo/bar -- a regression for a vc7 bug workaround +struct bar {}; +struct foo +{ + virtual void f() = 0; + operator bar() const { return bar(); } +}; + BOOST_PYTHON_MODULE(implicit_ext) { + implicitly_convertible(); implicitly_convertible(); def("x_value", x_value); From ff734e3269b9789e2e08de650c55c31afc5d83ac Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 8 Mar 2003 00:25:47 +0000 Subject: [PATCH 1028/1042] MIPSpro compatibility [SVN r17772] --- include/boost/python/enum.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/python/enum.hpp b/include/boost/python/enum.hpp index b1fac410..02092510 100644 --- a/include/boost/python/enum.hpp +++ b/include/boost/python/enum.hpp @@ -92,7 +92,7 @@ inline enum_& enum_::value(char const* name, T x) template inline enum_& enum_::export_values() { - this->enum_base::export_values(); + this->base::export_values(); return *this; } From ca64c961333f91327e6837f6fa06664eba0dea56 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 8 Mar 2003 03:53:19 +0000 Subject: [PATCH 1029/1042] Added dangling_reference FAQ Various idiomatic MPL cleanups in indirect_traits.hpp raw_function support Patches for CWPro7.2 Patches to pass tests under Python 2.3 with the new bool type. Tests for member operators returning const objects Fixes for testing Boost.Python under Cygwin [SVN r17777] --- doc/v2/def.html | 119 ++-- doc/v2/faq.html | 577 +++++++++--------- doc/v2/raw_function.html | 116 ++++ doc/v2/reference.html | 26 +- include/boost/python/class.hpp | 2 + include/boost/python/def.hpp | 7 +- .../boost/python/detail/indirect_traits.hpp | 157 +++-- include/boost/python/detail/is_shared_ptr.hpp | 18 + include/boost/python/init.hpp | 5 +- include/boost/python/object/inheritance.hpp | 11 +- .../boost/python/object/make_ptr_instance.hpp | 8 +- include/boost/python/raw_function.hpp | 47 ++ src/object/function.cpp | 96 ++- test/args.cpp | 10 + test/args.py | 8 + test/back_reference.py | 3 +- test/enum.cpp | 12 +- test/operators.cpp | 2 +- test/test_builtin_converters.py | 30 +- test/test_pointer_adoption.py | 6 +- 20 files changed, 789 insertions(+), 471 deletions(-) create mode 100755 doc/v2/raw_function.html create mode 100755 include/boost/python/detail/is_shared_ptr.hpp create mode 100755 include/boost/python/raw_function.hpp diff --git a/doc/v2/def.html b/doc/v2/def.html index fdd0516f..80978a87 100644 --- a/doc/v2/def.html +++ b/doc/v2/def.html @@ -3,7 +3,7 @@ + "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org"> @@ -75,6 +75,12 @@ void def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);

        +
      • If Fn is [derived from] object, it will be added to + the current scope as a single overload. To be useful, + fn should be callable.
      • +
      • If a1 is the result of an overload-dispatch-expression, @@ -104,67 +110,52 @@ void def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
      -
    • - Otherwise, a single function overload built around fn (which must - not be null) is added to the current - scope: - -
        -
      • If fn is a function or member function pointer, - a1-a3 (if supplied) may be selected - in any order from the table below.
      • - -
      • Otherwise, Fn must be [derived from] object, and - a1-a2 (if supplied) may be selcted in any order - from the first two rows of the table below. To be useful, - fn should be - callable.
      • -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Memnonic NameRequirements/Type propertiesEffects
      docstringAny ntbs.Value will be bound to the __doc__ attribute - of the resulting method overload.
      policiesA model of CallPoliciesA copy will be used as the call policies of the resulting - method overload.
      keywordsThe result of a keyword-expression - specifying no more arguments than the arity of fn.A copy will be used as the call policies of the resulting - method overload.
      -
    • +
    • Otherwise, fn must be a non-null function or member function + pointer, and a single function overload built around fn is added to + the current scope. If any of + a1-a3 are supplied, they may be selected + in any order from the table below.
    • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Memnonic NameRequirements/Type propertiesEffects
      docstringAny ntbs.Value will be bound to the __doc__ attribute of + the resulting method overload.
      policiesA model of CallPoliciesA copy will be used as the call policies of the resulting + method overload.
      keywordsThe result of a keyword-expression + specifying no more arguments than the arity of fn.A copy will be used as the call policies of the resulting + method overload.
      @@ -174,6 +165,8 @@ void def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&); #include <boost/python/module.hpp> #include <boost/python/args.hpp> +using namespace boost::python; + char const* foo(int x, int y) { return "foo"; } BOOST_PYTHON_MODULE(def_test) @@ -184,8 +177,8 @@ BOOST_PYTHON_MODULE(def_test)

      - 13 November, 2002 - + 7 March, 2003 +

      © Copyright + + "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org"> - - Boost.Python - FAQ - + + Boost.Python - FAQ + - +
      +
      -

      - C++ Boost -

      +

      C++ Boost

      -

      - Boost.Python -

      -

      - Frequently Asked Questions (FAQs) -

      +

      Boost.Python

      + +

      Frequently Asked Questions (FAQs)


      +
      -
      - Is return_internal_reference efficient? -
      -
      - How can I wrap functions which take C++ - containers as arguments? -
      -
      - fatal error C1204:Compiler limit:internal structure - overflow -
      -
      - How do I debug my Python extensions? -
      -
      - Why doesn't my *= operator work? -
      -
      - Does Boost.Python work with Mac OS X? -
      -
      - How can I find the existing PyObject that holds a C++ - object? -
      -
      - How can I wrap a function which needs to take - ownership of a raw pointer? -
      +
      I'm getting the "attempt to return dangling + reference" error. What am I doing wrong?
      + +
      Is return_internal_reference + efficient?
      + +
      How can I wrap functions which take C++ + containers as arguments?
      + +
      fatal error C1204:Compiler limit:internal + structure overflow
      + +
      How do I debug my Python extensions?
      + +
      Why doesn't my *= operator + work?
      + +
      Does Boost.Python work with Mac OS X?
      + +
      How can I find the existing PyObject that holds a + C++ object?
      + +
      How can I wrap a function which needs to take + ownership of a raw pointer?

      -

      - Is return_internal_reference efficient? -

      + +

      I'm getting the "attempt to return dangling + reference" error. What am I doing wrong?

      + That exception is protecting you from causing a nasty crash. It usually + happens in response to some code like this: +
      +period const& get_floating_frequency() const
      +{
      +  return boost::python::call_method<period const&>(
      +      m_self,"get_floating_frequency");
      +}
      +
      + And you get: +
      +ReferenceError: Attempt to return dangling reference to object of type:
      +class period
      +
      + +

      In this case, the Python method invoked by call_method + constructs a new Python object. You're trying to return a reference to a + C++ object (an instance of class period) contained within + and owned by that Python object. Because the called method handed back a + brand new object, the only reference to it is held for the duration of + get_floating_frequency() above. When the function returns, + the Python object will be destroyed, destroying the instance of + class period, and leaving the returned reference dangling. + That's already undefined behavior, and if you try to do anything with + that reference you're likely to cause a crash. Boost.Python detects this + situation at runtime and helpfully throws an exception instead of letting + you do that.
      +  

      +
      + +

      Is return_internal_reference efficient?

      +
      Q: I have an object composed of 12 doubles. A const& to this object is returned by a member function of another class. From the @@ -74,126 +99,129 @@ return_internal_reference. Are there considerations that would lead me to prefer one over the other, such as size of generated code or memory overhead? -

      - A: copy_const_reference will make an instance with storage for - one of your objects, size = base_size + 12 * sizeof(double). - return_internal_reference will make an instance with storage for a - pointer to one of your objects, size = base_size + sizeof(void*). - However, it will also create a weak reference object which goes in - the source object's weakreflist and a special callback object to - manage the lifetime of the internally-referenced object. My guess? - copy_const_reference is your friend here, resulting in less overall - memory use and less fragmentation, also probably fewer total cycles. -

      + +

      A: copy_const_reference will make an instance with storage + for one of your objects, size = base_size + 12 * sizeof(double). + return_internal_reference will make an instance with storage for a + pointer to one of your objects, size = base_size + sizeof(void*). + However, it will also create a weak reference object which goes in the + source object's weakreflist and a special callback object to manage the + lifetime of the internally-referenced object. My guess? + copy_const_reference is your friend here, resulting in less overall + memory use and less fragmentation, also probably fewer total + cycles.


      -

      - How can I wrap functions which take C++ - containers as arguments? -

      -

      - Ralf W. Grosse-Kunstleve provides these notes: -

      + +

      How can I wrap functions which take C++ + containers as arguments?

      + +

      Ralf W. Grosse-Kunstleve provides these notes:

      +
      1. Using the regular class_<> wrapper: -
        +
         class_<std::vector<double> >("std_vector_double")
           .def(...)
           ...
           ;
        -
        This can be moved to a template so that several types (double, int, -long, etc.) can be wrapped with the same code. This technique is used in the -file +
        + This can be moved to a template so that several types (double, int, + long, etc.) can be wrapped with the same code. This technique is used + in the file +
        scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h -
        in the "scitbx" package. The file could easily be - modified for wrapping std::vector<> instantiations. -

        - This type of C++/Python binding is most suitable for containers - that may contain a large number of elements (>10000). -

        + + in the "scitbx" package. The file could easily be modified for + wrapping std::vector<> instantiations. + +

        This type of C++/Python binding is most suitable for containers + that may contain a large number of elements (>10000).

      2. +
      3. Using custom rvalue converters. Boost.Python "rvalue converters" match function signatures such as: -
        +
         void foo(std::vector<double> const& array); // pass by const-reference
         void foo(std::vector<double> array); // pass by value
        -
        Some custom rvalue converters are implemented in the file +
        + Some custom rvalue converters are implemented in the file +
        scitbx/include/scitbx/boost_python/container_conversions.h -
        This code can be used to convert from C++ container - types such as std::vector<> or std::list<> to Python - tuples and vice versa. A few simple examples can be found in the file - + + This code can be used to convert from C++ container types such as + std::vector<> or std::list<> to Python tuples and vice + versa. A few simple examples can be found in the file +
        scitbx/array_family/boost_python/regression_test_module.cpp -
        Automatic C++ container <-> Python tuple - conversions are most suitable for containers of moderate size. These - converters generate significantly less object code compared to - alternative 1 above. + + Automatic C++ container <-> Python tuple conversions are most + suitable for containers of moderate size. These converters generate + significantly less object code compared to alternative 1 above.
      4. -
      A disadvantage of using alternative 2 is that operators such as + + A disadvantage of using alternative 2 is that operators such as arithmetic +,-,*,/,% are not available. It would be useful to have custom rvalue converters that convert to a "math_array" type instead of tuples. This is currently not implemented but is possible within the framework of Boost.Python V2 as it will be released in the next couple of weeks. [ed.: this was posted on 2002/03/10] -

      - It would also be useful to also have "custom lvalue converters" such as - std::vector<> <-> Python list. These converters would - support the modification of the Python list from C++. For example: -

      -

      - C++: -

      -
      +
      +    

      It would also be useful to also have "custom lvalue converters" such + as std::vector<> <-> Python list. These converters would + support the modification of the Python list from C++. For example:

      + +

      C++:

      +
       void foo(std::vector<double>& array)
       {
         for(std::size_t i=0;i<array.size();i++) {
           array[i] *= 2;
         }
       }
      -
      Python: -
      +
      + Python: +
       >>> l = [1, 2, 3]
       >>> foo(l)
       >>> print l
       [2, 4, 6]
      -
      Custom lvalue converters require changes to the Boost.Python core -library and are currently not available. -

      - P.S.: -

      -

      - The "scitbx" files referenced above are available via anonymous CVS: -

      -
      +
      + Custom lvalue converters require changes to the Boost.Python core library + and are currently not available. + +

      P.S.:

      + +

      The "scitbx" files referenced above are available via anonymous + CVS:

      +
       cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login
       cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
       

      -

      - fatal error C1204:Compiler limit:internal structure - overflow -

      + +

      fatal error C1204:Compiler limit:internal + structure overflow

      +
      Q: I get this error message when compiling a large source file. What can I do? -

      - A: You have two choices: -

      + +

      A: You have two choices:

      +
        -
      1. - Upgrade your compiler (preferred) -
      2. +
      3. Upgrade your compiler (preferred)
      4. +
      5. Break your source file up into multiple translation units. -

        - my_module.cpp: -

        -
        +
        +          

        my_module.cpp:

        +
         ...
         void more_of_my_module();
         BOOST_PYTHON_MODULE(my_module)
        @@ -203,23 +231,25 @@ BOOST_PYTHON_MODULE(my_module)
            ...
            more_of_my_module();
         }
        -
        more_of_my_module.cpp: -
        +
        + more_of_my_module.cpp: +
         void more_of_my_module()
         {
            def("baz", baz);
            ...
         }
        -
        If you find that a class_<...> declaration can't fit -in a single source file without triggering the error, you can always pass a -reference to the class_ object to a function in another source -file, and call some of its member functions (e.g. .def(...)) in -the auxilliary source file: -

        - more_of_my_class.cpp: -

        -
        +
        + If you find that a class_<...> declaration + can't fit in a single source file without triggering the error, you + can always pass a reference to the class_ object to a + function in another source file, and call some of its member + functions (e.g. .def(...)) in the auxilliary source + file: + +

        more_of_my_class.cpp:

        +
         void more_of_my_class(class<my_class>& x)
         {
            x
        @@ -234,12 +264,11 @@ void more_of_my_class(class<my_class>& x)
               

      -

      - How do I debug my Python extensions? -

      -

      - Greg Burley gives the following answer for Unix GCC users: -

      + +

      How do I debug my Python extensions?

      + +

      Greg Burley gives the following answer for Unix GCC users:

      +
      Once you have created a boost python extension for your c++ library or class, you may need to debug the code. Afterall this is one of the @@ -249,13 +278,12 @@ void more_of_my_class(class<my_class>& x) boost::python either works or it doesn't. (ie. While errors can occur when the wrapping method is invalid, most errors are caught by the compiler ;-). -

      - The basic steps required to initiate a gdb session to debug a c++ - library via python are shown here. Note, however that you should - start the gdb session in the directory that contains your BPL - my_ext.so module. -

      -
      +
      +      

      The basic steps required to initiate a gdb session to debug a c++ + library via python are shown here. Note, however that you should start + the gdb session in the directory that contains your BPL my_ext.so + module.

      +
       (gdb) target exec python
       (gdb) run
        >>> from my_ext import *
      @@ -269,44 +297,43 @@ Current language:  auto; currently c++
       (gdb) do debugging stuff
       
      -

      - Greg's approach works even better using Emacs' "gdb" - command, since it will show you each line of source as you step through - it. -

      -

      - On Windows, my favorite debugging solution is the debugger that - comes with Microsoft Visual C++ 7. This debugger seems to work with - code generated by all versions of Microsoft and Metrowerks toolsets; - it's rock solid and "just works" without requiring any special tricks - from the user. -

      -

      - Unfortunately for Cygwin and MinGW users, as of this writing gdb on - Windows has a very hard time dealing with shared libraries, which could - make Greg's approach next to useless for you. My best advice for you is - to use Metrowerks C++ for compiler conformance and Microsoft Visual - Studio as a debugger when you need one. -

      -

      - Debugging extensions through Boost.Build -

      If you are launching your extension module tests with Greg's approach works even better using Emacs' "gdb" + command, since it will show you each line of source as you step through + it.

      + +

      On Windows, my favorite debugging solution is the debugger that + comes with Microsoft Visual C++ 7. This debugger seems to work with code + generated by all versions of Microsoft and Metrowerks toolsets; it's rock + solid and "just works" without requiring any special tricks from the + user.

      + +

      Unfortunately for Cygwin and MinGW users, as of this writing gdb on + Windows has a very hard time dealing with shared libraries, which could + make Greg's approach next to useless for you. My best advice for you is + to use Metrowerks C++ for compiler conformance and Microsoft Visual + Studio as a debugger when you need one.

      + +

      Debugging extensions through Boost.Build

      + If you are launching your extension module tests with
      Boost.Build using the boost-python-runtest rule, you can ask it to launch your debugger for you by adding "-sPYTHON_LAUNCH=debugger" to your bjam command-line: -
      +
       bjam -sTOOLS=metrowerks "-sPYTHON_LAUNCH=devenv /debugexe" test
       bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
      -
      It can also be extremely useful to add the -d+2 option -when you run your test, because Boost.Build will then show you the exact -commands it uses to invoke it. This will invariably involve setting up -PYTHONPATH and other important environment variables such as LD_LIBRARY_PATH -which may be needed by your debugger in order to get things to work right. +
      + It can also be extremely useful to add the -d+2 option when + you run your test, because Boost.Build will then show you the exact + commands it uses to invoke it. This will invariably involve setting up + PYTHONPATH and other important environment variables such as + LD_LIBRARY_PATH which may be needed by your debugger in order to get + things to work right.
      -

      - Why doesn't my *= operator work? -

      + +

      Why doesn't my *= operator work?

      +
      Q: I have exported my class to python, with many overloaded operators. it works fine for me except the *= @@ -314,60 +341,57 @@ which may be needed by your debugger in order to get things to work right. type". If I use p1.__imul__(p2) instead of p1 *= p2, it successfully executes my code. What's wrong with me? -

      - A: There's nothing wrong with you. This is a bug in Python - 2.2. You can see the same effect in Pure Python (you can learn a lot - about what's happening in Boost.Python by playing with new-style - classes in Pure Python). -

      -
      +
      +      

      A: There's nothing wrong with you. This is a bug in Python + 2.2. You can see the same effect in Pure Python (you can learn a lot + about what's happening in Boost.Python by playing with new-style + classes in Pure Python).

      +
       >>> class X(object):
       ...     def __imul__(self, x):
       ...         print 'imul'
       ...
       >>> x = X()
       >>> x *= 1
      -
      To cure this problem, all you need to do is upgrade your Python to -version 2.2.1 or later. +
      + To cure this problem, all you need to do is upgrade your Python to + version 2.2.1 or later.

      -

      - Does Boost.Python work with Mac OS X? -

      + +

      Does Boost.Python work with Mac OS X?

      +
      -

      - The short answer: as of January 2003, unfortunately not. -

      -

      - The longer answer: using Mac OS 10.2.3 with the December Developer's - Kit, Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles - fine, including the examples. However, there are problems at runtime - (see http://mail.python.org/pipermail/c++-sig/2003-January/003267.html). - Solutions are currently unknown. -

      -

      - It is known that under certain circumstances objects are - double-destructed. See http://mail.python.org/pipermail/c++-sig/2003-January/003278.html - for details. It is not clear however if this problem is related to - the Boost.Python runtime issues. -

      +

      The short answer: as of January 2003, unfortunately not.

      + +

      The longer answer: using Mac OS 10.2.3 with the December Developer's + Kit, Python 2.3a1, and bjam's darwin-tools.jam, Boost.Python compiles + fine, including the examples. However, there are problems at runtime + (see http://mail.python.org/pipermail/c++-sig/2003-January/003267.html). + Solutions are currently unknown.

      + +

      It is known that under certain circumstances objects are + double-destructed. See http://mail.python.org/pipermail/c++-sig/2003-January/003278.html + for details. It is not clear however if this problem is related to the + Boost.Python runtime issues.


      -

      - How can I find the existing PyObject that holds a C++ - object? -

      + +

      How can I find the existing PyObject that holds a C++ + object?

      +
      "I am wrapping a function that always returns a pointer to an already-held C++ object." -
      One way to do that is to hijack the mechanisms used for - wrapping a class with virtual functions. If you make a wrapper class with - an initial PyObject* constructor argument and store that PyObject* as - "self", you can get back to it by casting down to that wrapper type in a - thin wrapper function. For example: -
      +    
      +    One way to do that is to hijack the mechanisms used for wrapping a class
      +    with virtual functions. If you make a wrapper class with an initial
      +    PyObject* constructor argument and store that PyObject* as "self", you
      +    can get back to it by casting down to that wrapper type in a thin wrapper
      +    function. For example: 
      +
       class X { X(int); virtual ~X(); ... };
       X* f();  // known to return Xs that are managed by Python objects
       
      @@ -393,44 +417,43 @@ def("f", f_wrap());
       class_<X,X_wrap>("X", init<int>())
          ...
          ;
      -
      Of course, if X has no virtual functions you'll have to use -static_cast instead of dynamic_cast with no runtime -check that it's valid. This approach also only works if the X -object was constructed from Python, because Xs constructed from -C++ are of course never X_wrap objects. -

      - Another approach to this requires some work on Boost.Python, but it's - work we've been meaning to get to anyway. Currently, when a - shared_ptr<X> is converted from Python, the - shared_ptr actually manages a reference to the containing Python - object. I plan to make it so that when a shared_ptr<X> is - converted back to Python, the library checks to see if it's one of - those "Python object managers" and if so just returns the original - Python object. To exploit this you'd have to be able to change the C++ - code you're wrapping so that it deals with shared_ptr instead of raw - pointers. -

      -

      - There are other approaches too. The functions that receive the Python - object that you eventually want to return could be wrapped with a thin - wrapper that records the correspondence between the object address and - its containing Python object, and you could have your f_wrap function - look in that mapping to get the Python object out. -

      -

      - How can I wrap a function which needs to take - ownership of a raw pointer? -

      +
      + Of course, if X has no virtual functions you'll have to use + static_cast instead of dynamic_cast with no + runtime check that it's valid. This approach also only works if the + X object was constructed from Python, because + Xs constructed from C++ are of course never + X_wrap objects. + +

      Another approach to this requires you to change your C++ code a bit; + if that's an option for you it might be a better way to go. work we've + been meaning to get to anyway. When a shared_ptr<X> is + converted from Python, the shared_ptr actually manages a reference to the + containing Python object. When a shared_ptr<X> is converted back to + Python, the library checks to see if it's one of those "Python object + managers" and if so just returns the original Python object. So you could + just write object(p) to get the Python object back. To + exploit this you'd have to be able to change the C++ code you're wrapping + so that it deals with shared_ptr instead of raw pointers.

      + +

      There are other approaches too. The functions that receive the Python + object that you eventually want to return could be wrapped with a thin + wrapper that records the correspondence between the object address and + its containing Python object, and you could have your f_wrap function + look in that mapping to get the Python object out.

      + +

      How can I wrap a function which needs to take + ownership of a raw pointer?

      +
      Part of an API that I'm wrapping goes something like this: -
      +
       struct A {}; struct B { void add( A* ); }
       where B::add() takes ownership of the pointer passed to it.
       
      -

      - However: -

      -
      +
      +      

      However:

      +
       a = mod.A()
       b = mod.B()
       b.add( a )
      @@ -439,41 +462,43 @@ del b
       # python interpreter crashes 
       # later due to memory corruption.
       
      -

      - Even binding the lifetime of a to b via - with_custodian_and_ward doesn't prevent the python object a from - ultimately trying to delete the object it's pointing to. Is there a - way to accomplish a 'transfer-of-ownership' of a wrapped C++ object? -

      -

      - --Bruce Lowery -

      -
      Yes: Make sure the C++ object is held by auto_ptr: -
      +
      +      

      Even binding the lifetime of a to b via + with_custodian_and_ward doesn't prevent the python object a from + ultimately trying to delete the object it's pointing to. Is there a way + to accomplish a 'transfer-of-ownership' of a wrapped C++ object?

      + +

      --Bruce Lowery

      + + Yes: Make sure the C++ object is held by auto_ptr: +
       class_<A, std::auto_ptr<A> >("A")
           ...
           ;
      -
      Then make a thin wrapper function which takes an auto_ptr parameter: -
      +
      + Then make a thin wrapper function which takes an auto_ptr parameter: +
       void b_insert(B& b, std::auto_ptr<A> a)
       {
           b.insert(a.get());
           a.release();
       }
      -
      Wrap that as B.add. Note that pointers returned via - manage_new_object - will also be held by auto_ptr, so this - transfer-of-ownership will also work correctly. +
      + Wrap that as B.add. Note that pointers returned via manage_new_object + will also be held by auto_ptr, so this transfer-of-ownership + will also work correctly.
      -

      - Revised - - 23 January, 2003 - -

      -

      - © Copyright Dave - Abrahams 2002-2003. All Rights Reserved. + +

      Revised + + 23 January, 2003 +

      + +

      © Copyright Dave Abrahams 2002-2003. All + Rights Reserved.

      + diff --git a/doc/v2/raw_function.html b/doc/v2/raw_function.html new file mode 100755 index 00000000..ae1ad6c0 --- /dev/null +++ b/doc/v2/raw_function.html @@ -0,0 +1,116 @@ + + + + + + + + + Boost.Python - <boost/python/raw_function.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header <boost/python/raw_function.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Introduction
      + +
      Functions
      + +
      +
      +
      raw_function
      +
      +
      + +
      Example
      +
      +
      + +

      Introduction

      + +

      raw_function(...) + is used to convert a function taking a tuple and a dict into a Python callable object + which accepts a variable number of arguments and arbitrary keyword + arguments. + +

      Functions

      + raw_function +
      +template <class F>
      +object raw_function(F f, std::size_t min_args = 0);
      +
      + +
      +
      Requires: f(tuple(), dict()) is + well-formed.
      + +
      Returns: a callable object which requires at least min_args arguments. When called, the actual non-keyword arguments will be passed in a tuple as the first argument to f, and the keyword arguments will be passed in a dict as the second argument to f. + + +
      + +

      Example

      +C++: +
      +#include <boost/python/def.hpp>
      +#include <boost/python/tuple.hpp>
      +#include <boost/python/dict.hpp>
      +#include <boost/python/module.hpp>
      +#include <boost/python/raw_function.hpp>
      +
      +using namespace boost::python;
      +
      +tuple raw(tuple args, dict kw)
      +{
      +    return make_tuple(args, kw);
      +}
      +
      +BOOST_PYTHON_MODULE(raw_test)
      +{
      +    def("raw", raw_function(raw));
      +}
      +
      + +Python: +
      +>>> from raw_test import *
      +
      +>>> raw(3, 4, foo = 'bar', baz = 42)
      +((3, 4), {'foo': 'bar', 'baz': 42})
      +
      +

      + + 7 March, 2003 + +

      + +

      © Copyright Dave Abrahams 2002. All Rights + Reserved.

      + + + diff --git a/doc/v2/reference.html b/doc/v2/reference.html index 55a3da34..ae2ec560 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -3,7 +3,7 @@ + "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org"> @@ -13,7 +13,7 @@ p.c3 {font-style: italic} h2.c2 {text-align: center} h1.c1 {text-align: center} - + @@ -527,6 +527,24 @@ + + +
      raw_function.hpp
      + +
      +
      +
      Functions
      + +
      +
      +
      raw_function
      +
      +
      +
      +
      + +

      Models of CallPolicies

      @@ -913,8 +931,8 @@

      Revised - 13 November, 2002 - + 7 March, 2003 +

      © Copyright > >::failed test0; +# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) typedef typename assertion >::failed test1; +# endif typedef typename assertion >::failed test2; not_a_derived_class_member(Fn()); } diff --git a/include/boost/python/def.hpp b/include/boost/python/def.hpp index 8914818b..1c77736d 100644 --- a/include/boost/python/def.hpp +++ b/include/boost/python/def.hpp @@ -76,12 +76,17 @@ namespace detail detail::define_with_defaults( name, stubs, current, detail::get_signature(sig)); } + + template + object make_function1(T fn, ...) { return make_function(fn); } + + object make_function1(object const& x, object const*) { return x; } } template void def(char const* name, Fn fn) { - detail::scope_setattr_doc(name, boost::python::make_function(fn), 0); + detail::scope_setattr_doc(name, detail::make_function1(fn, &fn), 0); } template diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index 3f6a0098..b1883cd3 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -6,7 +6,6 @@ #ifndef INDIRECT_TRAITS_DWA2002131_HPP # define INDIRECT_TRAITS_DWA2002131_HPP # include -# include # include # include # include @@ -16,8 +15,18 @@ # include # include # include + +# include + +# include +# if 0 && BOOST_WORKAROUND(__MWERKS__, <= 0x2407) +# include +# endif + # include # include +# include +# include # include # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -28,27 +37,24 @@ namespace boost { namespace python { namespace detail { # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template -struct is_reference_to_const +struct is_reference_to_const : mpl::false_ { - BOOST_STATIC_CONSTANT(bool, value = false); }; template -struct is_reference_to_const +struct is_reference_to_const : mpl::true_ { - BOOST_STATIC_CONSTANT(bool, value = true); }; # if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround template -struct is_reference_to_const +struct is_reference_to_const : mpl::true_ { - static const bool value = true; }; # endif template -struct is_reference_to_function : mpl::bool_ +struct is_reference_to_function : mpl::false_ { }; @@ -58,9 +64,8 @@ struct is_reference_to_function : is_function }; template -struct is_pointer_to_function : mpl::bool_ +struct is_pointer_to_function : mpl::false_ { - BOOST_STATIC_CONSTANT(bool, value = false); }; // There's no such thing as a pointer-to-cv-function, so we don't need @@ -71,7 +76,7 @@ struct is_pointer_to_function : is_function }; template -struct is_reference_to_member_function_pointer_impl : mpl::bool_ +struct is_reference_to_member_function_pointer_impl : mpl::false_ { }; @@ -91,23 +96,23 @@ struct is_reference_to_member_function_pointer template struct is_reference_to_function_pointer_aux + : mpl::and_< + is_reference + , is_pointer_to_function< + typename remove_cv< + typename remove_reference::type + >::type + > + > { // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those - BOOST_STATIC_CONSTANT(bool, value = ( - is_reference::value - & is_pointer_to_function< - typename remove_cv< - typename remove_reference::type - >::type - >::value)); - typedef mpl::bool_ type; }; template struct is_reference_to_function_pointer - : mpl::if_c< - is_reference_to_function::value - , mpl::bool_ + : mpl::if_< + is_reference_to_function + , mpl::false_ , is_reference_to_function_pointer_aux >::type { @@ -115,70 +120,60 @@ struct is_reference_to_function_pointer template struct is_reference_to_non_const + : mpl::and_< + is_reference + , mpl::not_< + is_reference_to_const + > + > { - BOOST_STATIC_CONSTANT( - bool, value = ( - ::boost::type_traits::ice_and< - ::boost::is_reference::value - , ::boost::type_traits::ice_not< - ::boost::python::detail::is_reference_to_const::value>::value - >::value) - ); }; template -struct is_reference_to_volatile +struct is_reference_to_volatile : mpl::false_ { - BOOST_STATIC_CONSTANT(bool, value = false); }; template -struct is_reference_to_volatile +struct is_reference_to_volatile : mpl::true_ { - BOOST_STATIC_CONSTANT(bool, value = true); }; # if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround template -struct is_reference_to_volatile +struct is_reference_to_volatile : mpl::true_ { - static const bool value = true; }; # endif template -struct is_reference_to_pointer +struct is_reference_to_pointer : mpl::false_ { - BOOST_STATIC_CONSTANT(bool, value = false); }; template -struct is_reference_to_pointer +struct is_reference_to_pointer : mpl::true_ { - BOOST_STATIC_CONSTANT(bool, value = true); }; template -struct is_reference_to_pointer +struct is_reference_to_pointer : mpl::true_ { - BOOST_STATIC_CONSTANT(bool, value = true); }; template -struct is_reference_to_pointer +struct is_reference_to_pointer : mpl::true_ { - BOOST_STATIC_CONSTANT(bool, value = true); }; template -struct is_reference_to_pointer +struct is_reference_to_pointer : mpl::true_ { - BOOST_STATIC_CONSTANT(bool, value = true); }; template -struct is_reference_to_class +struct is_reference_to_classx { BOOST_STATIC_CONSTANT( bool, value @@ -196,19 +191,47 @@ struct is_reference_to_class }; template -struct is_pointer_to_class +struct is_reference_to_class + : mpl::and_< + is_reference +# if 0 && BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + , mpl::not_< + is_enum< + typename remove_cv< + typename remove_reference::type + >::type + > + > +# endif + , is_class< + typename remove_cv< + typename remove_reference::type + >::type + > + > +{ +}; + +template +struct is_pointer_to_class + : mpl::and_< + is_pointer +# if 0 && BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + , mpl::not_< + is_enum< + typename remove_cv< + typename remove_pointer::type + >::type + > + > +# endif + , is_class< + typename remove_cv< + typename remove_pointer::type + >::type + > + > { - BOOST_STATIC_CONSTANT( - bool, value - = (boost::type_traits::ice_and< - is_pointer::value - , is_class< - typename remove_cv< - typename remove_pointer::type - >::type - >::value - >::value) - ); }; # else @@ -220,8 +243,8 @@ typedef char (&outer_no_type)[1]; template struct is_const_help { - typedef typename mpl::if_c< - is_const::value + typedef typename mpl::if_< + is_const , inner_yes_type , inner_no_type >::type type; @@ -230,8 +253,8 @@ struct is_const_help template struct is_volatile_help { - typedef typename mpl::if_c< - is_volatile::value + typedef typename mpl::if_< + is_volatile , inner_yes_type , inner_no_type >::type type; @@ -240,8 +263,8 @@ struct is_volatile_help template struct is_pointer_help { - typedef typename mpl::if_c< - is_pointer::value + typedef typename mpl::if_< + is_pointer , inner_yes_type , inner_no_type >::type type; @@ -250,8 +273,8 @@ struct is_pointer_help template struct is_class_help { - typedef typename mpl::if_c< - is_class::value + typedef typename mpl::if_< + is_class , inner_yes_type , inner_no_type >::type type; diff --git a/include/boost/python/detail/is_shared_ptr.hpp b/include/boost/python/detail/is_shared_ptr.hpp new file mode 100755 index 00000000..d3579a6a --- /dev/null +++ b/include/boost/python/detail/is_shared_ptr.hpp @@ -0,0 +1,18 @@ +// Copyright David Abrahams 2003. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef IS_SHARED_PTR_DWA2003224_HPP +# define IS_SHARED_PTR_DWA2003224_HPP + +# include +# include + +namespace boost { namespace python { namespace detail { + +BOOST_PYTHON_IS_XXX_DEF(shared_ptr, shared_ptr, 1) + +}}} // namespace boost::python::detail + +#endif // IS_SHARED_PTR_DWA2003224_HPP diff --git a/include/boost/python/init.hpp b/include/boost/python/init.hpp index bfc398d6..39bf4ac7 100644 --- a/include/boost/python/init.hpp +++ b/include/boost/python/init.hpp @@ -315,7 +315,10 @@ namespace detail , mpl::push_front<> >::type args; - typedef typename ClassT::holder_selector::type selector_t; + typedef typename ClassT::holder_selector holder_selector_t; +# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + typedef typename holder_selector_t::type selector_t; +# endif typedef typename ClassT::held_type held_type_t; cl.def( diff --git a/include/boost/python/object/inheritance.hpp b/include/boost/python/object/inheritance.hpp index de8cae43..610f458c 100644 --- a/include/boost/python/object/inheritance.hpp +++ b/include/boost/python/object/inheritance.hpp @@ -11,6 +11,7 @@ # include # include # include +# include namespace boost { namespace python { namespace objects { @@ -108,16 +109,20 @@ struct implicit_cast_generator template struct cast_generator { - // CWPro7 will return false sometimes, but that's OK since we can - // always cast up with dynamic_cast<> + // It's OK to return false, since we can always cast up with + // dynamic_cast<> if neccessary. +# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + BOOST_STATIC_CONSTANT(bool, is_upcast = false); +# else BOOST_STATIC_CONSTANT( bool, is_upcast = ( is_base_and_derived::value )); +# endif typedef typename mpl::if_c< is_upcast -# if defined(__MWERKS__) && __MWERKS__ <= 0x2406 +# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) // grab a few more implicit_cast cases for CodeWarrior || !is_polymorphic::value || !is_polymorphic::value diff --git a/include/boost/python/object/make_ptr_instance.hpp b/include/boost/python/object/make_ptr_instance.hpp index 0b07ae26..25dbd77c 100644 --- a/include/boost/python/object/make_ptr_instance.hpp +++ b/include/boost/python/object/make_ptr_instance.hpp @@ -48,8 +48,14 @@ struct make_ptr_instance } template - static inline PyTypeObject* get_derived_class_object(mpl::false_, U*) + static inline PyTypeObject* get_derived_class_object(mpl::false_, U* x) { +# if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) + if (typeid(*x) != typeid(U)) + return get_derived_class_object(mpl::true_(), x); +# else + (void)x; +# endif return 0; } }; diff --git a/include/boost/python/raw_function.hpp b/include/boost/python/raw_function.hpp new file mode 100755 index 00000000..3a28d127 --- /dev/null +++ b/include/boost/python/raw_function.hpp @@ -0,0 +1,47 @@ +// Copyright David Abrahams 2003. Permission to copy, use, +// modify, sell and distribute this software is granted provided this +// copyright notice appears in all copies. This software is provided +// "as is" without express or implied warranty, and with no claim as +// to its suitability for any purpose. +#ifndef RAW_FUNCTION_DWA200336_HPP +# define RAW_FUNCTION_DWA200336_HPP + +# include +# include +# include + +# include + +namespace boost { namespace python { + +namespace detail +{ + template + struct raw_dispatcher + { + raw_dispatcher(F f) : f(f) {} + + PyObject* operator()(PyObject* args, PyObject* keywords) + { + return incref( + object( + f(tuple(borrowed_reference(args)), dict(borrowed_reference(keywords))) + ).ptr() + ); + } + private: + F f; + }; + + object BOOST_PYTHON_DECL make_raw_function(objects::py_function, std::size_t min_args); +} + +template +object raw_function(F f, std::size_t min_args = 0) +{ + return detail::make_raw_function(detail::raw_dispatcher(f), min_args); +} + +}} // namespace boost::python + +#endif // RAW_FUNCTION_DWA200336_HPP diff --git a/src/object/function.cpp b/src/object/function.cpp index bf6e8665..761a9866 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -39,10 +39,15 @@ function::function( unsigned keyword_offset = m_max_arity > num_keywords ? m_max_arity - num_keywords : 0; - - m_arg_names = object(handle<>(PyTuple_New(m_max_arity))); - for (unsigned j = 0; j < keyword_offset; ++j) - PyTuple_SET_ITEM(m_arg_names.ptr(), j, incref(Py_None)); + + unsigned tuple_size = num_keywords ? m_max_arity : 0; + m_arg_names = object(handle<>(PyTuple_New(tuple_size))); + + if (num_keywords != 0) + { + for (unsigned j = 0; j < keyword_offset; ++j) + PyTuple_SET_ITEM(m_arg_names.ptr(), j, incref(Py_None)); + } for (unsigned i = 0; i < num_keywords; ++i) { @@ -68,7 +73,7 @@ function::function( function::~function() { } - + PyObject* function::call(PyObject* args, PyObject* keywords) const { std::size_t nargs = PyTuple_GET_SIZE(args); @@ -76,47 +81,68 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const std::size_t total_args = nargs + nkeywords; function const* f = this; + + // Try overloads looking for a match do { // Check for a plausible number of arguments if (total_args >= f->m_min_arity && total_args <= f->m_max_arity) { + // This will be the args that actually get passed handle<> args2(allow_null(borrowed(args))); - if (nkeywords > 0) + + if (nkeywords > 0) // Keyword arguments were supplied { - if (!f->m_arg_names - || static_cast(PyTuple_Size(f->m_arg_names.ptr())) < total_args) + if (f->m_arg_names.ptr() == Py_None) // this overload doesn't accept keywords { args2 = handle<>(); // signal failure } else { - // build a new arg tuple - args2 = handle<>(PyTuple_New(total_args)); + std::size_t max_args + = static_cast(PyTuple_Size(f->m_arg_names.ptr())); - // Fill in the positional arguments - for (std::size_t i = 0; i < nargs; ++i) - PyTuple_SET_ITEM(args2.get(), i, incref(PyTuple_GET_ITEM(args, i))); - - // Grab remaining arguments by name from the keyword dictionary - for (std::size_t j = nargs; j < total_args; ++j) + // "all keywords are none" is a special case + // indicating we will accept any number of keyword + // arguments + if (max_args == 0) { - PyObject* value = PyDict_GetItem( - keywords, PyTuple_GET_ITEM(f->m_arg_names.ptr(), j)); - - if (!value) + // no argument preprocessing + } + else if (max_args < total_args) + { + args2 = handle<>(); + } + else + { + // build a new arg tuple + args2 = handle<>(PyTuple_New(total_args)); + + // Fill in the positional arguments + for (std::size_t i = 0; i < nargs; ++i) + PyTuple_SET_ITEM(args2.get(), i, incref(PyTuple_GET_ITEM(args, i))); + + // Grab remaining arguments by name from the keyword dictionary + for (std::size_t j = nargs; j < total_args; ++j) { - PyErr_Clear(); - args2 = handle<>(); - break; + PyObject* value = PyDict_GetItem( + keywords, PyTuple_GET_ITEM(f->m_arg_names.ptr(), j)); + + if (!value) + { + PyErr_Clear(); + args2 = handle<>(); + break; + } + PyTuple_SET_ITEM(args2.get(), j, incref(value)); } - PyTuple_SET_ITEM(args2.get(), j, incref(value)); } } } - // Call the function - PyObject* result = args2 ? f->m_fn(args2.get(), 0) : 0; + // Call the function. Pass keywords in case it's a + // function accepting any number of keywords + PyObject* result = args2 ? f->m_fn(args2.get(), keywords) : 0; // If the result is NULL but no error was set, m_fn failed // the argument-matching test. @@ -482,4 +508,20 @@ handle<> function_handle_impl(py_function const& f, unsigned min_arity, unsigned new function(f, min_arity, max_arity, 0, 0))); } -}}} // namespace boost::python::objects +} + +namespace detail +{ + object BOOST_PYTHON_DECL make_raw_function(objects::py_function f, std::size_t min_args) + { + static keyword k; + + return objects::function_object( + f + , min_args + , std::numeric_limits::max() + , keyword_range(&k,&k)); + } +} + +}} // namespace boost::python::objects diff --git a/test/args.cpp b/test/args.cpp index 281ca236..a65933cb 100644 --- a/test/args.cpp +++ b/test/args.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "test_class.hpp" @@ -39,12 +40,20 @@ struct X BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_f_overloads, X::f, 0, 3) + +tuple raw_func(tuple args, dict kw) +{ + return make_tuple(args, kw); +} + BOOST_PYTHON_MODULE(args_ext) { def("f", f, args("x", "y", "z") , "This is f's docstring" ); + def("raw", raw_function(raw_func)); + #if defined(BOOST_MSVC) && BOOST_MSVC <= 1200 // MSVC6 gives a fatal error LNK1179: invalid or corrupt file: // duplicate comdat error if we try to re-use the exact type of f @@ -57,6 +66,7 @@ BOOST_PYTHON_MODULE(args_ext) class_("Y", init(args("value"), "Y's docstring")) .def("value", &Y::value) + .def("raw", raw_function(raw_func)) ; class_("X", "This is X's docstring") diff --git a/test/args.py b/test/args.py index 665fae41..2c9218b1 100644 --- a/test/args.py +++ b/test/args.py @@ -1,6 +1,9 @@ """ >>> from args_ext import * +>>> raw(3, 4, foo = 'bar', baz = 42) +((3, 4), {'foo': 'bar', 'baz': 42}) + >>> f(x= 1, y = 3, z = 'hello') (1, 3.0, 'hello') @@ -101,6 +104,11 @@ >>> inner(n = 1, self = q).value() 1 + +>>> y = Y(value = 33) +>>> y.raw(this = 1, that = 'the other')[1] +{'this': 1, 'that': 'the other'} + """ def run(args = None): import sys diff --git a/test/back_reference.py b/test/back_reference.py index 21d5d1c0..7eac13c3 100644 --- a/test/back_reference.py +++ b/test/back_reference.py @@ -10,8 +10,7 @@ >>> z2 = copy_Z(z) >>> x_instances() 4 ->>> y_identity(y) is y -1 +>>> assert y_identity(y) is y >>> y_equality(y, y) 1 ''' diff --git a/test/enum.cpp b/test/enum.cpp index 09a916c3..1a4f178b 100644 --- a/test/enum.cpp +++ b/test/enum.cpp @@ -7,11 +7,21 @@ #include #include #include - +#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) +# include +# include +#endif using namespace boost::python; enum color { red = 1, green = 2, blue = 4 }; +#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407) +namespace boost // Pro7 has a hard time detecting enums +{ + template <> struct is_enum : boost::mpl::true_ {}; +} +#endif + color identity_(color x) { return x; } struct colorized { diff --git a/test/operators.cpp b/test/operators.cpp index 9e7a1e5a..9096cb68 100755 --- a/test/operators.cpp +++ b/test/operators.cpp @@ -26,7 +26,7 @@ struct X : test_class<> typedef test_class<> base_t; X(int x) : base_t(x) {} - X const operator+(X const& r) { return X(value() + r.value()); } + X const operator+(X const& r) const { return X(value() + r.value()); } }; X operator-(X const& l, X const& r) { return X(l.value() - r.value()); } diff --git a/test/test_builtin_converters.py b/test/test_builtin_converters.py index 80e2149d..0b3bc645 100644 --- a/test/test_builtin_converters.py +++ b/test/test_builtin_converters.py @@ -61,19 +61,15 @@ r""" ... else: print 'expected an OverflowError!' ->>> abs(rewrap_value_float(4.2) - 4.2) < .000001 -1 +>>> assert abs(rewrap_value_float(4.2) - 4.2) < .000001 >>> rewrap_value_double(4.2) - 4.2 0.0 >>> rewrap_value_long_double(4.2) - 4.2 0.0 ->>> abs(rewrap_value_complex_float(4+.2j) - (4+.2j)) < .000001 -1 ->>> abs(rewrap_value_complex_double(4+.2j) - (4+.2j)) < .000001 -1 ->>> abs(rewrap_value_complex_long_double(4+.2j) - (4+.2j)) < .000001 -1 +>>> assert abs(rewrap_value_complex_float(4+.2j) - (4+.2j)) < .000001 +>>> assert abs(rewrap_value_complex_double(4+.2j) - (4+.2j)) < .000001 +>>> assert abs(rewrap_value_complex_long_double(4+.2j) - (4+.2j)) < .000001 >>> rewrap_value_cstring('hello, world') 'hello, world' @@ -136,19 +132,15 @@ r""" 42L ->>> abs(rewrap_const_reference_float(4.2) - 4.2) < .000001 -1 +>>> assert abs(rewrap_const_reference_float(4.2) - 4.2) < .000001 >>> rewrap_const_reference_double(4.2) - 4.2 0.0 >>> rewrap_const_reference_long_double(4.2) - 4.2 0.0 ->>> abs(rewrap_const_reference_complex_float(4+.2j) - (4+.2j)) < .000001 -1 ->>> abs(rewrap_const_reference_complex_double(4+.2j) - (4+.2j)) < .000001 -1 ->>> abs(rewrap_const_reference_complex_long_double(4+.2j) - (4+.2j)) < .000001 -1 +>>> assert abs(rewrap_const_reference_complex_float(4+.2j) - (4+.2j)) < .000001 +>>> assert abs(rewrap_const_reference_complex_double(4+.2j) - (4+.2j)) < .000001 +>>> assert abs(rewrap_const_reference_complex_long_double(4+.2j) - (4+.2j)) < .000001 >>> rewrap_const_reference_cstring('hello, world') 'hello, world' @@ -221,11 +213,9 @@ Check that classic classes also work ... else: print 'expected a TypeError exception' # show that arbitrary handle instantiations can be returned ->>> get_type(1) is type(1) -1 +>>> assert get_type(1) is type(1) ->>> return_null_handle() is None -1 +>>> assert return_null_handle() is None """ def run(args = None): diff --git a/test/test_pointer_adoption.py b/test/test_pointer_adoption.py index f684b062..d811bce8 100644 --- a/test/test_pointer_adoption.py +++ b/test/test_pointer_adoption.py @@ -70,11 +70,9 @@ Test call policies for constructors here >>> num_a_instances() 0 ->>> as_A(create('dynalloc')) is None -0 +>>> assert as_A(create('dynalloc')) is not None >>> base = Base() ->>> as_A(base) is None -1 +>>> assert as_A(base) is None """ def run(args = None): import sys From d34a11b584146474b976af6e2be2ee696259e3d6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 8 Mar 2003 05:28:54 +0000 Subject: [PATCH 1030/1042] Fix for Python 2.3 long->int conversion behavior change [SVN r17779] --- src/converter/builtin_converters.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/converter/builtin_converters.cpp b/src/converter/builtin_converters.cpp index af6fada9..72437e8c 100644 --- a/src/converter/builtin_converters.cpp +++ b/src/converter/builtin_converters.cpp @@ -101,7 +101,10 @@ namespace { static T extract(PyObject* intermediate) { - return numeric_cast(PyInt_AS_LONG(intermediate)); + long x = PyInt_AsLong(intermediate); + if (PyErr_Occurred()) + throw_error_already_set(); + return numeric_cast(x); } }; From 257a6c45f89175974d6b29449ef5b35151f63754 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 8 Mar 2003 08:51:45 +0000 Subject: [PATCH 1031/1042] Remove flotsam [SVN r17782] --- .../boost/python/detail/indirect_traits.hpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index b1883cd3..f4986143 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -172,24 +172,6 @@ struct is_reference_to_pointer : mpl::true_ { }; -template -struct is_reference_to_classx -{ - BOOST_STATIC_CONSTANT( - bool, value - = (boost::type_traits::ice_and< - is_reference::value - , is_class< - typename remove_cv< - typename remove_reference::type - >::type - >::value - >::value) - ); - typedef mpl::bool_ type; - BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) -}; - template struct is_reference_to_class : mpl::and_< From 6aa71e1f72d8cfb916f77f12beb0dd621eee775e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 8 Mar 2003 08:53:19 +0000 Subject: [PATCH 1032/1042] Remove flotsam [SVN r17783] --- .../boost/python/detail/indirect_traits.hpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index f4986143..3e80d519 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -176,15 +176,6 @@ template struct is_reference_to_class : mpl::and_< is_reference -# if 0 && BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - , mpl::not_< - is_enum< - typename remove_cv< - typename remove_reference::type - >::type - > - > -# endif , is_class< typename remove_cv< typename remove_reference::type @@ -198,15 +189,6 @@ template struct is_pointer_to_class : mpl::and_< is_pointer -# if 0 && BOOST_WORKAROUND(__MWERKS__, <= 0x2407) - , mpl::not_< - is_enum< - typename remove_cv< - typename remove_pointer::type - >::type - > - > -# endif , is_class< typename remove_cv< typename remove_pointer::type From 39195ac97abbecd34c987d3769c47d88f2d58217 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 8 Mar 2003 12:36:18 +0000 Subject: [PATCH 1033/1042] Fix for older EDGs [SVN r17786] --- include/boost/python/detail/indirect_traits.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/python/detail/indirect_traits.hpp b/include/boost/python/detail/indirect_traits.hpp index 3e80d519..170f3662 100644 --- a/include/boost/python/detail/indirect_traits.hpp +++ b/include/boost/python/detail/indirect_traits.hpp @@ -183,6 +183,7 @@ struct is_reference_to_class > > { + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) }; template @@ -196,6 +197,7 @@ struct is_pointer_to_class > > { + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_class,(T)) }; # else From 34bf1560a9d0e09253421598af2a22d7b04c5b4a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 9 Mar 2003 17:26:06 +0000 Subject: [PATCH 1034/1042] non-template function make_function1 must be inline [SVN r17791] --- include/boost/python/def.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/python/def.hpp b/include/boost/python/def.hpp index 1c77736d..d0db5528 100644 --- a/include/boost/python/def.hpp +++ b/include/boost/python/def.hpp @@ -80,6 +80,7 @@ namespace detail template object make_function1(T fn, ...) { return make_function(fn); } + inline object make_function1(object const& x, object const*) { return x; } } From 7dcacbcfc4f98873f9b4f62775629ad2b18e57dc Mon Sep 17 00:00:00 2001 From: Bruno da Silva de Oliveira Date: Tue, 11 Mar 2003 03:20:24 +0000 Subject: [PATCH 1035/1042] - first version [SVN r17804] --- pyste/README | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 pyste/README diff --git a/pyste/README b/pyste/README new file mode 100644 index 00000000..c3535a2b --- /dev/null +++ b/pyste/README @@ -0,0 +1,30 @@ +Pyste - Python Semi-Automatic Exporter +====================================== + +Pyste is a Boost.Python code generator. The user specifies the classes and +functions to be exported using a simple interface file, which following the +Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to +parse all the headers and extract the necessary information to automatically +generate C++ code. + +The documentation can be found in the file index.html accompaning this README. + +Enjoy! +Bruno da Silva de Oliveira (nicodemus@globalite.com.br) + +Thanks +====== + +- David Abrahams, creator of Boost.Python, for tips on the syntax of the interface +file and support. +- Marcelo Camelo, for design tips and support. +- Brad King, creator of the excellent GCCXML (http://www.gccxml.org) +- Fredrik Lundh, creator of the elementtree library (http://effbot.org) + +Bugs +==== + +Pyste is a young tool, so please help it to get better! Send bug reports to +nicodemus@globalite.com.br, accompaining the stack trace in case of exceptions. +If possible, run pyste with --debug, and send the resulting xmls too (pyste +will output a xml file with the same of each header it parsed). From 20c52def19220464dbf6cc48144051c375ad2842 Mon Sep 17 00:00:00 2001 From: Bruno da Silva de Oliveira Date: Tue, 11 Mar 2003 03:29:22 +0000 Subject: [PATCH 1036/1042] - first version [SVN r17805] --- ...orting_all_declarations_from_a_header.html | 76 ++ pyste/doc/introduction.html | 74 ++ pyste/doc/policies.html | 79 ++ pyste/doc/pyste.txt | 370 ++++++++++ pyste/doc/renaming_and_excluding.html | 68 ++ pyste/doc/running_pyste.html | 110 +++ pyste/doc/templates.html | 103 +++ pyste/doc/the_interface_files.html | 81 +++ pyste/doc/theme/alert.gif | Bin 0 -> 577 bytes pyste/doc/theme/arrow.gif | Bin 0 -> 70 bytes pyste/doc/theme/bkd.gif | Bin 0 -> 1317 bytes pyste/doc/theme/bkd2.gif | Bin 0 -> 2543 bytes pyste/doc/theme/bulb.gif | Bin 0 -> 944 bytes pyste/doc/theme/bullet.gif | Bin 0 -> 152 bytes pyste/doc/theme/c++boost.gif | Bin 0 -> 8819 bytes pyste/doc/theme/l_arr.gif | Bin 0 -> 147 bytes pyste/doc/theme/l_arr_disabled.gif | Bin 0 -> 91 bytes pyste/doc/theme/note.gif | Bin 0 -> 151 bytes pyste/doc/theme/r_arr.gif | Bin 0 -> 147 bytes pyste/doc/theme/r_arr_disabled.gif | Bin 0 -> 91 bytes pyste/doc/theme/smiley.gif | Bin 0 -> 879 bytes pyste/doc/theme/style.css | 170 +++++ pyste/doc/theme/u_arr.gif | Bin 0 -> 170 bytes pyste/doc/wrappers.html | 108 +++ pyste/index.html | 71 ++ pyste/src/.cvsignore | 1 + pyste/src/ClassExporter.py | 688 ++++++++++++++++++ pyste/src/CodeUnit.py | 78 ++ pyste/src/CppParser.py | 94 +++ pyste/src/EnumExporter.py | 30 + pyste/src/Exporter.py | 69 ++ pyste/src/FunctionExporter.py | 81 +++ pyste/src/GCCXMLParser.py | 395 ++++++++++ pyste/src/HeaderExporter.py | 67 ++ pyste/src/IncludeExporter.py | 19 + pyste/src/declarations.py | 452 ++++++++++++ pyste/src/enumerate.py | 7 + pyste/src/exporters.py | 3 + pyste/src/exporterutils.py | 26 + pyste/src/infos.py | 185 +++++ pyste/src/policies.py | 75 ++ pyste/src/pyste-profile.py | 17 + pyste/src/pyste.py | 154 ++++ pyste/src/settings.py | 12 + pyste/tests/GCCXMLParserUT.py | 338 +++++++++ pyste/tests/infosUT.py | 50 ++ pyste/tests/policiesUT.py | 59 ++ pyste/tests/runtests.py | 14 + 48 files changed, 4224 insertions(+) create mode 100644 pyste/doc/exporting_all_declarations_from_a_header.html create mode 100644 pyste/doc/introduction.html create mode 100644 pyste/doc/policies.html create mode 100644 pyste/doc/pyste.txt create mode 100644 pyste/doc/renaming_and_excluding.html create mode 100644 pyste/doc/running_pyste.html create mode 100644 pyste/doc/templates.html create mode 100644 pyste/doc/the_interface_files.html create mode 100644 pyste/doc/theme/alert.gif create mode 100644 pyste/doc/theme/arrow.gif create mode 100644 pyste/doc/theme/bkd.gif create mode 100644 pyste/doc/theme/bkd2.gif create mode 100644 pyste/doc/theme/bulb.gif create mode 100644 pyste/doc/theme/bullet.gif create mode 100644 pyste/doc/theme/c++boost.gif create mode 100644 pyste/doc/theme/l_arr.gif create mode 100644 pyste/doc/theme/l_arr_disabled.gif create mode 100644 pyste/doc/theme/note.gif create mode 100644 pyste/doc/theme/r_arr.gif create mode 100644 pyste/doc/theme/r_arr_disabled.gif create mode 100644 pyste/doc/theme/smiley.gif create mode 100644 pyste/doc/theme/style.css create mode 100644 pyste/doc/theme/u_arr.gif create mode 100644 pyste/doc/wrappers.html create mode 100644 pyste/index.html create mode 100644 pyste/src/.cvsignore create mode 100644 pyste/src/ClassExporter.py create mode 100644 pyste/src/CodeUnit.py create mode 100644 pyste/src/CppParser.py create mode 100644 pyste/src/EnumExporter.py create mode 100644 pyste/src/Exporter.py create mode 100644 pyste/src/FunctionExporter.py create mode 100644 pyste/src/GCCXMLParser.py create mode 100644 pyste/src/HeaderExporter.py create mode 100644 pyste/src/IncludeExporter.py create mode 100644 pyste/src/declarations.py create mode 100644 pyste/src/enumerate.py create mode 100644 pyste/src/exporters.py create mode 100644 pyste/src/exporterutils.py create mode 100644 pyste/src/infos.py create mode 100644 pyste/src/policies.py create mode 100644 pyste/src/pyste-profile.py create mode 100644 pyste/src/pyste.py create mode 100644 pyste/src/settings.py create mode 100644 pyste/tests/GCCXMLParserUT.py create mode 100644 pyste/tests/infosUT.py create mode 100644 pyste/tests/policiesUT.py create mode 100644 pyste/tests/runtests.py diff --git a/pyste/doc/exporting_all_declarations_from_a_header.html b/pyste/doc/exporting_all_declarations_from_a_header.html new file mode 100644 index 00000000..4f2418f5 --- /dev/null +++ b/pyste/doc/exporting_all_declarations_from_a_header.html @@ -0,0 +1,76 @@ + + + +Exporting All Declarations from a Header + + + + + + + + + +
      + + Exporting All Declarations from a Header +
      +
      + + + + + + +
      +

      +Pyste also supports a mechanism to export all declarations found in a header +file. Suppose again our file, hello.h:

      +
      +    struct World
      +    {
      +        World(std::string msg): msg(msg) {} 
      +        void set(std::string msg) { this->msg = msg; }
      +        std::string greet() { return msg; }
      +        std::string msg;
      +    };
      +
      +    enum choice { red, blue };
      +    
      +    void show(choice c) { std::cout << "value: " << (int)c << std::endl; } 
      +
      +

      +You can just use the AllFromHeader construct:

      +
      +    hello = AllFromHeader("hello.h")
      +
      +

      +this will export all the declarations found in hello.h, which is equivalent +to write:

      +
      +    Class("World", "hello.h")
      +    Enum("choice", "hello.h")
      +    Function("show", "hello.h")
      +
      +

      +Note that you can still use the functions rename, set_policy, exclude, etc. Just access +the members of the header object like this:

      +
      +    rename(hello.World.greet, "Greet")
      +    exclude(hello.World.set, "Set")
      +
      + + + + + + +
      +
      +
      + + diff --git a/pyste/doc/introduction.html b/pyste/doc/introduction.html new file mode 100644 index 00000000..ffb50e7e --- /dev/null +++ b/pyste/doc/introduction.html @@ -0,0 +1,74 @@ + + + +Introduction + + + + + + + + + +
      + + Introduction +
      +
      + + + + + + +
      +

      What is Pyste?

      +Pyste is a +Boost.Python code generator. The user specifies the classes and +functions to be exported using a simple interface file, which following the + +Boost.Python's philosophy, is simple Python code. Pyste then uses +GCCXML to +parse all the headers and extract the necessary information to automatically +generate C++ code.

      +

      Example

      +Let's borrow the class World from the +tutorial:

      +
      +    struct World
      +    {
      +        void set(std::string msg) { this->msg = msg; }
      +        std::string greet() { return msg; }
      +        std::string msg;
      +    };
      +
      +

      +Here's the interface file for it, named world.pyste:

      +
      +    Class("World", "world.h")
      +
      +

      +and that's it!

      +

      +The next step is invoke pyste in the command-line:

      +
      python pyste.py --module=hello world.pyste

      +this will create a file "hello.cpp" in the directory where the command was +run.

      +

      +Pyste supports the following features:

      +
      • Functions
      • Classes
      • Class Templates
      • Virtual Methods
      • Overloading
      • Attributes
      • Enums (both "free" enums and class enums)
      • Nested Classes
      + + + + + +
      +
      +
      + + diff --git a/pyste/doc/policies.html b/pyste/doc/policies.html new file mode 100644 index 00000000..2869889f --- /dev/null +++ b/pyste/doc/policies.html @@ -0,0 +1,79 @@ + + + +Policies + + + + + + + + + + +
      + + Policies +
      +
      + + + + + + +
      +

      +Even thought Pyste can identify various elements in the C++ code, like virtual +methods, attributes, and so on, one thing that it can't do is to guess the +semantics of functions that return pointers or references. In this case, the +user must manually specify the policy. Policies are explained in the + +tutorial.

      +

      +The policies in Pyste are named exactly as in +Boost.Python, only the syntax is +slightly different. For instance, this policy:

      +
      +    return_internal_reference<1, with_custodian_and_ward<1, 2> >()
      +
      +

      +becomes in Pyste:

      +
      +    return_internal_reference(1, with_custodian_and_ward(1, 2))
      +
      +

      +The user can specify policies for functions and methods with the set_policy +function:

      +
      +    set_policy(f, return_internal_reference())
      +    set_policy(C.foo, return_value_policy(manage_new_object))
      +
      + + + + +
      + + What if a function or method needs a policy and the user +doesn't set one?

      +If a function/method needs a policy and one was not set, Pyste will issue a error. +The user should then go in the interface file and set the policy for it, +otherwise the generated cpp won't compile. +
      + + + + + + +
      +
      +
      + + diff --git a/pyste/doc/pyste.txt b/pyste/doc/pyste.txt new file mode 100644 index 00000000..65c2cec9 --- /dev/null +++ b/pyste/doc/pyste.txt @@ -0,0 +1,370 @@ +[doc Pyste Documentation] + +[def GCCXML [@http://www.gccxml.org GCCXML]] +[def Boost.Python [@../../index.html Boost.Python]] + +[page Introduction] + +[h2 What is Pyste?] + +Pyste is a Boost.Python code generator. The user specifies the classes and +functions to be exported using a simple ['interface file], which following the +Boost.Python's philosophy, is simple Python code. Pyste then uses GCCXML to +parse all the headers and extract the necessary information to automatically +generate C++ code. + +[h2 Example] + +Let's borrow the class [^World] from the [@../../doc/tutorial/doc/exposing_classes.html tutorial]: + + struct World + { + void set(std::string msg) { this->msg = msg; } + std::string greet() { return msg; } + std::string msg; + }; + +Here's the interface file for it, named [^world.pyste]: + + Class("World", "world.h") + +and that's it! + +The next step is invoke pyste in the command-line: + +[pre python pyste.py --module=hello world.pyste] + +this will create a file "[^hello.cpp]" in the directory where the command was +run. + +Pyste supports the following features: + +* Functions +* Classes +* Class Templates +* Virtual Methods +* Overloading +* Attributes +* Enums (both "free" enums and class enums) +* Nested Classes + +[page Running Pyste] + +To run pyste, you will need: + +* Python 2.2, avaiable at [@http://www.python.org python's website]. +* The great [@http://effbot.org elementtree] library, from Fredrik Lundh. +* The excellent GCCXML, from Brad King. + +Installation for the tools is avaiable in their respective webpages. + +[blurb +[$theme/note.gif] GCCXML must be accessible in the PATH environment variable, so +that pyste can call it. How to do this varies from platform to platform. +] + +[h2 Ok, now what?] + +Well, now let's fire it up: + +[pre +''' +>python pyste.py + +Usage: + pyste [options] --module= interface-files + +where options are: + -I add an include path + -D define symbol + --no-using do not declare "using namespace boost"; + use explicit declarations instead + --pyste-ns= set the namespace where new types will be declared; + default is "pyste" +''' +] + +Options explained: + +The [^-I] and [^-D] are preprocessor flags, which are needed by gccxml to parse the header files correctly and by pyste to find the header files declared in the +interface files. + +[^--no-using] tells pyste to don't declare "[^using namespace boost;]" in the +generated cpp, using the namespace boost::python explicitly in all declarations. +Use only if you're having a name conflict in one of the files. + +Use [^--pyste-ns] to change the namespace where new types are declared (for +instance, the virtual wrappers). Use only if one of your header files declare a +namespace named "pyste" and this is causing conflicts. + +So, the usage is simple enough: + +[pre >python pyste.py --module=mymodule file.pyste file2.pyste ...] + +will generate a file [^mymodule.cpp] in the same dir where the command was +executed. Now you can compile the file using the same instructions of the +[@../../doc/tutorial/doc/building_hello_world.html tutorial]. + +[h2 Wait... how do I set those I and D flags?] + +Don't worry: normally GCCXML is already configured correctly for your plataform, +so the search path to the standard libraries and the standard defines should +already be set. You only have to set the paths to other libraries that your code +needs, like Boost, for example. + +Plus, Pyste automatically uses the contents of the environment variable +[^INCLUDE] if it exists. Windows users should run the [^Vcvars32.bat] file, +normally located at: + + C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat + +with that, you should have little trouble setting up the flags. + +[page The Interface Files] + +The interface files are the heart of Pyste. The user creates one or more +interface files declaring the classes and functions he wants to export, and then +invokes pyste passing the interface files to it. Pyste then generates a single +cpp file with Boost.Python code, with all the classes and functions exported. + +Besides declaring the classes and functions, the user has a number of other +options, like renaming classes and methods, excluding methods and attributes, +and so on. + +[h2 Basics] + +Suppose we have a class and some functions that we want to expose to Python +declared in the header [^hello.h]: + + struct World + { + World(std::string msg): msg(msg) {} + void set(std::string msg) { this->msg = msg; } + std::string greet() { return msg; } + std::string msg; + }; + + enum choice { red, blue }; + + namespace test { + + void show(choice c) { std::cout << "value: " << (int)c << std::endl; } + + } + +We create a file named [^hello.pyste] and create instances of the classes +[^Function], [^Class] and [^Enum]: + + Function("test::show", "hello.h") + Class("World", "hello.h") + Enum("choice", "hello.h") + +That will expose the class, the free function and the enum found in [^hello.h]. + +[page:1 Renaming and Excluding] + +You can easily rename functions, classes, methods, attributes, etc. Just use the +function [^rename], like this: + + World = Class("World", "hello.h") + rename(World, "IWorld") + show = Function("choice", "hello.h") + rename(show, "Show") + +You can rename methods and attributes using this syntax: + + rename(World.greet, "Greet") + rename(World.set, "Set") + choice = Enum("choice", "hello.h") + rename(choice.red, "Red") + rename(choice.blue, "Blue") + +You can exclude functions, classes, methods, attributes, etc, in the same way, +with the function [^exclude]: + + exclude(World.greet) + exclude(World.msg) + +Easy, huh? [$theme/smiley.gif] + +[page:1 Policies] + +Even thought Pyste can identify various elements in the C++ code, like virtual +methods, attributes, and so on, one thing that it can't do is to guess the +semantics of functions that return pointers or references. In this case, the +user must manually specify the policy. Policies are explained in the +[@../../doc/tutorial/doc/call_policies.html tutorial]. + +The policies in Pyste are named exactly as in Boost.Python, only the syntax is +slightly different. For instance, this policy: + + return_internal_reference<1, with_custodian_and_ward<1, 2> >() + +becomes in Pyste: + + return_internal_reference(1, with_custodian_and_ward(1, 2)) + +The user can specify policies for functions and methods with the [^set_policy] +function: + + set_policy(f, return_internal_reference()) + set_policy(C.foo, return_value_policy(manage_new_object)) + +[blurb +[$theme/note.gif] [*What if a function or method needs a policy and the user +doesn't set one?][br][br] +If a function/method needs a policy and one was not set, Pyste will issue a error. +The user should then go in the interface file and set the policy for it, +otherwise the generated cpp won't compile. +] + +[page:1 Templates] + +Template Classes can easily exported too, but you can't export the "Template" +itself... you have to export instantiations of it! So, if you want to export a +[^std::vector], you will have to export vectors of int, doubles, etc. + +Suppose we have this code: + + template + struct Point + { + T x; + T y; + }; + +And we want to export [^Point]s of int and double: + + Point = Template("Point", "point.h") + Point("int") + Point("double") + +Pyste will assign default names for each instantiation. In this example, those +would be "[^Point_int]" and "[^Point_double]", but most of the time users will want to +rename the instantiations: + + Point("int", "IPoint") // renames the instantiation + double_inst = Point("double") // another way to do the same + rename(double_inst, "DPoint") + +Note that you can rename, exclude, set policies, etc, in the [^Template] class +like you would do with a [^Function] or a [^Class]. This changes affect all +[*future] instantiations: + + Point = Template("Point", "point.h") + Point("float", "FPoint") // will have x and y as data members + rename(Point.x, "X") + rename(Point.y, "Y") + Point("int", "IPoint") // will have X and Y as data members + Point("double", "DPoint") // also will have X and Y as data member + +If you want to change a option of a particular instantiation, you can do so: + + Point = Template("Point", "point.h") + Point("int", "IPoint") + d_inst = Point("double", "DPoint") + rename(d_inst.x, "X") // only DPoint is affect by this renames, + rename(d_inst.y, "Y") // IPoint stays intact + +[blurb [$theme/note.gif] [*What if my template accepts more than one type?] +[br][br] +When you want to instantiate a Template with more than one type, you can pass +either a string with the types separated by whitespace, or a list of strings +'''("int double" or ["int", "double"]''' would both work). +] + +[page:1 Wrappers] + +Suppose you have this function: + + std::vector names(); + +But you don't want to export a vector, you want this function to return +a python list of strings. Boost.Python has an excellent support for that: + + list names_wrapper() + { + list result; + vector v = names(); + // put each string in the vector in the list + return result; + } + + BOOST_PYTHON_MODULE(test) + { + def("names", &names_wrapper); + } + +Nice heh? +Pyste supports this mechanism too. You declare the [^names_wrapper] function in a +header, like "[^test_wrappers.h]", and in the interface file: + + Include("test_wrappers.h") + names = Function("names", "test.h") + set_wrapper(names, "names_wrapper") + +You can optionally declare the function in the interface file itself: + + names_wrapper = Wrapper("names_wrapper", + """ + list names_wrapper() + { + // call name() and convert the vector to a list... + } + """) + names = Function("names", "test.h") + set_wrapper(names, names_wrapper) + +The same mechanism can be done with methods too. Just remember that the first +parameter of wrappers for methods is a pointer to the class, like in +Boost.Python: + + struct C + { + std::vector names(); + } + + list names_wrapper(C* c) + { + // same as before, calling c->names() and converting result to a list + } + +And then in the interface file: + + C = Class("C", "test.h") + set_wrapper(C.names, "names_wrapper") + +[page:1 Exporting All Declarations from a Header] + +Pyste also supports a mechanism to export all declarations found in a header +file. Suppose again our file, [^hello.h]: + + struct World + { + World(std::string msg): msg(msg) {} + void set(std::string msg) { this->msg = msg; } + std::string greet() { return msg; } + std::string msg; + }; + + enum choice { red, blue }; + + void show(choice c) { std::cout << "value: " << (int)c << std::endl; } + +You can just use the [^AllFromHeader] construct: + + hello = AllFromHeader("hello.h") + +this will export all the declarations found in [^hello.h], which is equivalent +to write: + + Class("World", "hello.h") + Enum("choice", "hello.h") + Function("show", "hello.h") + +Note that you can still use the functions [^rename], [^set_policy], [^exclude], etc. Just access +the members of the header object like this: + + rename(hello.World.greet, "Greet") + exclude(hello.World.set, "Set") + diff --git a/pyste/doc/renaming_and_excluding.html b/pyste/doc/renaming_and_excluding.html new file mode 100644 index 00000000..29a8001b --- /dev/null +++ b/pyste/doc/renaming_and_excluding.html @@ -0,0 +1,68 @@ + + + +Renaming and Excluding + + + + + + + + + + +
      + + Renaming and Excluding +
      +
      + + + + + + +
      +

      +You can easily rename functions, classes, methods, attributes, etc. Just use the +function rename, like this:

      +
      +    World = Class("World", "hello.h")
      +    rename(World, "IWorld")
      +    show = Function("choice", "hello.h")
      +    rename(show, "Show")
      +
      +

      +You can rename methods and attributes using this syntax:

      +
      +    rename(World.greet, "Greet")
      +    rename(World.set, "Set")
      +    choice = Enum("choice", "hello.h")
      +    rename(choice.red, "Red")
      +    rename(choice.blue, "Blue")
      +
      +

      +You can exclude functions, classes, methods, attributes, etc, in the same way, +with the function exclude:

      +
      +    exclude(World.greet)
      +    exclude(World.msg)
      +
      +

      +Easy, huh?

      + + + + + + +
      +
      +
      + + diff --git a/pyste/doc/running_pyste.html b/pyste/doc/running_pyste.html new file mode 100644 index 00000000..a67d5812 --- /dev/null +++ b/pyste/doc/running_pyste.html @@ -0,0 +1,110 @@ + + + +Running Pyste + + + + + + + + + + +
      + + Running Pyste +
      +
      + + + + + + +
      +

      +To run pyste, you will need:

      +

      +Installation for the tools is avaiable in their respective webpages.

      + + + + +
      + + +GCCXML must be accessible in the PATH environment variable, so +that pyste can call it. How to do this varies from platform to platform. +
      +

      Ok, now what?

      +Well, now let's fire it up:

      +
      +
      +>python pyste.py
      +
      +Usage:
      +    pyste [options] --module=<name> interface-files
      +
      +where options are:
      +    -I <path>           add an include path
      +    -D <symbol>         define symbol
      +    --no-using          do not declare "using namespace boost";
      +                        use explicit declarations instead
      +    --pyste-ns=<name>   set the namespace where new types will be declared;
      +                        default is "pyste"
      +                        
      +

      +Options explained:

      +

      +The -I and -D are preprocessor flags, which are needed by gccxml to parse the header files correctly and by pyste to find the header files declared in the +interface files.

      +

      +--no-using tells pyste to don't declare "using namespace boost;" in the +generated cpp, using the namespace boost::python explicitly in all declarations. +Use only if you're having a name conflict in one of the files.

      +

      +Use --pyste-ns to change the namespace where new types are declared (for +instance, the virtual wrappers). Use only if one of your header files declare a +namespace named "pyste" and this is causing conflicts.

      +

      +So, the usage is simple enough:

      +
      >python pyste.py --module=mymodule file.pyste file2.pyste ...

      +will generate a file mymodule.cpp in the same dir where the command was +executed. Now you can compile the file using the same instructions of the + +tutorial.

      +

      Wait... how do I set those I and D flags?

      +Don't worry: normally +GCCXML is already configured correctly for your plataform, +so the search path to the standard libraries and the standard defines should +already be set. You only have to set the paths to other libraries that your code +needs, like Boost, for example.

      +

      +Plus, Pyste automatically uses the contents of the environment variable +INCLUDE if it exists. Windows users should run the Vcvars32.bat file, +normally located at:

      +
      +    C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat
      +
      +

      +with that, you should have little trouble setting up the flags.

      + + + + + + +
      +
      +
      + + diff --git a/pyste/doc/templates.html b/pyste/doc/templates.html new file mode 100644 index 00000000..58548c72 --- /dev/null +++ b/pyste/doc/templates.html @@ -0,0 +1,103 @@ + + + +Templates + + + + + + + + + + +
      + + Templates +
      +
      + + + + + + +
      +

      +Template Classes can easily exported too, but you can't export the "Template" +itself... you have to export instantiations of it! So, if you want to export a +std::vector, you will have to export vectors of int, doubles, etc.

      +

      +Suppose we have this code:

      +
      +    template <class T>
      +    struct Point
      +    {
      +        T x;
      +        T y;
      +    };
      +
      +

      +And we want to export Points of int and double:

      +
      +    Point = Template("Point", "point.h")
      +    Point("int")
      +    Point("double")
      +
      +

      +Pyste will assign default names for each instantiation. In this example, those +would be "Point_int" and "Point_double", but most of the time users will want to +rename the instantiations:

      +
      +    Point("int", "IPoint")         // renames the instantiation
      +    double_inst = Point("double")  // another way to do the same
      +    rename(double_inst, "DPoint")
      +
      +

      +Note that you can rename, exclude, set policies, etc, in the Template class +like you would do with a Function or a Class. This changes affect all +future instantiations:

      +
      +    Point = Template("Point", "point.h")
      +    Point("float", "FPoint")        // will have x and y as data members
      +    rename(Point.x, "X")
      +    rename(Point.y, "Y")
      +    Point("int", "IPoint")          // will have X and Y as data members
      +    Point("double", "DPoint")       // also will have X and Y as data member
      +
      +

      +If you want to change a option of a particular instantiation, you can do so:

      +
      +    Point = Template("Point", "point.h")
      +    Point("int", "IPoint")          
      +    d_inst = Point("double", "DPoint")       
      +    rename(d_inst.x, "X")           // only DPoint is affect by this renames,
      +    rename(d_inst.y, "Y")           // IPoint stays intact
      +
      + + + + +
      + What if my template accepts more than one type? +

      +When you want to instantiate a Template with more than one type, you can pass +either a string with the types separated by whitespace, or a list of strings +("int double" or ["int", "double"] would both work). +
      + + + + + + +
      +
      +
      + + diff --git a/pyste/doc/the_interface_files.html b/pyste/doc/the_interface_files.html new file mode 100644 index 00000000..77246af7 --- /dev/null +++ b/pyste/doc/the_interface_files.html @@ -0,0 +1,81 @@ + + + +The Interface Files + + + + + + + + + + +
      + + The Interface Files +
      +
      + + + + + + +
      +

      +The interface files are the heart of Pyste. The user creates one or more +interface files declaring the classes and functions he wants to export, and then +invokes pyste passing the interface files to it. Pyste then generates a single +cpp file with +Boost.Python code, with all the classes and functions exported.

      +

      +Besides declaring the classes and functions, the user has a number of other +options, like renaming classes and methods, excluding methods and attributes, +and so on.

      +

      Basics

      +Suppose we have a class and some functions that we want to expose to Python +declared in the header hello.h:

      +
      +    struct World
      +    {
      +        World(std::string msg): msg(msg) {} 
      +        void set(std::string msg) { this->msg = msg; }
      +        std::string greet() { return msg; }
      +        std::string msg;
      +    };
      +
      +    enum choice { red, blue };
      +    
      +    namespace test {
      +    
      +    void show(choice c) { std::cout << "value: " << (int)c << std::endl; }
      +    
      +    }
      +
      +

      +We create a file named hello.pyste and create instances of the classes +Function, Class and Enum:

      +
      +    Function("test::show", "hello.h")
      +    Class("World", "hello.h")
      +    Enum("choice", "hello.h")
      +
      +

      +That will expose the class, the free function and the enum found in hello.h.

      + + + + + + +
      +
      +
      + + diff --git a/pyste/doc/theme/alert.gif b/pyste/doc/theme/alert.gif new file mode 100644 index 0000000000000000000000000000000000000000..270764cc58716d36f8545c07ffbccb76a3dbc7f4 GIT binary patch literal 577 zcmZ?wbhEHb6krfwc*el+^5x4HFJ3%)^yuNkhj;GW`TvCB_N{CGA2IyD%W(C|x&OBr z{@-G_a_Q{m__~8F~vDYEl>qqZpDSjq@WJa>5z1Lm6Vd z86rG+L!23`^cb|27{rAb*jO1D7#RNl{|}<5jTL{gu!=AwGw6T}2E_>j`@DwarsiZ7 zvzCqy8~4s$Mnes@-VRGi5tqr$%yz7-+I%yUbrd6_%=Konm?$SD`KoeGb{17nO!DDy z>t(PKkWWZ*<cQAmnAE=fsD%$UE$ROUW+NUZ1+QQKJ-!ms2) z!wk-f=<_sLpE#kg){9r_k3+JcmI}v|3yP=3Bn5<=JQ5$B644M)RP)^A(&gG6!^Fs7 F4FJH#(p~@n literal 0 HcmV?d00001 diff --git a/pyste/doc/theme/arrow.gif b/pyste/doc/theme/arrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..e33db0fb4dd85e0fe527343d95a3f28a0ebb74f9 GIT binary patch literal 70 zcmZ?wbhEHb6lLIGn8?8J9}E~6W->4^DE?&OC-XFJFH7^5yH-udiOcdjJ0Y=g*&CzkdDw`}cS6-hKG+ zVdct|pFVy1_U+rhfB)XRdGq$|+aEuEeEj(F|NsB1R;~K`_wVY}tN;A@vu4ej6)RT! z{{8#cuU~7|u3fio-TL+GfByWrapT4f8#Zj(v}yC^&D*wZ+q!k@mMvR$@7{gjz=7@C zx9{A!bMM~0yLRo`vuDr#{rh+9*s*WlzC(u&9X)#V)TvV^Po6w- zyLay%Jb3Wz*|X1|Kfizf{+Tmpu3fwK^y$-^H*a3Qe*M|AXXnnHJAeNCg$oysA3uKe z>eWk^E+4<0lBLU*@T^?5dd(`K^&2*BTFEI`2zd3>o;z)v)s9R@BSUeM~|O8Wn_5q^405CHt*hl`1r~B%hzw;zdQW;{pasr zF9v2V8Hs|fgUuYmej5*MSa`TSY=y@hkBv&AY7)j-cRDt)dE zU9$D{^$pSTGkte&%f01a^!nae>+L=F4>WVj`|WA_`1r(RZF9M$J3l|aF#GrnzrDM@ zzP^$C;>NkXyT8BJIMglgzi&_FC%sFnlY$n!TsEid z)yw4z+N54FEt!_}YUPS$t6r^IvuM`A)fY$|rssS*xogRqPp5XWJpOdrfW7(58I$WZ zJ;oN#*L*&AD&X$RBj zw_mR(wCjGmkup8^+s%ySYroyf+5Yz1?SkXF-|v)M&;5S4;`!R|_iFabaxho}0O~&E Au>b%7 literal 0 HcmV?d00001 diff --git a/pyste/doc/theme/bkd2.gif b/pyste/doc/theme/bkd2.gif new file mode 100644 index 0000000000000000000000000000000000000000..b03d9ba97ca7a4c4de297b5413fd3d3df8e0fb49 GIT binary patch literal 2543 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 literal 0 HcmV?d00001 diff --git a/pyste/doc/theme/bulb.gif b/pyste/doc/theme/bulb.gif new file mode 100644 index 0000000000000000000000000000000000000000..74f3baac42f12ac0551040a00f78cb573360a0ad GIT binary patch literal 944 zcmZ?wbhEHbU2JX=yWO8qb`WHgo38Gifu=q@6jF_W#UGhBGsb&&*6a zGjrydnP<+-{D0;Q!i=IrIPje+GvC495Q% z(*85d1W7Xd|8LCj-`M!SaoT_5nIN^s|No~k{7*CfpO*GNZ6-)-+W-GE8UD{S{y#JA z|IC>nlV<+^e}>`z8RP$8cYq8A8~y)3Nb~>yAnE^L0P?^n9t{C$ zm!W3VRz=HX0SO5P1_s5SEQ|~c3=BFT0%V2*i>ts1&-4h1-QU}6JQPJ#9Az#qP{_IL z>m8xcQ#>ccK&B>uvC-M7@I$1?63NFG4AfGLn>kr6)<~>7uC&oZb>E%VNA7Gc3=Gx) DZ>u*X literal 0 HcmV?d00001 diff --git a/pyste/doc/theme/c++boost.gif b/pyste/doc/theme/c++boost.gif new file mode 100644 index 0000000000000000000000000000000000000000..58be431a3fafbd5adfa01e829ce8d80a03a83ed0 GIT binary patch literal 8819 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 literal 0 HcmV?d00001 diff --git a/pyste/doc/theme/l_arr.gif b/pyste/doc/theme/l_arr.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b3cb1cbf07e316c3655ac84c9ba72dfbe2e25a1 GIT binary patch literal 147 zcmZ?wbhEHb6k!l%*vtR|#>U2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#U2JX=yW!8D`F$dFITS|7mIeXEOYsnf8C?%>QSM|DT!p z|3Ab3|7ZS#f#OdVMg|6c1|5)2kQodtE+0;Mrh1v)&NktlbFtDU2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#&gTE>G6muSe93zS-%fd>Q)&EUbx3v}%NcRk;>%V0Cvz}Z0{|MoM2G+Y literal 0 HcmV?d00001 diff --git a/pyste/doc/theme/r_arr_disabled.gif b/pyste/doc/theme/r_arr_disabled.gif new file mode 100644 index 0000000000000000000000000000000000000000..2100f78bf35a47e09ca76ffcc6e80c5a2b11e359 GIT binary patch literal 91 zcmZ?wbhEHb6k!l%n8?5|bLPzZ_wWDz|DS<@LGdRGs|W)VgAM}&0|Q8&fk|gd|H|rv v@(cz3o}Svfg4O3$GVLgQHgm3)*?|1&XIvGFi0itr1TiFoeP&p1C|3gi5M|Dy8)Dq>pVFYM_y+=U^T ztHBMdj+tQ(A2Y*wF$RYE_4D-@jtU##9xMTW{_9v6c`wK7#J8B1sE6<80-`n z7><}aTg5mA1O&%;g!uX}*f26MGK54pa~u~3ne&L_xcGT71qKC%`|QWX?G$<#K=P%G z=f$!jvLf=G=8H2hFfyd8*(n?_D`m7(uv4gs=yaGbo~{-bxlJUa@tDY4zP5<9g6(Q8 z@$VV#2iy??g*_vVXy`OS*Qv? literal 0 HcmV?d00001 diff --git a/pyste/doc/theme/style.css b/pyste/doc/theme/style.css new file mode 100644 index 00000000..53a6205e --- /dev/null +++ b/pyste/doc/theme/style.css @@ -0,0 +1,170 @@ +body +{ + background-image: url(bkd.gif); + background-color: #FFFFFF; + margin: 1em 2em 1em 2em; +} + +h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; } +h2 { font: 140% sans-serif; font-weight: bold; text-align: left; } +h3 { font: 120% sans-serif; font-weight: bold; text-align: left; } +h4 { font: bold 100% sans-serif; font-weight: bold; text-align: left; } +h5 { font: italic 100% sans-serif; font-weight: bold; text-align: left; } +h6 { font: small-caps 100% sans-serif; font-weight: bold; text-align: left; } + +pre +{ + border-top: gray 1pt solid; + border-right: gray 1pt solid; + border-left: gray 1pt solid; + border-bottom: gray 1pt solid; + + padding-top: 2pt; + padding-right: 2pt; + padding-left: 2pt; + padding-bottom: 2pt; + + display: block; + font-family: "courier new", courier, mono; + background-color: #eeeeee; font-size: small +} + +code +{ + font-family: "Courier New", Courier, mono; + font-size: small +} + +tt +{ + display: inline; + font-family: "Courier New", Courier, mono; + color: #000099; + font-size: small +} + +p +{ + text-align: justify; + font-family: Georgia, "Times New Roman", Times, serif +} + +ul +{ + list-style-image: url(bullet.gif); + font-family: Georgia, "Times New Roman", Times, serif +} + +ol +{ + font-family: Georgia, "Times New Roman", Times, serif +} + +a +{ + font-weight: bold; + color: #003366; + text-decoration: none; +} + +a:hover { color: #8080FF; } + +.literal { color: #666666; font-style: italic} +.keyword { color: #000099} +.identifier {} +.comment { font-style: italic; color: #990000} +.special { color: #800040} +.preprocessor { color: #FF0000} +.string { font-style: italic; color: #666666} +.copyright { color: #666666; font-size: small} +.white_bkd { background-color: #FFFFFF} +.dk_grey_bkd { background-color: #999999} +.quotes { color: #666666; font-style: italic; font-weight: bold} + +.note_box +{ + display: block; + + border-top: gray 1pt solid; + border-right: gray 1pt solid; + border-left: gray 1pt solid; + border-bottom: gray 1pt solid; + + padding-right: 12pt; + padding-left: 12pt; + padding-bottom: 12pt; + padding-top: 12pt; + + font-family: Arial, Helvetica, sans-serif; + background-color: #E2E9EF; + font-size: small; text-align: justify +} + +.table_title +{ + background-color: #648CCA; + + font-family: Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; + font-weight: bold +; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px +} + +.table_cells +{ + background-color: #E2E9EF; + + font-family: Geneva, Arial, Helvetica, san-serif; + font-size: small +; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px +} + +.toc +{ + DISPLAY: block; + background-color: #E2E9EF + font-family: Arial, Helvetica, sans-serif; + + border-top: gray 1pt solid; + border-left: gray 1pt solid; + border-bottom: gray 1pt solid; + border-right: gray 1pt solid; + + padding-top: 24pt; + padding-right: 24pt; + padding-left: 24pt; + padding-bottom: 24pt; +} + +.toc_title +{ + background-color: #648CCA; + padding-top: 4px; + padding-right: 4px; + padding-bottom: 4px; + padding-left: 4px; + font-family: Geneva, Arial, Helvetica, san-serif; + color: #FFFFFF; + font-weight: bold +} + +.toc_cells +{ + background-color: #E2E9EF; + padding-top: 4px; + padding-right: 4px; + padding-bottom: 4px; + padding-left: 4px; + font-family: Geneva, Arial, Helvetica, san-serif; + font-size: small +} + +div.logo +{ + float: right; +} + +.toc_cells_L0 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } +.toc_cells_L1 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 44px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } +.toc_cells_L2 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 88px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } +.toc_cells_L3 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 122px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } +.toc_cells_L4 { background-color: #E2E9EF; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 166px; font-family: Geneva, Arial, Helvetica, san-serif; font-size: small } diff --git a/pyste/doc/theme/u_arr.gif b/pyste/doc/theme/u_arr.gif new file mode 100644 index 0000000000000000000000000000000000000000..ada3d6e043d2e4314a20d6783f2800f2f21d89c9 GIT binary patch literal 170 zcmZ?wbhEHb6k!l%*vtR|#>U2JX=yWO&OCGG%>OfK|If_)4`TfP|DWOif8+oE)BgXT z`Tzf!|NsBLfB#pCE@bTiY5O-A{7vV42g%c7%l^E8u0x + + +Wrappers + + + + + + + + + + +
      + + Wrappers +
      +
      + + + + + + +
      +

      +Suppose you have this function:

      +
      +    std::vector<std::string> names();
      +
      +

      +But you don't want to export a vector<string>, you want this function to return +a python list of strings. +Boost.Python has an excellent support for that:

      +
      +    list names_wrapper()
      +    {
      +        list result;
      +        vector<string> v = names();
      +        // put each string in the vector in the list
      +        return result;
      +    }
      +    
      +    BOOST_PYTHON_MODULE(test)
      +    {
      +        def("names", &names_wrapper);
      +    }
      +
      +

      +Nice heh? +Pyste supports this mechanism too. You declare the names_wrapper function in a +header, like "test_wrappers.h", and in the interface file:

      +
      +    Include("test_wrappers.h")
      +    names = Function("names", "test.h")
      +    set_wrapper(names, "names_wrapper")
      +
      +

      +You can optionally declare the function in the interface file itself:

      +
      +    names_wrapper = Wrapper("names_wrapper",
      +    """
      +    list names_wrapper()
      +    {
      +        // call name() and convert the vector to a list...
      +    }
      +    """)
      +    names = Function("names", "test.h")
      +    set_wrapper(names, names_wrapper)
      +
      +

      +The same mechanism can be done with methods too. Just remember that the first +parameter of wrappers for methods is a pointer to the class, like in + +Boost.Python:

      +
      +    struct C
      +    {
      +        std::vector<std::string> names();
      +    }
      +
      +    list names_wrapper(C* c)
      +    {
      +        // same as before, calling c->names() and converting result to a list
      +    }
      +
      +

      +And then in the interface file:

      +
      +    C = Class("C", "test.h")
      +    set_wrapper(C.names, "names_wrapper")
      +
      + + + + + + +
      +
      +
      + + diff --git a/pyste/index.html b/pyste/index.html new file mode 100644 index 00000000..ff153b50 --- /dev/null +++ b/pyste/index.html @@ -0,0 +1,71 @@ + + + +Pyste Documentation + + + + + + + + + +
      + + Pyste Documentation +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Table of contents
      + Introduction +
      + Running Pyste +
      + The Interface Files +
      + Renaming and Excluding +
      + Policies +
      + Templates +
      + Wrappers +
      + Exporting All Declarations from a Header +
      +
      +
      + + diff --git a/pyste/src/.cvsignore b/pyste/src/.cvsignore new file mode 100644 index 00000000..0d20b648 --- /dev/null +++ b/pyste/src/.cvsignore @@ -0,0 +1 @@ +*.pyc diff --git a/pyste/src/ClassExporter.py b/pyste/src/ClassExporter.py new file mode 100644 index 00000000..d72ff9db --- /dev/null +++ b/pyste/src/ClassExporter.py @@ -0,0 +1,688 @@ +import exporters +from Exporter import Exporter +from declarations import * +from enumerate import enumerate +from settings import * +from CodeUnit import CodeUnit +from EnumExporter import EnumExporter + + +#============================================================================== +# ClassExporter +#============================================================================== +class ClassExporter(Exporter): + 'Generates boost.python code to export a class declaration' + + + def __init__(self, info, parser_tail=None): + Exporter.__init__(self, info, parser_tail) + # sections of code + self.sections = {} + # template: each item in the list is an item into the class_<...> + # section. + self.sections['template'] = [] + # constructor: each item in the list is a parameter to the class_ + # constructor, like class_(...) + self.sections['constructor'] = [] + # inside: everything within the class_<> statement + self.sections['inside'] = [] + # scope: items outside the class statement but within its scope. + # scope* s = new scope(class<>()); + # ... + # delete s; + self.sections['scope'] = [] + # declarations: outside the BOOST_PYTHON_MODULE macro + self.sections['declaration'] = [] + self.sections['include'] = [] + # a list of Method instances + self.methods = [] + # a list of Constructor instances + self.constructors = [] + # a dict of methodname => _WrapperVirtualMethod instances + self.virtual_wrappers = {} + # a list of code units, generated by nested declarations + self.nested_codeunits = [] + + + def ScopeName(self): + return _ID(self.class_.FullName()) + '_scope' + + + def Name(self): + return self.class_.FullName() + + + def SetDeclarations(self, declarations): + Exporter.SetDeclarations(self, declarations) + decl = self.GetDeclaration(self.info.name) + if isinstance(decl, Typedef): + self.class_ = decl.type + if not self.info.rename: + self.info.rename = decl.name + else: + self.class_ = decl + self.public_members = \ + [x for x in self.class_.members if x.visibility == Scope.public] + + + def Order(self): + '''Return the TOTAL number of bases that this class has, including the + bases' bases. Do this because base classes must be instantialized + before the derived classes in the module definition. + ''' + + def BasesCount(classname): + decl = self.GetDeclaration(classname) + bases = [x.name for x in decl.bases] + total = 0 + for base in bases: + total += BasesCount(base) + return len(bases) + total + + return BasesCount(self.class_.FullName()) + + + def Export(self, codeunit, exported_names): + self.GetMethods() + self.ExportBasics() + self.ExportBases(exported_names) + self.ExportConstructors() + self.ExportVariables() + self.ExportMethods() + self.GenerateVirtualWrapper() + self.ExportOperators() + self.ExportNestedClasses(exported_names) + self.ExportNestedEnums() + self.Write(codeunit) + + + def Write(self, codeunit): + indent = self.INDENT + boost_ns = namespaces.python + pyste_ns = namespaces.pyste + code = '' + # begin a scope for this class if needed + nested_codeunits = self.nested_codeunits + needs_scope = self.sections['scope'] or nested_codeunits + if needs_scope: + scope_name = self.ScopeName() + code += indent + boost_ns + 'scope* %s = new %sscope(\n' %\ + (scope_name, boost_ns) + # export the template section + template_params = ', '.join(self.sections['template']) + code += indent + boost_ns + 'class_< %s >' % template_params + # export the constructor section + constructor_params = ', '.join(self.sections['constructor']) + code += '(%s)\n' % constructor_params + # export the inside section + in_indent = indent*2 + for line in self.sections['inside']: + code += in_indent + line + '\n' + # write the scope section and end it + if not needs_scope: + code += indent + ';\n' + else: + code += indent + ');\n' + for line in self.sections['scope']: + code += indent + line + '\n' + # write the contents of the nested classes + for nested_unit in nested_codeunits: + code += '\n' + nested_unit.Section('module') + # close the scope + code += indent + 'delete %s;\n' % scope_name + + # write the code to the module section in the codeunit + codeunit.Write('module', code + '\n') + + # write the declarations to the codeunit + declarations = '\n'.join(self.sections['declaration']) + for nested_unit in nested_codeunits: + declarations += nested_unit.Section('declaration') + if declarations: + codeunit.Write('declaration', declarations + '\n') + + # write the includes to the codeunit + includes = '\n'.join(self.sections['include']) + for nested_unit in nested_codeunits: + includes += nested_unit.Section('include') + if includes: + codeunit.Write('include', includes) + + + def Add(self, section, item): + 'Add the item into the corresponding section' + self.sections[section].append(item.strip()) + + + def ExportBasics(self): + 'Export the name of the class and its class_ statement' + self.Add('template', self.class_.FullName()) + name = self.info.rename or self.class_.name + self.Add('constructor', '"%s"' % name) + + + def ExportBases(self, exported_names): + 'Expose the bases of the class into the template section' + bases = self.class_.bases + bases_list = [] + for base in bases: + if base.visibility == Scope.public and base.name in exported_names: + bases_list.append(base.name) + if bases_list: + code = namespaces.python + 'bases< %s > ' % \ + (', '.join(bases_list)) + self.Add('template', code) + + + def ExportConstructors(self): + '''Exports all the public contructors of the class, plus indicates if the + class is noncopyable. + ''' + py_ns = namespaces.python + indent = self.INDENT + + def init_code(cons): + 'return the init<>() code for the given contructor' + param_list = [p.FullName() for p in cons.parameters] + min_params_list = param_list[:cons.minArgs] + max_params_list = param_list[cons.minArgs:] + min_params = ', '.join(min_params_list) + max_params = ', '.join(max_params_list) + init = py_ns + 'init< ' + init += min_params + if max_params: + if min_params: + init += ', ' + init += py_ns + ('optional< %s >' % max_params) + init += ' >()' + return init + + constructors = [x for x in self.public_members if isinstance(x, Constructor)] + self.constructors = constructors[:] + if not constructors: + # declare no_init + self.Add('constructor', py_ns + 'no_init') + else: + # write one of the constructors to the class_ constructor + self.Add('constructor', init_code(constructors.pop(0))) + # write the rest to the inside section, using def() + for cons in constructors: + code = '.def(%s)' % init_code(cons) + self.Add('inside', code) + # check if the class is copyable + if not self.class_.HasCopyConstructor() or self.class_.abstract: + self.Add('template', namespaces.boost + 'noncopyable') + + + def ExportVariables(self): + 'Export the variables of the class, both static and simple variables' + vars = [x for x in self.public_members if isinstance(x, Variable)] + for var in vars: + if self.info[var.name].exclude: + continue + name = self.info[var.name].rename or var.name + fullname = var.FullName() + if var.static: + code = '%s->attr("%s") = %s;' % (self.ScopeName(), name, fullname) + self.Add('scope', code) + else: + if var.type.const: + def_ = '.def_readonly' + else: + def_ = '.def_readwrite' + code = '%s("%s", &%s)' % (def_, name, fullname) + self.Add('inside', code) + + + def GetMethods(self): + 'fill self.methods with a list of Method instances' + # get a list of all methods + def IsValid(m): + 'Returns true if the given method is exportable by this routine' + ignore = (Constructor, ClassOperator, Destructor) + return isinstance(m, Method) and not isinstance(m, ignore) + + self.methods = [x for x in self.public_members if IsValid(x)] + + + + printed_policy_warnings = {} + + def CheckPolicy(self, m): + 'Warns the user if this method needs a policy' + def IsString(type): + return type.const and type.name == 'char' and isinstance(type, PointerType) + needs_policy = isinstance(m.result, (ReferenceType, PointerType)) + if IsString(m.result): + needs_policy = False + has_policy = self.info[m.name].policy is not None + if needs_policy and not has_policy: + warning = '---> Error: Method "%s" needs a policy.' % m.FullName() + if warning not in self.printed_policy_warnings: + print warning + print + self.printed_policy_warnings[warning] = 1 + + + def ExportMethods(self): + 'Export all the methods of the class' + + def OverloadName(m): + 'Returns the name of the overloads struct for the given method' + + return _ID(m.FullName()) + ('_overloads_%i_%i' % (m.minArgs, m.maxArgs)) + + declared = {} + def DeclareOverloads(m): + 'Declares the macro for the generation of the overloads' + if m.virtual: + func = self.virtual_wrappers[m.PointerDeclaration()].DefaultName() + else: + func = m.name + code = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(%s, %s, %i, %i)\n' + code = code % (OverloadName(m), func, m.minArgs, m.maxArgs) + if code not in declared: + declared[code] = True + self.Add('declaration', code) + + + def Pointer(m): + 'returns the correct pointer declaration for the method m' + # check if this method has a wrapper set for him + wrapper = self.info[method.name].wrapper + if wrapper: + return '&' + wrapper.FullName() + # if this method is virtual, return the pointers to the class and its wrapper + if m.virtual: + return self.virtual_wrappers[m.PointerDeclaration()].Pointer() + # return normal pointers to the methods of the class + is_unique = self.class_.IsUnique(m.name) + if is_unique: + return '&' + method.FullName() + else: + return method.PointerDeclaration() + + + for method in self.methods: + if self.info[method.name].exclude: + continue # skip this method + + name = self.info[method.name].rename or method.name + # check if this method needs to be wrapped as a virtual method + if method.virtual: + wrapper = _WrapperVirtualMethod(self.class_, method, name) + self.virtual_wrappers[method.PointerDeclaration()] = wrapper + # abstract methods don't need to be exported + if method.abstract: + continue # skip .def declaration for abstract methods + # warn the user if this method needs a policy and doesn't have one + self.CheckPolicy(method) + + # check for policies + policy = self.info[method.name].policy or '' + if policy: + policy = ', %s%s()' % (namespaces.python, policy.Code()) + # check for overloads + overload = '' + if method.minArgs != method.maxArgs: + # add the overloads for this method + overload_name = OverloadName(method) + DeclareOverloads(method) + if not method.virtual: + overload = ', %s%s()' % (namespaces.pyste, overload_name) + else: + pyste_ns = namespaces.pyste + pointer = self.virtual_wrappers[method.PointerDeclaration()].DefaultPointer() + defcode = '.def("%s", %s, %s%s())' % \ + (name, pointer, pyste_ns, overload_name) + self.Add('inside', defcode) + # build the string to export the method + pointer = Pointer(method) + code = '.def("%s", %s' % (name, pointer) + code += policy + code += overload + code += ')' + self.Add('inside', code) + # static method + if method.static: + code = '.staticmethod("%s")' % name + self.Add('inside', code) + # add wrapper code if this method has one + wrapper = self.info[method.name].wrapper + if wrapper and wrapper.code: + self.Add('declaration', wrapper.code) + + + def GenerateVirtualWrapper(self): + 'Generate the wrapper to dispatch virtual methods' + # check if this class needs a wrapper first + for m in self.methods: + if m.virtual: + break + else: + return + # add the wrapper name to the template section + wrapper_name = _WrapperName(self.class_) + self.Add('template', namespaces.pyste + wrapper_name) + indent = self.INDENT + method_codes = [x.Code(indent) for x in self.virtual_wrappers.values()] + body = '\n'.join(method_codes) + # generate the class code + class_name = self.class_.FullName() + code = 'struct %s: %s\n' % (wrapper_name, class_name) + code += '{\n' + # generate constructors + for cons in self.constructors: + params, param_names, param_types = _ParamsInfo(cons) + if params: + params = ', ' + params + cons_code = indent + '%s(PyObject* self_%s):\n' % (wrapper_name, params) + cons_code += indent*2 + '%s(%s), self(self_) {}\n\n' % \ + (class_name, ', '.join(param_names)) + code += cons_code + code += body + '\n' + code += indent + 'PyObject* self;\n' + code += '};\n' + self.Add('declaration', code) + + + # operators natively supported by boost + BOOST_SUPPORTED_OPERATORS = '+ - * / % ^ & ! ~ | < > == != <= >= << >> && || += -='\ + '*= /= %= ^= &= |= <<= >>='.split() + # create a map for faster lookup + BOOST_SUPPORTED_OPERATORS = dict(zip(BOOST_SUPPORTED_OPERATORS, range(len(BOOST_SUPPORTED_OPERATORS)))) + + # a dict of operators that are not directly supported by boost, but can be exposed + # simply as a function with a special signature + BOOST_RENAME_OPERATORS = { + '()' : '__call__', + } + + # converters which has a special name in python + SPECIAL_CONVETERS = { + 'double' : '__float__', + 'float' : '__float__', + 'int' : '__int__', + } + + + def ExportOperators(self): + 'Export all member operators and free operators related to this class' + + def GetFreeOperators(): + 'Get all the free (global) operators related to this class' + operators = [] + for decl in self.declarations: + if isinstance(decl, Operator): + # check if one of the params is this class + for param in decl.parameters: + if param.name == self.class_.FullName(): + operators.append(decl) + break + return operators + + def GetOperand(param): + 'Returns the operand of this parameter (either "self", or "other")' + if param.name == self.class_.FullName(): + return namespaces.python + 'self' + else: + return namespaces.python + ('other< %s >()' % param.name) + + + def HandleSpecialOperator(operator): + # gatter information about the operator and its parameters + result_name = operator.result.name + param1_name = '' + if operator.parameters: + param1_name = operator.parameters[0].name + + # check for str + ostream = 'basic_ostream' + is_str = result_name.find(ostream) != -1 and param1_name.find(ostream) != -1 + if is_str: + namespace = namespaces.python + 'self_ns::' + self_ = namespaces.python + 'self' + return '.def(%sstr(%s))' % (namespace, self_) + + # is not a special operator + return None + + + + frees = GetFreeOperators() + members = [x for x in self.public_members if type(x) == ClassOperator] + all_operators = frees + members + operators = [x for x in all_operators if not self.info['operator'][x.name].exclude] + + for operator in operators: + # gatter information about the operator, for use later + wrapper = self.info['operator'][operator.name].wrapper + if wrapper: + pointer = '&' + wrapper.FullName() + if wrapper.code: + self.Add('declaration', wrapper.code) + elif isinstance(operator, ClassOperator) and self.class_.IsUnique(operator.name): + pointer = '&' + operator.FullName() + else: + pointer = operator.PointerDeclaration() + rename = self.info['operator'][operator.name].rename + + # check if this operator will be exported as a method + export_as_method = wrapper or rename or operator.name in self.BOOST_RENAME_OPERATORS + + # check if this operator has a special representation in boost + special_code = HandleSpecialOperator(operator) + has_special_representation = special_code is not None + + if export_as_method: + # export this operator as a normal method, renaming or using the given wrapper + if not rename: + if wrapper: + rename = wrapper.name + else: + rename = self.BOOST_RENAME_OPERATORS[operator.name] + policy = '' + policy_obj = self.info['operator'][operator.name].policy + if policy_obj: + policy = ', %s()' % policy_obj.Code() + self.Add('inside', '.def("%s", %s%s)' % (rename, pointer, policy)) + + elif has_special_representation: + self.Add('inside', special_code) + + elif operator.name in self.BOOST_SUPPORTED_OPERATORS: + # export this operator using boost's facilities + op = operator + is_unary = isinstance(op, Operator) and len(op.parameters) == 1 or\ + isinstance(op, ClassOperator) and len(op.parameters) == 0 + if is_unary: + self.Add('inside', '.def( %s%sself )' % \ + (operator.name, namespaces.python)) + else: + # binary operator + if len(operator.parameters) == 2: + left_operand = GetOperand(operator.parameters[0]) + right_operand = GetOperand(operator.parameters[1]) + else: + left_operand = namespaces.python + 'self' + right_operand = GetOperand(operator.parameters[0]) + self.Add('inside', '.def( %s %s %s )' % \ + (left_operand, operator.name, right_operand)) + + # export the converters. + # export them as simple functions with a pre-determined name + + converters = [x for x in self.public_members if type(x) == ConverterOperator] + + def ConverterMethodName(converter): + result_fullname = converter.result.name + # extract the last name from the full name + result_name = _ID(result_fullname.split('::')[-1]) + return 'to_' + result_name + + for converter in converters: + info = self.info['operator'][converter.result.name] + # check if this operator should be excluded + if info.exclude: + continue + + special_code = HandleSpecialOperator(converter) + if info.rename or not special_code: + # export as method + name = info.rename or ConverterMethodName(converter) + if self.class_.IsUnique(converter.name): + pointer = '&' + converter.FullName() + else: + pointer = converter.PointerDeclaration() + policy_code = '' + if info.policy: + policy_code = ', %s()' % info.policy.Code() + self.Add('inside', '.def("%s", %s%s)' % (name, pointer, policy_code)) + + elif special_code: + self.Add('inside', special_code) + + + + def ExportNestedClasses(self, exported_names): + nested_classes = [x for x in self.public_members if isinstance(x, NestedClass)] + for nested_class in nested_classes: + nested_info = self.info[nested_class.name] + nested_info.include = self.info.include + nested_info.name = nested_class.FullName() + exporter = ClassExporter(nested_info) + exporter.SetDeclarations(self.declarations + [nested_class]) + codeunit = CodeUnit(None) + exporter.Export(codeunit, exported_names) + self.nested_codeunits.append(codeunit) + + + def ExportNestedEnums(self): + nested_enums = [x for x in self.public_members if isinstance(x, ClassEnumeration)] + for enum in nested_enums: + enum_info = self.info[enum.name] + enum_info.include = self.info.include + enum_info.name = enum.FullName() + exporter = EnumExporter(enum_info) + exporter.SetDeclarations(self.declarations + [enum]) + codeunit = CodeUnit(None) + exporter.Export(codeunit, None) + self.nested_codeunits.append(codeunit) + + + + +def _ID(name): + 'Returns the name as a valid identifier' + for invalidchar in ('::', '<', '>', ' ', ','): + name = name.replace(invalidchar, '_') + # avoid duplications of '_' chars + names = [x for x in name.split('_') if x] + return '_'.join(names) + + +#============================================================================== +# Virtual Wrapper utils +#============================================================================== + +def _WrapperName(class_): + return _ID(class_.FullName()) + '_Wrapper' + + +def _ParamsInfo(m): + param_names = ['p%i' % i for i in range(len(m.parameters))] + param_types = [x.FullName() for x in m.parameters] + params = ['%s %s' % (t, n) for t, n in zip(param_types, param_names)] + for i, p in enumerate(m.parameters): + if p.default is not None: + #params[i] += '=%s' % p.default + params[i] += '=%s' % (p.name + '()') + params = ', '.join(params) + return params, param_names, param_types + + +class _WrapperVirtualMethod(object): + 'Holds information about a virtual method that will be wrapped' + + def __init__(self, class_, method, rename): + self.method = method + if rename is None: + rename = method.name + self.rename = rename + self.class_ = class_ + + + def DefaultName(self): + return 'default_' + self.method.name + + + def DefaultPointer(self): + ns = namespaces.pyste + wrapper_name = _WrapperName(self.class_) + default_name = self.DefaultName() + fullname = '%s%s::%s' % (ns, wrapper_name, default_name) + if self.class_.IsUnique(self.method.name): + return '&%s' % fullname + else: + # the method is not unique, so we must specify the entire signature with it + param_list = [x.FullName() for x in self.method.parameters] + params = ', '.join(param_list) + result = self.method.result.FullName() + signature = '%s (%s%s::*)(%s)' % (result, ns, wrapper_name, params) + return '(%s)%s' % (signature, fullname) + + + def Pointer(self): + '''Returns the "pointer" declaration for this method, ie, the contents + of the .def after the method name (.def("name", ))''' + ns = namespaces.pyste + default_name = self.DefaultName() + name = self.method.name + class_name = self.class_.FullName() + wrapper = ns + _WrapperName(self.class_) + if self.class_.IsUnique(self.method.name): + return '&%s::%s, &%s::%s' % (class_name, name, wrapper, default_name) + else: + # the method is not unique, so we must specify the entire signature with it + param_list = [x.FullName() for x in self.method.parameters] + params = ', '.join(param_list) + result = self.method.result.FullName() + default_sig = '%s (%s::*)(%s)' % (result, wrapper, params) + normal_sig = '%s (%s::*)(%s)' % (result, class_name, params) + return '(%s)%s::%s, (%s)%s::%s' % \ + (normal_sig, class_name, name, default_sig, wrapper, default_name) + + + def Code(self, indent): + params, param_names, param_types = _ParamsInfo(self.method) + result = self.method.result.FullName() + return_ = 'return ' + if result == 'void': + return_ = '' + param_names = ', '.join(param_names) + class_name = self.class_.FullName() + method_name = self.method.name + default_name = self.DefaultName() + # constantness + const = '' + if self.method.const: + const = 'const ' + code = '' + # create default_method if this method has a default implementation + if not self.method.abstract: + default_sig = '%s %s(%s) %s' % (result, default_name, params, const) + body = '{ %s%s::%s(%s); } ' % \ + (return_, class_name, method_name, param_names) + code += indent + default_sig + body + '\n' + # create normal method + normal_sig = '%s %s(%s) %s' % (result, method_name, params, const) + if param_names: + param_names = ', ' + param_names + body = '{ %s%scall_method< %s >(self, "%s"%s); }' % \ + (return_, namespaces.python, result, self.rename, param_names) + code += indent + normal_sig + body + '\n' + + return code + + + diff --git a/pyste/src/CodeUnit.py b/pyste/src/CodeUnit.py new file mode 100644 index 00000000..ac123f99 --- /dev/null +++ b/pyste/src/CodeUnit.py @@ -0,0 +1,78 @@ +from settings import * + +#============================================================================== +# RemoveDuplicatedLines +#============================================================================== +def RemoveDuplicatedLines(text): + includes = text.splitlines() + d = dict([(include, 0) for include in includes]) + return '\n'.join(d.keys()) + + +#============================================================================== +# CodeUnit +#============================================================================== +class CodeUnit: + ''' + Represents a cpp file, where other objects can write in one of the + predefined sections. + The avaiable sections are: + include - The include area of the cpp file + declaration - The part before the module definition + module - Inside the BOOST_PYTHON_MODULE macro + ''' + + USING_BOOST_NS = True + + def __init__(self, modulename): + self.modulename = modulename + # define the avaiable sections + self.code = {} + self.code['include'] = '' + self.code['declaration'] = '' + self.code['module'] = '' + + + def Write(self, section, code): + 'write the given code in the section of the code unit' + if section not in self.code: + raise RuntimeError, 'Invalid CodeUnit section: %s' % section + self.code[section] += code + + + def Section(self, section): + return self.code[section] + + + def Save(self, filename): + 'Writes this code unit to the filename' + space = '\n\n' + fout = file(filename, 'w') + # includes + includes = RemoveDuplicatedLines(self.code['include']) + fout.write('\n' + self._leftEquals('Includes')) + fout.write('#include \n') + fout.write(includes) + fout.write(space) + # using + if self.USING_BOOST_NS: + fout.write(self._leftEquals('Using')) + fout.write('using namespace boost::python;\n\n') + # declarations + if self.code['declaration']: + pyste_namespace = namespaces.pyste[:-2] + fout.write(self._leftEquals('Declarations')) + fout.write('namespace %s {\n\n\n' % pyste_namespace) + fout.write(self.code['declaration']) + fout.write('\n\n}// namespace %s\n' % pyste_namespace) + fout.write(space) + # module + fout.write(self._leftEquals('Module')) + fout.write('BOOST_PYTHON_MODULE(%s)\n{\n' % self.modulename) + fout.write(self.code['module']) + fout.write('}\n') + + + def _leftEquals(self, s): + s = '// %s ' % s + return s + ('='*(80-len(s))) + '\n' diff --git a/pyste/src/CppParser.py b/pyste/src/CppParser.py new file mode 100644 index 00000000..2dd9c9ff --- /dev/null +++ b/pyste/src/CppParser.py @@ -0,0 +1,94 @@ +from GCCXMLParser import ParseDeclarations +import tempfile +import shutil +import os +import os.path +import settings + +class CppParserError(Exception): pass + + +class CppParser: + 'Parses a header file and returns a list of declarations' + + def __init__(self, includes=None, defines=None): + 'includes and defines ar the directives given to gcc' + if includes is None: + includes = [] + if defines is None: + defines = [] + self.includes = includes + self.defines = defines + + + def _includeparams(self, filename): + includes = self.includes[:] + filedir = os.path.dirname(filename) + if not filedir: + filedir = '.' + includes.insert(0, filedir) + includes = ['-I "%s"' % x for x in includes] + return ' '.join(includes) + + + def _defineparams(self): + defines = ['-D "%s"' % x for x in self.defines] + return ' '.join(defines) + + + def FindFileName(self, include): + if os.path.isfile(include): + return include + for path in self.includes: + filename = os.path.join(path, include) + if os.path.isfile(filename): + return filename + name = os.path.basename(include) + raise RuntimeError, 'Header file "%s" not found!' % name + + + def parse(self, include, symbols=None, tail=None): + '''Parses the given filename, and returns (declaration, header). The + header returned is normally the same as the given to this method, + except if tail is not None: in this case, the header is copied to a temp + filename and the tail code is appended to it before being passed on to gcc. + This temp filename is then returned. + ''' + filename = self.FindFileName(include) + # copy file to temp folder, if needed + if tail: + tempfilename = tempfile.mktemp('.h') + infilename = tempfilename + shutil.copy(filename, infilename) + f = file(infilename, 'a') + f.write('\n\n'+tail) + f.close() + else: + infilename = filename + xmlfile = tempfile.mktemp('.xml') + try: + # get the params + includes = self._includeparams(filename) + defines = self._defineparams() + # call gccxml + cmd = 'gccxml %s %s %s -fxml=%s' \ + % (includes, defines, infilename, xmlfile) + if symbols: + cmd += ' -fxml-start=' + ','.join(symbols) + status = os.system(cmd) + if status != 0 or not os.path.isfile(xmlfile): + raise CppParserError, 'Error executing gccxml' + # parse the resulting xml + declarations = ParseDeclarations(xmlfile) + # return the declarations + return declarations, infilename + finally: + if settings.DEBUG and os.path.isfile(xmlfile): + filename = os.path.basename(include) + shutil.copy(xmlfile, os.path.splitext(filename)[0] + '.xml') + # delete the temporary files + try: + os.remove(xmlfile) + if tail: + os.remove(tempfilename) + except OSError: pass diff --git a/pyste/src/EnumExporter.py b/pyste/src/EnumExporter.py new file mode 100644 index 00000000..fda4d721 --- /dev/null +++ b/pyste/src/EnumExporter.py @@ -0,0 +1,30 @@ +from Exporter import Exporter +from settings import * + +#============================================================================== +# EnumExporter +#============================================================================== +class EnumExporter(Exporter): + 'Exports enumerators' + + def __init__(self, info): + Exporter.__init__(self, info) + + + def SetDeclarations(self, declarations): + Exporter.SetDeclarations(self, declarations) + self.enum = self.GetDeclaration(self.info.name) + + + def Export(self, codeunit, expoted_names): + indent = self.INDENT + in_indent = self.INDENT*2 + rename = self.info.rename or self.enum.name + full_name = self.enum.FullName() + code = indent + namespaces.python + 'enum_< %s >("%s")\n' % (full_name, rename) + for name in self.enum.values: + rename = self.info[name].rename or name + value_fullname = self.enum.ValueFullName(name) + code += in_indent + '.value("%s", %s)\n' % (rename, value_fullname) + code += indent + ';\n\n' + codeunit.Write('module', code) diff --git a/pyste/src/Exporter.py b/pyste/src/Exporter.py new file mode 100644 index 00000000..02259582 --- /dev/null +++ b/pyste/src/Exporter.py @@ -0,0 +1,69 @@ +import os.path + +#============================================================================== +# Exporter +#============================================================================== +class Exporter: + 'Base class for objects capable to generate boost.python code.' + + INDENT = ' ' * 4 + + def __init__(self, info, parser_tail=None): + self.info = info + self.parser_tail = parser_tail + + + def Parse(self, parser): + self.parser = parser + header = self.info.include + tail = self.parser_tail + declarations, parser_header = parser.parse(header, tail=tail) + self.parser_header = parser_header + self.SetDeclarations(declarations) + + + def SetDeclarations(self, declarations): + self.declarations = declarations + + + def GenerateCode(self, codeunit, exported_names): + self.WriteInclude(codeunit) + self.Export(codeunit, exported_names) + + + def WriteInclude(self, codeunit): + codeunit.Write('include', '#include <%s>\n' % self.info.include) + + + def Export(self, codeunit, exported_names): + 'subclasses must override this to do the real work' + pass + + + def Name(self): + '''Returns the name of this Exporter. The name will be added to the + list of names exported, which may have a use for other exporters. + ''' + return None + + + def GetDeclarations(self, fullname): + decls = [x for x in self.declarations if x.FullName() == fullname] + if not decls: + raise RuntimeError, 'no %s declaration found!' % fullname + return decls + + + def GetDeclaration(self, fullname): + decls = self.GetDeclarations(fullname) + assert len(decls) == 1 + return decls[0] + + + def Order(self): + '''Returns a number that indicates to which order this exporter + belongs. The exporters will be called from the lowest order to the + highest order. + This function will only be called after Parse has been called. + ''' + return None # don't care diff --git a/pyste/src/FunctionExporter.py b/pyste/src/FunctionExporter.py new file mode 100644 index 00000000..2638a776 --- /dev/null +++ b/pyste/src/FunctionExporter.py @@ -0,0 +1,81 @@ +from Exporter import Exporter +from policies import * +from declarations import * +from settings import * + + +class FunctionExporter(Exporter): + 'Generates boost.python code to export the given function.' + + def __init__(self, info, tail=None): + Exporter.__init__(self, info, tail) + + + def Export(self, codeunit, exported_names): + decls = self.GetDeclarations(self.info.name) + for decl in decls: + self.CheckPolicy(decl) + self.ExportDeclaration(decl, len(decls) == 1, codeunit) + self.GenerateOverloads(decls, codeunit) + + + def Name(self): + return self.info.name + + + def CheckPolicy(self, func): + 'Warns the user if this function needs a policy' + needs_policy = isinstance(func.result, (ReferenceType, PointerType)) + if needs_policy and self.info.policy is None: + print '---> Error: Function "%s" needs a policy.' % func.FullName() + print + + def ExportDeclaration(self, decl, unique, codeunit): + name = self.info.rename or decl.name + defs = namespaces.python + 'def("%s", ' % name + wrapper = self.info.wrapper + if wrapper: + pointer = '&' + wrapper.FullName() + elif not unique: + pointer = decl.PointerDeclaration() + else: + pointer = '&' + decl.FullName() + defs += pointer + defs += self.PolicyCode() + overload = self.OverloadName(decl) + if overload: + defs += ', %s()' % (namespaces.pyste + overload) + defs += ');' + codeunit.Write('module', self.INDENT + defs + '\n') + # add the code of the wrapper + if wrapper and wrapper.code: + codeunit.Write('declaration', code + '\n') + + + def OverloadName(self, decl): + if decl.minArgs != decl.maxArgs: + return '%s_overloads_%i_%i' % \ + (decl.name, decl.minArgs, decl.maxArgs) + else: + return '' + + + def GenerateOverloads(self, declarations, codeunit): + codes = {} + for decl in declarations: + overload = self.OverloadName(decl) + if overload and overload not in codes: + code = 'BOOST_PYTHON_FUNCTION_OVERLOADS(%s, %s, %i, %i)' %\ + (overload, decl.FullName(), decl.minArgs, decl.maxArgs) + codeunit.Write('declaration', code + '\n') + codes[overload] = None + + + def PolicyCode(self): + policy = self.info.policy + if policy is not None: + assert isinstance(policy, Policy) + return ', %s()' % policy.Code() + else: + return '' + diff --git a/pyste/src/GCCXMLParser.py b/pyste/src/GCCXMLParser.py new file mode 100644 index 00000000..937db92f --- /dev/null +++ b/pyste/src/GCCXMLParser.py @@ -0,0 +1,395 @@ +from declarations import * +from elementtree.ElementTree import ElementTree +from xml.parsers.expat import ExpatError +from copy import deepcopy + + +class InvalidXMLError(Exception): pass + +class ParserError(Exception): pass + +class InvalidContextError(ParserError): pass + + +class GCCXMLParser(object): + 'Parse a GCC_XML file and extract the top-level declarations.' + + interested_tags = {'Class':0, 'Function':0, 'Variable':0, 'Enumeration':0} + + def Parse(self, filename): + self.elements = self.GetElementsFromXML(filename) + # high level declarations + self.declarations = [] + # parse the elements + for id in self.elements: + element, decl = self.elements[id] + if decl is None: + try: + self.ParseElement(id, element) + except InvalidContextError: + pass # ignore those nodes with invalid context + # (workaround gccxml bug) + + + def Declarations(self): + return self.declarations + + + def AddDecl(self, decl): + self.declarations.append(decl) + + + def ParseElement(self, id, element): + method = 'Parse' + element.tag + if hasattr(self, method): + func = getattr(self, method) + func(id, element) + + + def GetElementsFromXML(self,filename): + 'Extracts a dictionary of elements from the gcc_xml file.' + + tree = ElementTree() + try: + tree.parse(filename) + except ExpatError: + raise InvalidXMLError, 'Not a XML file: %s' % filename + + root = tree.getroot() + if root.tag != 'GCC_XML': + raise InvalidXMLError, 'Not a valid GCC_XML file' + + # build a dictionary of id -> element, None + elementlist = root.getchildren() + elements = {} + for element in elementlist: + id = element.get('id') + if id: + elements[id] = element, None + return elements + + + def GetDecl(self, id): + if id not in self.elements: + if id == '_0': + raise InvalidContextError, 'Invalid context found in the xml file.' + else: + msg = 'ID not found in elements: %s' % id + raise ParserError, msg + + elem, decl = self.elements[id] + if decl is None: + self.ParseElement(id, elem) + elem, decl = self.elements[id] + if decl is None: + raise ParserError, 'Could not parse element: %s' % elem.tag + return decl + + + def GetType(self, id): + const = False + volatile = False + if id[-1] == 'v': + volatile = True + id = id[:-1] + if id[-1] == 'c': + const = True + id = id[:-1] + decl = self.GetDecl(id) + if isinstance(decl, Type): + res = deepcopy(decl) + if const: + res.const = const + if volatile: + res.volatile = volatile + else: + res = Type(decl.FullName(), const) + res.volatile = volatile + return res + + + def GetLocation(self, location): + file, line = location.split(':') + file = self.GetDecl(file) + return file, int(line) + + + def Update(self, id, decl): + element, _ = self.elements[id] + self.elements[id] = element, decl + + + def ParseNamespace(self, id, element): + namespace = element.get('name') + context = element.get('context') + if context: + outerns = self.GetDecl(context) + if not outerns.endswith('::'): + outerns += '::' + namespace = outerns + namespace + if namespace.startswith('::'): + namespace = namespace[2:] + self.Update(id, namespace) + + + def ParseFile(self, id, element): + filename = element.get('name') + self.Update(id, filename) + + + def ParseVariable(self, id, element): + # in gcc_xml, a static Field is declared as a Variable, so we check + # this and call the Field parser if apply. + context = self.GetDecl(element.get('context')) + if isinstance(context, Class): + self.ParseField(id, element) + elem, decl = self.elements[id] + decl.static = True + else: + namespace = context + name = element.get('name') + type_ = self.GetType(element.get('type')) + location = self.GetLocation(element.get('location')) + variable = Variable(type_, name, namespace) + variable.location = location + self.AddDecl(variable) + self.Update(id, variable) + + + def GetArguments(self, element): + args = [] + for child in element: + if child.tag == 'Argument': + type_ = self.GetType(child.get('type')) + type_.default = child.get('default') + args.append(type_) + return args + + + def ParseFunction(self, id, element, functionType=Function): + '''functionType is used because a Operator is identical to a normal + function, only the type of the function changes.''' + name = element.get('name') + returns = self.GetType(element.get('returns')) + namespace = self.GetDecl(element.get('context')) + location = self.GetLocation(element.get('location')) + params = self.GetArguments(element) + function = functionType(name, namespace, returns, params) + function.location = location + self.AddDecl(function) + self.Update(id, function) + + + def ParseOperatorFunction(self, id, element): + self.ParseFunction(id, element, Operator) + + + def GetBases(self, bases): + 'Parses the string "bases" from the xml into a list of Base instances.' + + if bases is None: + return [] + bases = bases.split() + baseobjs = [] + for base in bases: + # get the visibility + split = base.split(':') + if len(split) == 2: + visib = split[0] + base = split[1] + else: + visib = Scope.public + decl = self.GetDecl(base) + baseobj = Base(decl.FullName(), visib) + baseobjs.append(baseobj) + return baseobjs + + + def GetMembers(self, members): + # members must be a string with the ids of the members + if members is None: + return [] + memberobjs = [] + for member in members.split(): + memberobjs.append(self.GetDecl(member)) + return memberobjs + + + def ParseClass(self, id, element): + name = element.get('name') + abstract = bool(int(element.get('abstract', '0'))) + bases = self.GetBases(element.get('bases')) + location = self.GetLocation(element.get('location')) + context = self.GetDecl(element.get('context')) + if isinstance(context, Class): # a nested class + visib = element.get('access', Scope.public) + class_ = NestedClass( + name, context.FullName(), visib, [], abstract, bases) + else: + assert isinstance(context, str) + class_ = Class(name, context, [], abstract, bases) + self.AddDecl(class_) + # we have to add the declaration of the class before trying + # to parse its members, to avoid recursion. + class_.location = location + self.Update(id, class_) + # now we can get the members + class_.members = self.GetMembers(element.get('members')) + + + def ParseStruct(self, id, element): + self.ParseClass(id, element) + + + def ParseFundamentalType(self, id, element): + name = element.get('name') + type_ = FundamentalType(name) + self.Update(id, type_) + + + def ParseArrayType(self, id, element): + type_ = self.GetType(element.get('type')) + min = element.get('min') + max = element.get('max') + if min: + min = int(min) + if max: + max = int(max) + array = ArrayType(type_.name, min, max, type_.const) + self.Update(id, array) + + + def ParseReferenceType(self, id, element): + type_ = self.GetType(element.get('type')) + expand = not isinstance(type_, FunctionType) + ref = ReferenceType(type_.name, type_.const, None, expand) + self.Update(id, ref) + + + def ParsePointerType(self, id, element): + type_ = self.GetType(element.get('type')) + expand = not isinstance(type_, FunctionType) + ref = PointerType(type_.name, type_.const, None, expand) + self.Update(id, ref) + + + def ParseFunctionType(self, id, element): + result = self.GetType(element.get('returns')) + args = self.GetArguments(element) + func = FunctionType(result, args) + self.Update(id, func) + + + def ParseMethodType(self, id, element): + class_ = self.GetDecl(element.get('basetype')).FullName() + result = self.GetType(element.get('returns')) + args = self.GetArguments(element) + method = MethodType(result, args, class_) + self.Update(id, method) + + + def ParseField(self, id, element): + name = element.get('name') + visib = element.get('access', Scope.public) + classname = self.GetDecl(element.get('context')).FullName() + type_ = self.GetType(element.get('type')) + static = bool(int(element.get('extern', '0'))) + location = self.GetLocation(element.get('location')) + var = ClassVariable(type_, name, classname, visib, static) + var.location = location + self.Update(id, var) + + + def ParseMethod(self, id, element, methodType=Method): + name = element.get('name') + result = self.GetType(element.get('returns')) + classname = self.GetDecl(element.get('context')).FullName() + visib = element.get('access', Scope.public) + static = bool(int(element.get('static', '0'))) + virtual = bool(int(element.get('virtual', '0'))) + abstract = bool(int(element.get('pure_virtual', '0'))) + const = bool(int(element.get('const', '0'))) + location = self.GetLocation(element.get('location')) + params = self.GetArguments(element) + method = methodType( + name, classname, result, params, visib, virtual, abstract, static, const) + method.location = location + self.Update(id, method) + + + def ParseOperatorMethod(self, id, element): + self.ParseMethod(id, element, ClassOperator) + + + def ParseConstructor(self, id, element): + name = element.get('name') + visib = element.get('access', Scope.public) + classname = self.GetDecl(element.get('context')).FullName() + location = self.GetLocation(element.get('location')) + params = self.GetArguments(element) + ctor = Constructor(name, classname, params, visib) + ctor.location = location + self.Update(id, ctor) + + + def ParseDestructor(self, id, element): + name = element.get('name') + visib = element.get('access', Scope.public) + classname = self.GetDecl(element.get('context')).FullName() + virtual = bool(int(element.get('virtual', '0'))) + location = self.GetLocation(element.get('location')) + des = Destructor(name, classname, visib, virtual) + des.location = location + self.Update(id, des) + + + def ParseConverter(self, id, element): + self.ParseMethod(id, element, ConverterOperator) + + + def ParseTypedef(self, id, element): + name = element.get('name') + type = self.GetDecl(element.get('type')) + context = self.GetDecl(element.get('context')) + if isinstance(context, Class): + context = context.FullName() + typedef = Typedef(type, name, context) + self.Update(id, typedef) + self.AddDecl(typedef) + + + def ParseEnumeration(self, id, element): + name = element.get('name') + location = self.GetLocation(element.get('location')) + context = self.GetDecl(element.get('context')) + if isinstance(context, Class): + visib = element.get('access', Scope.public) + enum = ClassEnumeration(name, context.FullName(), visib) + else: + enum = Enumeration(name, context) + self.AddDecl(enum) # in this case, is a top level decl + enum.location = location + for child in element: + if child.tag == 'EnumValue': + name = child.get('name') + value = int(child.get('init')) + enum.values[name] = value + self.Update(id, enum) + + + def ParseUnimplemented(self, id, element): + 'No idea of what this is' + self.Update(id, Declaration('', '')) + + + def ParseUnion(self, id, element): + self.Update(id, Declaration(element.get('name'), '')) + + + +def ParseDeclarations(filename): + 'Returns a list of the top declarations found in the gcc_xml file.' + + parser = GCCXMLParser() + parser.Parse(filename) + return parser.Declarations() diff --git a/pyste/src/HeaderExporter.py b/pyste/src/HeaderExporter.py new file mode 100644 index 00000000..9234e8af --- /dev/null +++ b/pyste/src/HeaderExporter.py @@ -0,0 +1,67 @@ +from Exporter import Exporter +from ClassExporter import ClassExporter +from FunctionExporter import FunctionExporter +from EnumExporter import EnumExporter +from infos import * +from declarations import * +import os.path +import exporters + +#============================================================================== +# HeaderExporter +#============================================================================== +class HeaderExporter(Exporter): + 'Exports all declarations found in the given header' + + def __init__(self, info, parser_tail=None): + Exporter.__init__(self, info, parser_tail) + + + def WriteInclude(self, codeunit): + pass + + + def SetDeclarations(self, declarations): + def IsInternalName(name): + '''Returns true if the given name looks like a internal compiler + structure''' + return name.startswith('__') + + Exporter.SetDeclarations(self, declarations) + header = os.path.normpath(self.parser_header) + for decl in declarations: + # check if this declaration is in the header + location = os.path.normpath(decl.location[0]) + if location != header or IsInternalName(decl.name): + continue + # ok, check the type of the declaration and export it accordingly + self.HandleDeclaration(decl) + + + def HandleDeclaration(self, decl): + '''Dispatch the declaration to the appropriate method, that must create + a suitable info object for a Exporter, create a Exporter, set its + declarations and append it to the list of exporters. + ''' + dispatch_table = { + Class : ClassExporter, + Enumeration : EnumExporter, + Function : FunctionExporter, + } + + for decl_type, exporter_type in dispatch_table.items(): + if type(decl) == decl_type: + self.HandleExporter(decl, exporter_type) + break + + + def HandleExporter(self, decl, exporter_type): + info = self.info[decl.name] + info.name = decl.FullName() + info.include = self.info.include + exporter = exporter_type(info) + exporter.SetDeclarations(self.declarations) + exporters.exporters.append(exporter) + + + diff --git a/pyste/src/IncludeExporter.py b/pyste/src/IncludeExporter.py new file mode 100644 index 00000000..2a7b0602 --- /dev/null +++ b/pyste/src/IncludeExporter.py @@ -0,0 +1,19 @@ +import os.path +from Exporter import Exporter + +#============================================================================== +# IncludeExporter +#============================================================================== +class IncludeExporter(Exporter): + '''Writes an include declaration to the module. Useful to add extra code + for use in the Wrappers. + This class just reimplements the Parse method to do nothing: the + WriteInclude in Exporter already does the work for us. + ''' + + def __init__(self, info, parser_tail=None): + Exporter.__init__(self, info, parser_tail) + + def Parse(self, parser): + pass + diff --git a/pyste/src/declarations.py b/pyste/src/declarations.py new file mode 100644 index 00000000..adba6fd3 --- /dev/null +++ b/pyste/src/declarations.py @@ -0,0 +1,452 @@ +''' +Module declarations + + Defines classes that represent declarations found in C++ header files. + +''' + +class Declaration(object): + 'Represents a basic declaration.' + + def __init__(self, name, namespace): + # the declaration name + self.name = name + # all the namespaces, separated by '::' = 'boost::inner' + self.namespace = namespace + # tuple (filename, line) + self.location = '', -1 + + + def FullName(self): + 'Returns the full qualified name: "boost::inner::Test"' + namespace = self.namespace or '' + #if not namespace: + # namespace = '' + if namespace and not namespace.endswith('::'): + namespace += '::' + return namespace + self.name + + + def __repr__(self): + return '' % (self.FullName(), id(self)) + + + def __str__(self): + return 'Declaration of %s' % self.FullName() + + + +class Class(Declaration): + 'The declaration of a class or struct.' + + def __init__(self, name, namespace, members, abstract, bases): + Declaration.__init__(self, name, namespace) + # list of members + self.members = members + # whatever the class has any abstract methods + self.abstract = abstract + # instances of Base + self.bases = bases + self._members_count = {} + + + def __iter__(self): + return iter(self.members) + + + def IsAbstract(self): + 'Returns True if any method of this class is abstract' + for member in self.members: + if isinstance(member, Method): + if member.abstract: + return True + return False + + + def RawName(self): + 'Returns the raw name of a template class. name = Foo, raw = Foo' + lesspos = self.name.find('<') + if lesspos != -1: + return self.name[:lesspos] + else: + return self.name + + + def Constructors(self, publics_only=True): + constructors = [] + for member in self: + if isinstance(member, Constructor): + if publics_only and member.visibility != Scope.public: + continue + constructors.append(member) + return constructors + + + def HasCopyConstructor(self): + for cons in self.Constructors(): + if cons.IsCopy(): + return True + return False + + + def HasDefaultConstructor(self): + for cons in self.Constructors(): + if cons.IsDefault(): + return True + return False + + + def IsUnique(self, member_name): + if not self._members_count: + for m in self: + self._members_count[m.name] = self._members_count.get(m.name, 0) + 1 + try: + return self._members_count[member_name] == 1 + except KeyError: + print self._members_count + print 'Key', member_name + + + +class NestedClass(Class): + 'The declaration of a class/struct inside another class/struct.' + + def __init__(self, name, class_, visib, members, abstract, bases): + Class.__init__(self, name, None, members, abstract, bases) + self.class_ = class_ + self.visibility = visib + + + def FullName(self): + return '%s::%s' % (self.class_, self.name) + + + +class Base: + 'Represents a base class of another class.' + + def __init__(self, name, visibility=None): + # class_ is the full name of the base class + self.name = name + # visibility of the derivation + if visibility is None: + visibility = Scope.public + self.visibility = visibility + + + +class Scope: + public = 'public' + private = 'private' + protected = 'protected' + + + +class Function(Declaration): + 'The declaration of a function.' + + def __init__(self, name, namespace, result, params): + Declaration.__init__(self, name, namespace) + # the result type: instance of Type, or None (constructors) + self.result = result + # the parameters: instances of Type + self.parameters = params + + + def PointerDeclaration(self): + 'returns a declaration of a pointer to this function' + result = self.result.FullName() + params = ', '.join([x.FullName() for x in self.parameters]) + return '(%s (*)(%s))%s' % (result, params, self.FullName()) + + + def _MinArgs(self): + min = 0 + for arg in self.parameters: + if arg.default is None: + min += 1 + return min + + minArgs = property(_MinArgs) + + + def _MaxArgs(self): + return len(self.parameters) + + maxArgs = property(_MaxArgs) + + + +class Operator(Function): + 'The declaration of a custom operator.' + def FullName(self): + namespace = self.namespace or '' + if not namespace.endswith('::'): + namespace += '::' + return namespace + 'operator' + self.name + + + +class Method(Function): + 'The declaration of a method.' + + def __init__(self, name, class_, result, params, visib, virtual, abstract, static, const): + Function.__init__(self, name, None, result, params) + self.visibility = visib + self.virtual = virtual + self.abstract = abstract + self.static = static + self.class_ = class_ + self.const = const + + + def FullName(self): + return self.class_ + '::' + self.name + + + def PointerDeclaration(self): + 'returns a declaration of a pointer to this function' + result = self.result.FullName() + params = ', '.join([x.FullName() for x in self.parameters]) + const = '' + if self.const: + const = 'const' + return '(%s (%s::*)(%s) %s)%s' %\ + (result, self.class_, params, const, self.FullName()) + + +class Constructor(Method): + 'A constructor of a class.' + + def __init__(self, name, class_, params, visib): + Method.__init__(self, name, class_, None, params, visib, False, False, False, False) + + + def IsDefault(self): + return len(self.parameters) == 0 + + + def IsCopy(self): + if len(self.parameters) != 1: + return False + param = self.parameters[0] + class_as_param = self.parameters[0].name == self.class_ + param_reference = isinstance(param, ReferenceType) + return param_reference and class_as_param and param.const + + +class Destructor(Method): + 'The destructor of a class.' + + def __init__(self, name, class_, visib, virtual): + Method.__init__(self, name, class_, None, [], visib, virtual, False, False, False) + + def FullName(self): + return self.class_ + '::~' + self.name + + + +class ClassOperator(Method): + 'The declaration of a custom operator in a class.' + + def FullName(self): + return self.class_ + '::operator ' + self.name + + + +class ConverterOperator(ClassOperator): + 'An operator in the form "operator OtherClass()".' + + def FullName(self): + return self.class_ + '::operator ' + self.result.name + + + +class Type(Declaration): + 'Represents a type.' + + def __init__(self, name, const=False, default=None): + Declaration.__init__(self, name, None) + # whatever the type is constant or not + self.const = const + # used when the Type is a function argument + self.default = default + self.volatile = False + + def __repr__(self): + if self.const: + const = 'const ' + else: + const = '' + return '' + + + def FullName(self): + if self.const: + const = 'const ' + else: + const = '' + return const + self.name + + + +class ArrayType(Type): + 'Represents an array.' + + def __init__(self, name, min, max, const=False): + 'min and max can be None.' + Type.__init__(self, name, const) + self.min = min + self.max = max + + + +class ReferenceType(Type): + 'A reference type.' + + def __init__(self, name, const=False, default=None, expandRef=True): + Type.__init__(self, name, const, default) + self.expand = expandRef + + + def FullName(self): + 'expand is False for function pointers' + expand = ' &' + if not self.expand: + expand = '' + return Type.FullName(self) + expand + + + +class PointerType(Type): + 'A pointer type.' + + def __init__(self, name, const=False, default=None, expandPointer=False): + Type.__init__(self, name, const, default) + self.expand = expandPointer + + + def FullName(self): + 'expand is False for function pointer' + expand = ' *' + if not self.expand: + expand = '' + return Type.FullName(self) + expand + + + +class FundamentalType(Type): + 'One of the fundamental types (int, void...).' + + def __init__(self, name, const=False): + Type.__init__(self, name, const) + + + +class FunctionType(Type): + 'A pointer to a function.' + + def __init__(self, result, params): + Type.__init__(self, '', False) + self.result = result + self.parameters = params + self.name = self.FullName() + + + def FullName(self): + full = '%s (*)' % self.result.FullName() + params = [x.FullName() for x in self.parameters] + full += '(%s)' % ', '.join(params) + return full + + + +class MethodType(FunctionType): + 'A pointer to a member function of a class.' + + def __init__(self, result, params, class_): + Type.__init__(self, '', False) + self.result = result + self.parameters = params + self.class_ = class_ + self.name = self.FullName() + + def FullName(self): + full = '%s (%s::*)' % (self.result.FullName(), self.class_) + params = [x.FullName() for x in self.parameters] + full += '(%s)' % ', '.join(params) + return full + + + +class Variable(Declaration): + 'Represents a global variable.' + + def __init__(self, type, name, namespace): + Declaration.__init__(self, name, namespace) + # instance of Type + self.type = type + + + +class ClassVariable(Variable): + 'Represents a class variable.' + + def __init__(self, type, name, class_, visib, static): + Variable.__init__(self, type, name, None) + self.visibility = visib + self.static = static + self.class_ = class_ + + + def FullName(self): + return self.class_ + '::' + self.name + + + +class Enumeration(Declaration): + + def __init__(self, name, namespace): + Declaration.__init__(self, name, namespace) + self.values = {} # dict of str => int + + def ValueFullName(self, name): + assert name in self.values + namespace = self.namespace + if namespace: + namespace += '::' + return namespace + name + + + +class ClassEnumeration(Enumeration): + + def __init__(self, name, class_, visib): + Enumeration.__init__(self, name, None) + self.class_ = class_ + self.visibility = visib + + + def FullName(self): + return '%s::%s' % (self.class_, self.name) + + + def ValueFullName(self, name): + assert name in self.values + return '%s::%s' % (self.class_, name) + + + +class Typedef(Declaration): + + def __init__(self, type, name, namespace): + Declaration.__init__(self, name, namespace) + self.type = type + self.visibility = Scope.public + + + + + + + diff --git a/pyste/src/enumerate.py b/pyste/src/enumerate.py new file mode 100644 index 00000000..099e42ba --- /dev/null +++ b/pyste/src/enumerate.py @@ -0,0 +1,7 @@ +from __future__ import generators + +def enumerate(seq): + i = 0 + for x in seq: + yield i, x + i += 1 diff --git a/pyste/src/exporters.py b/pyste/src/exporters.py new file mode 100644 index 00000000..65536780 --- /dev/null +++ b/pyste/src/exporters.py @@ -0,0 +1,3 @@ + +# a list of Exporter instances +exporters = [] diff --git a/pyste/src/exporterutils.py b/pyste/src/exporterutils.py new file mode 100644 index 00000000..5134a1e5 --- /dev/null +++ b/pyste/src/exporterutils.py @@ -0,0 +1,26 @@ +''' +Various helpers for interface files. +''' + +from settings import * + +#============================================================================== +# FunctionWrapper +#============================================================================== +class FunctionWrapper(object): + '''Holds information about a wrapper for a function or a method. It is in 2 + parts: the name of the Wrapper, and its code. The code is placed in the + declaration section of the module, while the name is used to def' the + function or method (with the pyste namespace prepend to it). If code is None, + the name is left unchanged. + ''' + + def __init__(self, name, code=None): + self.name = name + self.code = code + + def FullName(self): + if self.code: + return namespaces.pyste + self.name + else: + return self.name diff --git a/pyste/src/infos.py b/pyste/src/infos.py new file mode 100644 index 00000000..3d23537e --- /dev/null +++ b/pyste/src/infos.py @@ -0,0 +1,185 @@ +import os.path +import copy +import exporters +from ClassExporter import ClassExporter +from FunctionExporter import FunctionExporter +from IncludeExporter import IncludeExporter +from EnumExporter import EnumExporter +from HeaderExporter import HeaderExporter +from exporterutils import FunctionWrapper + + +#============================================================================== +# DeclarationInfo +#============================================================================== +class DeclarationInfo(object): + + def __init__(self, otherInfo=None): + self.__infos = {} + self.__attributes = {} + if otherInfo is not None: + self.__infos = otherInfo.__infos.copy() + self.__attributes = otherInfo.__attributes.copy() + + + def __getitem__(self, name): + 'Used to access sub-infos' + default = DeclarationInfo() + default._Attribute('name', name) + return self.__infos.setdefault(name, default) + + + def __getattr__(self, name): + return self[name] + + + def _Attribute(self, name, value=None): + if value is None: + # get value + return self.__attributes.get(name) + else: + # set value + self.__attributes[name] = value + + +#============================================================================== +# FunctionInfo +#============================================================================== +class FunctionInfo(DeclarationInfo): + + def __init__(self, name, include, tail=None, otherOption=None): + DeclarationInfo.__init__(self, otherOption) + self._Attribute('name', name) + self._Attribute('include', include) + # create a FunctionExporter + exporter = FunctionExporter(InfoWrapper(self), tail) + exporters.exporters.append(exporter) + + +#============================================================================== +# ClassInfo +#============================================================================== +class ClassInfo(DeclarationInfo): + + def __init__(self, name, include, tail=None, otherOption=None): + DeclarationInfo.__init__(self, otherOption) + self._Attribute('name', name) + self._Attribute('include', include) + # create a ClassExporter + exporter = ClassExporter(InfoWrapper(self), tail) + exporters.exporters.append(exporter) + + +#============================================================================== +# IncludeInfo +#============================================================================== +class IncludeInfo(DeclarationInfo): + + def __init__(self, include): + DeclarationInfo.__init__(self) + self._Attribute('include', include) + exporter = IncludeExporter(InfoWrapper(self)) + exporters.exporters.append(exporter) + + +#============================================================================== +# templates +#============================================================================== +def GenerateName(name, type_list): + name = name.replace('::', '_') + names = [name] + type_list + return '_'.join(names) + + +class ClassTemplateInfo(DeclarationInfo): + + def __init__(self, name, include): + DeclarationInfo.__init__(self) + self._Attribute('name', name) + self._Attribute('include', include) + + + def Instantiate(self, type_list, rename=None): + if not rename: + rename = GenerateName(self._Attribute('name'), type_list) + # generate code to instantiate the template + types = ', '.join(type_list) + tail = 'typedef %s< %s > %s;\n' % (self._Attribute('name'), types, rename) + tail += 'void __instantiate_%s()\n' % rename + tail += '{ sizeof(%s); }\n\n' % rename + # create a ClassInfo + class_ = ClassInfo(rename, self._Attribute('include'), tail, self) + return class_ + + + def __call__(self, types, rename=None): + if isinstance(types, str): + types = types.split() + return self.Instantiate(types, rename) + +#============================================================================== +# EnumInfo +#============================================================================== +class EnumInfo(DeclarationInfo): + + def __init__(self, name, include): + DeclarationInfo.__init__(self) + self._Attribute('name', name) + self._Attribute('include', include) + exporter = EnumExporter(InfoWrapper(self)) + exporters.exporters.append(exporter) + + +#============================================================================== +# HeaderInfo +#============================================================================== +class HeaderInfo(DeclarationInfo): + + def __init__(self, include): + DeclarationInfo.__init__(self) + self._Attribute('include', include) + exporter = HeaderExporter(InfoWrapper(self)) + exporters.exporters.append(exporter) + + +#============================================================================== +# InfoWrapper +#============================================================================== +class InfoWrapper: + 'Provides a nicer interface for a info' + + def __init__(self, info): + self.__dict__['_info'] = info # so __setattr__ is not called + + def __getitem__(self, name): + return InfoWrapper(self._info[name]) + + def __getattr__(self, name): + return self._info._Attribute(name) + + def __setattr__(self, name, value): + self._info._Attribute(name, value) + + +#============================================================================== +# Functions +#============================================================================== +def exclude(option): + option._Attribute('exclude', True) + +def set_policy(option, policy): + option._Attribute('policy', policy) + +def rename(option, name): + option._Attribute('rename', name) + +def set_wrapper(option, wrapper): + if isinstance(wrapper, str): + wrapper = FunctionWrapper(wrapper) + option._Attribute('wrapper', wrapper) + +def instantiate(template, types, rename=None): + if isinstance(types, str): + types = types.split() + return template.Instantiate(types, rename) + diff --git a/pyste/src/policies.py b/pyste/src/policies.py new file mode 100644 index 00000000..977e7f92 --- /dev/null +++ b/pyste/src/policies.py @@ -0,0 +1,75 @@ + + +class Policy: + 'Represents one of the call policies of boost.python.' + + def __init__(self): + raise RuntimeError, "Can't create an instance of the class Policy" + + + def Code(self): + 'Returns the string corresponding to a instancialization of the policy.' + pass + + + def _next(self): + if self.next is not None: + return ', %s >' % self.next.Code() + else: + return ' >' + + + +class return_internal_reference(Policy): + 'Ties the return value to one of the parameters.' + + def __init__(self, param=1, next=None): + ''' + param is the position of the parameter, or None for "self". + next indicates the next policy, or None. + ''' + self.param = param + self.next=next + + + def Code(self): + c = 'return_internal_reference< %i' % self.param + c += self._next() + return c + + + +class with_custodian_and_ward(Policy): + 'Ties lifetime of two arguments of a function.' + + def __init__(self, custodian, ward, next=None): + self.custodian = custodian + self.ward = ward + self.next = next + + def Code(self): + c = 'with_custodian_and_ward< %i, %i' % (self.custodian, self.ward) + c += self._next() + return c + + + +class return_value_policy(Policy): + 'Policy to convert return values.' + + def __init__(self, which, next=None): + self.which = which + self.next = next + + + def Code(self): + c = 'return_value_policy< %s' % self.which + c += self._next() + return c + + +# values for return_value_policy +reference_existing_object = 'reference_existing_object' +copy_const_reference = 'copy_const_reference' +copy_non_const_reference = 'copy_non_const_reference' +manage_new_object = 'manage_new_object' diff --git a/pyste/src/pyste-profile.py b/pyste/src/pyste-profile.py new file mode 100644 index 00000000..d7afff45 --- /dev/null +++ b/pyste/src/pyste-profile.py @@ -0,0 +1,17 @@ +import profile +import pstats +import pyste + +import psyco +import elementtree.XMLTreeBuilder as XMLTreeBuilder +import GCCXMLParser + + +if __name__ == '__main__': + #psyco.bind(XMLTreeBuilder.fixtext) + #psyco.bind(XMLTreeBuilder.fixname) + #psyco.bind(XMLTreeBuilder.TreeBuilder) + #psyco.bind(GCCXMLParser.GCCXMLParser) + profile.run('pyste.Main()', 'profile') + p = pstats.Stats('profile') + p.strip_dirs().sort_stats(-1).print_stats() diff --git a/pyste/src/pyste.py b/pyste/src/pyste.py new file mode 100644 index 00000000..090c7fd9 --- /dev/null +++ b/pyste/src/pyste.py @@ -0,0 +1,154 @@ +''' +Usage: + pyste [options] --module= interface-files + +where options are: + -I add an include path + -D define symbol + --no-using do not declare "using namespace boost"; + use explicit declarations instead + --pyste-ns= set the namespace where new types will be declared; + default is "pyste" +''' + +import sys +import os +import getopt +import exporters +import CodeUnit +import infos +import exporterutils +import settings +from policies import * +from CppParser import CppParser, CppParserError +from Exporter import Exporter +from FunctionExporter import FunctionExporter +from ClassExporter import ClassExporter +from IncludeExporter import IncludeExporter +from HeaderExporter import HeaderExporter + + +def GetDefaultIncludes(): + if 'INCLUDE' in os.environ: + include = os.environ['INCLUDE'] + return include.split(os.pathsep) + else: + return [] + + +def ParseArguments(): + + def Usage(): + print __doc__ + sys.exit(1) + + options, files = getopt.getopt(sys.argv[1:], 'I:D:', ['module=', 'out=', 'no-using', 'pyste-ns=', 'debug']) + includes = GetDefaultIncludes() + defines = [] + module = None + out = None + for opt, value in options: + if opt == '-I': + includes.append(value) + elif opt == '-D': + defines.append(value) + elif opt == '--module': + module = value + elif opt == '--out': + out = value + elif opt == '--no-using': + settings.namespaces.python = 'boost::python::' + CodeUnit.CodeUnit.USING_BOOST_NS = False + elif opt == '--pyste-ns': + settings.namespaces.pyste = value + '::' + elif opt == '--debug': + settings.DEBUG = True + else: + print 'Unknown option:', opt + Usage() + + if not files or not module: + Usage() + if not out: + out = module + '.cpp' + return includes, defines, module, out, files + + +def CreateContext(): + 'create the context where a interface file can be executed' + context = {} + # infos + context['Function'] = infos.FunctionInfo + context['Class'] = infos.ClassInfo + context['Include'] = infos.IncludeInfo + context['Template'] = infos.ClassTemplateInfo + context['Enum'] = infos.EnumInfo + context['AllFromHeader'] = infos.HeaderInfo + # functions + context['rename'] = infos.rename + context['set_policy'] = infos.set_policy + context['exclude'] = infos.exclude + context['set_wrapper'] = infos.set_wrapper + # policies + context['return_internal_reference'] = return_internal_reference + context['with_custodian_and_ward'] = with_custodian_and_ward + context['return_value_policy'] = return_value_policy + context['reference_existing_object'] = reference_existing_object + context['copy_const_reference'] = copy_const_reference + context['copy_non_const_reference'] = copy_non_const_reference + context['manage_new_object'] = manage_new_object + # utils + context['Wrapper'] = exporterutils.FunctionWrapper + return context + + +def Main(): + includes, defines, module, out, interfaces = ParseArguments() + # execute the interface files + for interface in interfaces: + context = CreateContext() + execfile(interface, context) + # parse all the C++ code + parser = CppParser(includes, defines) + exports = exporters.exporters[:] + for export in exports: + try: + export.Parse(parser) + except CppParserError, e: + print '\n' + print '***', e, ': exitting' + return 2 + print + # sort the exporters by its order + exports = [(x.Order(), x) for x in exporters.exporters] + exports.sort() + exports = [x for _, x in exports] + # now generate the wrapper code + codeunit = CodeUnit.CodeUnit(module) + exported_names = [] + for export in exports: + export.GenerateCode(codeunit, exported_names) + exported_names.append(export.Name()) + codeunit.Save(out) + print 'Module %s generated' % module + return 0 + + +def UsePsyco(): + 'Tries to use psyco if it is installed' + try: + import psyco + import elementtree.XMLTreeBuilder as XMLTreeBuilder + import GCCXMLParser + + psyco.bind(XMLTreeBuilder.fixtext) + psyco.bind(XMLTreeBuilder.fixname) + psyco.bind(XMLTreeBuilder.TreeBuilder) + psyco.bind(GCCXMLParser.GCCXMLParser) + except ImportError: pass + + +if __name__ == '__main__': + UsePsyco() + status = Main() + sys.exit(status) diff --git a/pyste/src/settings.py b/pyste/src/settings.py new file mode 100644 index 00000000..e5adfc25 --- /dev/null +++ b/pyste/src/settings.py @@ -0,0 +1,12 @@ + +#============================================================================== +# Global information +#============================================================================== + +DEBUG = False + +class namespaces: + boost = 'boost::' + pyste = '' + python = '' # default is to not use boost::python namespace explicitly, so + # use the "using namespace" statement instead diff --git a/pyste/tests/GCCXMLParserUT.py b/pyste/tests/GCCXMLParserUT.py new file mode 100644 index 00000000..c0a17b33 --- /dev/null +++ b/pyste/tests/GCCXMLParserUT.py @@ -0,0 +1,338 @@ +import sys +sys.path.append('..') +import unittest +import tempfile +import os.path +import GCCXMLParser +from declarations import * + + +class Tester(unittest.TestCase): + + def TestConstructor(self, class_, method, visib): + self.assert_(isinstance(method, Constructor)) + self.assertEqual(method.FullName(), class_.FullName() + '::' + method.name) + self.assertEqual(method.result, None) + self.assertEqual(method.visibility, visib) + self.assert_(not method.virtual) + self.assert_(not method.abstract) + self.assert_(not method.static) + + def TestDefaultConstructor(self, class_, method, visib): + self.TestConstructor(class_, method, visib) + self.assert_(method.IsDefault()) + + def TestCopyConstructor(self, class_, method, visib): + self.TestConstructor(class_, method, visib) + self.assertEqual(len(method.parameters), 1) + param = method.parameters[0] + self.TestType( + param, + ReferenceType, + class_.FullName(), + 'const %s &' % class_.FullName(), + True) + self.assert_(method.IsCopy()) + + + def TestType(self, type_, classtype_, name, fullname, const): + self.assert_(isinstance(type_, classtype_)) + self.assertEqual(type_.name, name) + self.assertEqual(type_.namespace, None) + self.assertEqual(type_.FullName(), fullname) + self.assertEqual(type_.const, const) + + +class ClassBaseTest(Tester): + + def setUp(self): + self.base = GetDecl('Base') + + def testClass(self): + 'test the properties of the class Base' + self.assert_(isinstance(self.base, Class)) + self.assert_(self.base.abstract) + self.assertEqual(self.base.RawName(), 'Base') + + + def testFoo(self): + 'test function foo in class Base' + foo = GetMember(self.base, 'foo') + self.assert_(isinstance(foo, Method)) + self.assertEqual(foo.visibility, Scope.public) + self.assert_(foo.virtual) + self.assert_(foo.abstract) + self.failIf(foo.static) + self.assertEqual(foo.class_, 'test::Base') + self.failIf(foo.const) + self.assertEqual(foo.FullName(), 'test::Base::foo') + self.assertEqual(foo.result.name, 'void') + self.assertEqual(len(foo.parameters), 1) + param = foo.parameters[0] + self.TestType(param, FundamentalType, 'int', 'int', False) + self.assertEqual(foo.namespace, None) + self.assertEqual( + foo.PointerDeclaration(), '(void (test::Base::*)(int) )test::Base::foo') + + def testX(self): + 'test the member x in class Base' + x = GetMember(self.base, 'x') + self.assertEqual(x.class_, 'test::Base') + self.assertEqual(x.FullName(), 'test::Base::x') + self.assertEqual(x.namespace, None) + self.assertEqual(x.visibility, Scope.private) + self.TestType(x.type, FundamentalType, 'int', 'int', False) + self.assertEqual(x.static, False) + + def testConstructors(self): + 'test constructors in class Base' + constructors = GetMembers(self.base, 'Base') + for cons in constructors: + if len(cons.parameters) == 0: + self.TestDefaultConstructor(self.base, cons, Scope.public) + elif len(cons.parameters) == 1: # copy constructor + self.TestCopyConstructor(self.base, cons, Scope.public) + elif len(cons.parameters) == 2: # other constructor + intp, floatp = cons.parameters + self.TestType(intp, FundamentalType, 'int', 'int', False) + self.TestType(floatp, FundamentalType, 'float', 'float', False) + + def testSimple(self): + 'test function simple in class Base' + simple = GetMember(self.base, 'simple') + self.assert_(isinstance(simple, Method)) + self.assertEqual(simple.visibility, Scope.protected) + self.assertEqual(simple.FullName(), 'test::Base::simple') + self.assertEqual(len(simple.parameters), 1) + param = simple.parameters[0] + self.TestType(param, ReferenceType, 'std::string', 'const std::string &', True) + self.TestType(simple.result, FundamentalType, 'bool', 'bool', False) + self.assertEqual( + simple.PointerDeclaration(), + '(bool (test::Base::*)(const std::string &) )test::Base::simple') + + + def testZ(self): + z = GetMember(self.base, 'z') + self.assert_(isinstance(z, Variable)) + self.assertEqual(z.visibility, Scope.public) + self.assertEqual(z.FullName(), 'test::Base::z') + self.assertEqual(z.type.name, 'int') + self.assertEqual(z.type.const, False) + self.assert_(z.static) + + +class ClassTemplateTest(Tester): + + def setUp(self): + self.template = GetDecl('Template') + + def testClass(self): + 'test the properties of the Template class' + self.assert_(isinstance(self.template, Class)) + self.assert_(not self.template.abstract) + self.assertEqual(self.template.FullName(), 'Template') + self.assertEqual(self.template.namespace, '') + self.assertEqual(self.template.name, 'Template') + self.assertEqual(self.template.RawName(), 'Template') + + def testConstructors(self): + 'test the automatic constructors of the class Template' + constructors = GetMembers(self.template, 'Template') + for cons in constructors: + if len(cons.parameters) == 0: + self.TestDefaultConstructor(self.template, cons, Scope.public) + elif len(cons.parameters) == 1: + self.TestCopyConstructor(self.template, cons, Scope.public) + + + def testValue(self): + 'test the class variable value' + value = GetMember(self.template, 'value') + self.assert_(isinstance(value, ClassVariable)) + self.assert_(value.name, 'value') + self.TestType(value.type, FundamentalType, 'int', 'int', False) + self.assert_(not value.static) + self.assertEqual(value.visibility, Scope.public) + self.assertEqual(value.class_, 'Template') + self.assertEqual(value.FullName(), 'Template::value') + + def testBase(self): + 'test the superclasses of Template' + bases = self.template.bases + self.assertEqual(len(bases), 1) + base = bases[0] + self.assert_(isinstance(base, Base)) + self.assertEqual(base.name, 'test::Base') + self.assertEqual(base.visibility, Scope.protected) + + + +class FreeFuncTest(Tester): + + def setUp(self): + self.func = GetDecl('FreeFunc') + + def testFunc(self): + 'test attributes of FreeFunc' + self.assert_(isinstance(self.func, Function)) + self.assertEqual(self.func.name, 'FreeFunc') + self.assertEqual(self.func.FullName(), 'test::FreeFunc') + self.assertEqual(self.func.namespace, 'test') + self.assertEqual( + self.func.PointerDeclaration(), + '(const test::Base & (*)(const std::string &, int))test::FreeFunc') + + + def testResult(self): + 'test the return value of FreeFunc' + res = self.func.result + self.TestType(res, ReferenceType, 'test::Base', 'const test::Base &', True) + + def testParameters(self): + 'test the parameters of FreeFunc' + self.assertEqual(len(self.func.parameters), 2) + strp, intp = self.func.parameters + self.TestType(strp, ReferenceType, 'std::string', 'const std::string &', True) + self.assertEqual(strp.default, None) + self.TestType(intp, FundamentalType, 'int', 'int', False) + self.assertEqual(intp.default, '10') + + + +class testFunctionPointers(Tester): + + def testMethodPointer(self): + 'test declaration of a pointer-to-method' + meth = GetDecl('MethodTester') + param = meth.parameters[0] + fullname = 'void (test::Base::*)(int)' + self.TestType(param, PointerType, fullname, fullname, False) + + def testFunctionPointer(self): + 'test declaration of a pointer-to-function' + func = GetDecl('FunctionTester') + param = func.parameters[0] + fullname = 'void (*)(int)' + self.TestType(param, PointerType, fullname, fullname, False) + + + +# ============================================================================= +# Support routines +# ============================================================================= + +cppcode = ''' +namespace std { + class string; +} +namespace test { +class Base +{ +public: + Base(); + Base(const Base&); + Base(int, float); + + virtual void foo(int = 0.0) = 0; + static int z; +protected: + bool simple(const std::string&); +private: + int x; +}; + +void MethodTester( void (Base::*)(int) ); +void FunctionTester( void (*)(int) ); + + +const Base & FreeFunc(const std::string&, int=10); + +} + +template +struct Template: protected test::Base +{ + T value; + virtual void foo(int); +}; + +Template __aTemplateInt; +''' + +def GetXMLFile(): + '''Generates an gccxml file using the code from the global cppcode. + Returns the xml's filename.''' + # write the code to a header file + tmpfile = tempfile.mktemp() + '.h' + f = file(tmpfile, 'w') + f.write(cppcode) + f.close() + # run gccxml + outfile = tmpfile + '.xml' + if os.system('gccxml "%s" "-fxml=%s"' % (tmpfile, outfile)) != 0: + raise RuntimeError, 'Error executing GCCXML.' + # read the output file into the xmlcode + f = file(outfile) + xmlcode = f.read() + #print xmlcode + f.close() + # remove the header + os.remove(tmpfile) + return outfile + + + +def GetDeclarations(): + 'Uses the GCCXMLParser module to get the declarations.' + xmlfile = GetXMLFile() + declarations = GCCXMLParser.ParseDeclarations(xmlfile) + os.remove(xmlfile) + return declarations + +# the declarations to be analysed +declarations = GetDeclarations() + + +def GetDecl(name): + 'returns one of the top declarations given its name' + for decl in declarations: + if decl.name == name: + return decl + else: + raise RuntimeError, 'Declaration not found: %s' % name + + +def GetMember(class_, name): + 'gets the member of the given class by its name' + + res = None + multipleFound = False + for member in class_: + if member.name == name: + if res is not None: + multipleFound = True + break + res = member + if res is None or multipleFound: + raise RuntimeError, \ + 'No member or more than one member found in class %s: %s' \ + % (class_.name, name) + return res + + +def GetMembers(class_, name): + 'gets the members of the given class by its name' + res = [] + for member in class_: + if member.name == name: + res.append(member) + if len(res) in (0, 1): + raise RuntimeError, \ + 'GetMembers: 0 or 1 members found in class %s: %s' \ + % (class_.name, name) + return res + + +if __name__ == '__main__': + unittest.main() diff --git a/pyste/tests/infosUT.py b/pyste/tests/infosUT.py new file mode 100644 index 00000000..71d5e368 --- /dev/null +++ b/pyste/tests/infosUT.py @@ -0,0 +1,50 @@ +import sys +sys.path.append('../src') +from infos import * +from policies import * +from exporterutils import * +import unittest + + +class InfosTest(unittest.TestCase): + + def testFunctionInfo(self): + info = FunctionInfo('test::foo', 'foo.h') + rename(info, 'hello') + set_policy(info, return_internal_reference()) + set_wrapper(info, FunctionWrapper('foo_wrapper')) + + info = InfoWrapper(info) + + self.assertEqual(info.rename, 'hello') + self.assertEqual(info.policy.Code(), 'return_internal_reference< 1 >') + self.assertEqual(info.wrapper.name, 'foo_wrapper') + + + def testClassInfo(self): + info = ClassInfo('test::IFoo', 'foo.h') + rename(info.name, 'Name') + rename(info.exclude, 'Exclude') + rename(info, 'Foo') + rename(info.Bar, 'bar') + set_policy(info.Baz, return_internal_reference()) + rename(info.operator['>>'], 'from_string') + exclude(info.Bar) + set_wrapper(info.Baz, FunctionWrapper('baz_wrapper')) + + info = InfoWrapper(info) + + self.assertEqual(info.rename, 'Foo') + self.assertEqual(info['Bar'].rename, 'bar') + self.assertEqual(info['name'].rename, 'Name') + self.assertEqual(info['exclude'].rename, 'Exclude') + self.assertEqual(info['Bar'].exclude, True) + self.assertEqual(info['Baz'].policy.Code(), 'return_internal_reference< 1 >') + self.assertEqual(info['Baz'].wrapper.name, 'baz_wrapper') + self.assertEqual(info['operator']['>>'].rename, 'from_string') + + + + +if __name__ == '__main__': + unittest.main() diff --git a/pyste/tests/policiesUT.py b/pyste/tests/policiesUT.py new file mode 100644 index 00000000..bde08543 --- /dev/null +++ b/pyste/tests/policiesUT.py @@ -0,0 +1,59 @@ +import sys +sys.path.append('..') +import unittest +from policies import * + +class PoliciesTest(unittest.TestCase): + + def testReturnInternal(self): + 'tests the code from a simple internal_reference' + + x = return_internal_reference(1) + self.assertEqual(x.Code(), 'return_internal_reference< 1 >') + x = return_internal_reference(3) + self.assertEqual(x.Code(), 'return_internal_reference< 3 >') + + + def testCustodian(self): + 'tests the code from a simple custodian_and_ward' + + x = with_custodian_and_ward(1,2) + self.assertEqual(x.Code(), 'with_custodian_and_ward< 1, 2 >') + x = with_custodian_and_ward(3,4) + self.assertEqual(x.Code(), 'with_custodian_and_ward< 3, 4 >') + + + def testReturnPolicies(self): + 'tests all the return_value_policies' + + ret = 'return_value_policy< %s >' + x = return_value_policy(reference_existing_object) + self.assertEqual(x.Code(), ret % 'reference_existing_object') + x = return_value_policy(copy_const_reference) + self.assertEqual(x.Code(), ret % 'copy_const_reference') + x = return_value_policy(copy_non_const_reference) + self.assertEqual(x.Code(), ret % 'copy_non_const_reference') + x = return_value_policy(manage_new_object) + self.assertEqual(x.Code(), ret % 'manage_new_object') + + + def testReturnWithCustodiam(self): + 'test the mix of return_internal with custodian' + + x = return_internal_reference(1, with_custodian_and_ward(3,2)) + self.assertEqual( + x.Code(), + 'return_internal_reference< 1, with_custodian_and_ward< 3, 2 > >') + + + def testReturnPoliciesWithInternal(self): + 'test the mix of return_internal with return_policy' + + x = return_internal_reference(1, return_value_policy(manage_new_object)) + self.assertEqual( + x.Code(), + 'return_internal_reference< 1, return_value_policy< manage_new_object > >') + + +if __name__ == '__main__': + unittest.main() diff --git a/pyste/tests/runtests.py b/pyste/tests/runtests.py new file mode 100644 index 00000000..f670e3d4 --- /dev/null +++ b/pyste/tests/runtests.py @@ -0,0 +1,14 @@ +import sys +sys.path.append('../src') +import unittest +import os.path +from glob import glob + +if __name__ == '__main__': + loader = unittest.defaultTestLoader + tests = [] + for name in glob('*UT.py'): + module = __import__(os.path.splitext(name)[0]) + tests.append(loader.loadTestsFromModule(module)) + runner = unittest.TextTestRunner() + runner.run(unittest.TestSuite(tests)) From 415991f6fc8cc2129a9ae08f94cc0c8605847912 Mon Sep 17 00:00:00 2001 From: Bruno da Silva de Oliveira Date: Tue, 11 Mar 2003 03:34:28 +0000 Subject: [PATCH 1037/1042] - added a link to the Pyste documentation [SVN r17806] --- doc/index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/index.html b/doc/index.html index 599a8ca6..6e585a44 100644 --- a/doc/index.html +++ b/doc/index.html @@ -84,6 +84,8 @@
      Support Resources
      Frequently Asked Questions (FAQs)
      + +
      Pyste (Boost.Python code generator)
      News/Change Log
      From ca9920874fcbd4c2c2b64b86c27e49bb33b6df55 Mon Sep 17 00:00:00 2001 From: Bruno da Silva de Oliveira Date: Wed, 12 Mar 2003 01:32:00 +0000 Subject: [PATCH 1038/1042] - fixed default arguments in virtual methods [SVN r17823] --- pyste/src/ClassExporter.py | 372 +++++++++++++++++++--------------- pyste/src/FunctionExporter.py | 4 + 2 files changed, 209 insertions(+), 167 deletions(-) diff --git a/pyste/src/ClassExporter.py b/pyste/src/ClassExporter.py index d72ff9db..64bf3834 100644 --- a/pyste/src/ClassExporter.py +++ b/pyste/src/ClassExporter.py @@ -34,12 +34,9 @@ class ClassExporter(Exporter): # declarations: outside the BOOST_PYTHON_MODULE macro self.sections['declaration'] = [] self.sections['include'] = [] - # a list of Method instances - self.methods = [] # a list of Constructor instances self.constructors = [] - # a dict of methodname => _WrapperVirtualMethod instances - self.virtual_wrappers = {} + self.wrapper_generator = None # a list of code units, generated by nested declarations self.nested_codeunits = [] @@ -83,13 +80,12 @@ class ClassExporter(Exporter): def Export(self, codeunit, exported_names): - self.GetMethods() self.ExportBasics() self.ExportBases(exported_names) self.ExportConstructors() self.ExportVariables() self.ExportMethods() - self.GenerateVirtualWrapper() + self.ExportVirtualMethods() self.ExportOperators() self.ExportNestedClasses(exported_names) self.ExportNestedEnums() @@ -151,7 +147,7 @@ class ClassExporter(Exporter): def Add(self, section, item): 'Add the item into the corresponding section' - self.sections[section].append(item.strip()) + self.sections[section].append(item) def ExportBasics(self): @@ -203,8 +199,14 @@ class ClassExporter(Exporter): # declare no_init self.Add('constructor', py_ns + 'no_init') else: - # write one of the constructors to the class_ constructor - self.Add('constructor', init_code(constructors.pop(0))) + # write the constructor with less parameters to the constructor section + smaller = None + for cons in constructors: + if smaller is None or len(cons.parameters) < len(smaller.parameters): + smaller = cons + assert smaller is not None + self.Add('constructor', init_code(smaller)) + constructors.remove(smaller) # write the rest to the inside section, using def() for cons in constructors: code = '.def(%s)' % init_code(cons) @@ -234,18 +236,6 @@ class ClassExporter(Exporter): self.Add('inside', code) - def GetMethods(self): - 'fill self.methods with a list of Method instances' - # get a list of all methods - def IsValid(m): - 'Returns true if the given method is exportable by this routine' - ignore = (Constructor, ClassOperator, Destructor) - return isinstance(m, Method) and not isinstance(m, ignore) - - self.methods = [x for x in self.public_members if IsValid(x)] - - - printed_policy_warnings = {} def CheckPolicy(self, m): @@ -265,25 +255,22 @@ class ClassExporter(Exporter): def ExportMethods(self): - 'Export all the methods of the class' + 'Export all the non-virtual methods of this class' def OverloadName(m): - 'Returns the name of the overloads struct for the given method' - + 'Returns the name of the overloads struct for the given method' return _ID(m.FullName()) + ('_overloads_%i_%i' % (m.minArgs, m.maxArgs)) declared = {} def DeclareOverloads(m): 'Declares the macro for the generation of the overloads' - if m.virtual: - func = self.virtual_wrappers[m.PointerDeclaration()].DefaultName() - else: + if not m.virtual: func = m.name - code = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(%s, %s, %i, %i)\n' - code = code % (OverloadName(m), func, m.minArgs, m.maxArgs) - if code not in declared: - declared[code] = True - self.Add('declaration', code) + code = 'BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(%s, %s, %i, %i)\n' + code = code % (OverloadName(m), func, m.minArgs, m.maxArgs) + if code not in declared: + declared[code] = True + self.Add('declaration', code) def Pointer(m): @@ -292,9 +279,6 @@ class ClassExporter(Exporter): wrapper = self.info[method.name].wrapper if wrapper: return '&' + wrapper.FullName() - # if this method is virtual, return the pointers to the class and its wrapper - if m.virtual: - return self.virtual_wrappers[m.PointerDeclaration()].Pointer() # return normal pointers to the methods of the class is_unique = self.class_.IsUnique(m.name) if is_unique: @@ -302,19 +286,19 @@ class ClassExporter(Exporter): else: return method.PointerDeclaration() - - for method in self.methods: + def IsExportable(m): + 'Returns true if the given method is exportable by this routine' + ignore = (Constructor, ClassOperator, Destructor) + return isinstance(m, Method) and not isinstance(m, ignore) and not m.virtual + + methods = [x for x in self.public_members if IsExportable(x)] + + for method in methods: if self.info[method.name].exclude: continue # skip this method name = self.info[method.name].rename or method.name - # check if this method needs to be wrapped as a virtual method - if method.virtual: - wrapper = _WrapperVirtualMethod(self.class_, method, name) - self.virtual_wrappers[method.PointerDeclaration()] = wrapper - # abstract methods don't need to be exported - if method.abstract: - continue # skip .def declaration for abstract methods + # warn the user if this method needs a policy and doesn't have one self.CheckPolicy(method) @@ -328,15 +312,9 @@ class ClassExporter(Exporter): # add the overloads for this method overload_name = OverloadName(method) DeclareOverloads(method) - if not method.virtual: - overload = ', %s%s()' % (namespaces.pyste, overload_name) - else: - pyste_ns = namespaces.pyste - pointer = self.virtual_wrappers[method.PointerDeclaration()].DefaultPointer() - defcode = '.def("%s", %s, %s%s())' % \ - (name, pointer, pyste_ns, overload_name) - self.Add('inside', defcode) - # build the string to export the method + overload = ', %s%s()' % (namespaces.pyste, overload_name) + + # build the .def string to export the method pointer = Pointer(method) code = '.def("%s", %s' % (name, pointer) code += policy @@ -353,38 +331,21 @@ class ClassExporter(Exporter): self.Add('declaration', wrapper.code) - def GenerateVirtualWrapper(self): - 'Generate the wrapper to dispatch virtual methods' - # check if this class needs a wrapper first - for m in self.methods: - if m.virtual: + def ExportVirtualMethods(self): + # check if this class has any virtual methods + has_virtual_methods = False + for member in self.class_.members: + if type(member) == Method and member.virtual: + has_virtual_methods = True break - else: - return - # add the wrapper name to the template section - wrapper_name = _WrapperName(self.class_) - self.Add('template', namespaces.pyste + wrapper_name) - indent = self.INDENT - method_codes = [x.Code(indent) for x in self.virtual_wrappers.values()] - body = '\n'.join(method_codes) - # generate the class code - class_name = self.class_.FullName() - code = 'struct %s: %s\n' % (wrapper_name, class_name) - code += '{\n' - # generate constructors - for cons in self.constructors: - params, param_names, param_types = _ParamsInfo(cons) - if params: - params = ', ' + params - cons_code = indent + '%s(PyObject* self_%s):\n' % (wrapper_name, params) - cons_code += indent*2 + '%s(%s), self(self_) {}\n\n' % \ - (class_name, ', '.join(param_names)) - code += cons_code - code += body + '\n' - code += indent + 'PyObject* self;\n' - code += '};\n' - self.Add('declaration', code) + if has_virtual_methods: + generator = _VirtualWrapperGenerator(self.class_, self.info) + self.Add('template', generator.FullName()) + for definition in generator.GenerateDefinitions(): + self.Add('inside', definition) + self.Add('declaration', generator.GenerateVirtualWrapper(self.INDENT)) + # operators natively supported by boost BOOST_SUPPORTED_OPERATORS = '+ - * / % ^ & ! ~ | < > == != <= >= << >> && || += -='\ @@ -585,104 +546,181 @@ def _ID(name): # Virtual Wrapper utils #============================================================================== -def _WrapperName(class_): - return _ID(class_.FullName()) + '_Wrapper' - - -def _ParamsInfo(m): - param_names = ['p%i' % i for i in range(len(m.parameters))] - param_types = [x.FullName() for x in m.parameters] +def _ParamsInfo(m, count=None): + if count is None: + count = len(m.parameters) + param_names = ['p%i' % i for i in range(count)] + param_types = [x.FullName() for x in m.parameters[:count]] params = ['%s %s' % (t, n) for t, n in zip(param_types, param_names)] - for i, p in enumerate(m.parameters): - if p.default is not None: - #params[i] += '=%s' % p.default - params[i] += '=%s' % (p.name + '()') + #for i, p in enumerate(m.parameters[:count]): + # if p.default is not None: + # #params[i] += '=%s' % p.default + # params[i] += '=%s' % (p.name + '()') params = ', '.join(params) return params, param_names, param_types -class _WrapperVirtualMethod(object): - 'Holds information about a virtual method that will be wrapped' +class _VirtualWrapperGenerator(object): + 'Generates code to export the virtual methods of the given class' - def __init__(self, class_, method, rename): - self.method = method - if rename is None: - rename = method.name - self.rename = rename + def __init__(self, class_, info): self.class_ = class_ + self.info = info + self.wrapper_name = _ID(class_.FullName()) + '_Wrapper' - def DefaultName(self): - return 'default_' + self.method.name - - - def DefaultPointer(self): - ns = namespaces.pyste - wrapper_name = _WrapperName(self.class_) - default_name = self.DefaultName() - fullname = '%s%s::%s' % (ns, wrapper_name, default_name) - if self.class_.IsUnique(self.method.name): - return '&%s' % fullname + def DefaultImplementationNames(self, method): + '''Returns a list of default implementations for this method, one for each + number of default arguments. Always returns at least one name, and return from + the one with most arguments to the one with the least. + ''' + base_name = 'default_' + method.name + minArgs = method.minArgs + maxArgs = method.maxArgs + if minArgs == maxArgs: + return [base_name] else: - # the method is not unique, so we must specify the entire signature with it - param_list = [x.FullName() for x in self.method.parameters] - params = ', '.join(param_list) - result = self.method.result.FullName() - signature = '%s (%s%s::*)(%s)' % (result, ns, wrapper_name, params) - return '(%s)%s' % (signature, fullname) + return [base_name + ('_%i' % i) for i in range(minArgs, maxArgs+1)] + + + def Declaration(self, method, indent): + '''Returns a string with the declarations of the virtual wrapper and + its default implementations. This string must be put inside the Wrapper + body. + ''' + pyste = namespaces.pyste + python = namespaces.python + rename = self.info[method.name].rename or method.name + result = method.result.FullName() + return_str = 'return ' + if result == 'void': + return_str = '' + params, param_names, param_types = _ParamsInfo(method) + constantness = '' + if method.const: + constantness = ' const' + + # call_method callback + decl = indent + '%s %s(%s)%s {\n' % (result, method.name, params, constantness) + param_names_str = ', '.join(param_names) + if param_names_str: + param_names_str = ', ' + param_names_str + decl += indent*2 + '%s%scall_method<%s>(self, "%s"%s);\n' %\ + (return_str, python, result, rename, param_names_str) + decl += indent + '}\n' + + # default implementations (with overloading) + if not method.abstract: + minArgs = method.minArgs + maxArgs = method.maxArgs + impl_names = self.DefaultImplementationNames(method) + for impl_name, argNum in zip(impl_names, range(minArgs, maxArgs+1)): + params, param_names, param_types = _ParamsInfo(method, argNum) + decl += '\n' + decl += indent + '%s %s(%s)%s {\n' % (result, impl_name, params, constantness) + decl += indent*2 + '%s%s::%s(%s);\n' % \ + (return_str, self.class_.FullName(), method.name, ', '.join(param_names)) + decl += indent + '}\n' + return decl - def Pointer(self): - '''Returns the "pointer" declaration for this method, ie, the contents - of the .def after the method name (.def("name", ))''' - ns = namespaces.pyste - default_name = self.DefaultName() - name = self.method.name + def MethodDefinition(self, method): + '''Returns a list of lines, which should be put inside the class_ + statement to export this method.''' + # dont define abstract methods + if method.abstract: + return [] + pyste = namespaces.pyste + rename = self.info[method.name].rename or method.name + default_names = self.DefaultImplementationNames(method) class_name = self.class_.FullName() - wrapper = ns + _WrapperName(self.class_) - if self.class_.IsUnique(self.method.name): - return '&%s::%s, &%s::%s' % (class_name, name, wrapper, default_name) + wrapper_name = pyste + self.wrapper_name + result = method.result.FullName() + is_method_unique = self.class_.IsUnique(method.name) + constantness = '' + if method.const: + constantness = ' const' + + # create a list of default-impl pointers + minArgs = method.minArgs + maxArgs = method.maxArgs + if is_method_unique: + default_pointers = ['&%s::%s' % (wrapper_name, x) for x in default_names] else: - # the method is not unique, so we must specify the entire signature with it - param_list = [x.FullName() for x in self.method.parameters] - params = ', '.join(param_list) - result = self.method.result.FullName() - default_sig = '%s (%s::*)(%s)' % (result, wrapper, params) - normal_sig = '%s (%s::*)(%s)' % (result, class_name, params) - return '(%s)%s::%s, (%s)%s::%s' % \ - (normal_sig, class_name, name, default_sig, wrapper, default_name) + default_pointers = [] + for impl_name, argNum in zip(default_names, range(minArgs, maxArgs+1)): + param_list = [x.FullName() for x in method.parameters[:argNum]] + params = ', '.join(param_list) + signature = '%s (%s::*)(%s)%s' % (result, wrapper_name, params, constantness) + default_pointer = '(%s)%s::%s' % (signature, wrapper_name, impl_name) + default_pointers.append(default_pointer) + + # get the pointer of the method + if is_method_unique: + pointer = '&' + method.FullName() + else: + pointer = method.PointerDeclaration() + # generate the defs + definitions = [] + # basic def + definitions.append('.def("%s", %s, %s)' % (rename, pointer, default_pointers[-1])) + for default_pointer in default_pointers[:-1]: + definitions.append('.def("%s", %s)' % (rename, default_pointer)) + return definitions - def Code(self, indent): - params, param_names, param_types = _ParamsInfo(self.method) - result = self.method.result.FullName() - return_ = 'return ' - if result == 'void': - return_ = '' - param_names = ', '.join(param_names) - class_name = self.class_.FullName() - method_name = self.method.name - default_name = self.DefaultName() - # constantness - const = '' - if self.method.const: - const = 'const ' - code = '' - # create default_method if this method has a default implementation - if not self.method.abstract: - default_sig = '%s %s(%s) %s' % (result, default_name, params, const) - body = '{ %s%s::%s(%s); } ' % \ - (return_, class_name, method_name, param_names) - code += indent + default_sig + body + '\n' - # create normal method - normal_sig = '%s %s(%s) %s' % (result, method_name, params, const) - if param_names: - param_names = ', ' + param_names - body = '{ %s%scall_method< %s >(self, "%s"%s); }' % \ - (return_, namespaces.python, result, self.rename, param_names) - code += indent + normal_sig + body + '\n' - - return code - - + def FullName(self): + return namespaces.pyste + self.wrapper_name + + + def VirtualMethods(self): + return [m for m in self.class_.members if type(m) == Method and m.virtual] + + + def Constructors(self): + return [m for m in self.class_.members if isinstance(m, Constructor)] + + + def GenerateDefinitions(self): + defs = [] + for method in self.VirtualMethods(): + if not self.info[method.name].exclude: + defs.extend(self.MethodDefinition(method)) + return defs + + + def GenerateVirtualWrapper(self, indent): + 'Return the wrapper for this class' + + # generate the class code + class_name = self.class_.FullName() + code = 'struct %s: %s\n' % (self.wrapper_name, class_name) + code += '{\n' + # generate constructors (with the overloads for each one) + for cons in self.Constructors(): + minArgs = cons.minArgs + maxArgs = cons.maxArgs + # from the min number of arguments to the max number, generate + # all version of the given constructor + cons_code = '' + for argNum in range(minArgs, maxArgs+1): + params, param_names, param_types = _ParamsInfo(cons, argNum) + if params: + params = ', ' + params + cons_code += indent + '%s(PyObject* self_%s):\n' % \ + (self.wrapper_name, params) + cons_code += indent*2 + '%s(%s), self(self_) {}\n\n' % \ + (class_name, ', '.join(param_names)) + code += cons_code + # generate the body + body = [] + for method in self.VirtualMethods(): + if not self.info[method.name].exclude: + body.append(self.Declaration(method, indent)) + body = '\n'.join(body) + code += body + '\n' + # add the self member + code += indent + 'PyObject* self;\n' + code += '};\n' + return code diff --git a/pyste/src/FunctionExporter.py b/pyste/src/FunctionExporter.py index 2638a776..60735ca0 100644 --- a/pyste/src/FunctionExporter.py +++ b/pyste/src/FunctionExporter.py @@ -25,7 +25,11 @@ class FunctionExporter(Exporter): def CheckPolicy(self, func): 'Warns the user if this function needs a policy' + def IsString(type): + return type.const and type.name == 'char' and isinstance(type, PointerType) needs_policy = isinstance(func.result, (ReferenceType, PointerType)) + if IsString(func.result): + needs_policy = False if needs_policy and self.info.policy is None: print '---> Error: Function "%s" needs a policy.' % func.FullName() print From bc4feb42b580bbe27222284b1d49494f3253e41d Mon Sep 17 00:00:00 2001 From: Bruno da Silva de Oliveira Date: Wed, 12 Mar 2003 01:32:48 +0000 Subject: [PATCH 1039/1042] - fixed "deepcopy" of infos bug [SVN r17824] --- pyste/src/infos.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pyste/src/infos.py b/pyste/src/infos.py index 3d23537e..ce8334c5 100644 --- a/pyste/src/infos.py +++ b/pyste/src/infos.py @@ -12,18 +12,20 @@ from exporterutils import FunctionWrapper #============================================================================== # DeclarationInfo #============================================================================== -class DeclarationInfo(object): +class DeclarationInfo: def __init__(self, otherInfo=None): self.__infos = {} self.__attributes = {} if otherInfo is not None: - self.__infos = otherInfo.__infos.copy() - self.__attributes = otherInfo.__attributes.copy() + self.__infos = copy.deepcopy(otherInfo.__infos) + self.__attributes = copy.deepcopy(otherInfo.__attributes) def __getitem__(self, name): 'Used to access sub-infos' + if name.startswith('__'): + raise AttributeError default = DeclarationInfo() default._Attribute('name', name) return self.__infos.setdefault(name, default) @@ -61,8 +63,8 @@ class FunctionInfo(DeclarationInfo): #============================================================================== class ClassInfo(DeclarationInfo): - def __init__(self, name, include, tail=None, otherOption=None): - DeclarationInfo.__init__(self, otherOption) + def __init__(self, name, include, tail=None, otherInfo=None): + DeclarationInfo.__init__(self, otherInfo) self._Attribute('name', name) self._Attribute('include', include) # create a ClassExporter From 7d5c453f5986d609b9d10d1f939e567543264ff0 Mon Sep 17 00:00:00 2001 From: Bruno da Silva de Oliveira Date: Wed, 12 Mar 2003 01:39:28 +0000 Subject: [PATCH 1040/1042] no message [SVN r17825] --- pyste/README | 5 +-- pyste/doc/pyste.txt | 4 +-- pyste/doc/running_pyste.html | 4 +-- pyste/example/README | 5 +++ pyste/example/basic.h | 21 +++++++++++++ pyste/example/basic.pyste | 2 ++ pyste/example/enums.h | 18 +++++++++++ pyste/example/enums.pyste | 8 +++++ pyste/example/header_test.h | 23 ++++++++++++++ pyste/example/header_test.pyste | 1 + pyste/example/nested.h | 21 +++++++++++++ pyste/example/nested.pyste | 1 + pyste/example/operator.h | 47 ++++++++++++++++++++++++++++ pyste/example/operator.pyste | 12 +++++++ pyste/example/templates.h | 8 +++++ pyste/example/templates.pyste | 8 +++++ pyste/example/wrappertest.h | 35 +++++++++++++++++++++ pyste/example/wrappertest.pyste | 15 +++++++++ pyste/example/wrappertest_wrappers.h | 26 +++++++++++++++ 19 files changed, 258 insertions(+), 6 deletions(-) create mode 100644 pyste/example/README create mode 100644 pyste/example/basic.h create mode 100644 pyste/example/basic.pyste create mode 100644 pyste/example/enums.h create mode 100644 pyste/example/enums.pyste create mode 100644 pyste/example/header_test.h create mode 100644 pyste/example/header_test.pyste create mode 100644 pyste/example/nested.h create mode 100644 pyste/example/nested.pyste create mode 100644 pyste/example/operator.h create mode 100644 pyste/example/operator.pyste create mode 100644 pyste/example/templates.h create mode 100644 pyste/example/templates.pyste create mode 100644 pyste/example/wrappertest.h create mode 100644 pyste/example/wrappertest.pyste create mode 100644 pyste/example/wrappertest_wrappers.h diff --git a/pyste/README b/pyste/README index c3535a2b..b0cc7d36 100644 --- a/pyste/README +++ b/pyste/README @@ -16,8 +16,9 @@ Thanks ====== - David Abrahams, creator of Boost.Python, for tips on the syntax of the interface -file and support. -- Marcelo Camelo, for design tips and support. + file and support. +- Marcelo Camelo, for design tips, support and inspiration for this project. + Also, the name was his idea. 8) - Brad King, creator of the excellent GCCXML (http://www.gccxml.org) - Fredrik Lundh, creator of the elementtree library (http://effbot.org) diff --git a/pyste/doc/pyste.txt b/pyste/doc/pyste.txt index 65c2cec9..b6fbb281 100644 --- a/pyste/doc/pyste.txt +++ b/pyste/doc/pyste.txt @@ -113,8 +113,8 @@ already be set. You only have to set the paths to other libraries that your code needs, like Boost, for example. Plus, Pyste automatically uses the contents of the environment variable -[^INCLUDE] if it exists. Windows users should run the [^Vcvars32.bat] file, -normally located at: +[^INCLUDE] if it exists. Visual C++ users should run the [^Vcvars32.bat] file, +which for Visual C++ 6 is normally located at: C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat diff --git a/pyste/doc/running_pyste.html b/pyste/doc/running_pyste.html index a67d5812..42834000 100644 --- a/pyste/doc/running_pyste.html +++ b/pyste/doc/running_pyste.html @@ -86,8 +86,8 @@ already be set. You only have to set the paths to other libraries that your code needs, like Boost, for example.

      Plus, Pyste automatically uses the contents of the environment variable -INCLUDE if it exists. Windows users should run the Vcvars32.bat file, -normally located at:

      +INCLUDE if it exists. Visual C++ users should run the Vcvars32.bat file, +which for Visual C++ 6 is normally located at:

           C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat
       
      diff --git a/pyste/example/README b/pyste/example/README new file mode 100644 index 00000000..2f917a4e --- /dev/null +++ b/pyste/example/README @@ -0,0 +1,5 @@ +To use this examples, just execute in the command-line: + +pyste --module= .pyste + +For more information, please refer to the documentation. diff --git a/pyste/example/basic.h b/pyste/example/basic.h new file mode 100644 index 00000000..5a619e72 --- /dev/null +++ b/pyste/example/basic.h @@ -0,0 +1,21 @@ +struct C +{ + virtual int f(int x = 10) + { + return x*2; + } + + int foo(int x=1){ + return x+1; + } +}; + +int call_f(C& c) +{ + return c.f(); +} + +int call_f(C& c, int x) +{ + return c.f(x); +} diff --git a/pyste/example/basic.pyste b/pyste/example/basic.pyste new file mode 100644 index 00000000..a6b4e17b --- /dev/null +++ b/pyste/example/basic.pyste @@ -0,0 +1,2 @@ +Class('C', 'basic.h') +Function('call_f', 'basic.h') diff --git a/pyste/example/enums.h b/pyste/example/enums.h new file mode 100644 index 00000000..440cefd2 --- /dev/null +++ b/pyste/example/enums.h @@ -0,0 +1,18 @@ +namespace test { +enum color { red, blue }; + +struct X +{ + enum choices + { + good = 1, + bad = 2 + }; + + int set(choices c) + { + return (int)c; + } +}; + +} diff --git a/pyste/example/enums.pyste b/pyste/example/enums.pyste new file mode 100644 index 00000000..dd9d7fbc --- /dev/null +++ b/pyste/example/enums.pyste @@ -0,0 +1,8 @@ +color = Enum('test::color', 'enums.h') +rename(color.red, 'Red') +rename(color.blue, 'Blue') +X = Class('test::X', 'enums.h') +rename(X.choices.bad, 'Bad') +rename(X.choices.good, 'Good') +rename(X.choices, 'Choices') + diff --git a/pyste/example/header_test.h b/pyste/example/header_test.h new file mode 100644 index 00000000..d3d60fcc --- /dev/null +++ b/pyste/example/header_test.h @@ -0,0 +1,23 @@ +#include +#include +#include + +enum choice { red, blue }; + +void print_choice(choice c) +{ + std::map choice_map; + choice_map[red] = "red"; + choice_map[blue] = "blue"; + std::cout << "You chose: " << choice_map[c] << std::endl; +} + +struct C +{ + choice c; + + void print_() + { + print_choice(c); + } +}; diff --git a/pyste/example/header_test.pyste b/pyste/example/header_test.pyste new file mode 100644 index 00000000..b0e752ff --- /dev/null +++ b/pyste/example/header_test.pyste @@ -0,0 +1 @@ +AllFromHeader('header_test.h') diff --git a/pyste/example/nested.h b/pyste/example/nested.h new file mode 100644 index 00000000..35804fbb --- /dev/null +++ b/pyste/example/nested.h @@ -0,0 +1,21 @@ + +struct X +{ + struct Y + { + int valueY; + static int staticYValue; + struct Z + { + int valueZ; + }; + }; + + static int staticXValue; + int valueX; +}; + +int X::staticXValue = 10; +int X::Y::staticYValue = 20; + +typedef X Root; diff --git a/pyste/example/nested.pyste b/pyste/example/nested.pyste new file mode 100644 index 00000000..b6291385 --- /dev/null +++ b/pyste/example/nested.pyste @@ -0,0 +1 @@ +Class('Root', 'nested.h') diff --git a/pyste/example/operator.h b/pyste/example/operator.h new file mode 100644 index 00000000..5c07549b --- /dev/null +++ b/pyste/example/operator.h @@ -0,0 +1,47 @@ +#include + + +struct C +{ + static double x; + double value; + + const C operator+(const C other) const + { + C c; + c.value = value + other.value; + return c; + } + operator int() const + { + return value; + } + double operator()() + { + return x; + } + + double operator()(double other) + { + return x + other; + } + + +}; + +double C::x = 10; + +const C operator*(const C& lhs, const C& rhs) +{ + C c; + c.value = lhs.value * rhs.value; + return c; +} + +std::ostream& operator <<( std::ostream& s, const C& c) +{ + std::cout << "here"; + s << "C instance: "; + return s; +} + diff --git a/pyste/example/operator.pyste b/pyste/example/operator.pyste new file mode 100644 index 00000000..ffa5725c --- /dev/null +++ b/pyste/example/operator.pyste @@ -0,0 +1,12 @@ +Include('iostream') +test = Wrapper('sum', +''' +const C sum(const C&, const C&) +{ + std::cout << "sum!" << std::endl; + return C(); +} +''' +) +C = Class('C', 'operator.h') +set_wrapper(C.operator['+'], test) diff --git a/pyste/example/templates.h b/pyste/example/templates.h new file mode 100644 index 00000000..de2afe44 --- /dev/null +++ b/pyste/example/templates.h @@ -0,0 +1,8 @@ + +template +struct Point +{ + X x; + Y y; +}; + diff --git a/pyste/example/templates.pyste b/pyste/example/templates.pyste new file mode 100644 index 00000000..30bef79e --- /dev/null +++ b/pyste/example/templates.pyste @@ -0,0 +1,8 @@ +Point = Template('Point', 'templates.h') +rename(Point.x, 'i') +rename(Point.y, 'j') +IPoint = Point('int double') +FPoint = Point('double int') +rename(IPoint, 'IPoint') +rename(IPoint.x, '_x_') + diff --git a/pyste/example/wrappertest.h b/pyste/example/wrappertest.h new file mode 100644 index 00000000..a75cddcc --- /dev/null +++ b/pyste/example/wrappertest.h @@ -0,0 +1,35 @@ +#ifndef WRAPPER_TEST +#define WRAPPER_TEST + + +#include + +std::vector Range(int count) +{ + std::vector v; + v.reserve(count); + for (int i = 0; i < count; ++i){ + v.push_back(i); + } + return v; +} + + +struct C +{ + C() {} + + std::vector Mul(int value) + { + std::vector res; + res.reserve(value); + std::vector::const_iterator it; + std::vector v(Range(value)); + for (it = v.begin(); it != v.end(); ++it){ + res.push_back(*it * value); + } + return res; + } +}; + +#endif diff --git a/pyste/example/wrappertest.pyste b/pyste/example/wrappertest.pyste new file mode 100644 index 00000000..80c76cda --- /dev/null +++ b/pyste/example/wrappertest.pyste @@ -0,0 +1,15 @@ +Include('wrappertest_wrappers.h') + +f = Function('Range', 'wrappertest.h') +set_wrapper(f, 'RangeWrapper') + +mul = Wrapper('MulWrapper', +''' +list MulWrapper(C& c, int value){ + return VectorToList(c.Mul(value)); +} +''' +) + +C = Class('C', 'wrappertest.h') +set_wrapper(C.Mul, mul) diff --git a/pyste/example/wrappertest_wrappers.h b/pyste/example/wrappertest_wrappers.h new file mode 100644 index 00000000..a45c3671 --- /dev/null +++ b/pyste/example/wrappertest_wrappers.h @@ -0,0 +1,26 @@ +#ifndef WRAPPER_TEST_WRAPPERS +#define WRAPPER_TEST_WRAPPERS + +#include +#include +#include "wrappertest.h" + +using namespace boost::python; + +template +list VectorToList(const std::vector & v) +{ + list res; + std::vector::const_iterator it; + for(it = v.begin(); it != v.end(); ++it){ + res.append(*it); + } + Py_XINCREF(res.ptr()); + return res; +} + +list RangeWrapper(int count){ + return VectorToList(Range(count)); +} + +#endif From f1b7620c9ed5c35b79b5abe229d360ff96ff1fd1 Mon Sep 17 00:00:00 2001 From: Bruno da Silva de Oliveira Date: Wed, 12 Mar 2003 03:42:37 +0000 Subject: [PATCH 1041/1042] no message [SVN r17828] --- pyste/example/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyste/example/README b/pyste/example/README index 2f917a4e..868345b0 100644 --- a/pyste/example/README +++ b/pyste/example/README @@ -1,4 +1,4 @@ -To use this examples, just execute in the command-line: +To use this examples, just execute the command-line: pyste --module= .pyste From f81ca21b22b6a7230d6c153d4b8c6be022a5a6f1 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 12 Mar 2003 12:47:44 +0000 Subject: [PATCH 1042/1042] opaque pointer conversions from Gottfried.Ganssauge@haufe.de Acknowledgements for all [SVN r17834] --- doc/v2/acknowledgments.html | 30 ++- doc/v2/opaque_pointer_converter.html | 142 +++++++++++ doc/v2/reference.html | 228 ++++++++++++++++++ doc/v2/return_opaque_pointer.html | 189 +++++++++++++++ include/boost/python.hpp | 2 + .../boost/python/opaque_pointer_converter.hpp | 124 ++++++++++ .../boost/python/return_opaque_pointer.hpp | 46 ++++ test/Jamfile | 2 + test/opaque.cpp | 75 ++++++ test/opaque.py | 72 ++++++ 10 files changed, 900 insertions(+), 10 deletions(-) create mode 100644 doc/v2/opaque_pointer_converter.html create mode 100644 doc/v2/return_opaque_pointer.html create mode 100644 include/boost/python/opaque_pointer_converter.hpp create mode 100644 include/boost/python/return_opaque_pointer.hpp create mode 100644 test/opaque.cpp create mode 100644 test/opaque.py diff --git a/doc/v2/acknowledgments.html b/doc/v2/acknowledgments.html index 82cea6a2..3cc24edb 100644 --- a/doc/v2/acknowledgments.html +++ b/doc/v2/acknowledgments.html @@ -31,6 +31,15 @@

      Dave Abrahams is the architect, designer, and implementor of Boost.Python.

      +

      Brett Calcott + contributed and maintains the Visual Studio project files and + documentation.

      + +

      Gottfried + Ganßauge supplied support for opaque pointer conversions, + complete with documentation and a regression test (and I didn't + even have to ask him for those)! +

      Joel de Guzman implemented the default argument support and wrote the excellent tutorial documentation.

      @@ -63,6 +72,17 @@ use the new preproccessor metaprogramming constructs and helping us to work around buggy and slow C++ preprocessors.

      +

      Bruno da Silva de + Oliveira contributed the ingenious Pyste ("Pie-Steh") + code generator. + +

      Nikolay Mladenov contributed + staticmethod support.

      + +

      Martin Casado solved some sticky problems which allow us to build the + Boost.Python shared library for AIX's crazy dynamic linking model.

      +

      Achim Domma contributed some of the Object Wrappers and HTML templates for this documentation. Dave Hawkes contributed @@ -71,16 +91,6 @@ definition syntax. Pearu Pearson wrote some of the test cases that are in the current test suite.

      -

      Brett Calcott - contributed and maintains the Visual Studio project files and - documentation.

      - -

      Nikolay Mladenov contributed - staticmethod support.

      - -

      Martin Casado solved some sticky problems which allow us to build the - Boost.Python shared library for AIX's crazy dynamic linking model.

      -

      The development of this version of Boost.Python was funded in part by the Lawrence Livermore National Laboratories and by the Computational diff --git a/doc/v2/opaque_pointer_converter.html b/doc/v2/opaque_pointer_converter.html new file mode 100644 index 00000000..61dbb531 --- /dev/null +++ b/doc/v2/opaque_pointer_converter.html @@ -0,0 +1,142 @@ + + + + + + + + Boost.Python - <boost/python/opaque_pointer_converter.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header + <boost/python/opaque_pointer_converter.hpp>

      +
      +


      + +

      Contents

      + +
      +
      Classes
      + +
      +
      +
      Class template + opaque_pointer_converter<P>
      + +
      +
      +
      Class template + opaque_pointer_converter synopsis
      +
      +
      +
      +
      + +
      Macros
      +
      +
      +
      Macro + BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID
      +
      +
      + +
      Example
      + +
      See Also
      +
      +
      + +

      Classes

      + +

      Class template + opaque_pointer_converter<P>

      + +

      opaque_pointer_converter<> is derived from + + to_python_converter + and registers itself as an + + lvalue_from_pytype converter from Python objects + into pointers to undefined types. + Thus it may be used as a converter from opaque pointers into + Python objects and vice versa.

      + +

      Class template + opaque_pointer_converter synopsis

      +
      +namespace boost { namespace python
      +{
      +    template<class Pointer>
      +    struct opaque_pointer_converter
      +        : to_python_converter<
      +          Pointer, opaque_pointer_converter<Pointer> >
      +    {
      +        explicit opaque_pointer_converter(char const* name);
      +    };
      +}}
      +
      + +

      Class template + opaque_pointer_converter constructor

      +
      +explicit opaque_pointer_converter(char const* name);
      +
      + +
      +
      Effects: +

      Registers the instance as a + + lvalue_from_pytype converter from Python objects + into opaque pointers.

      +

      The name is used for the type of the Python Objects created; + it should be printable but needn't be an + ntbs because the object type is + not supposed to be user constructible within python scripts.

      +
      +
      + +

      Macros

      + +

      + Macro BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee)

      +

      This macro must be used to define specializations of the + type_id function + which can't be instantiated for incomplete types.

      +

      Note

      +

      In order for this to work in a cross-module environment the macro must + be invoked in every translation unit which uses the + opaque_pointer_converter.

      + +

      Example

      + + please see example for + return_opaque_pointer. + +

      See Also

      +

      + return_opaque_pointer +

      + +

      Revised + 10 March, 2003 +

      + +

      © Copyright 2003 Haufe Mediengruppe. All Rights + Reserved.

      + + + diff --git a/doc/v2/reference.html b/doc/v2/reference.html index ae2ec560..22245385 100644 --- a/doc/v2/reference.html +++ b/doc/v2/reference.html @@ -749,6 +749,96 @@ + +
      return_opaque_pointer.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + return_opaque_pointer
      +
      +
      +
      +
      + +
      return_opaque_pointer.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + return_opaque_pointer
      +
      +
      +
      +
      + +
      return_opaque_pointer.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + return_opaque_pointer
      +
      +
      +
      +
      + +
      return_opaque_pointer.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + return_opaque_pointer
      +
      +
      +
      +
      + +
      return_opaque_pointer.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + return_opaque_pointer
      +
      +
      +
      +
      + +
      return_opaque_pointer.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + return_opaque_pointer
      +
      +
      +
      +
      @@ -806,6 +896,144 @@ +
      opaque_pointer_converter.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + opaque_pointer_converter
      +
      +
      +
      Macros
      + +
      +
      +
      + BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID
      +
      +
      +
      +
      + +
      opaque_pointer_converter.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + opaque_pointer_converter
      +
      +
      +
      Macros
      + +
      +
      +
      + BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID
      +
      +
      +
      +
      + +
      opaque_pointer_converter.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + opaque_pointer_converter
      +
      +
      +
      Macros
      + +
      +
      +
      + BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID
      +
      +
      +
      +
      + +
      opaque_pointer_converter.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + opaque_pointer_converter
      +
      +
      +
      Macros
      + +
      +
      +
      + BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID
      +
      +
      +
      +
      + +
      opaque_pointer_converter.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + opaque_pointer_converter
      +
      +
      +
      Macros
      + +
      +
      +
      + BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID
      +
      +
      +
      +
      + +
      opaque_pointer_converter.hpp
      + +
      +
      +
      Classes
      + +
      +
      +
      + opaque_pointer_converter
      +
      +
      +
      Macros
      + +
      +
      +
      + BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID
      +
      +
      +
      +
      +
      to_python_converter.hpp
      diff --git a/doc/v2/return_opaque_pointer.html b/doc/v2/return_opaque_pointer.html new file mode 100644 index 00000000..f50b864f --- /dev/null +++ b/doc/v2/return_opaque_pointer.html @@ -0,0 +1,189 @@ + + + + + + + + Boost.Python - <boost/python/return_opaque_pointer.hpp> + + + + + + + + + +
      +

      C++ Boost

      +
      +

      Boost.Python

      + +

      Header + <boost/python/return_opaque_pointer.hpp>

      +
      +
      + +

      Contents

      + +
      +
      Classes
      + +
      +
      +
      Class + return_opaque_pointer
      + +
      +
      +
      Class + return_opaque_pointer synopsis
      + +
      Class + return_opaque_pointer metafunctions
      +
      +
      +
      +
      + +
      Example
      + +
      See Also
      +
      +
      + +

      Classes

      + +

      Class + return_opaque_pointer

      + +

      return_opaque_pointer is a model of + + ResultConverterGenerator + which can be used to wrap C++ functions returning pointers to + undefined types such that the return value is copied into a + new Python object.

      +

      In addition to specifying the return_opaque_pointer + policy the + BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID macro must be + used to define specializations for the + type_id function + on the type pointed to by returned pointer.

      + +

      Class + return_opaque_pointer synopsis

      +
      +namespace boost { namespace python
      +{
      +    struct return_opaque_pointer
      +    {
      +        template <class R> struct apply;
      +    };
      +}}
      +
      + +

      Class + return_opaque_pointer metafunctions

      +
      +template <class R> struct apply
      +
      + +
      +
      Returns: typedef + detail::opaque_conversion_holder<R> + type;
      +
      + +

      Example

      + +

      C++ Module Definition

      +
      +# include <boost/python/return_opaque_pointer.hpp>
      +# include <boost/python/def.hpp>
      +# include <boost/python/module.hpp>
      +# include <boost/python/return_value_policy.hpp>
      +
      +typedef struct opaque_ *opaque;
      +
      +opaque the_op   = ((opaque) 0x47110815);
      +
      +opaque get () { return the_op; }
      +void use (opaque op) {
      +    if (op != the_op)
      +	throw std::runtime_error (std::string ("failed"));
      +}
      +
      +void failuse (opaque op) {
      +    if (op == the_op)
      +	throw std::runtime_error (std::string ("success"));
      +}
      +
      +BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_)
      +
      +namespace bpl = boost::python;
      +
      +BOOST_PYTHON_MODULE(opaque_ext)
      +{
      +    bpl::def (
      +        "get", &::get, bpl::return_value_policy<bpl::return_opaque_pointer>());
      +    bpl::def ("use", &::use);
      +    bpl::def ("failuse", &::failuse);
      +}
      +
      + +

      Python Code

      +
      +"""
      +>>> from opaque_ext import *
      +>>> #
      +>>> # Check for correct conversion
      +>>> use(get())
      +>>> failuse(get())
      +Traceback (most recent call last):
      +        ...
      +RuntimeError: success
      +>>> #
      +>>> # Check that there is no conversion from integers ...
      +>>> use(0)
      +Traceback (most recent call last):
      +        ...
      +TypeError: bad argument type for built-in operation
      +>>> #
      +>>> # ... and from strings to opaque objects
      +>>> use("")
      +Traceback (most recent call last):
      +        ...
      +TypeError: bad argument type for built-in operation
      +"""
      +def run(args = None):
      +    import sys
      +    import doctest
      +
      +    if args is not None:
      +        sys.argv = args
      +    return doctest.testmod(sys.modules.get(__name__))
      +    
      +if __name__ == '__main__':
      +    print "running..."
      +    import sys
      +    sys.exit(run()[0])
      +
      + +

      See Also

      +

      + + opaque_pointer_converter +

      + +

      Revised + 28 January, 2003 +

      + +

      © Copyright 2003 Haufe Mediengruppe. All Rights + Reserved.

      + + + diff --git a/include/boost/python.hpp b/include/boost/python.hpp index db665d8d..bdca0b2f 100644 --- a/include/boost/python.hpp +++ b/include/boost/python.hpp @@ -44,12 +44,14 @@ # include # include # include +# include # include # include # include # include # include # include +# include # include # include # include diff --git a/include/boost/python/opaque_pointer_converter.hpp b/include/boost/python/opaque_pointer_converter.hpp new file mode 100644 index 00000000..9fd3e84e --- /dev/null +++ b/include/boost/python/opaque_pointer_converter.hpp @@ -0,0 +1,124 @@ +/* + * Generic Conversion of opaque C++-pointers to a Python-Wrapper. + */ +# ifndef OPAQUE_POINTER_CONVERTER_HPP_ +# define OPAQUE_POINTER_CONVERTER_HPP_ +# include +# include +# include +# include +# include + +// opaque_pointer_converter -- +// +// usage: opaque_pointer_converter("name") +// +// registers to- and from- python conversions for a type Pointer, +// and a corresponding Python type called "name". +// +// Note: +// In addition you need to define specializations for type_id +// on the type pointed to by Pointer using +// BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) +// +// For an example see libs/python/test/opaque.cpp +// +namespace boost { namespace python { + namespace detail { + template + struct opaque_pointer_converter_requires_a_pointer_type +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} +# endif + ; + } + +template +struct opaque_pointer_converter + : to_python_converter< + Pointer, opaque_pointer_converter > +{ + BOOST_STATIC_CONSTANT( + bool, ok = is_pointer::value); + + typedef typename mpl::if_c< + ok + , Pointer + , detail::opaque_pointer_converter_requires_a_pointer_type + >::type ptr_type; + + struct instance; + + explicit opaque_pointer_converter(char const* name) + { + type_object.tp_name = const_cast (name); + + lvalue_from_pytype< + opaque_pointer_converter, + &opaque_pointer_converter::type_object + >(); + } + + static PyObject* convert(ptr_type x) + { + PyObject *result = 0; + + if (x != 0) { + instance *o = PyObject_New (instance, &type_object); + + o->x = x; + result = &o->base_; + } else { + result = detail::none(); + } + + return (result); + } + + static typename ::boost::remove_pointer::type& + execute(instance &p_) + { + return *p_.x; + } + +private: + static PyTypeObject type_object; + + // This is a POD so we can use PyObject_Del on it, for example. + struct instance + { + PyObject base_; + ptr_type x; + }; +}; + +template +PyTypeObject opaque_pointer_converter::type_object = +{ + PyObject_HEAD_INIT(NULL) + 0, + 0, + sizeof(typename opaque_pointer_converter::instance), + 0, + ::boost::python::detail::dealloc +}; +}} // namespace boost::python +# ifdef BOOST_MSVC +// MSC works without this workaround, but needs another one ... +# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \ +BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(Pointee) +# else +# define BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(Pointee) \ +namespace boost { namespace python { \ + template<> \ + inline type_info type_id(boost::type*) { \ + return type_info (typeid (Pointee *)); \ + } \ + template<> \ + inline type_info type_id( \ + boost::type*) { \ + return type_info (typeid (Pointee *)); \ + } \ +}} +# endif +# endif // OPAQUE_POINTER_CONVERTER_HPP_ diff --git a/include/boost/python/return_opaque_pointer.hpp b/include/boost/python/return_opaque_pointer.hpp new file mode 100644 index 00000000..863c92bf --- /dev/null +++ b/include/boost/python/return_opaque_pointer.hpp @@ -0,0 +1,46 @@ +/* + * Generic Return value converter generator for opaque C++-pointers + */ +# ifndef RETURN_OPAQUE_POINTER_HPP_ +# define RETURN_OPAQUE_POINTER_HPP_ +# include +# include +# include + +namespace boost { namespace python { + namespace detail { + template + struct opaque_conversion_holder { + inline PyObject *operator () (Pointer p) { + static opaque_pointer_converter converter ( + typeid (Pointer).name()); + + return converter.convert(p); + } + }; + + template + struct return_opaque_pointer_requires_a_pointer_type +# if defined(__GNUC__) && __GNUC__ >= 3 || defined(__EDG__) + {} +# endif + ; + } + + struct return_opaque_pointer + { + template + struct apply + { + BOOST_STATIC_CONSTANT( + bool, ok = is_pointer::value); + + typedef typename mpl::if_c< + ok + , detail::opaque_conversion_holder + , detail::return_opaque_pointer_requires_a_pointer_type + >::type type; + }; + }; +}} // namespace boost::python +# endif // RETURN_OPAQUE_POINTER_HPP_ diff --git a/test/Jamfile b/test/Jamfile index 4a5b14d9..1852a2b2 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -124,6 +124,8 @@ bpl-test iterator : iterator.py iterator.cpp input_iterator.cpp ; bpl-test extract ; +bpl-test opaque ; + bpl-test pickle1 ; bpl-test pickle2 ; bpl-test pickle3 ; diff --git a/test/opaque.cpp b/test/opaque.cpp new file mode 100644 index 00000000..d5de0a21 --- /dev/null +++ b/test/opaque.cpp @@ -0,0 +1,75 @@ +// Copyright David Abrahams and Gottfried Ganssauge 2003. Permission +// to copy, use, modify, sell and distribute this software is granted +// provided this copyright notice appears in all copies. This software +// is provided "as is" without express or implied warranty, and with +// no claim as to its suitability for any purpose. +# include +# include +# include +# include + +typedef struct opaque_ *opaque; +typedef struct opaque2_ *opaque2; + +opaque the_op = ((opaque) 0x47110815); +opaque2 the_op2 = ((opaque2) 0x08154711); + +opaque get() { return the_op; } + +void use(opaque op) +{ + if (op != the_op) + throw std::runtime_error (std::string ("failed")); +} + +int useany(opaque op) +{ + return op ? 1 : 0; +} + +opaque getnull() +{ + return 0; +} + +void failuse (opaque op) +{ + if (op == the_op) + throw std::runtime_error (std::string ("success")); +} + +opaque2 get2 () { return the_op2; } + +void use2 (opaque2 op) +{ + if (op != the_op2) + throw std::runtime_error (std::string ("failed")); +} + +void failuse2 (opaque2 op) +{ + if (op == the_op2) + throw std::runtime_error (std::string ("success")); +} + +BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) +BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque2_) + +namespace bpl = boost::python; + +BOOST_PYTHON_MODULE(opaque_ext) +{ + bpl::def ( + "get", &::get, bpl::return_value_policy()); + bpl::def ("use", &::use); + bpl::def ("useany", &::useany); + bpl::def ("getnull", &::getnull, bpl::return_value_policy()); + bpl::def ("failuse", &::failuse); + + bpl::def ( + "get2", + &::get2, + bpl::return_value_policy()); + bpl::def ("use2", &::use2); + bpl::def ("failuse2", &::failuse2); +} diff --git a/test/opaque.py b/test/opaque.py new file mode 100644 index 00000000..35aadd53 --- /dev/null +++ b/test/opaque.py @@ -0,0 +1,72 @@ +""" +>>> from opaque_ext import * +>>> # +>>> # Check for correct conversion +>>> use(get()) + +# Check that None is converted to a NULL opaque pointer +>>> useany(get()) +1 +>>> useany(None) +0 + +# check that we don't lose type information by converting NULL opaque +# pointers to None +>>> assert getnull() is None +>>> useany(getnull()) +0 + +>>> failuse(get()) +Traceback (most recent call last): + ... +RuntimeError: success +>>> # +>>> # Check that there is no conversion from integers ... +>>> use(0) +Traceback (most recent call last): + ... +TypeError: bad argument type for built-in operation +>>> # +>>> # ... and from strings to opaque objects +>>> use("") +Traceback (most recent call last): + ... +TypeError: bad argument type for built-in operation +>>> # +>>> # Now check the same for another opaque pointer type +>>> use2(get2()) +>>> failuse2(get2()) +Traceback (most recent call last): + ... +RuntimeError: success +>>> use2(0) +Traceback (most recent call last): + ... +TypeError: bad argument type for built-in operation +>>> use2("") +Traceback (most recent call last): + ... +TypeError: bad argument type for built-in operation +>>> # +>>> # Check that opaque types are distinct +>>> use(get2()) +Traceback (most recent call last): + ... +TypeError: bad argument type for built-in operation +>>> use2(get()) +Traceback (most recent call last): + ... +TypeError: bad argument type for built-in operation +""" +def run(args = None): + import sys + import doctest + + if args is not None: + sys.argv = args + return doctest.testmod(sys.modules.get(__name__)) + +if __name__ == '__main__': + print "running..." + import sys + sys.exit(run()[0])